@optique/core 1.4.0-dev.2957 → 1.4.0-dev.2962

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.
@@ -562,9 +562,21 @@ const fileSuggestionTypes = new Set([
562
562
  "directory",
563
563
  "any"
564
564
  ]);
565
+ function isOptionalOfType(item, key, check) {
566
+ const value = Reflect.get(item, key);
567
+ return value === void 0 || check(value);
568
+ }
569
+ function isString(value) {
570
+ return typeof value === "string";
571
+ }
572
+ function isStringArray(value) {
573
+ return Array.isArray(value) && value.every(isString);
574
+ }
565
575
  /**
566
- * Screens a provider item for the required `Suggestion` fields. This is basic
567
- * shape checking, not full validation; optional fields are trusted.
576
+ * Screens a provider item for the `Suggestion` fields that completion encoding
577
+ * relies on: required fields and the types of optional ones. This is shape
578
+ * checking, not full validation; message terms inside a description are
579
+ * trusted.
568
580
  */
569
581
  function screenSuggestionInput(item) {
570
582
  if (typeof item === "string") return {
@@ -572,8 +584,9 @@ function screenSuggestionInput(item) {
572
584
  text: item
573
585
  };
574
586
  if (item == null || typeof item !== "object" || !("kind" in item)) return void 0;
587
+ if (!isOptionalOfType(item, "description", Array.isArray)) return void 0;
575
588
  if (item.kind === "literal") return "text" in item && typeof item.text === "string" ? item : void 0;
576
- if (item.kind === "file") return "type" in item && fileSuggestionTypes.has(item.type) ? item : void 0;
589
+ if (item.kind === "file") return "type" in item && fileSuggestionTypes.has(item.type) && isOptionalOfType(item, "pattern", isString) && isOptionalOfType(item, "prefix", isString) && isOptionalOfType(item, "extensions", isStringArray) && isOptionalOfType(item, "includeHidden", (value) => typeof value === "boolean") ? item : void 0;
577
590
  return void 0;
578
591
  }
579
592
  function createSuggestionProcessors(prefix, filterByPrefix) {
@@ -620,6 +633,7 @@ function* guardedSuggestions(getSource, process) {
620
633
  let suggestion;
621
634
  try {
622
635
  const step = iterator.next();
636
+ if (!isObjectLike(step)) return;
623
637
  if (step.done) {
624
638
  finished = true;
625
639
  return;
@@ -649,6 +663,7 @@ async function* guardedSuggestionsAsync(getSource, process) {
649
663
  let suggestion;
650
664
  try {
651
665
  const step = await iterator.next();
666
+ if (!isObjectLike(step)) return;
652
667
  if (step.done) {
653
668
  finished = true;
654
669
  return;
@@ -562,9 +562,21 @@ const fileSuggestionTypes = new Set([
562
562
  "directory",
563
563
  "any"
564
564
  ]);
565
+ function isOptionalOfType(item, key, check) {
566
+ const value = Reflect.get(item, key);
567
+ return value === void 0 || check(value);
568
+ }
569
+ function isString(value) {
570
+ return typeof value === "string";
571
+ }
572
+ function isStringArray(value) {
573
+ return Array.isArray(value) && value.every(isString);
574
+ }
565
575
  /**
566
- * Screens a provider item for the required `Suggestion` fields. This is basic
567
- * shape checking, not full validation; optional fields are trusted.
576
+ * Screens a provider item for the `Suggestion` fields that completion encoding
577
+ * relies on: required fields and the types of optional ones. This is shape
578
+ * checking, not full validation; message terms inside a description are
579
+ * trusted.
568
580
  */
569
581
  function screenSuggestionInput(item) {
570
582
  if (typeof item === "string") return {
@@ -572,8 +584,9 @@ function screenSuggestionInput(item) {
572
584
  text: item
573
585
  };
574
586
  if (item == null || typeof item !== "object" || !("kind" in item)) return void 0;
587
+ if (!isOptionalOfType(item, "description", Array.isArray)) return void 0;
575
588
  if (item.kind === "literal") return "text" in item && typeof item.text === "string" ? item : void 0;
576
- if (item.kind === "file") return "type" in item && fileSuggestionTypes.has(item.type) ? item : void 0;
589
+ if (item.kind === "file") return "type" in item && fileSuggestionTypes.has(item.type) && isOptionalOfType(item, "pattern", isString) && isOptionalOfType(item, "prefix", isString) && isOptionalOfType(item, "extensions", isStringArray) && isOptionalOfType(item, "includeHidden", (value) => typeof value === "boolean") ? item : void 0;
577
590
  return void 0;
578
591
  }
579
592
  function createSuggestionProcessors(prefix, filterByPrefix) {
@@ -620,6 +633,7 @@ function* guardedSuggestions(getSource, process) {
620
633
  let suggestion;
621
634
  try {
622
635
  const step = iterator.next();
636
+ if (!isObjectLike(step)) return;
623
637
  if (step.done) {
624
638
  finished = true;
625
639
  return;
@@ -649,6 +663,7 @@ async function* guardedSuggestionsAsync(getSource, process) {
649
663
  let suggestion;
650
664
  try {
651
665
  const step = await iterator.next();
666
+ if (!isObjectLike(step)) return;
652
667
  if (step.done) {
653
668
  finished = true;
654
669
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "1.4.0-dev.2957",
3
+ "version": "1.4.0-dev.2962",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",
@@ -269,7 +269,7 @@
269
269
  },
270
270
  "sideEffects": false,
271
271
  "devDependencies": {
272
- "@optique/env": "1.4.0-dev.2957+57b3bbe7",
272
+ "@optique/env": "1.4.0-dev.2962+be57ac90",
273
273
  "@types/node": "^24.0.0",
274
274
  "fast-check": "^4.7.0",
275
275
  "tsdown": "^0.13.0",