happy-css-modules 2.1.1 → 3.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/README.md +5 -0
- package/dist/cli.js.map +1 -1
- package/dist/emitter/dts.js +8 -7
- package/dist/emitter/dts.js.map +1 -1
- package/dist/emitter/dts.test.js +1 -1
- package/dist/emitter/dts.test.js.map +1 -1
- package/dist/emitter/file-system.js.map +1 -1
- package/dist/emitter/index.js +1 -1
- package/dist/emitter/index.js.map +1 -1
- package/dist/emitter/source-map.js +2 -2
- package/dist/emitter/source-map.js.map +1 -1
- package/dist/emitter/source-map.test.js +2 -2
- package/dist/emitter/source-map.test.js.map +1 -1
- package/dist/integration-test/go-to-definition.test.js +1 -1
- package/dist/integration-test/go-to-definition.test.js.map +1 -1
- package/dist/locator/index.js +6 -1
- package/dist/locator/index.js.map +1 -1
- package/dist/locator/index.test.js +1 -1
- package/dist/locator/index.test.js.map +1 -1
- package/dist/locator/postcss.js.map +1 -1
- package/dist/logger.js.map +1 -1
- package/dist/regression-test/issue-168.test.js.map +1 -1
- package/dist/resolver/index.d.ts +1 -1
- package/dist/resolver/index.js +2 -0
- package/dist/resolver/index.js.map +1 -1
- package/dist/resolver/node-resolver.js +2 -2
- package/dist/resolver/node-resolver.js.map +1 -1
- package/dist/resolver/webpack-resolver.js +7 -8
- package/dist/resolver/webpack-resolver.js.map +1 -1
- package/dist/runner.js +9 -7
- package/dist/runner.js.map +1 -1
- package/dist/runner.test.js +16 -15
- package/dist/runner.test.js.map +1 -1
- package/dist/test-util/jest/resolver.cjs +3 -2
- package/dist/test-util/jest/resolver.cjs.map +1 -1
- package/dist/test-util/tsserver.d.ts +2 -2
- package/dist/test-util/tsserver.js +6 -7
- package/dist/test-util/tsserver.js.map +1 -1
- package/dist/test-util/util.js +3 -1
- package/dist/test-util/util.js.map +1 -1
- package/dist/transformer/index.d.ts +1 -1
- package/dist/transformer/index.js.map +1 -1
- package/dist/transformer/less-transformer.js +1 -0
- package/dist/transformer/less-transformer.js.map +1 -1
- package/dist/transformer/scss-transformer.js +3 -2
- package/dist/transformer/scss-transformer.js.map +1 -1
- package/dist/util.d.ts +1 -1
- package/dist/util.js +9 -6
- package/dist/util.js.map +1 -1
- package/package.json +17 -17
- package/src/emitter/dts.test.ts +1 -1
- package/src/emitter/dts.ts +10 -9
- package/src/emitter/index.ts +1 -1
- package/src/emitter/source-map.test.ts +2 -2
- package/src/emitter/source-map.ts +2 -2
- package/src/integration-test/go-to-definition.test.ts +1 -1
- package/src/locator/index.ts +6 -1
- package/src/resolver/index.ts +3 -1
- package/src/resolver/node-resolver.ts +2 -2
- package/src/resolver/webpack-resolver.ts +7 -8
- package/src/runner.test.ts +17 -17
- package/src/runner.ts +9 -8
- package/src/test-util/jest/resolver.cjs +3 -2
- package/src/test-util/tsserver.ts +7 -11
- package/src/test-util/util.ts +3 -1
- package/src/transformer/index.ts +1 -1
- package/src/transformer/less-transformer.ts +1 -0
- package/src/transformer/postcss-transformer.ts +1 -1
- package/src/transformer/scss-transformer.ts +2 -1
- package/src/util.ts +9 -6
package/src/locator/index.ts
CHANGED
|
@@ -98,6 +98,7 @@ export class Locator {
|
|
|
98
98
|
for (const dependency of dependencies) {
|
|
99
99
|
const entry = this.cache.get(dependency);
|
|
100
100
|
if (!entry) return true;
|
|
101
|
+
// eslint-disable-next-line no-await-in-loop
|
|
101
102
|
const mtime = (await stat(dependency)).mtime.getTime();
|
|
102
103
|
if (entry.mtime !== mtime) return true;
|
|
103
104
|
}
|
|
@@ -124,7 +125,7 @@ export class Locator {
|
|
|
124
125
|
dependencies: result.dependencies
|
|
125
126
|
.map((dep) => {
|
|
126
127
|
if (typeof dep === 'string') return dep;
|
|
127
|
-
if (dep.protocol !== 'file:') throw new Error(
|
|
128
|
+
if (dep.protocol !== 'file:') throw new Error(`Unsupported protocol: ${dep.protocol}`);
|
|
128
129
|
return dep.pathname;
|
|
129
130
|
})
|
|
130
131
|
.filter((dep) => {
|
|
@@ -171,7 +172,9 @@ export class Locator {
|
|
|
171
172
|
const importedSheetPath = parseAtImport(atImport);
|
|
172
173
|
if (!importedSheetPath) continue;
|
|
173
174
|
if (isIgnoredSpecifier(importedSheetPath)) continue;
|
|
175
|
+
// eslint-disable-next-line no-await-in-loop
|
|
174
176
|
const from = await this.resolver(importedSheetPath, { request: filePath });
|
|
177
|
+
// eslint-disable-next-line no-await-in-loop
|
|
175
178
|
const result = await this._load(from);
|
|
176
179
|
const externalTokens = result.tokens;
|
|
177
180
|
dependencies.push(from, ...result.dependencies);
|
|
@@ -197,7 +200,9 @@ export class Locator {
|
|
|
197
200
|
const declarationDetail = parseComposesDeclarationWithFromUrl(composesDeclaration);
|
|
198
201
|
if (!declarationDetail) continue;
|
|
199
202
|
if (isIgnoredSpecifier(declarationDetail.from)) continue;
|
|
203
|
+
// eslint-disable-next-line no-await-in-loop
|
|
200
204
|
const from = await this.resolver(declarationDetail.from, { request: filePath });
|
|
205
|
+
// eslint-disable-next-line no-await-in-loop
|
|
201
206
|
const result = await this._load(from);
|
|
202
207
|
const externalTokens = result.tokens.filter((token) => declarationDetail.tokenNames.includes(token.name));
|
|
203
208
|
dependencies.push(from, ...result.dependencies);
|
package/src/resolver/index.ts
CHANGED
|
@@ -11,7 +11,7 @@ export type ResolverOptions = {
|
|
|
11
11
|
/**
|
|
12
12
|
* The function to resolve the path of the imported file.
|
|
13
13
|
* @returns The resolved path of the imported file. `false` means to skip resolving.
|
|
14
|
-
|
|
14
|
+
*/
|
|
15
15
|
export type Resolver = (specifier: string, options: ResolverOptions) => string | false | Promise<string | false>;
|
|
16
16
|
|
|
17
17
|
export type DefaultResolverOptions = WebpackResolverOptions;
|
|
@@ -43,8 +43,10 @@ export const createDefaultResolver: (defaultResolverOptions?: DefaultResolverOpt
|
|
|
43
43
|
return async (specifier, options) => {
|
|
44
44
|
for (const resolver of resolvers) {
|
|
45
45
|
try {
|
|
46
|
+
// eslint-disable-next-line no-await-in-loop
|
|
46
47
|
const resolved = await resolver(specifier, options);
|
|
47
48
|
if (resolved !== false) {
|
|
49
|
+
// eslint-disable-next-line no-await-in-loop
|
|
48
50
|
const isExists = await exists(resolved);
|
|
49
51
|
if (isExists) return resolved;
|
|
50
52
|
}
|
|
@@ -2,6 +2,6 @@ import { fileURLToPath, pathToFileURL } from 'url';
|
|
|
2
2
|
import { resolve } from 'import-meta-resolve';
|
|
3
3
|
import type { Resolver } from './index.js';
|
|
4
4
|
|
|
5
|
-
export const createNodeResolver: () => Resolver = () =>
|
|
6
|
-
return fileURLToPath(
|
|
5
|
+
export const createNodeResolver: () => Resolver = () => (specifier, options) => {
|
|
6
|
+
return fileURLToPath(resolve(specifier, pathToFileURL(options.request).href));
|
|
7
7
|
};
|
|
@@ -44,14 +44,13 @@ export const createWebpackResolver: (webpackResolverOptions?: WebpackResolverOpt
|
|
|
44
44
|
* @see https://github.com/webpack-contrib/css-loader/blob/897e7dd250ccdb0d31e6c66d4cd0d009f2022a85/src/plugins/postcss-import-parser.js#L228-L235
|
|
45
45
|
*/
|
|
46
46
|
const cssLoaderResolver = enhancedResolve.create.sync({
|
|
47
|
-
dependencyType: 'css',
|
|
48
47
|
conditionNames: ['style'],
|
|
49
48
|
// We are not sure how "..." affects behavior...
|
|
50
49
|
mainFields: ['css', 'style', 'main', '...'],
|
|
51
50
|
mainFiles: ['index', '...'],
|
|
52
51
|
extensions: ['.css', '...'],
|
|
53
52
|
preferRelative: true,
|
|
54
|
-
alias: webpackResolveAlias,
|
|
53
|
+
alias: webpackResolveAlias ?? {},
|
|
55
54
|
});
|
|
56
55
|
|
|
57
56
|
/**
|
|
@@ -60,14 +59,13 @@ export const createWebpackResolver: (webpackResolverOptions?: WebpackResolverOpt
|
|
|
60
59
|
* @see https://github.com/webpack-contrib/sass-loader/blob/49a578a218574ddc92a597c7e365b6c21960717e/src/utils.js#L531-L539
|
|
61
60
|
*/
|
|
62
61
|
const sassLoaderResolver = enhancedResolve.create.sync({
|
|
63
|
-
dependencyType: 'sass',
|
|
64
62
|
conditionNames: ['sass', 'style'],
|
|
65
63
|
mainFields: ['sass', 'style', 'main', '...'],
|
|
66
64
|
mainFiles: ['_index', 'index', '...'],
|
|
67
65
|
extensions: ['.sass', '.scss', '.css'],
|
|
68
|
-
restrictions: [/\.((sa|sc|c)ss)$/
|
|
66
|
+
restrictions: [/\.((sa|sc|c)ss)$/iu],
|
|
69
67
|
preferRelative: true,
|
|
70
|
-
alias: webpackResolveAlias,
|
|
68
|
+
alias: webpackResolveAlias ?? {},
|
|
71
69
|
modules: ['node_modules', ...(sassLoadPaths ?? [])],
|
|
72
70
|
});
|
|
73
71
|
|
|
@@ -77,13 +75,12 @@ export const createWebpackResolver: (webpackResolverOptions?: WebpackResolverOpt
|
|
|
77
75
|
* @see https://github.com/webpack-contrib/less-loader/blob/d74f740c100c4006b00dfb3e02c6d5aaf8713519/src/utils.js#L35-L42
|
|
78
76
|
*/
|
|
79
77
|
const lessLoaderResolver = enhancedResolve.create.sync({
|
|
80
|
-
dependencyType: 'less',
|
|
81
78
|
conditionNames: ['less', 'style'],
|
|
82
79
|
mainFields: ['less', 'style', 'main', '...'],
|
|
83
80
|
mainFiles: ['index', '...'],
|
|
84
81
|
extensions: ['.less', '.css'],
|
|
85
82
|
preferRelative: true,
|
|
86
|
-
alias: webpackResolveAlias,
|
|
83
|
+
alias: webpackResolveAlias ?? {},
|
|
87
84
|
modules: ['node_modules', ...(lessIncludePaths ?? [])],
|
|
88
85
|
});
|
|
89
86
|
|
|
@@ -96,6 +93,7 @@ export const createWebpackResolver: (webpackResolverOptions?: WebpackResolverOpt
|
|
|
96
93
|
// ref: https://github.com/webpack-contrib/css-loader/blob/5e6cf91fd3f0c8b5fb4b91197b98dc56abdef4bf/src/utils.js#L92-L95
|
|
97
94
|
// ref: https://github.com/webpack-contrib/sass-loader/blob/49a578a218574ddc92a597c7e365b6c21960717e/src/utils.js#L368-L370
|
|
98
95
|
// ref: https://github.com/webpack-contrib/less-loader/blob/d74f740c100c4006b00dfb3e02c6d5aaf8713519/src/utils.js#L72-L75
|
|
96
|
+
// eslint-disable-next-line no-param-reassign
|
|
99
97
|
if (specifier.startsWith('~')) specifier = specifier.slice(1);
|
|
100
98
|
|
|
101
99
|
for (const resolver of resolvers) {
|
|
@@ -104,13 +102,14 @@ export const createWebpackResolver: (webpackResolverOptions?: WebpackResolverOpt
|
|
|
104
102
|
? // Support partial import for sass
|
|
105
103
|
// https://sass-lang.com/documentation/at-rules/import#partials
|
|
106
104
|
// https://github.com/webpack-contrib/sass-loader/blob/0e9494074f69a6b6d47efea6c083a02a31a5ae84/test/sass/import-with-underscore.sass
|
|
107
|
-
[join(dirname(specifier),
|
|
105
|
+
[join(dirname(specifier), `_${basename(specifier)}`), specifier]
|
|
108
106
|
: [specifier];
|
|
109
107
|
|
|
110
108
|
for (const specifierVariant of specifierVariants) {
|
|
111
109
|
try {
|
|
112
110
|
const resolved = resolver(dirname(options.request), specifierVariant);
|
|
113
111
|
if (resolved !== false) {
|
|
112
|
+
// eslint-disable-next-line no-await-in-loop
|
|
114
113
|
const isExists = await exists(resolved);
|
|
115
114
|
if (isExists) return resolved;
|
|
116
115
|
}
|
package/src/runner.test.ts
CHANGED
|
@@ -3,23 +3,22 @@ import { randomUUID } from 'node:crypto';
|
|
|
3
3
|
import { createRequire } from 'node:module';
|
|
4
4
|
import { dirname, join, resolve } from 'path';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
|
-
import * as
|
|
6
|
+
import * as fileCacheCore from '@file-cache/core';
|
|
7
|
+
import type { CreateCacheOptions } from '@file-cache/core';
|
|
7
8
|
import { jest } from '@jest/globals';
|
|
8
9
|
import dedent from 'dedent';
|
|
9
10
|
import type { RunnerOptions, Watcher } from './runner.js';
|
|
10
11
|
import { createFixtures, exists, getFixturePath, waitForAsyncTask } from './test-util/util.js';
|
|
11
12
|
|
|
12
|
-
const packageRootDir = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
13
|
-
|
|
14
13
|
const require = createRequire(import.meta.url);
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
const uuid = randomUUID();
|
|
16
|
+
jest.unstable_mockModule('@file-cache/core', () => ({
|
|
17
|
+
...fileCacheCore, // Inherit native functions
|
|
18
|
+
createCache: async (options: CreateCacheOptions) => {
|
|
19
|
+
options.keys.push(() => uuid); // Add a random key to avoid cache collision
|
|
20
|
+
return fileCacheCore.createCache(options);
|
|
21
|
+
},
|
|
23
22
|
}));
|
|
24
23
|
|
|
25
24
|
const { run } = await import('./runner.js');
|
|
@@ -144,6 +143,7 @@ test('uses cache in watch mode', async () => {
|
|
|
144
143
|
await waitForAsyncTask(500); // Wait until the file is written
|
|
145
144
|
|
|
146
145
|
// The updated 1.css will be processed, and the non-updated 2.css will be skipped.
|
|
146
|
+
// eslint-disable-next-line require-atomic-updates
|
|
147
147
|
watcher = await run({ ...defaultOptions, declarationMap: true, logLevel: 'debug', cache: true, watch: true });
|
|
148
148
|
await waitForAsyncTask(1000); // Wait until the watcher is ready
|
|
149
149
|
expect(consoleLogSpy).toBeCalledTimes(3);
|
|
@@ -187,7 +187,7 @@ test('does not emit declaration map if declarationMap is false', async () => {
|
|
|
187
187
|
});
|
|
188
188
|
await run({ ...defaultOptions, declarationMap: false });
|
|
189
189
|
await expect(readFile(getFixturePath('/test/1.css.d.ts'), 'utf8')).resolves.not.toThrow();
|
|
190
|
-
await expect(readFile(getFixturePath('/test/1.css.d.ts.map'), 'utf8')).rejects.toThrow(/ENOENT/);
|
|
190
|
+
await expect(readFile(getFixturePath('/test/1.css.d.ts.map'), 'utf8')).rejects.toThrow(/ENOENT/u);
|
|
191
191
|
});
|
|
192
192
|
test('supports transformer', async () => {
|
|
193
193
|
createFixtures({
|
|
@@ -205,17 +205,17 @@ test('watches for changes in files', async () => {
|
|
|
205
205
|
|
|
206
206
|
await writeFile(getFixturePath('/test/1.css'), '.a-1 {}');
|
|
207
207
|
await waitForAsyncTask(500); // Wait until the file is written
|
|
208
|
-
expect(await readFile(getFixturePath('/test/1.css.d.ts'), 'utf8')).toMatch(/a-1/);
|
|
208
|
+
expect(await readFile(getFixturePath('/test/1.css.d.ts'), 'utf8')).toMatch(/a-1/u);
|
|
209
209
|
|
|
210
210
|
await writeFile(getFixturePath('/test/1.css'), '.a-2 {}');
|
|
211
211
|
await waitForAsyncTask(500); // Wait until the file is written
|
|
212
|
-
expect(await readFile(getFixturePath('/test/1.css.d.ts'), 'utf8')).toMatch(/a-2/);
|
|
212
|
+
expect(await readFile(getFixturePath('/test/1.css.d.ts'), 'utf8')).toMatch(/a-2/u);
|
|
213
213
|
|
|
214
214
|
await writeFile(getFixturePath('/test/2.css'), '.b {}');
|
|
215
215
|
await writeFile(getFixturePath('/test/3.css'), '.c {}');
|
|
216
216
|
await waitForAsyncTask(500); // Wait until the file is written
|
|
217
|
-
expect(await readFile(getFixturePath('/test/2.css.d.ts'), 'utf8')).toMatch(/b/);
|
|
218
|
-
expect(await readFile(getFixturePath('/test/3.css.d.ts'), 'utf8')).toMatch(/c/);
|
|
217
|
+
expect(await readFile(getFixturePath('/test/2.css.d.ts'), 'utf8')).toMatch(/b/u);
|
|
218
|
+
expect(await readFile(getFixturePath('/test/3.css.d.ts'), 'utf8')).toMatch(/c/u);
|
|
219
219
|
});
|
|
220
220
|
test('returns an error if the file fails to process in non-watch mode', async () => {
|
|
221
221
|
createFixtures({
|
|
@@ -230,8 +230,8 @@ test('returns an error if the file fails to process in non-watch mode', async ()
|
|
|
230
230
|
const error = maybeError as AggregateError;
|
|
231
231
|
expect(error.message).toMatchInlineSnapshot(`"Failed to process files"`);
|
|
232
232
|
expect(error.errors).toHaveLength(2);
|
|
233
|
-
expect(error.errors[0]).toMatchInlineSnapshot(`<fixtures>/test/
|
|
234
|
-
expect(error.errors[1]).toMatchInlineSnapshot(`<fixtures>/test/
|
|
233
|
+
expect(error.errors[0]).toMatchInlineSnapshot(`<fixtures>/test/3.css:1:1: Unknown word`);
|
|
234
|
+
expect(error.errors[1]).toMatchInlineSnapshot(`<fixtures>/test/2.css:1:1: Unknown word`);
|
|
235
235
|
|
|
236
236
|
// The valid files are emitted.
|
|
237
237
|
expect(await exists(getFixturePath('/test/1.css.d.ts'))).toBe(true);
|
package/src/runner.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { resolve, relative } from 'path';
|
|
2
2
|
import * as process from 'process';
|
|
3
|
-
import * as util from 'util';
|
|
4
3
|
import { createCache } from '@file-cache/core';
|
|
5
4
|
import { createNpmPackageKey } from '@file-cache/npm';
|
|
6
5
|
import AwaitLock from 'await-lock';
|
|
7
6
|
import chalk from 'chalk';
|
|
8
7
|
import * as chokidar from 'chokidar';
|
|
9
|
-
import
|
|
8
|
+
import { glob } from 'glob';
|
|
10
9
|
import { DEFAULT_ARBITRARY_EXTENSIONS } from './config.js';
|
|
11
10
|
import { isGeneratedFilesExist, emitGeneratedFiles } from './emitter/index.js';
|
|
12
11
|
import { Locator } from './locator/index.js';
|
|
@@ -16,8 +15,6 @@ import { createDefaultResolver } from './resolver/index.js';
|
|
|
16
15
|
import { createDefaultTransformer, type Transformer } from './transformer/index.js';
|
|
17
16
|
import { getInstalledPeerDependencies, isMatchByGlob } from './util.js';
|
|
18
17
|
|
|
19
|
-
const glob = util.promisify(_glob);
|
|
20
|
-
|
|
21
18
|
export type Watcher = {
|
|
22
19
|
close: () => Promise<void>;
|
|
23
20
|
};
|
|
@@ -94,6 +91,7 @@ type OverrideProp<T, K extends keyof T, V extends T[K]> = Omit<T, K> & { [P in K
|
|
|
94
91
|
export async function run(options: OverrideProp<RunnerOptions, 'watch', true>): Promise<Watcher>;
|
|
95
92
|
export async function run(options: RunnerOptions): Promise<void>;
|
|
96
93
|
export async function run(options: RunnerOptions): Promise<Watcher | void> {
|
|
94
|
+
// eslint-disable-next-line new-cap
|
|
97
95
|
const lock = new AwaitLock.default();
|
|
98
96
|
const logger = new Logger(options.logLevel ?? 'info');
|
|
99
97
|
|
|
@@ -108,8 +106,9 @@ export async function run(options: RunnerOptions): Promise<Watcher | void> {
|
|
|
108
106
|
});
|
|
109
107
|
const transformer = options.transformer ?? createDefaultTransformer({ cwd, postcssConfig: options.postcssConfig });
|
|
110
108
|
|
|
111
|
-
const installedPeerDependencies =
|
|
109
|
+
const installedPeerDependencies = getInstalledPeerDependencies();
|
|
112
110
|
const cache = await createCache({
|
|
111
|
+
name: 'happy-css-modules',
|
|
113
112
|
mode: options.cacheStrategy ?? 'content',
|
|
114
113
|
keys: [
|
|
115
114
|
() => createNpmPackageKey(['happy-css-modules', ...installedPeerDependencies]),
|
|
@@ -128,6 +127,7 @@ export async function run(options: RunnerOptions): Promise<Watcher | void> {
|
|
|
128
127
|
async function processFile(filePath: string) {
|
|
129
128
|
async function isChangedFile(filePath: string) {
|
|
130
129
|
const result = await cache.getAndUpdateCache(filePath);
|
|
130
|
+
// eslint-disable-next-line @typescript-eslint/no-throw-literal
|
|
131
131
|
if (result.error) throw result.error;
|
|
132
132
|
return result.changed;
|
|
133
133
|
}
|
|
@@ -175,6 +175,7 @@ export async function run(options: RunnerOptions): Promise<Watcher | void> {
|
|
|
175
175
|
|
|
176
176
|
const errors: unknown[] = [];
|
|
177
177
|
for (const filePath of filePaths) {
|
|
178
|
+
// eslint-disable-next-line no-await-in-loop
|
|
178
179
|
await processFile(filePath).catch((e) => errors.push(e));
|
|
179
180
|
}
|
|
180
181
|
|
|
@@ -184,13 +185,13 @@ export async function run(options: RunnerOptions): Promise<Watcher | void> {
|
|
|
184
185
|
}
|
|
185
186
|
|
|
186
187
|
if (!options.watch) {
|
|
187
|
-
logger.info(
|
|
188
|
+
logger.info(`Generate .d.ts for ${options.pattern}...`);
|
|
188
189
|
await processAllFiles();
|
|
189
190
|
// Write cache state to file for persistence
|
|
190
191
|
} else {
|
|
191
192
|
// First, watch files.
|
|
192
|
-
logger.info(
|
|
193
|
-
const watcher = chokidar.watch([options.pattern.replace(/\\/
|
|
193
|
+
logger.info(`Watch ${options.pattern}...`);
|
|
194
|
+
const watcher = chokidar.watch([options.pattern.replace(/\\/gu, '/')], { cwd });
|
|
194
195
|
watcher.on('all', (eventName, relativeFilePath) => {
|
|
195
196
|
const filePath = resolve(cwd, relativeFilePath);
|
|
196
197
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports
|
|
1
2
|
const nativeModule = require('node:module');
|
|
2
3
|
|
|
3
4
|
// workaround for https://github.com/facebook/jest/issues/12270#issuecomment-1194746382
|
|
@@ -14,7 +15,7 @@ const nativeModule = require('node:module');
|
|
|
14
15
|
* pathFilter?: (pkg: any, path: string, relativePath: string) => string;
|
|
15
16
|
* rootDir?: string;
|
|
16
17
|
* }} ResolverOptions
|
|
17
|
-
|
|
18
|
+
*/
|
|
18
19
|
|
|
19
20
|
/** @type {(path: string, options: ResolverOptions) => string} */
|
|
20
21
|
function resolver(module, options) {
|
|
@@ -22,7 +23,7 @@ function resolver(module, options) {
|
|
|
22
23
|
try {
|
|
23
24
|
return defaultResolver(module, options);
|
|
24
25
|
// eslint-disable-next-line no-unused-vars
|
|
25
|
-
} catch (
|
|
26
|
+
} catch (_error) {
|
|
26
27
|
return nativeModule.createRequire(basedir).resolve(module);
|
|
27
28
|
}
|
|
28
29
|
}
|
|
@@ -2,14 +2,12 @@ import { readFileSync } from 'fs';
|
|
|
2
2
|
import { mkdir, writeFile as nativeWriteFile } from 'fs/promises';
|
|
3
3
|
import { dirname } from 'path';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
|
-
import { promisify } from 'util';
|
|
6
5
|
import serverHarness from '@typescript/server-harness';
|
|
7
|
-
import
|
|
6
|
+
import { glob } from 'glob';
|
|
8
7
|
import { resolve } from 'import-meta-resolve';
|
|
9
8
|
import lineColumn from 'line-column';
|
|
10
9
|
import type { server } from 'typescript/lib/tsserverlibrary.js';
|
|
11
10
|
import { getFixturePath } from './util.js';
|
|
12
|
-
const glob = promisify(_glob);
|
|
13
11
|
|
|
14
12
|
async function writeFile(path: string, content: string): Promise<void> {
|
|
15
13
|
await mkdir(dirname(path), { recursive: true });
|
|
@@ -37,14 +35,11 @@ type Definition = {
|
|
|
37
35
|
};
|
|
38
36
|
};
|
|
39
37
|
|
|
40
|
-
export
|
|
41
|
-
const server = serverHarness.launchServer(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
'--disableAutomaticTypingAcquisition',
|
|
46
|
-
],
|
|
47
|
-
);
|
|
38
|
+
export function createTSServer() {
|
|
39
|
+
const server = serverHarness.launchServer(fileURLToPath(resolve('typescript/lib/tsserver.js', import.meta.url)), [
|
|
40
|
+
// ATA generates some extra network traffic and isn't usually relevant when profiling
|
|
41
|
+
'--disableAutomaticTypingAcquisition',
|
|
42
|
+
]);
|
|
48
43
|
|
|
49
44
|
return {
|
|
50
45
|
async getIdentifierDefinitions(filePath: string, identifier: string): Promise<Definition[]> {
|
|
@@ -67,6 +62,7 @@ export async function createTSServer() {
|
|
|
67
62
|
const results: { identifier: string; definitions: Definition[] }[] = [];
|
|
68
63
|
|
|
69
64
|
for (let i = 0; i < identifiers.length; i++) {
|
|
65
|
+
// eslint-disable-next-line no-await-in-loop
|
|
70
66
|
const response: server.protocol.DefinitionResponse = await server.message({
|
|
71
67
|
seq: 0,
|
|
72
68
|
type: 'request',
|
package/src/test-util/util.ts
CHANGED
|
@@ -53,7 +53,9 @@ export function fakeToken(args: {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
export async function waitForAsyncTask(ms?: number): Promise<void> {
|
|
56
|
-
await new Promise((resolve) =>
|
|
56
|
+
await new Promise((resolve) => {
|
|
57
|
+
setTimeout(resolve, ms ?? 0);
|
|
58
|
+
});
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
export async function exists(path: string): Promise<boolean> {
|
package/src/transformer/index.ts
CHANGED
|
@@ -44,6 +44,7 @@ function createLessPluginResolver(Less: typeof import('less'), options: Transfor
|
|
|
44
44
|
export const createLessTransformer: () => Transformer = () => {
|
|
45
45
|
let less: typeof import('less');
|
|
46
46
|
return async (source, options) => {
|
|
47
|
+
// eslint-disable-next-line require-atomic-updates
|
|
47
48
|
less ??= (await import('less').catch(handleImportError('less'))).default;
|
|
48
49
|
const result = await less.render(source, {
|
|
49
50
|
filename: options.from,
|
|
@@ -8,7 +8,7 @@ const require = createRequire(import.meta.url);
|
|
|
8
8
|
|
|
9
9
|
const postcssrc: typeof import('postcss-load-config') = require('postcss-load-config');
|
|
10
10
|
|
|
11
|
-
//ref: https://github.com/postcss/postcss-import#dependency-message-support
|
|
11
|
+
// ref: https://github.com/postcss/postcss-import#dependency-message-support
|
|
12
12
|
interface DependencyMessage extends Message {
|
|
13
13
|
type: 'dependency';
|
|
14
14
|
file: string;
|
|
@@ -22,7 +22,8 @@ function promisifySassRender(sass: typeof import('sass')) {
|
|
|
22
22
|
export const createScssTransformer: () => Transformer = () => {
|
|
23
23
|
let sass: typeof import('sass');
|
|
24
24
|
return async (source, options) => {
|
|
25
|
-
|
|
25
|
+
// eslint-disable-next-line require-atomic-updates
|
|
26
|
+
sass ??= await import('sass').catch(handleImportError('sass'));
|
|
26
27
|
const render = promisifySassRender(sass);
|
|
27
28
|
const result = await render({
|
|
28
29
|
data: source,
|
package/src/util.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { access } from 'fs/promises';
|
|
|
3
3
|
import { join, dirname, resolve } from 'path';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
import { resolve as importMetaResolve } from 'import-meta-resolve';
|
|
6
|
-
import minimatch from 'minimatch';
|
|
6
|
+
import { minimatch } from 'minimatch';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* The SystemError type of Node.js.
|
|
@@ -73,14 +73,17 @@ export function getPackageJson() {
|
|
|
73
73
|
return JSON.parse(readFileSync(resolve(dirname(fileURLToPath(import.meta.url)), '../package.json'), 'utf-8'));
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
export
|
|
76
|
+
export function getInstalledPeerDependencies(): string[] {
|
|
77
77
|
const pkgJson = getPackageJson();
|
|
78
78
|
const result = [];
|
|
79
79
|
for (const deps of Object.keys(pkgJson.peerDependencies)) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
try {
|
|
81
|
+
importMetaResolve(deps, import.meta.url);
|
|
82
|
+
// If the package is installed, push it to the result array.
|
|
83
|
+
result.push(deps);
|
|
84
|
+
} catch {
|
|
85
|
+
// If the package is not installed, do nothing.
|
|
86
|
+
}
|
|
84
87
|
}
|
|
85
88
|
return result;
|
|
86
89
|
}
|