Skip to content

Instantly share code, notes, and snippets.

@P0lip
Last active September 30, 2022 15:52
Show Gist options
  • Save P0lip/c31e437e97e9263d8a0cf7c29022873c to your computer and use it in GitHub Desktop.
Save P0lip/c31e437e97e9263d8a0cf7c29022873c to your computer and use it in GitHub Desktop.
Spectral spell-checker custom function
// https://cdn.skypack.dev/nspell
import nspell from 'https://cdn.skypack.dev/pin/[email protected]/mode=imports,min/optimized/nspell.js';
import { fetch } from '@stoplight/spectral-runtime';
import { createRulesetFunction } from '@stoplight/spectral-core';
function fetchAsset(lang, ext) {
return fetch(`https://unpkg.com/dictionary-${lang}/index.${ext}`).then(r => r.text());
}
const instances = new Map();
async function createSpellChecker(lang) {
const instance = instances.get(lang);
if (instance !== void 0) return instance;
const [aff, dic] = await Promise.all([fetchAsset(lang, 'aff'), fetchAsset(lang, 'dic')]);
const spell = nspell({ aff, dic });
instances.set(lang, spell);
return spell;
}
function printSuggested(suggested) {
return suggested.map(JSON.stringify).join(' or ');
}
export default createRulesetFunction(
{
input: {
type: 'string',
},
options: {
type: 'object',
properties: {
lang: {
enum: ['en'],
},
},
required: ['lang'],
additionalProperties: false,
},
},
async function dictionary(input, opts) {
try {
const checker = await createSpellChecker(opts.lang);
const results = [];
for (const word of input.split(/\s+/)) {
const suggested = checker.suggest(word);
if (suggested.length !== 0) {
results.push({
message: `"${word}" is misspelled. Did you mean ${printSuggested(suggested)}?`,
});
}
}
return results;
} catch (ex) {
return [
{
message: ex instanceof Error ? ex.message : String(ex),
},
];
}
},
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment