@uniformdev/cli 20.57.2-alpha.22 → 20.57.2-alpha.23

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.
@@ -1,4 +1,4 @@
1
- import { C as CLIConfiguration, E as EntityTypes } from './index-Cs_pXOjF.mjs';
1
+ import { C as CLIConfiguration, E as EntityTypes } from './index-DlNAs61A.mjs';
2
2
 
3
3
  type UniformConfigAllOptions = {
4
4
  /**
@@ -12,21 +12,22 @@ type EntityConfigurationBase = {
12
12
  format?: SyncFileFormat;
13
13
  disabled?: true;
14
14
  };
15
+ type EntityFilterCriteriaConfig = {
16
+ type: 'ids';
17
+ match: string[];
18
+ } | {
19
+ type: 'nameContains';
20
+ match: string;
21
+ };
15
22
  type EntityFilterInclude = {
16
23
  /** If set, only entities matching the criteria will be synced. Cannot be combined with `exclude`. */
17
- include: {
18
- ids?: string[];
19
- namePattern?: string;
20
- };
24
+ include: EntityFilterCriteriaConfig;
21
25
  exclude?: never;
22
26
  };
23
27
  type EntityFilterExclude = {
24
28
  include?: never;
25
29
  /** If set, entities matching the criteria will be excluded from sync. Cannot be combined with `include`. */
26
- exclude: {
27
- ids?: string[];
28
- namePattern?: string;
29
- };
30
+ exclude: EntityFilterCriteriaConfig;
30
31
  };
