fixnow 1.0.1 → 2.0.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/fr.d.cts ADDED
@@ -0,0 +1,10 @@
1
+ import { CheckOptions, SpellIssue, BoundChecker, IsCorrectOptions } from './index.cjs';
2
+ export { DEFAULT_PROTECTED_PATTERN, Dictionary, LANGUAGES, LanguageInfo, tokenize } from './index.cjs';
3
+
4
+ declare const checker: BoundChecker;
5
+ declare const check: (text: string, options?: Omit<CheckOptions, "language">) => Promise<SpellIssue[]>;
6
+ declare const suggest: (word: string, max?: number) => Promise<string[]>;
7
+ declare const isCorrect: (word: string, options?: IsCorrectOptions) => Promise<boolean>;
8
+ declare const warmup: () => Promise<void>;
9
+
10
+ export { BoundChecker, CheckOptions, IsCorrectOptions, SpellIssue, check, checker, isCorrect, suggest, warmup };
package/dist/fr.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { CheckOptions, SpellIssue, BoundChecker, IsCorrectOptions } from './index.js';
2
+ export { DEFAULT_PROTECTED_PATTERN, Dictionary, LANGUAGES, LanguageInfo, tokenize } from './index.js';
3
+
4
+ declare const checker: BoundChecker;
5
+ declare const check: (text: string, options?: Omit<CheckOptions, "language">) => Promise<SpellIssue[]>;
6
+ declare const suggest: (word: string, max?: number) => Promise<string[]>;
7
+ declare const isCorrect: (word: string, options?: IsCorrectOptions) => Promise<boolean>;
8
+ declare const warmup: () => Promise<void>;
9
+
10
+ export { BoundChecker, CheckOptions, IsCorrectOptions, SpellIssue, check, checker, isCorrect, suggest, warmup };
package/dist/fr.js ADDED
@@ -0,0 +1,20 @@
1
+ import {
2
+ DEFAULT_PROTECTED_PATTERN,
3
+ LANGUAGES,
4
+ createChecker,
5
+ tokenize
6
+ } from "./chunk-FX7T7BEL.js";
7
+
8
+ // src/entries/fr.ts
9
+ var checker = createChecker("fr");
10
+ var { check, suggest, isCorrect, warmup } = checker;
11
+ export {
12
+ DEFAULT_PROTECTED_PATTERN,
13
+ LANGUAGES,
14
+ check,
15
+ checker,
16
+ isCorrect,
17
+ suggest,
18
+ tokenize,
19
+ warmup
20
+ };
package/dist/index.cjs CHANGED
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
+ DEFAULT_PROTECTED_PATTERN: () => DEFAULT_PROTECTED_PATTERN,
23
24
  LANGUAGES: () => LANGUAGES,
24
25
  SUPPORTED_LANGUAGES: () => SUPPORTED_LANGUAGES,
25
26
  checkText: () => checkText,
@@ -4832,11 +4833,11 @@ function consolidate(root) {
4832
4833
  knownMap.set(orig, n);
4833
4834
  return n;
4834
4835
  }
