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