@jxsuite/parser 4.1.2 → 4.3.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/content.js CHANGED
@@ -80,6 +80,9 @@ function isRef(value) {
80
80
  function isNodeObject(value) {
81
81
  return isJsonObject(value);
82
82
  }
83
+ function isTemplateString(value) {
84
+ return typeof value === "string" && value.includes("${");
85
+ }
83
86
  function isPlainTagName(tagName) {
84
87
  return typeof tagName === "string";
85
88
  }
@@ -332,8 +335,65 @@ function parseComparable(a, b) {
332
335
  function includesValue(items, value) {
333
336
  return items.includes(value);
334
337
  }
338
+ function fieldValue(entry, field) {
339
+ if (field === "id") {
340
+ return entry.id;
341
+ }
342
+ if (!field.includes(".") || Object.hasOwn(entry.data, field)) {
343
+ return entry.data[field];
344
+ }
345
+ let found = [entry.data];
346
+ let crossed = false;
347
+ for (const key of field.split(".")) {
348
+ const next = [];
349
+ for (const value of found) {
350
+ const items = Array.isArray(value) ? value : [value];
351
+ crossed ||= Array.isArray(value);
352
+ for (const item of items) {
353
+ if (isNonNullObject(item) && !Array.isArray(item) && Object.hasOwn(item, key)) {
354
+ next.push(item[key]);
355
+ }
356
+ }
357
+ }
358
+ found = next;
359
+ }
360
+ if (!crossed) {
361
+ return found[0];
362
+ }
363
+ return found.flatMap((value) => Array.isArray(value) ? value : [value]);
364
+ }
365
+ function resolveRuleValue(value, document) {
366
+ if (!isRef(value)) {
367
+ return value;
368
+ }
369
+ const ref = value.$ref;
370
+ if (ref.startsWith("#/$params/")) {
371
+ return document?.route?._pathParams?.[ref.slice("#/$params/".length)];
372
+ }
373
+ if (!ref.startsWith("#/state/")) {
374
+ return value;
375
+ }
376
+ let current = document?.state;
377
+ for (const token of ref.slice("#/state/".length).split("/")) {
378
+ const key = token.replaceAll("~1", "/").replaceAll("~0", "~");
379
+ if (Array.isArray(current) && /^(0|[1-9]\d*)$/.test(key)) {
380
+ current = current[Number(key)];
381
+ } else if (isJsonObject(current) && Object.hasOwn(current, key)) {
382
+ current = current[key];
383
+ } else {
384
+ return;
385
+ }
386
+ }
387
+ return current;
388
+ }
389
+ function filterRules(filter) {
390
+ if (Array.isArray(filter)) {
391
+ return filter;
392
+ }
393
+ return Object.entries(filter).map(([field, value]) => ({ field, op: "==", value }));
394
+ }
335
395
  function evaluateFilterRule(rule, entry) {
336
- const actual = rule.field === "id" ? entry.id : entry.data[rule.field];
396
+ const actual = fieldValue(entry, rule.field);
337
397
  switch (rule.op) {
338
398
  case "==": {
339
399
  return actual === rule.value;
@@ -357,6 +417,9 @@ function evaluateFilterRule(rule, entry) {
357
417
  if (Array.isArray(actual)) {
358
418
  return !includesValue(actual, rule.value);
359
419
  }
420
+ if (actual == null) {
421
+ return true;
422
+ }
360
423
  return isString(actual) && !actual.includes(String(rule.value ?? ""));
361
424
  }
362
425
  case ">": {
@@ -383,26 +446,15 @@ function evaluateFilterRule(rule, entry) {
383
446
  function queryContentType(entries, query = {}) {
384
447
  let result = [...entries];
385
448
  if (query.filter) {
386
- let rules;
387
- if (Array.isArray(query.filter)) {
388
- rules = query.filter;
389
- } else if (isNonNullObject(query.filter)) {
390
- rules = Object.entries(query.filter).map(([field, value]) => ({
391
- field,
392
- op: "==",
393
- value
394
- }));
395
- } else {
396
- rules = [];
397
- }
449
+ const rules = isNonNullObject(query.filter) ? filterRules(query.filter) : [];
398
450
  result = result.filter((entry) => rules.every((rule) => evaluateFilterRule(rule, entry)));
399
451
  }
400
452
  if (query.sort) {
401
453
  const sortRules = Array.isArray(query.sort) ? query.sort : [query.sort];
402
454
  result.sort((a, b) => {
403
455
  for (const { field, order = "asc" } of sortRules) {
404
- const aVal = field === "id" ? a.id : a.data[field] ?? "";
405
- const bVal = field === "id" ? b.id : b.data[field] ?? "";
456
+ const aVal = fieldValue(a, field) ?? "";
457
+ const bVal = fieldValue(b, field) ?? "";
406
458
  if (aVal < bVal) {
407
459
  return order === "asc" ? -1 : 1;
408
460
  }
@@ -429,14 +481,21 @@ class ContentCollection {
429
481
  this.config = config;
430
482
  }
431
483
  async resolve() {
432
- const { contentType, filter, sort, limit, _project } = this.config;
433
- const entries = await entriesOf(_project?.content, contentType ?? "");
434
- if (!entries) {
484
+ const { contentType, filter, sort, limit, _project, _document } = this.config;
485
+ const entries = [];
486
+ for (const type of Array.isArray(contentType) ? contentType : [contentType ?? ""]) {
487
+ entries.push(...await entriesOf(_project?.content, type) ?? []);
488
+ }
489
+ if (entries.length === 0) {
435
490
  return [];
436
491
  }
437
492
  const query = {};
438
- if (filter != null) {
439
- query.filter = filter;
493
+ if (isNonNullObject(filter)) {
494
+ query.filter = filterRules(filter).map((rule) => ({
495
+ field: rule.field,
496
+ op: rule.op,
497
+ value: resolveRuleValue(rule.value, _document)
498
+ }));
440
499
  }
441
500
  if (sort != null) {
442
501
  query.sort = sort;
@@ -505,6 +564,8 @@ export {
505
564
  ContentCollection,
506
565
  ContentEntry,
507
566
  evaluateFilterRule,
567
+ fieldValue,
508
568
  findEntry,
509
- queryContentType
569
+ queryContentType,
570
+ resolveRuleValue
510
571
  };