31
32
  type EntityFilterNone = {
32
33
  include?: never;
package/dist/index.d.mts CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- export { C as CLIConfiguration } from './index-Cs_pXOjF.mjs';
2
+ export { C as CLIConfiguration } from './index-DlNAs61A.mjs';
package/dist/index.mjs CHANGED
@@ -560,68 +560,139 @@ async function createArraySyncEngineDataSource({
560
560
 
561
561
  // src/sync/entityFilter.ts
562
562
  function resolveEntityFilter(entityConfig, operation) {
563
+ if (entityConfig) {
564
+ validateEntityConfig(entityConfig, operation);
565
+ }
563
566
  const directional = entityConfig?.[operation];
564
567
  const resolvedInclude = directional?.include ?? entityConfig?.include;
565
568
  const resolvedExclude = directional?.exclude ?? entityConfig?.exclude;
566
- const includeIds = resolvedInclude?.ids;
567
- const excludeIds = resolvedExclude?.ids;
568
- const includeNamePattern = resolvedInclude?.namePattern;
569
- const excludeNamePattern = resolvedExclude?.namePattern;
570
- const hasInclude = !!(includeIds?.length || includeNamePattern);
571
- const hasExclude = !!(excludeIds?.length || excludeNamePattern);
569
+ const hasInclude = hasCriteria(resolvedInclude);
570
+ const hasExclude = hasCriteria(resolvedExclude);
572
571
  if (hasInclude && hasExclude) {
573
572
  const includeSource = directional?.include ? `${operation}.include` : "include";
574
573
  const excludeSource = directional?.exclude ? `${operation}.exclude` : "exclude";
575
574
  throw new Error(
576
- `Entity filter for '${operation}' resolved both ${includeSource} and ${excludeSource}. Use one or the other. If a top-level filter conflicts with a per-direction filter, set the unwanted direction to { ids: [] } to clear it.`
575
+ `Entity filter for '${operation}' resolved both ${includeSource} and ${excludeSource}. Use one or the other. If a top-level filter conflicts with a per-direction filter, set the unwanted direction to { type: 'ids', match: [] } to clear it.`
577
576
  );
578
577
  }
579
- return createEntityFilter(
580
- { ids: includeIds, namePattern: includeNamePattern },
581
- { ids: excludeIds, namePattern: excludeNamePattern }
582
- );
578
+ return createEntityFilter(resolvedInclude, resolvedExclude);
583
579
  }
584
580
  function createEntityFilter(include, exclude) {
585
- const includeIds = Array.isArray(include) ? include : include?.ids;
586
- const excludeIds = Array.isArray(exclude) ? exclude : exclude?.ids;
587
- const includeNamePattern = Array.isArray(include) ? void 0 : include?.namePattern;
588
- const excludeNamePattern = Array.isArray(exclude) ? void 0 : exclude?.namePattern;
589
- const hasInclude = !!(includeIds?.length || includeNamePattern);
590
- const hasExclude = !!(excludeIds?.length || excludeNamePattern);
581
+ const normalizedInclude = normalizeCriteria(include);
582
+ const normalizedExclude = normalizeCriteria(exclude);
583
+ const hasInclude = hasCriteria(normalizedInclude);
584
+ const hasExclude = hasCriteria(normalizedExclude);
591
585
  if (hasInclude && hasExclude) {
592
586
  throw new Error("Entity filter cannot have both `include` and `exclude` defined. Use one or the other.");
593
587
  }
594
588
  if (!hasInclude && !hasExclude) {
595
589
  return void 0;
596
590
  }
597
- const includeRegex = includeNamePattern ? safeRegex(includeNamePattern) : void 0;
598
- const excludeRegex = excludeNamePattern ? safeRegex(excludeNamePattern) : void 0;
599
591
  if (hasInclude) {
600
- const includeSet = includeIds?.length ? new Set(includeIds) : void 0;
592
+ return buildMatcher(normalizedInclude, true);
593
+ }
594
+ return buildMatcher(normalizedExclude, false);
595
+ }
596
+ function normalizeCriteria(criteria) {
597
+ if (Array.isArray(criteria)) {
598
+ return criteria.length > 0 ? { type: "ids", match: criteria } : void 0;
599
+ }
600
+ return criteria;
601
+ }
602
+ var VALID_FILTER_TYPES = ["ids", "nameContains"];
603
+ var VALID_FILTER_FIELDS = ["include", "exclude"];
604
+ var VALID_DIRECTION_KEYS = ["pull", "push"];
605
+ var VALID_ENTITY_CONFIG_KEYS = /* @__PURE__ */ new Set([...VALID_DIRECTION_KEYS, ...VALID_FILTER_FIELDS]);
606
+ function validateEntityConfig(entityConfig, operation) {
607
+ const validKeysLabel = [...VALID_ENTITY_CONFIG_KEYS].join(", ");
608
+ for (const key of Object.keys(entityConfig)) {
609
+ if (!VALID_ENTITY_CONFIG_KEYS.has(key)) {
610
+ const suggestion = VALID_DIRECTION_KEYS.find((valid) => key.startsWith(valid));
611
+ const hint = suggestion ? ` Did you mean "${suggestion}"?` : "";
612
+ throw new Error(`Unknown entity filter key "${key}".${hint} Valid keys are: ${validKeysLabel}.`);
613
+ }
614
+ }
615
+ const directional = entityConfig[operation];
616
+ if (directional && typeof directional === "object") {
617
+ const validFilterLabel = VALID_FILTER_FIELDS.join(", ");
618
+ for (const key of Object.keys(directional)) {
619
+ if (!VALID_FILTER_FIELDS.includes(key)) {
620
+ throw new Error(
621
+ `Unknown key "${key}" in ${operation} filter config. Valid keys are: ${validFilterLabel}.`
622
+ );
623
+ }
624
+ }
625
+ }
626
+ for (const field of VALID_FILTER_FIELDS) {
627
+ validateFilterValue(entityConfig[field], field);
628
+ }
629
+ if (directional && typeof directional === "object") {
630
+ for (const field of VALID_FILTER_FIELDS) {
631
+ validateFilterValue(directional[field], `${operation}.${field}`);
632
+ }
633
+ }
634
+ }
635
+ function validateFilterValue(value, label) {
636
+ if (value === void 0 || value === null) {
637
+ return;
638
+ }
639
+ if (typeof value === "string") {
640
+ throw new Error(
641
+ `"${label}" must be an object like { type: 'nameContains', match: '${value}' }, not a plain string.`
642
+ );
643
+ }
644
+ if (Array.isArray(value)) {
645
+ throw new Error(`"${label}" must be an object like { type: 'ids', match: [...] }, not a plain array.`);
646
+ }
647
+ if (typeof value !== "object") {
648
+ throw new Error(`"${label}" must be an object with "type" and "match" fields, but got ${typeof value}.`);
649
+ }
650
+ const criteria = value;
651
+ if (!criteria.type) {
652
+ throw new Error(
653
+ `${label} is missing required "type" field. Expected one of: ${VALID_FILTER_TYPES.join(", ")}.`
654
+ );
655
+ }
656
+ if (!VALID_FILTER_TYPES.includes(criteria.type)) {
657
+ throw new Error(
658
+ `${label} has unknown type "${criteria.type}". Expected one of: ${VALID_FILTER_TYPES.join(", ")}.`
659
+ );
660
+ }
661
+ if (criteria.type === "ids" && !Array.isArray(criteria.match)) {
662
+ throw new Error(
663
+ `${label} with type "ids" requires "match" to be a string array, but got ${typeof criteria.match}.`
664
+ );
665
+ }
666
+ if (criteria.type === "nameContains" && typeof criteria.match !== "string") {
667
+ throw new Error(
668
+ `${label} with type "nameContains" requires "match" to be a string, but got ${typeof criteria.match}.`
669
+ );
670
+ }
671
+ }
672
+ function hasCriteria(criteria) {
673
+ if (!criteria) {
674
+ return false;
675
+ }
676
+ if (criteria.type === "ids") {
677
+ return criteria.match.length > 0;
678
+ }
679
+ return criteria.match.length > 0;
680
+ }
681
+ function buildMatcher(criteria, isInclude) {
682
+ if (criteria.type === "ids") {
683
+ const idSet = new Set(criteria.match);
601
684
  return (obj) => {
602
685
  const ids = Array.isArray(obj.id) ? obj.id : [obj.id];
603
- const matchesIds = includeSet ? ids.some((id) => includeSet.has(id)) : true;
604
- const matchesName = includeRegex ? includeRegex.test(obj.displayName ?? "") : true;
605
- return matchesIds && matchesName;
686
+ const matches = ids.some((id) => idSet.has(id));
687
+ return isInclude ? matches : !matches;
606
688
  };
607
689
  }
608
- const excludeSet = excludeIds?.length ? new Set(excludeIds) : void 0;
690
+ const needle = criteria.match.toLowerCase();
609
691
  return (obj) => {
610
- const ids = Array.isArray(obj.id) ? obj.id : [obj.id];
611
- const matchesIds = excludeSet ? ids.some((id) => excludeSet.has(id)) : false;
612
- const matchesName = excludeRegex ? excludeRegex.test(obj.displayName ?? "") : false;
613
- return !(matchesIds || matchesName);
692
+ const matches = (obj.displayName ?? "").toLowerCase().includes(needle);
693
+ return isInclude ? matches : !matches;
614
694
  };
615
695
  }
616
- function safeRegex(pattern) {
617
- try {
618
- return new RegExp(pattern);
619
- } catch {
620
- throw new Error(
621
- `Invalid namePattern regex: "${pattern}". Provide a valid JavaScript regular expression.`
622
- );
623
- }
624
- }
625
696
 
626
697
  // src/sync/fileSyncEngineDataSource.ts
627
698
  import { red } from "colorette";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniformdev/cli",
3
- "version": "20.57.2-alpha.22+a76473d7ee",
3
+ "version": "20.57.2-alpha.23+75d5946be1",
4
4
  "description": "Uniform command line interface tool",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "main": "./cli.js",
@@ -28,13 +28,13 @@
28
28
  "dependencies": {
29
29
  "@inquirer/prompts": "^7.10.1",
30
30
  "@thi.ng/mime": "^2.2.23",
31
- "@uniformdev/assets": "20.57.2-alpha.22+a76473d7ee",
32
- "@uniformdev/canvas": "20.57.2-alpha.22+a76473d7ee",
33
- "@uniformdev/context": "20.57.2-alpha.22+a76473d7ee",
34
- "@uniformdev/files": "20.57.2-alpha.22+a76473d7ee",
35
- "@uniformdev/project-map": "20.57.2-alpha.22+a76473d7ee",
36
- "@uniformdev/redirect": "20.57.2-alpha.22+a76473d7ee",
37
- "@uniformdev/richtext": "20.57.2-alpha.22+a76473d7ee",
31
+ "@uniformdev/assets": "20.57.2-alpha.23+75d5946be1",
32
+ "@uniformdev/canvas": "20.57.2-alpha.23+75d5946be1",
33
+ "@uniformdev/context": "20.57.2-alpha.23+75d5946be1",
34
+ "@uniformdev/files": "20.57.2-alpha.23+75d5946be1",
35
+ "@uniformdev/project-map": "20.57.2-alpha.23+75d5946be1",
36
+ "@uniformdev/redirect": "20.57.2-alpha.23+75d5946be1",
37
+ "@uniformdev/richtext": "20.57.2-alpha.23+75d5946be1",
38
38
  "call-bind": "^1.0.2",
39
39
  "colorette": "2.0.20",
40
40
  "cosmiconfig": "9.0.0",
@@ -81,5 +81,5 @@
81
81
  "publishConfig": {
82
82
  "access": "public"
83
83
  },
84
- "gitHead": "a76473d7ee17e2c8745b1f240d670afb90108f36"
84
+ "gitHead": "75d5946be1860adc22df527dd84b2d553dd61f54"
85
85
  }