4835
- function process(n) {
4836
+ function process2(n) {
4836
4837
  if (cached.has(n)) return n;
4837
4838
  if (Object.isFrozen(n)) return knownMap.get(n) || deepCopy(n);
4838
4839
  if (n.c) {
4839
- const children = Object.entries(n.c).sort((a, b) => a[0] < b[0] ? -1 : 1).map(([k, n2]) => [k, process(n2)]);
4840
+ const children = Object.entries(n.c).sort((a, b) => a[0] < b[0] ? -1 : 1).map(([k, n2]) => [k, process2(n2)]);
4840
4841
  n.c = Object.fromEntries(children);
4841
4842
  }
4842
4843
  const sig = signature(n);
@@ -4852,7 +4853,7 @@ function consolidate(root) {
4852
4853
  };
4853
4854
  signatures.set(signature(eow), eow);
4854
4855
  cached.set(eow, count2++);
4855
- return trieNodeToRoot(process(root), root);
4856
+ return trieNodeToRoot(process2(root), root);
4856
4857
  }
4857
4858
  function decodeBTrie(data) {
4858
4859
  return TrieBlob.decodeBin(data);
@@ -5917,7 +5918,9 @@ var TrieDictionary = class {
5917
5918
  return this.trie.suggest(word, { numSuggestions: max2 });
5918
5919
  }
5919
5920
  };
5920
- var cache = /* @__PURE__ */ new Map();
5921
+ var CACHE_SYMBOL = /* @__PURE__ */ Symbol.for("fixnow.dictionaryCache.v2");
5922
+ var globalRegistry = globalThis;
5923
+ var cache = globalRegistry[CACHE_SYMBOL] ?? (globalRegistry[CACHE_SYMBOL] = /* @__PURE__ */ new Map());
5921
5924
  function loadDictionary(language) {
5922
5925
  if (!isSupportedLanguage(language)) {
5923
5926
  return Promise.reject(
@@ -5973,15 +5976,10 @@ var ENCLITICS = [
5973
5976
  ];
5974
5977
  var ACUTE_ACCENT = {
5975
5978
  a: "\xE1",
5976
- // á
5977
5979
  e: "\xE9",
5978
- // é
5979
5980
  i: "\xED",
5980
- // í
5981
5981
  o: "\xF3",
5982
- // ó
5983
5982
  u: "\xFA"
5984
- // ú
5985
5983
  };
5986
5984
  function deaccent(value) {
5987
5985
  return value.normalize("NFD").replace(/[̀-ͯ]/g, "");
@@ -6014,26 +6012,34 @@ function isEncliticVerb(lowerWord, dict) {
6014
6012
  }
6015
6013
  return false;
6016
6014
  }
6017
- function acceptSpanish(word, dict, strict) {
6015
+ function acceptSpanish(word, dict, caseSensitive, acceptAccentOmissions) {
6018
6016
  const lower = word.toLowerCase();
6019
- const inDictionary = strict ? dict.has(word) || dict.has(lower) : dict.has(word) || matchesIgnoringAccents(lower, dict);
6017
+ const inDictionary = caseSensitive ? dict.has(word) || acceptAccentOmissions && word === lower && matchesIgnoringAccents(lower, dict) : acceptAccentOmissions ? dict.has(word) || matchesIgnoringAccents(lower, dict) : dict.has(word) || dict.has(lower);
6020
6018
  return inDictionary || isEncliticVerb(lower, dict);
6021
6019
  }
6022
6020
 
6023
6021
  // src/lang/index.ts
6024
- function isAccepted(word, language, dict, strict) {
6025
- if (language === "es") return acceptSpanish(word, dict, strict);
6026
- return dict.has(word) || dict.has(word.toLowerCase());
6022
+ function isAccepted(word, language, dict, caseSensitive, acceptAccentOmissions) {
6023
+ if (language === "es") return acceptSpanish(word, dict, caseSensitive, acceptAccentOmissions);
6024
+ if (dict.has(word)) return true;
6025
+ if (!caseSensitive && dict.has(word.toLowerCase())) return true;
6026
+ return false;
6027
6027
  }
6028
6028
 
6029
6029
  // src/tokenize.ts
6030
- var PROTECTED_PATTERN = /\[(?:Image|Code|Text) #\d+[^\]\n]*\]|\[Skills? #[^\]\n]+\]|\/skills #\d+|\/skill\b|```[\s\S]*?```|`[^`\n]+`|https?:\/\/[^\s"'`<>]+|[\w.-]+@[\w.-]+\.\w{2,}|(?:\.{1,2}\/|~\/|\/)[^\s"'`<>]+|[A-Za-z]:\\[^\s"'`<>]+|#[0-9a-fA-F]{3,8}\b|\b[A-Z][A-Z0-9_]{1,}\b|(?<!\S)--?[A-Za-z][\w-]*(?:=[^\s"'`<>]+)?|\b(?:@[\w.-]+\/)?[\w.-]+@[\w.-]+\b|\b[\w.-]+\.(?:ts|tsx|js|jsx|mjs|cjs|json|html|css|scss|sass|md|mdx|svg|png|jpg|jpeg|gif|webp|yml|yaml|toml|env|lock)\b|\b[$A-Za-z_][\w$]*(?:[._:$][\w$-]+)+\b/g;
6030
+ var DEFAULT_PROTECTED_PATTERN = /```[\s\S]*?```|`[^`\n]+`|https?:\/\/[^\s"'`<>]+|[\w.-]+@[\w.-]+\.\w{2,}|(?:\.{1,2}\/|~\/|\/)[^\s"'`<>]+|[A-Za-z]:\\[^\s"'`<>]+|#[0-9a-fA-F]{3,8}\b|\b[A-Z][A-Z0-9_]{1,}\b|(?<!\S)--?[A-Za-z][\w-]*(?:=[^\s"'`<>]+)?|\b(?:@[\w.-]+\/)?[\w.-]+@[\w.-]+\b|\b[\w.-]+\.(?:ts|tsx|js|jsx|mjs|cjs|json|html|css|scss|sass|md|mdx|svg|png|jpg|jpeg|gif|webp|yml|yaml|toml|env|lock)\b|\b[$A-Za-z_][\w$]*(?:[._:$][\w$-]+)+\b/g;
6031
6031
  var WORD_PATTERN = /[\p{L}\p{M}]+/gu;
6032
- function* tokenize(text) {
6032
+ function* tokenize(text, protectedSegments) {
6033
6033
  const protectedRanges = [];
6034
- for (const match of text.matchAll(PROTECTED_PATTERN)) {
6035
- const start = match.index ?? 0;
6036
- protectedRanges.push([start, start + match[0].length]);
6034
+ if (protectedSegments !== false) {
6035
+ const patterns = protectedSegments == null ? [DEFAULT_PROTECTED_PATTERN] : Array.isArray(protectedSegments) ? protectedSegments : [protectedSegments];
6036
+ for (const pattern of patterns) {
6037
+ const re = pattern.flags.includes("g") ? pattern : new RegExp(pattern.source, pattern.flags + "g");
6038
+ for (const match of text.matchAll(re)) {
6039
+ const start = match.index ?? 0;
6040
+ protectedRanges.push([start, start + match[0].length]);
6041
+ }
6042
+ }
6037
6043
  }
6038
6044
  const isProtected = (offset) => protectedRanges.some(([start, end]) => offset >= start && offset < end);
6039
6045
  for (const match of text.matchAll(WORD_PATTERN)) {
@@ -6044,16 +6050,15 @@ function* tokenize(text) {
6044
6050
  }
6045
6051
 
6046
6052
  // src/checker.ts
6047
- var DEFAULT_LANGUAGE = "es";
6048
6053
  var DEFAULT_MIN_WORD_LENGTH = 3;
6049
6054
  var DEFAULT_MAX_SUGGESTIONS = 5;
6050
6055
  var MAX_VERDICT_CACHE = 5e3;
6051
6056
  var verdictCache = /* @__PURE__ */ new Map();
6052
- function acceptedVerdict(word, language, strict, dict) {
6053
- const key = `${language}:${strict ? 1 : 0}:${word}`;
6057
+ function acceptedVerdict(word, language, caseSensitive, acceptAccentOmissions, dict) {
6058
+ const key = `${language}:${caseSensitive ? 1 : 0}:${acceptAccentOmissions ? 1 : 0}:${word}`;
6054
6059
  const cached = verdictCache.get(key);
6055
6060
  if (cached !== void 0) return cached;
6056
- const accepted = isAccepted(word, language, dict, strict);
6061
+ const accepted = isAccepted(word, language, dict, caseSensitive, acceptAccentOmissions);
6057
6062
  if (verdictCache.size >= MAX_VERDICT_CACHE) {
6058
6063
  const oldest = verdictCache.keys().next().value;
6059
6064
  if (oldest !== void 0) verdictCache.delete(oldest);
@@ -6061,11 +6066,30 @@ function acceptedVerdict(word, language, strict, dict) {
6061
6066
  verdictCache.set(key, accepted);
6062
6067
  return accepted;
6063
6068
  }
6064
- async function checkText(text, options = {}) {
6069
+ var strictDeprecationWarned = false;
6070
+ function resolveStrictness(options) {
6071
+ let caseSensitive = options.caseSensitive;
6072
+ let acceptAccentOmissions = options.acceptAccentOmissions;
6073
+ if ("strict" in options && options.strict !== void 0) {
6074
+ if (!strictDeprecationWarned && process.env.NODE_ENV !== "production") {
6075
+ console.warn(
6076
+ "[fixnow] `strict` is deprecated; use `caseSensitive` and `acceptAccentOmissions` instead."
6077
+ );
6078
+ strictDeprecationWarned = true;
6079
+ }
6080
+ caseSensitive ??= false;
6081
+ acceptAccentOmissions ??= options.strict === false && options.language === "es";
6082
+ }
6083
+ return {
6084
+ caseSensitive: caseSensitive ?? false,
6085
+ acceptAccentOmissions: acceptAccentOmissions ?? false
6086
+ };
6087
+ }
6088
+ async function checkText(text, options) {
6065
6089
  if (!text || text.trim().length < 2) return [];
6066
- const language = options.language ?? DEFAULT_LANGUAGE;
6090
+ const { language } = options;
6067
6091
  const minWordLength = options.minWordLength ?? DEFAULT_MIN_WORD_LENGTH;
6068
- const strict = options.strict ?? false;
6092
+ const { caseSensitive, acceptAccentOmissions } = resolveStrictness(options);
6069
6093
  const withSuggestions = options.suggestions ?? false;
6070
6094
  const maxSuggestions = options.maxSuggestions ?? DEFAULT_MAX_SUGGESTIONS;
6071
6095
  const ignore = toLowerSet(options.ignoreWords);
@@ -6078,7 +6102,7 @@ async function checkText(text, options = {}) {
6078
6102
  return issue;
6079
6103
  };
6080
6104
  const issues = [];
6081
- for (const { word, offset } of tokenize(text)) {
6105
+ for (const { word, offset } of tokenize(text, options.protectedSegments)) {
6082
6106
  const lower = word.toLowerCase();
6083
6107
  if (ignore?.has(lower)) continue;
6084
6108
  if (isProtectedWord?.(word)) continue;
@@ -6087,14 +6111,15 @@ async function checkText(text, options = {}) {
6087
6111
  continue;
6088
6112
  }
6089
6113
  if (word.length < minWordLength) continue;
6090
- if (acceptedVerdict(word, language, strict, dict)) continue;
6114
+ if (acceptedVerdict(word, language, caseSensitive, acceptAccentOmissions, dict)) continue;
6091
6115
  issues.push(makeIssue(word, offset));
6092
6116
  }
6093
6117
  return issues;
6094
6118
  }
6095
- async function isCorrect(word, language = DEFAULT_LANGUAGE, strict = false) {
6119
+ async function isCorrect(word, language, options = {}) {
6096
6120
  const dict = await loadDictionary(language);
6097
- return acceptedVerdict(word, language, strict, dict);
6121
+ const { caseSensitive, acceptAccentOmissions } = resolveStrictness({ ...options, language });
6122
+ return acceptedVerdict(word, language, caseSensitive, acceptAccentOmissions, dict);
6098
6123
  }
6099
6124
  function toLowerSet(words) {
6100
6125
  if (!words) return void 0;
@@ -6109,16 +6134,17 @@ function createChecker(language) {
6109
6134
  language,
6110
6135
  check: (text, options) => checkText(text, { ...options, language }),
6111
6136
  suggest: async (word, max2 = 5) => (await loadDictionary(language)).suggest(word, max2),
6112
- isCorrect: (word, strict = false) => isCorrect(word, language, strict),
6137
+ isCorrect: (word, options) => isCorrect(word, language, options),
6113
6138
  warmup: () => warmup(language)
6114
6139
  };
6115
6140
  }
6116
- async function suggest(word, options = {}) {
6117
- const dict = await loadDictionary(options.language ?? "es");
6141
+ async function suggest(word, options) {
6142
+ const dict = await loadDictionary(options.language);
6118
6143
  return dict.suggest(word, options.max ?? 5);
6119
6144
  }
6120
6145
  // Annotate the CommonJS export names for ESM import in node:
6121
6146
  0 && (module.exports = {
6147
+ DEFAULT_PROTECTED_PATTERN,
6122
6148
  LANGUAGES,
6123
6149
  SUPPORTED_LANGUAGES,
6124
6150
  checkText,
package/dist/index.d.cts CHANGED
@@ -26,11 +26,19 @@ interface SpellIssue {
26
26
  suggestions?: string[];
27
27
  }
28
28
  interface CheckOptions {
29
- /** Dictionary to check against. Defaults to `'es'`. */
30
- language?: LanguageCode;
29
+ /** Dictionary to check against. Required. */
30
+ language: LanguageCode;
31
+ /** When true, dictionary lookups are case-sensitive. Default: false. */
32
+ caseSensitive?: boolean;
31
33
  /**
32
- * Spanish only: when true, accent omissions (e.g. "codigo" for "código") are
33
- * flagged. When false (default) they are accepted as harmless.
34
+ * Spanish-specific. When true, words missing an acute accent
35
+ * (e.g. "codigo" for "código") are accepted as correct. Default: false.
36
+ * No effect for any other language.
37
+ */
38
+ acceptAccentOmissions?: boolean;
39
+ /**
40
+ * @deprecated Removed in 3.0.0. Use `caseSensitive` and
41
+ * `acceptAccentOmissions` instead.
34
42
  */
35
43
  strict?: boolean;
36
44
  /** Attach correction suggestions to every issue. Defaults to false. */
@@ -49,6 +57,21 @@ interface CheckOptions {
49
57
  flagWords?: Iterable<string>;
50
58
  /** Custom predicate to skip a word before it is checked (e.g. protected terms). */
51
59
  isProtectedWord?: (word: string) => boolean;
60
+ /**
61
+ * Override or disable the protected-segment tokenizer pattern. See
62
+ * `tokenize` for details. Defaults to the bundled default pattern.
63
+ */
64
+ protectedSegments?: RegExp | RegExp[] | false;
65
+ }
66
+ /** Options for `isCorrect` / bound checker `isCorrect`. */
67
+ interface IsCorrectOptions {
68
+ /** When true, dictionary lookups are case-sensitive. Default: false. */
69
+ caseSensitive?: boolean;
70
+ /**
71
+ * Spanish-specific. When true, words missing an acute accent are accepted
72
+ * as correct. Default: false. No effect for any other language.
73
+ */
74
+ acceptAccentOmissions?: boolean;
52
75
  }
53
76
  /** A loaded, decoded dictionary. Membership and suggestion lookups are synchronous. */
54
77
  interface Dictionary {
@@ -59,9 +82,11 @@ interface Dictionary {
59
82
  }
60
83
 
61
84
  /** Finds misspelled words in `text` for the given language. */
62
- declare function checkText(text: string, options?: CheckOptions): Promise<SpellIssue[]>;
85
+ declare function checkText(text: string, options: CheckOptions): Promise<SpellIssue[]>;
63
86
  /** Whether a single word is correctly spelled in the given language. */
64
- declare function isCorrect(word: string, language?: LanguageCode, strict?: boolean): Promise<boolean>;
87
+ declare function isCorrect(word: string, language: LanguageCode, options?: IsCorrectOptions & {
88
+ strict?: boolean;
89
+ }): Promise<boolean>;
65
90
 
66
91
  /** Loads and decodes a language dictionary, caching the result. */
67
92
  declare function loadDictionary(language: LanguageCode): Promise<Dictionary>;
@@ -71,22 +96,32 @@ declare function loadDictionary(language: LanguageCode): Promise<Dictionary>;
71
96
  */
72
97
  declare function warmup(language?: LanguageCode | LanguageCode[]): Promise<void>;
73
98
 
99
+ declare const DEFAULT_PROTECTED_PATTERN: RegExp;
74
100
  interface Token {
75
101
  word: string;
76
102
  offset: number;
77
103
  }
78
104
  /**
79
105
  * Yields candidate words from `text`, skipping anything inside a protected
80
- * segment (code, URLs, paths, acronyms, …).
106
+ * segment.
107
+ *
108
+ * `protectedSegments` controls what is skipped:
109
+ * - `undefined` (default) → the bundled {@link DEFAULT_PROTECTED_PATTERN}.
110
+ * - `RegExp` / `RegExp[]` → use the given patterns instead of the default.
111
+ * Pass `[DEFAULT_PROTECTED_PATTERN, myPattern]` to compose.
112
+ * - `false` → no segment protection at all.
113
+ *
114
+ * Non-global regexes are auto-wrapped with the `g` flag; originals are never
115
+ * mutated.
81
116
  */
82
- declare function tokenize(text: string): Generator<Token>;
117
+ declare function tokenize(text: string, protectedSegments?: RegExp | RegExp[] | false): Generator<Token>;
83
118
 
84
119
  /** A checker bound to a single language, for convenient repeated use. */
85
120
  interface BoundChecker {
86
121
  readonly language: LanguageCode;
87
122
  check(text: string, options?: Omit<CheckOptions, 'language'>): Promise<SpellIssue[]>;
88
123
  suggest(word: string, max?: number): Promise<string[]>;
89
- isCorrect(word: string, strict?: boolean): Promise<boolean>;
124
+ isCorrect(word: string, options?: IsCorrectOptions): Promise<boolean>;
90
125
  warmup(): Promise<void>;
91
126
  }
92
127
  /**
@@ -99,9 +134,9 @@ interface BoundChecker {
99
134
  */
100
135
  declare function createChecker(language: LanguageCode): BoundChecker;
101
136
  /** Correction suggestions for a single word. */
102
- declare function suggest(word: string, options?: {
103
- language?: LanguageCode;
137
+ declare function suggest(word: string, options: {
138
+ language: LanguageCode;
104
139
  max?: number;
105
140
  }): Promise<string[]>;
106
141
 
107
- export { type BoundChecker, type CheckOptions, type Dictionary, LANGUAGES, type LanguageCode, type LanguageInfo, SUPPORTED_LANGUAGES, type SpellIssue, checkText, createChecker, isCorrect, isSupportedLanguage, loadDictionary, suggest, tokenize, warmup };
142
+ export { type BoundChecker, type CheckOptions, DEFAULT_PROTECTED_PATTERN, type Dictionary, type IsCorrectOptions, LANGUAGES, type LanguageCode, type LanguageInfo, SUPPORTED_LANGUAGES, type SpellIssue, checkText, createChecker, isCorrect, isSupportedLanguage, loadDictionary, suggest, tokenize, warmup };
package/dist/index.d.ts CHANGED
@@ -26,11 +26,19 @@ interface SpellIssue {
26
26
  suggestions?: string[];
27
27
  }
28
28
  interface CheckOptions {
29
- /** Dictionary to check against. Defaults to `'es'`. */
30
- language?: LanguageCode;
29
+ /** Dictionary to check against. Required. */
30
+ language: LanguageCode;
31
+ /** When true, dictionary lookups are case-sensitive. Default: false. */
32
+ caseSensitive?: boolean;
31
33
  /**
32
- * Spanish only: when true, accent omissions (e.g. "codigo" for "código") are
33
- * flagged. When false (default) they are accepted as harmless.
34
+ * Spanish-specific. When true, words missing an acute accent
35
+ * (e.g. "codigo" for "código") are accepted as correct. Default: false.
36
+ * No effect for any other language.
37
+ */
38
+ acceptAccentOmissions?: boolean;
39
+ /**
40
+ * @deprecated Removed in 3.0.0. Use `caseSensitive` and
41
+ * `acceptAccentOmissions` instead.
34
42
  */
35
43
  strict?: boolean;
36
44
  /** Attach correction suggestions to every issue. Defaults to false. */
@@ -49,6 +57,21 @@ interface CheckOptions {
49
57
  flagWords?: Iterable<string>;
50
58
  /** Custom predicate to skip a word before it is checked (e.g. protected terms). */
51
59
  isProtectedWord?: (word: string) => boolean;
60
+ /**
61
+ * Override or disable the protected-segment tokenizer pattern. See
62
+ * `tokenize` for details. Defaults to the bundled default pattern.
63
+ */
64
+ protectedSegments?: RegExp | RegExp[] | false;
65
+ }
66
+ /** Options for `isCorrect` / bound checker `isCorrect`. */
67
+ interface IsCorrectOptions {
68
+ /** When true, dictionary lookups are case-sensitive. Default: false. */
69
+ caseSensitive?: boolean;
70
+ /**
71
+ * Spanish-specific. When true, words missing an acute accent are accepted
72
+ * as correct. Default: false. No effect for any other language.
73
+ */
74
+ acceptAccentOmissions?: boolean;
52
75
  }
53
76
  /** A loaded, decoded dictionary. Membership and suggestion lookups are synchronous. */
54
77
  interface Dictionary {
@@ -59,9 +82,11 @@ interface Dictionary {
59
82
  }
60
83
 
61
84
  /** Finds misspelled words in `text` for the given language. */
62
- declare function checkText(text: string, options?: CheckOptions): Promise<SpellIssue[]>;
85
+ declare function checkText(text: string, options: CheckOptions): Promise<SpellIssue[]>;
63
86
  /** Whether a single word is correctly spelled in the given language. */
64
- declare function isCorrect(word: string, language?: LanguageCode, strict?: boolean): Promise<boolean>;
87
+ declare function isCorrect(word: string, language: LanguageCode, options?: IsCorrectOptions & {
88
+ strict?: boolean;
89
+ }): Promise<boolean>;
65
90
 
66
91
  /** Loads and decodes a language dictionary, caching the result. */
67
92
  declare function loadDictionary(language: LanguageCode): Promise<Dictionary>;
@@ -71,22 +96,32 @@ declare function loadDictionary(language: LanguageCode): Promise<Dictionary>;
71
96
  */
72
97
  declare function warmup(language?: LanguageCode | LanguageCode[]): Promise<void>;
73
98
 
99
+ declare const DEFAULT_PROTECTED_PATTERN: RegExp;
74
100
  interface Token {
75
101
  word: string;
76
102
  offset: number;
77
103
  }
78
104
  /**
79
105
  * Yields candidate words from `text`, skipping anything inside a protected
80
- * segment (code, URLs, paths, acronyms, …).
106
+ * segment.
107
+ *
108
+ * `protectedSegments` controls what is skipped:
109
+ * - `undefined` (default) → the bundled {@link DEFAULT_PROTECTED_PATTERN}.
110
+ * - `RegExp` / `RegExp[]` → use the given patterns instead of the default.
111
+ * Pass `[DEFAULT_PROTECTED_PATTERN, myPattern]` to compose.
112
+ * - `false` → no segment protection at all.
113
+ *
114
+ * Non-global regexes are auto-wrapped with the `g` flag; originals are never
115
+ * mutated.
81
116
  */
82
- declare function tokenize(text: string): Generator<Token>;
117
+ declare function tokenize(text: string, protectedSegments?: RegExp | RegExp[] | false): Generator<Token>;
83
118
 
84
119
  /** A checker bound to a single language, for convenient repeated use. */
85
120
  interface BoundChecker {
86
121
  readonly language: LanguageCode;
87
122
  check(text: string, options?: Omit<CheckOptions, 'language'>): Promise<SpellIssue[]>;
88
123
  suggest(word: string, max?: number): Promise<string[]>;
89
- isCorrect(word: string, strict?: boolean): Promise<boolean>;
124
+ isCorrect(word: string, options?: IsCorrectOptions): Promise<boolean>;
90
125
  warmup(): Promise<void>;
91
126
  }
92
127
  /**
@@ -99,9 +134,9 @@ interface BoundChecker {
99
134
  */
100
135
  declare function createChecker(language: LanguageCode): BoundChecker;
101
136
  /** Correction suggestions for a single word. */
102
- declare function suggest(word: string, options?: {
103
- language?: LanguageCode;
137
+ declare function suggest(word: string, options: {
138
+ language: LanguageCode;
104
139
  max?: number;
105
140
  }): Promise<string[]>;
106
141
 
107
- export { type BoundChecker, type CheckOptions, type Dictionary, LANGUAGES, type LanguageCode, type LanguageInfo, SUPPORTED_LANGUAGES, type SpellIssue, checkText, createChecker, isCorrect, isSupportedLanguage, loadDictionary, suggest, tokenize, warmup };
142
+ export { type BoundChecker, type CheckOptions, DEFAULT_PROTECTED_PATTERN, type Dictionary, type IsCorrectOptions, LANGUAGES, type LanguageCode, type LanguageInfo, SUPPORTED_LANGUAGES, type SpellIssue, checkText, createChecker, isCorrect, isSupportedLanguage, loadDictionary, suggest, tokenize, warmup };