Skip to content

Commit

Permalink
feat: Support ESM configuration (#4995)
Browse files Browse the repository at this point in the history
Co-authored-by: street-side-software-automation[bot] <74785433+street-side-software-automation[bot]@users.noreply.github.com>
  • Loading branch information
1 parent 947fad2 commit 680eb86
Show file tree
Hide file tree
Showing 69 changed files with 1,726 additions and 923 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ Repository: Azure/azure-rest-api-specs
Url: "https://github.com/Azure/azure-rest-api-specs.git"
Args: ["--config=cSpell.json","**/*.{md,ts,js}"]
Lines:
File: "./Azure/azure-rest-api-specs/cSpell.json"
CSpell: Files checked: 2216, Issues found: 2596 in 796 files
exit code: 1
./CONTRIBUTING.md:24:6 - Unknown word (tocstop) -- <!-- tocstop -->
Expand Down Expand Up @@ -487,4 +486,3 @@ Lines:
./specification/windowsiot/resource-manager/readme.az.md:7:15 - Unknown word (windowsiotservices) -- extensions: windowsiotservices
./specification/workloads/resource-manager/Microsoft.Workloads/SAPVirtualInstance/readme.az.md:9:17 - Unknown word (sapvirtualinstance) -- extensions: sapvirtualinstance
./specification/workloads/resource-manager/Microsoft.Workloads/monitors/readme.az.md:9:17 - Unknown word (sapmonitors) -- extensions: sapmonitors
Legacy config file version found: "0.1", upgrade to "0.2"
4 changes: 2 additions & 2 deletions integration-tests/snapshots/eslint/eslint/report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ Url: https://github.com/eslint/eslint
Args: '["**","--exclude=bin/**","--exclude=CHANGELOG.md","--exclude=_data","--exclude=tests/bench/large.js","--exclude=docs/src/_includes","--exclude=docs/src/assets/{fonts,s?css,images}"]'
Summary:
files: 1898
filesWithIssues: 1258
issues: 5491
filesWithIssues: 1257
issues: 5490
errors: 0
Errors: []

Expand Down
2 changes: 1 addition & 1 deletion integration-tests/snapshots/eslint/eslint/snapshot.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Repository: eslint/eslint
Url: "https://github.com/eslint/eslint"
Args: ["**","--exclude=bin/**","--exclude=CHANGELOG.md","--exclude=_data","--exclude=tests/bench/large.js","--exclude=docs/src/_includes","--exclude=docs/src/assets/{fonts,s?css,images}"]
Lines:
CSpell: Files checked: 1898, Issues found: 5491 in 1258 files
CSpell: Files checked: 1898, Issues found: 5490 in 1257 files
exit code: 1
./Makefile.js:144:88 - Unknown word (ined) -- followed by the string "ined".
./Makefile.js:150:48 - Unknown word (blogpost) -- render(cat("./templates/blogpost.md.ejs"), renderContext
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { CSpellSettings } from '@cspell/cspell-types';
import { describe, expect, test } from 'vitest';

import { CSpellConfigFileInMemory } from './CSpellConfigFileInMemory.js';

describe('CSpellConfigFileInMemory', () => {
const url = new URL('https://example.com/config');
const settings: CSpellSettings = {};

test('should create an instance of CSpellConfigFileInMemory', () => {
const configFile = new CSpellConfigFileInMemory(url, settings);
expect(configFile).toBeInstanceOf(CSpellConfigFileInMemory);
});

test('should have the correct URL', () => {
const configFile = new CSpellConfigFileInMemory(url, settings);
expect(configFile.url).toEqual(url);
});

test('should have the correct settings', () => {
const configFile = new CSpellConfigFileInMemory(url, settings);
expect(configFile.settings).toEqual(settings);
});

test('should be readonly', () => {
const configFile = new CSpellConfigFileInMemory(url, settings);
expect(configFile.readonly).toBe(true);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { CSpellSettings } from '@cspell/cspell-types';

import { ImplCSpellConfigFile } from '../CSpellConfigFile.js';

export class CSpellConfigFileInMemory extends ImplCSpellConfigFile {
constructor(
/** A url representing where it might exist, used to resolve imports. */
readonly url: URL,
readonly settings: CSpellSettings,
) {
super(url, settings);
}

get readonly(): boolean {
return true;
}
}
1 change: 1 addition & 0 deletions packages/cspell-config-lib/src/CSpellConfigFile/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { CSpellConfigFileInMemory } from './CSpellConfigFileInMemory.js';
export { CSpellConfigFileJavaScript } from './CSpellConfigFileJavaScript.js';
export { CSpellConfigFileJson } from './CSpellConfigFileJson.js';
export { CSpellConfigFilePackageJson } from './CSpellConfigFilePackageJson.js';
Expand Down
1 change: 1 addition & 0 deletions packages/cspell-config-lib/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export { createReaderWriter } from './createReaderWriter.js';
export { CSpellConfigFile } from './CSpellConfigFile.js';
export {
CSpellConfigFileInMemory,
CSpellConfigFileJavaScript,
CSpellConfigFileJson,
CSpellConfigFilePackageJson,
Expand Down
23 changes: 18 additions & 5 deletions packages/cspell-config-lib/src/loaders/loaderJavaScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,25 @@ import type { CSpellConfigFile } from '../CSpellConfigFile.js';
import { CSpellConfigFileJavaScript } from '../CSpellConfigFile/CSpellConfigFileJavaScript.js';
import type { FileLoaderMiddleware, LoaderNext, LoadRequest } from '../FileLoader.js';

type Log = typeof console.log;

const _debug = false;
const _log: Log = _debug ? console.warn.bind(console) : () => undefined;

async function importJavaScript(url: URL, hashSuffix: number | string): Promise<CSpellConfigFileJavaScript> {
const _url = new URL(url.href);
_url.hash = `${_url.hash};loaderSuffix=${hashSuffix}`;
const result = await import(_url.href);
const settings = result.default ?? result;
return new CSpellConfigFileJavaScript(url, settings);
try {
const _url = new URL(url.href);
_url.hash = `${_url.hash};loaderSuffix=${hashSuffix}`;
_log('importJavaScript: %o', { url: _url.href });
const result = await import(_url.href);
const settings = result.default ?? result;
return new CSpellConfigFileJavaScript(url, settings);
} catch (e) {
_log('importJavaScript Error: %o', { url: url.href, error: e, hashSuffix });
throw e;
} finally {
_log('importJavaScript Done: %o', { url: url.href, hashSuffix });
}
}

export class LoaderJavaScript implements FileLoaderMiddleware {
Expand Down
33 changes: 17 additions & 16 deletions packages/cspell-lib/api/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ interface NodePackage {
name: string | undefined;
filename: string;
}
declare function listGlobalImports(): ListGlobalImportsResults;
declare function listGlobalImports(): Promise<ListGlobalImportsResults>;
interface AddPathsToGlobalImportsResults {
success: boolean;
resolvedSettings: ResolveSettingsResult[];
error: string | undefined;
}
declare function addPathsToGlobalImports(paths: string[]): AddPathsToGlobalImportsResults;
declare function addPathsToGlobalImports(paths: string[]): Promise<AddPathsToGlobalImportsResults>;
interface RemovePathsFromGlobalImportsResult {
success: boolean;
error: string | undefined;
Expand All @@ -75,7 +75,7 @@ interface RemovePathsFromGlobalImportsResult {
* Note: for Idempotent reasons, asking to remove a path that is not in the global settings is considered a success.
* It is possible to check for this by looking at the returned list of removed paths.
*/
declare function removePathsFromGlobalImports(paths: string[]): RemovePathsFromGlobalImportsResult;
declare function removePathsFromGlobalImports(paths: string[]): Promise<RemovePathsFromGlobalImportsResult>;
interface ResolveSettingsResult {
filename: string;
resolvedToFilename: string | undefined;
Expand Down Expand Up @@ -321,6 +321,8 @@ declare function getLanguagesForBasename(basename: string): string[];
declare const currentSettingsFileVersion = "0.2";
declare const ENV_CSPELL_GLOB_ROOT = "CSPELL_GLOB_ROOT";

type LoaderResult = URL | undefined;

/**
* The keys of an object where the values cannot be undefined.
*/
Expand Down Expand Up @@ -360,13 +362,6 @@ interface DictionaryFileDefinitionInternal extends Readonly<DictionaryDefinition
readonly __source?: string | undefined;
}

declare class ImportError extends Error {
readonly cause: Error | undefined;
constructor(msg: string, cause?: Error | unknown);
}

type LoaderResult = Uri | undefined;

type PnPSettingsOptional = OptionalOrUndefined<PnPSettings>;

type CSpellSettingsWST$1 = CSpellSettingsWithSourceTrace;
Expand All @@ -375,26 +370,27 @@ type CSpellSettingsI$1 = CSpellSettingsInternal;
declare const sectionCSpell = "cSpell";
declare const defaultFileName = "cspell.json";
declare const defaultConfigFilenames: readonly string[];
declare function loadPnP(pnpSettings: PnPSettingsOptional, searchFrom: URL): Promise<LoaderResult>;
declare function loadPnPSync(pnpSettings: PnPSettingsOptional, searchFrom: URL): LoaderResult;

/**
*
* @param searchFrom the directory / file to start searching from.
* @param pnpSettings - related to Using Yarn PNP.
* @returns the resulting settings
*/
declare function searchForConfig(searchFrom: string | undefined, pnpSettings?: PnPSettingsOptional): Promise<CSpellSettingsI$1 | undefined>;
declare function searchForConfig(searchFrom: URL | string | undefined, pnpSettings?: PnPSettingsOptional): Promise<CSpellSettingsI$1 | undefined>;
/**
* Load a CSpell configuration files.
* @param file - path or package reference to load.
* @param pnpSettings - PnP settings
* @returns normalized CSpellSettings
*/
declare function loadConfig(file: string, pnpSettings?: PnPSettingsOptional): Promise<CSpellSettingsI$1>;
declare function loadPnP(pnpSettings: PnPSettingsOptional, searchFrom: Uri): Promise<LoaderResult>;
declare function loadPnPSync(pnpSettings: PnPSettingsOptional, searchFrom: Uri): LoaderResult;
declare function readRawSettings(filename: string, relativeTo?: string): CSpellSettingsWST$1;
declare function getGlobalSettings(): CSpellSettingsI$1;
declare function getCachedFileSize(): number;
declare function clearCachedSettingsFiles(): void;
declare function readRawSettings(filename: string | URL, relativeTo?: string | URL): Promise<CSpellSettingsWST$1>;

declare function extractImportErrors(settings: CSpellSettingsWST$1): ImportFileRefWithError$1[];
interface ImportFileRefWithError$1 extends ImportFileRef {
Expand Down Expand Up @@ -431,6 +427,11 @@ declare function readSettings(filename: string | URL, relativeTo: string | URL,
*/
declare function readSettingsFiles(filenames: string[]): Promise<CSpellSettingsI$1>;

declare class ImportError extends Error {
readonly cause: Error | undefined;
constructor(msg: string, cause?: Error | unknown);
}

type CSpellSettingsWST = AdvancedCSpellSettingsWithSourceTrace;
type CSpellSettingsWSTO = OptionalOrUndefined<AdvancedCSpellSettingsWithSourceTrace>;
type CSpellSettingsI = CSpellSettingsInternal;
Expand Down Expand Up @@ -465,7 +466,7 @@ interface ConfigurationDependencies {
}
declare function extractDependencies(settings: CSpellSettingsWSTO | CSpellSettingsI): ConfigurationDependencies;

declare function getDefaultSettings(useDefaultDictionaries?: boolean): CSpellSettingsInternal;
declare function getDefaultSettings(useDefaultDictionaries?: boolean): Promise<CSpellSettingsInternal>;
declare function getDefaultBundledSettingsAsync(): Promise<CSpellSettingsInternal>;

declare function combineTextAndLanguageSettings(settings: CSpellUserSettings, text: string | undefined, languageId: string | string[]): CSpellSettingsInternal;
Expand Down Expand Up @@ -694,7 +695,7 @@ declare class DocumentValidator {
checkDocument(forceCheck?: boolean): ValidationIssue[];
checkDocumentDirectives(forceCheck?: boolean): ValidationIssue[];
get document(): TextDocument;
updateDocumentText(text: string): void;
updateDocumentText(text: string): Promise<void>;
private defaultParser;
private _checkParsedText;
private addPossibleError;
Expand Down
1 change: 0 additions & 1 deletion packages/cspell-lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@
"clear-module": "^4.1.2",
"comment-json": "^4.2.3",
"configstore": "^6.0.0",
"cosmiconfig": "8.0.0",
"cspell-config-lib": "workspace:*",
"cspell-dictionary": "workspace:*",
"cspell-glob": "workspace:*",
Expand Down
28 changes: 28 additions & 0 deletions packages/cspell-lib/samples/esm-config/cspell.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict';

/** @type { import("@cspell/cspell-types").CSpellUserSettings } */
const cspell = {
description: 'cspell.config.cjs file in samples/esm-config',
languageSettings: [
{
languageId: 'cpp',
allowCompoundWords: false,
patterns: [
{
name: 'pound-includes',
pattern: /^\s*#include.*/g,
},
],
ignoreRegExpList: ['pound-includes'],
},
],
dictionaryDefinitions: [
{
name: 'custom-words',
path: './custom-words.txt',
},
],
dictionaries: ['custom-words'],
};

module.exports = cspell;
27 changes: 27 additions & 0 deletions packages/cspell-lib/samples/esm-config/cspell.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/** @type { import("@cspell/cspell-types").CSpellUserSettings } */

const cspell = {
description: 'cspell.config.js file in samples/esm-config',
languageSettings: [
{
languageId: 'cpp',
allowCompoundWords: false,
patterns: [
{
name: 'pound-includes',
pattern: /^\s*#include.*/g,
},
],
ignoreRegExpList: ['pound-includes'],
},
],
dictionaryDefinitions: [
{
name: 'custom-words',
path: './custom-words.txt',
},
],
dictionaries: ['custom-words'],
};

export default cspell;
27 changes: 27 additions & 0 deletions packages/cspell-lib/samples/esm-config/cspell.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/** @type { import("@cspell/cspell-types").CSpellUserSettings } */

const cspell = {
description: 'cspell.config.mjs file in samples/esm-config',
languageSettings: [
{
languageId: 'cpp',
allowCompoundWords: false,
patterns: [
{
name: 'pound-includes',
pattern: /^\s*#include.*/g,
},
],
ignoreRegExpList: ['pound-includes'],
},
],
dictionaryDefinitions: [
{
name: 'custom-words',
path: './custom-words.txt',
},
],
dictionaries: ['custom-words'],
};

export default cspell;
4 changes: 4 additions & 0 deletions packages/cspell-lib/samples/esm-config/custom-words.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
here
are
some
words
3 changes: 3 additions & 0 deletions packages/cspell-lib/samples/esm-config/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "module"
}
1 change: 1 addition & 0 deletions packages/cspell-lib/samples/esm-config/text.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Here are some words.
1 change: 1 addition & 0 deletions packages/cspell-lib/samples/package-json/nested/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Sample README
8 changes: 8 additions & 0 deletions packages/cspell-lib/samples/package-json/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "package-test",
"cspell": {
"words": [
"package"
]
}
}

0 comments on commit 680eb86

Please sign in to comment.