fixnow 1.0.2 → 2.0.1

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/README.md CHANGED
@@ -59,10 +59,18 @@ npm i fixnow
59
59
  ```ts
60
60
  import { checkText, suggest, createChecker } from "fixnow";
61
61
 
62
- // Detect misspellings (defaults to Spanish)
63
- const issues = await checkText("Esto es un herror", {
62
+ // English
63
+ const enIssues = await checkText("This sentance has a typo", {
64
+ language: "en",
65
+ suggestions: true,
66
+ });
67
+ // -> [{ offset: 5, length: 8, word: 'sentance', suggestions: [...] }]
68
+
69
+ // Spanish — opt in to accent leniency if you don't want "codigo" flagged.
70
+ const esIssues = await checkText("Esto es un herror", {
64
71
  language: "es",
65
72
  suggestions: true,
73
+ acceptAccentOmissions: true,
66
74
  });
67
75
  // -> [{ offset: 11, length: 6, word: 'herror', suggestions: [...] }]
68
76
 
@@ -82,15 +90,115 @@ const { checkText } = require("fixnow");
82
90
 
83
91
  ### API
84
92
 
85
- - `checkText(text, options?)` → `Promise<SpellIssue[]>`
86
- - `isCorrect(word, language?, strict?)` → `Promise<boolean>`
87
- - `suggest(word, { language?, max? })` → `Promise<string[]>`
93
+ - `checkText(text, options)` → `Promise<SpellIssue[]>`
94
+ - `isCorrect(word, language, options?)` → `Promise<boolean>`
95
+ - `suggest(word, { language, max? })` → `Promise<string[]>`
88
96
  - `createChecker(language)` → bound `{ check, suggest, isCorrect, warmup }`
89
97
  - `warmup(language?)` — preload dictionaries (skip first-call decode cost)
98
+ - `tokenize(text, protectedSegments?)`, `DEFAULT_PROTECTED_PATTERN`
90
99
  - `SUPPORTED_LANGUAGES`, `LANGUAGES`, `isSupportedLanguage`
91
100
 
92
- **`CheckOptions`:** `language` (default `'es'`), `strict` (Spanish accent strictness),
93
- `suggestions`, `maxSuggestions` (5), `minWordLength` (3), `ignoreWords`, `flagWords`, `isProtectedWord`.
101
+ **`CheckOptions`:** `language` (required), `caseSensitive` (false), `acceptAccentOmissions`
102
+ (false; Spanish only), `suggestions`, `maxSuggestions` (5), `minWordLength` (3),
103
+ `ignoreWords`, `flagWords`, `isProtectedWord`, `protectedSegments`.
104
+
105
+ ### Tokenization
106
+
107
+ `checkText` skips anything inside a "protected segment" (code spans, URLs, emails, paths,
108
+ CLI flags, hex colors, ACRONYMS, file names and dotted identifiers). Override the
109
+ patterns with `protectedSegments`:
110
+
111
+ ```ts
112
+ import { checkText, DEFAULT_PROTECTED_PATTERN } from "fixnow";
113
+
114
+ // Use only your own pattern
115
+ await checkText(text, { language: "en", protectedSegments: /\{\{[^}]+\}\}/g });
116
+
117
+ // Compose with the default
118
+ await checkText(text, {
119
+ language: "en",
120
+ protectedSegments: [DEFAULT_PROTECTED_PATTERN, /\{\{[^}]+\}\}/g],
121
+ });
122
+
123
+ // Disable protection entirely
124
+ await checkText(text, { language: "en", protectedSegments: false });
125
+ ```
126
+
127
+ The same option is exposed on `tokenize(text, protectedSegments)`.
128
+
129
+ ### Slim builds
130
+
131
+ If you only need one language, import it via the language subpath. Your bundler only
132
+ copies the dictionary you actually use:
133
+
134
+ ```ts
135
+ import { check, suggest } from "fixnow/es";
136
+
137
+ const issues = await check("Esto es un herror", { suggestions: true });
138
+ await suggest("bonjoor", 3); // bound suggest is (word, max?)
139
+ ```
140
+
141
+ The slim entries (`fixnow/ar`, `fixnow/de`, `fixnow/en`, `fixnow/es`, `fixnow/fr`,
142
+ `fixnow/pt`, `fixnow/ru`, `fixnow/vi`) re-export a checker pre-bound to that language.
143
+
144
+ ## Bundling
145
+
146
+ fixnow reads its dictionaries from disk at runtime — they ship as files under
147
+ `node_modules/fixnow/dictionaries/`, not as inlined bytes in the JS. So any bundler
148
+ must treat `fixnow` as **external**, leaving it to load from `node_modules` at runtime.
149
+ This is required for **VS Code extensions** and any **CJS bundle**: inlining fixnow into
150
+ a CJS output strips the path anchor it uses to find its dictionaries, and it will throw
151
+ a clear "mark 'fixnow' as external" error instead of resolving them.
152
+
153
+ ```js
154
+ // esbuild
155
+ await esbuild.build({
156
+ entryPoints: ["src/extension.ts"],
157
+ bundle: true,
158
+ format: "cjs",
159
+ platform: "node",
160
+ external: ["fixnow"],
161
+ });
162
+ ```
163
+
164
+ The matching option for other bundlers:
165
+
166
+ - **Vite** — `build.rollupOptions.external: ['fixnow']`
167
+ - **Rollup** — `external: ['fixnow']`
168
+ - **webpack** — `externals: { fixnow: 'commonjs fixnow' }`
169
+
170
+ ## Migrating from 1.x
171
+
172
+ `2.0.0` cleans up three rough edges from the extraction-from-F1 release. Each is a
173
+ breaking change:
174
+
175
+ - **`language` is now required.** There is no default language anymore.
176
+ ```ts
177
+ // before
178
+ await checkText("hola"); // implicitly Spanish
179
+ // after
180
+ await checkText("hola", { language: "es" });
181
+ ```
182
+ - **`strict` is split into `caseSensitive` and `acceptAccentOmissions`.** The new
183
+ default is strict (the old `strict: true`). If you relied on `strict: false` to
184
+ tolerate Spanish accent omissions, opt in explicitly:
185
+ ```ts
186
+ // before
187
+ await checkText("codigo", { language: "es" }); // accepted
188
+ // after
189
+ await checkText("codigo", { language: "es", acceptAccentOmissions: true });
190
+ ```
191
+ The legacy `strict` key still works in 2.x with a `console.warn`; it is removed in `3.0.0`.
192
+ - **F1-specific markers are gone from the default tokenizer.** `[Image #1]`, `[Skills #…]`,
193
+ `/skills #N`, and `/skill` no longer auto-skip. If you need them, pass them via
194
+ `protectedSegments`:
195
+ ```ts
196
+ const F1_MARKERS = /\[(?:Image|Code|Text) #\d+[^\]\n]*\]|\[Skills? #[^\]\n]+\]|\/skills #\d+|\/skill\b/g;
197
+ await checkText(text, {
198
+ language: "en",
199
+ protectedSegments: [DEFAULT_PROTECTED_PATTERN, F1_MARKERS],
200
+ });
201
+ ```
94
202
 
95
203
  ## License
96
204