happy-css-modules 3.1.0 → 3.1.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.
Files changed (130) hide show
  1. package/dist/cli.d.ts +6 -0
  2. package/dist/cli.js +121 -0
  3. package/dist/cli.js.map +1 -0
  4. package/dist/cli.test.d.ts +1 -0
  5. package/dist/cli.test.js +66 -0
  6. package/dist/cli.test.js.map +1 -0
  7. package/dist/config.d.ts +1 -0
  8. package/dist/config.js +2 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/emitter/dts.d.ts +14 -0
  11. package/dist/emitter/dts.js +128 -0
  12. package/dist/emitter/dts.js.map +1 -0
  13. package/dist/emitter/dts.test.d.ts +1 -0
  14. package/dist/emitter/dts.test.js +205 -0
  15. package/dist/emitter/dts.test.js.map +1 -0
  16. package/dist/emitter/file-system.d.ts +6 -0
  17. package/dist/emitter/file-system.js +26 -0
  18. package/dist/emitter/file-system.js.map +1 -0
  19. package/dist/emitter/file-system.test.d.ts +1 -0
  20. package/dist/emitter/file-system.test.js +34 -0
  21. package/dist/emitter/file-system.test.js.map +1 -0
  22. package/dist/emitter/index.d.ts +34 -0
  23. package/dist/emitter/index.js +49 -0
  24. package/dist/emitter/index.js.map +1 -0
  25. package/dist/emitter/index.test.d.ts +1 -0
  26. package/dist/emitter/index.test.js +68 -0
  27. package/dist/emitter/index.test.js.map +1 -0
  28. package/dist/emitter/source-map.d.ts +8 -0
  29. package/dist/emitter/source-map.js +16 -0
  30. package/dist/emitter/source-map.js.map +1 -0
  31. package/dist/emitter/source-map.test.d.ts +1 -0
  32. package/dist/emitter/source-map.test.js +13 -0
  33. package/dist/emitter/source-map.test.js.map +1 -0
  34. package/dist/index.d.ts +5 -0
  35. package/dist/index.js +6 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/integration-test/go-to-definition.test.d.ts +1 -0
  38. package/dist/integration-test/go-to-definition.test.js +334 -0
  39. package/dist/integration-test/go-to-definition.test.js.map +1 -0
  40. package/dist/library/source-map/index.d.ts +8 -0
  41. package/dist/library/source-map/index.js +5 -0
  42. package/dist/library/source-map/index.js.map +1 -0
  43. package/dist/locator/index.d.ts +46 -0
  44. package/dist/locator/index.js +173 -0
  45. package/dist/locator/index.js.map +1 -0
  46. package/dist/locator/index.test.d.ts +1 -0
  47. package/dist/locator/index.test.js +393 -0
  48. package/dist/locator/index.test.js.map +1 -0
  49. package/dist/locator/postcss.d.ts +91 -0
  50. package/dist/locator/postcss.js +241 -0
  51. package/dist/locator/postcss.js.map +1 -0
  52. package/dist/locator/postcss.test.d.ts +1 -0
  53. package/dist/locator/postcss.test.js +256 -0
  54. package/dist/locator/postcss.test.js.map +1 -0
  55. package/dist/logger.d.ts +9 -0
  56. package/dist/logger.js +28 -0
  57. package/dist/logger.js.map +1 -0
  58. package/dist/regression-test/issue-168.test.d.ts +1 -0
  59. package/dist/regression-test/issue-168.test.js +30 -0
  60. package/dist/regression-test/issue-168.test.js.map +1 -0
  61. package/dist/resolver/index.d.ts +22 -0
  62. package/dist/resolver/index.js +44 -0
  63. package/dist/resolver/index.js.map +1 -0
  64. package/dist/resolver/index.test.d.ts +1 -0
  65. package/dist/resolver/index.test.js +16 -0
  66. package/dist/resolver/index.test.js.map +1 -0
  67. package/dist/resolver/node-resolver.d.ts +2 -0
  68. package/dist/resolver/node-resolver.js +6 -0
  69. package/dist/resolver/node-resolver.js.map +1 -0
  70. package/dist/resolver/node-resolver.test.d.ts +1 -0
  71. package/dist/resolver/node-resolver.test.js +25 -0
  72. package/dist/resolver/node-resolver.test.js.map +1 -0
  73. package/dist/resolver/relative-resolver.d.ts +2 -0
  74. package/dist/resolver/relative-resolver.js +5 -0
  75. package/dist/resolver/relative-resolver.js.map +1 -0
  76. package/dist/resolver/relative-resolver.test.d.ts +1 -0
  77. package/dist/resolver/relative-resolver.test.js +12 -0
  78. package/dist/resolver/relative-resolver.test.js.map +1 -0
  79. package/dist/resolver/webpack-resolver.d.ts +24 -0
  80. package/dist/resolver/webpack-resolver.js +91 -0
  81. package/dist/resolver/webpack-resolver.js.map +1 -0
  82. package/dist/resolver/webpack-resolver.test.d.ts +1 -0
  83. package/dist/resolver/webpack-resolver.test.js +89 -0
  84. package/dist/resolver/webpack-resolver.test.js.map +1 -0
  85. package/dist/runner.d.ts +76 -0
  86. package/dist/runner.js +120 -0
  87. package/dist/runner.js.map +1 -0
  88. package/dist/runner.test.d.ts +1 -0
  89. package/dist/runner.test.js +287 -0
  90. package/dist/runner.test.js.map +1 -0
  91. package/dist/test-util/jest/resolver.cjs +31 -0
  92. package/dist/test-util/jest/resolver.cjs.map +1 -0
  93. package/dist/test-util/jest/resolver.d.cts +16 -0
  94. package/dist/test-util/tsserver.d.ts +31 -0
  95. package/dist/test-util/tsserver.js +112 -0
  96. package/dist/test-util/tsserver.js.map +1 -0
  97. package/dist/test-util/util.d.ts +29 -0
  98. package/dist/test-util/util.js +85 -0
  99. package/dist/test-util/util.js.map +1 -0
  100. package/dist/transformer/index.d.ts +30 -0
  101. package/dist/transformer/index.js +25 -0
  102. package/dist/transformer/index.js.map +1 -0
  103. package/dist/transformer/index.test.d.ts +1 -0
  104. package/dist/transformer/index.test.js +66 -0
  105. package/dist/transformer/index.test.js.map +1 -0
  106. package/dist/transformer/less-transformer.d.ts +2 -0
  107. package/dist/transformer/less-transformer.js +45 -0
  108. package/dist/transformer/less-transformer.js.map +1 -0
  109. package/dist/transformer/less-transformer.test.d.ts +1 -0
  110. package/dist/transformer/less-transformer.test.js +134 -0
  111. package/dist/transformer/less-transformer.test.js.map +1 -0
  112. package/dist/transformer/postcss-transformer.d.ts +12 -0
  113. package/dist/transformer/postcss-transformer.js +32 -0
  114. package/dist/transformer/postcss-transformer.js.map +1 -0
  115. package/dist/transformer/postcss-transformer.test.d.ts +1 -0
  116. package/dist/transformer/postcss-transformer.test.js +178 -0
  117. package/dist/transformer/postcss-transformer.test.js.map +1 -0
  118. package/dist/transformer/scss-transformer.d.ts +2 -0
  119. package/dist/transformer/scss-transformer.js +40 -0
  120. package/dist/transformer/scss-transformer.js.map +1 -0
  121. package/dist/transformer/scss-transformer.test.d.ts +1 -0
  122. package/dist/transformer/scss-transformer.test.js +149 -0
  123. package/dist/transformer/scss-transformer.test.js.map +1 -0
  124. package/dist/util.d.ts +21 -0
  125. package/dist/util.js +72 -0
  126. package/dist/util.js.map +1 -0
  127. package/dist/util.test.d.ts +1 -0
  128. package/dist/util.test.js +74 -0
  129. package/dist/util.test.js.map +1 -0
  130. package/package.json +1 -1
@@ -0,0 +1,46 @@
1
+ import type { Resolver } from '../resolver/index.js';
2
+ import { type Transformer } from '../transformer/index.js';
3
+ import { type Location } from './postcss.js';
4
+ export { collectNodes, type Location } from './postcss.js';
5
+ /** The exported token. */
6
+ export type Token = {
7
+ /** The token name. */
8
+ name: string;
9
+ /** The name of the imported token. */
10
+ importedName?: string;
11
+ /** The original location of the token in the source file. */
12
+ originalLocation: Location;
13
+ };
14
+ /** The result of `Locator#load`. */
15
+ export type LoadResult = {
16
+ /** The path of the file imported from the source file with `@import`. */
17
+ dependencies: string[];
18
+ /** The tokens exported by the source file. */
19
+ tokens: Token[];
20
+ };
21
+ export type LocatorOptions = {
22
+ /** The function to transform source code. */
23
+ transformer?: Transformer | undefined;
24
+ /** The function to resolve the path of the imported file. */
25
+ resolver?: Resolver | undefined;
26
+ };
27
+ /** The resolver that throws an exception if resolving fails. */
28
+ export type StrictlyResolver = (...args: Parameters<Resolver>) => Promise<string>;
29
+ /** This class collects information on tokens exported from CSS Modules files. */
30
+ export declare class Locator {
31
+ private readonly cache;
32
+ private readonly transformer;
33
+ private readonly resolver;
34
+ private loading;
35
+ constructor(options?: LocatorOptions);
36
+ /** Returns `true` if the cache is outdated. */
37
+ private isCacheOutdated;
38
+ /**
39
+ * Reads the source file and returns the code.
40
+ * If transformer is specified, the code is transformed before returning.
41
+ */
42
+ private readCSS;
43
+ /** Returns information about the tokens exported from the CSS Modules file. */
44
+ load(filePath: string): Promise<LoadResult>;
45
+ private _load;
46
+ }
@@ -0,0 +1,173 @@
1
+ import { readFile, stat } from 'fs/promises';
2
+ import postcss from 'postcss';
3
+ import { createDefaultResolver } from '../resolver/index.js';
4
+ import { createDefaultTransformer } from '../transformer/index.js';
5
+ import { unique, uniqueBy } from '../util.js';
6
+ import { getOriginalLocationOfClassSelector, getOriginalLocationOfAtValue, generateLocalTokenNames, parseAtImport, collectNodes, parseAtValue, } from './postcss.js';
7
+ export { collectNodes } from './postcss.js';
8
+ /**
9
+ * Whether the specifier should be ignored.
10
+ * For example, specifiers starting with `http://` or `https://` should be ignored.
11
+ */
12
+ function isIgnoredSpecifier(specifier) {
13
+ return specifier.startsWith('http://') || specifier.startsWith('https://');
14
+ }
15
+ /** This class collects information on tokens exported from CSS Modules files. */
16
+ export class Locator {
17
+ constructor(options) {
18
+ this.cache = new Map();
19
+ this.loading = false;
20
+ this.transformer = options?.transformer ?? createDefaultTransformer();
21
+ this.resolver = async (specifier, resolverOptions) => {
22
+ const resolver = options?.resolver ?? createDefaultResolver();
23
+ const resolved = await resolver(specifier, resolverOptions);
24
+ if (resolved === false)
25
+ throw new Error(`Could not resolve '${specifier}' in '${resolverOptions.request}'.`);
26
+ return resolved;
27
+ };
28
+ }
29
+ /** Returns `true` if the cache is outdated. */
30
+ async isCacheOutdated(filePath) {
31
+ const entry = this.cache.get(filePath);
32
+ if (!entry)
33
+ return true;
34
+ const mtime = (await stat(filePath)).mtime.getTime();
35
+ if (entry.mtime !== mtime)
36
+ return true;
37
+ const { dependencies } = entry.result;
38
+ for (const dependency of dependencies) {
39
+ const entry = this.cache.get(dependency);
40
+ if (!entry)
41
+ return true;
42
+ // eslint-disable-next-line no-await-in-loop
43
+ const mtime = (await stat(dependency)).mtime.getTime();
44
+ if (entry.mtime !== mtime)
45
+ return true;
46
+ }
47
+ return false;
48
+ }
49
+ /**
50
+ * Reads the source file and returns the code.
51
+ * If transformer is specified, the code is transformed before returning.
52
+ */
53
+ async readCSS(filePath) {
54
+ const css = await readFile(filePath, 'utf-8');
55
+ if (!this.transformer)
56
+ return { css, map: undefined, dependencies: [] };
57
+ const result = await this.transformer(css, { from: filePath, resolver: this.resolver, isIgnoredSpecifier });
58
+ if (result === false)
59
+ return { css, map: undefined, dependencies: [] };
60
+ return {
61
+ css: result.css,
62
+ map: result.map,
63
+ dependencies: result.dependencies
64
+ .map((dep) => {
65
+ if (typeof dep === 'string')
66
+ return dep;
67
+ if (dep.protocol !== 'file:')
68
+ throw new Error(`Unsupported protocol: ${dep.protocol}`);
69
+ return dep.pathname;
70
+ })
71
+ .filter((dep) => {
72
+ // less makes a remote module inline, so it may be included in dependencies.
73
+ // However, the dependencies field of happy-css-modules is not yet designed to store http protocol URLs.
74
+ // Therefore, we exclude them from the dependencies field for now.
75
+ return !isIgnoredSpecifier(dep);
76
+ }),
77
+ };
78
+ }
79
+ /** Returns information about the tokens exported from the CSS Modules file. */
80
+ async load(filePath) {
81
+ if (this.loading)
82
+ throw new Error('Cannot call `Locator#load` concurrently.');
83
+ this.loading = true;
84
+ const result = await this._load(filePath).finally(() => {
85
+ this.loading = false;
86
+ });
87
+ return result;
88
+ }
89
+ async _load(filePath) {
90
+ if (!(await this.isCacheOutdated(filePath))) {
91
+ const cacheEntry = this.cache.get(filePath);
92
+ return cacheEntry.result;
93
+ }
94
+ const mtime = (await stat(filePath)).mtime.getTime();
95
+ const { css, map, dependencies } = await this.readCSS(filePath);
96
+ const ast = postcss.parse(css, { from: filePath, map: map ? { inline: false, prev: map } : { inline: false } });
97
+ // Get the local tokens exported by the source file.
98
+ // The tokens are fetched using `postcss-modules` plugin.
99
+ const localTokenNames = await generateLocalTokenNames(ast);
100
+ const tokens = [];
101
+ const { atImports, atValues, classSelectors } = collectNodes(ast);
102
+ // Load imported sheets recursively.
103
+ for (const atImport of atImports) {
104
+ const importedSheetPath = parseAtImport(atImport);
105
+ if (!importedSheetPath)
106
+ continue;
107
+ if (isIgnoredSpecifier(importedSheetPath))
108
+ continue;
109
+ // eslint-disable-next-line no-await-in-loop
110
+ const from = await this.resolver(importedSheetPath, { request: filePath });
111
+ // eslint-disable-next-line no-await-in-loop
112
+ const result = await this._load(from);
113
+ const externalTokens = result.tokens;
114
+ dependencies.push(from, ...result.dependencies);
115
+ tokens.push(...externalTokens);
116
+ }
117
+ // Traverse the source file to find a class selector that matches the local token.
118
+ for (const { rule, classSelector } of classSelectors) {
119
+ // Consider a class selector to be the origin of a token if it matches a token fetched by postcss-modules.
120
+ // NOTE: This method has false positives. However, it works as expected in many cases.
121
+ if (!localTokenNames.includes(classSelector.value))
122
+ continue;
123
+ const originalLocation = getOriginalLocationOfClassSelector(rule, classSelector);
124
+ tokens.push({
125
+ name: classSelector.value,
126
+ originalLocation,
127
+ });
128
+ }
129
+ for (const atValue of atValues) {
130
+ const parsedAtValue = parseAtValue(atValue);
131
+ if (parsedAtValue.type === 'valueDeclaration') {
132
+ tokens.push({
133
+ name: parsedAtValue.tokenName,
134
+ originalLocation: getOriginalLocationOfAtValue(atValue, parsedAtValue),
135
+ });
136
+ }
137
+ else if (parsedAtValue.type === 'valueImportDeclaration') {
138
+ if (isIgnoredSpecifier(parsedAtValue.from))
139
+ continue;
140
+ // eslint-disable-next-line no-await-in-loop
141
+ const from = await this.resolver(parsedAtValue.from, { request: filePath });
142
+ // eslint-disable-next-line no-await-in-loop
143
+ const result = await this._load(from);
144
+ dependencies.push(from, ...result.dependencies);
145
+ for (const token of result.tokens) {
146
+ const matchedImport = parsedAtValue.imports.find((i) => i.importedTokenName === token.name);
147
+ if (!matchedImport)
148
+ continue;
149
+ if (matchedImport.localTokenName === matchedImport.importedTokenName) {
150
+ tokens.push({
151
+ name: matchedImport.localTokenName,
152
+ originalLocation: token.originalLocation,
153
+ });
154
+ }
155
+ else {
156
+ tokens.push({
157
+ name: matchedImport.localTokenName,
158
+ importedName: matchedImport.importedTokenName,
159
+ originalLocation: token.originalLocation,
160
+ });
161
+ }
162
+ }
163
+ }
164
+ }
165
+ const result = {
166
+ dependencies: unique(dependencies).filter((dep) => dep !== filePath),
167
+ tokens: uniqueBy(tokens, (token) => JSON.stringify(token)),
168
+ };
169
+ this.cache.set(filePath, { mtime, result });
170
+ return result;
171
+ }
172
+ }
173
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/locator/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,393 @@
1
+ import { readFile, writeFile } from 'fs/promises';
2
+ import { randomUUID } from 'node:crypto';
3
+ import { jest } from '@jest/globals';
4
+ import dedent from 'dedent';
5
+ import { Locator, createDefaultTransformer } from '../index.js';
6
+ import { createFixtures, getFixturePath } from '../test-util/util.js';
7
+ import { sleepSync } from '../util.js';
8
+ const locator = new Locator();
9
+ test('basic', async () => {
10
+ createFixtures({
11
+ '/test/1.css': dedent `
12
+ .a {}
13
+ .b {}
14
+ `,
15
+ });
16
+ const result = await locator.load(getFixturePath('/test/1.css'));
17
+ expect(result).toMatchInlineSnapshot(`
18
+ {
19
+ dependencies: [],
20
+ tokens: [
21
+ {
22
+ name: "a",
23
+ originalLocation: {
24
+ filePath: "<fixtures>/test/1.css",
25
+ start: { line: 1, column: 1 },
26
+ end: { line: 1, column: 2 },
27
+ },
28
+ },
29
+ {
30
+ name: "b",
31
+ originalLocation: {
32
+ filePath: "<fixtures>/test/1.css",
33
+ start: { line: 2, column: 1 },
34
+ end: { line: 2, column: 2 },
35
+ },
36
+ },
37
+ ],
38
+ }
39
+ `);
40
+ });
41
+ test('tracks other files when `@import` is present', async () => {
42
+ createFixtures({
43
+ '/test/1.css': dedent `
44
+ @import './2.css';
45
+ @import '3.css';
46
+ @import '${getFixturePath('/test/4.css')}';
47
+ @import './5.css';
48
+ `,
49
+ '/test/2.css': dedent `
50
+ .a {}
51
+ `,
52
+ '/test/3.css': dedent `
53
+ .b {}
54
+ `,
55
+ '/test/4.css': dedent `
56
+ .c {}
57
+ `,
58
+ '/test/5.css': dedent `
59
+ @import './5-recursive.css';
60
+ `,
61
+ '/test/5-recursive.css': dedent `
62
+ .d {}
63
+ `,
64
+ });
65
+ const result = await locator.load(getFixturePath('/test/1.css'));
66
+ expect(result).toMatchInlineSnapshot(`
67
+ {
68
+ dependencies: [
69
+ "<fixtures>/test/2.css",
70
+ "<fixtures>/test/3.css",
71
+ "<fixtures>/test/4.css",
72
+ "<fixtures>/test/5.css",
73
+ "<fixtures>/test/5-recursive.css",
74
+ ],
75
+ tokens: [
76
+ {
77
+ name: "a",
78
+ originalLocation: {
79
+ filePath: "<fixtures>/test/2.css",
80
+ start: { line: 1, column: 1 },
81
+ end: { line: 1, column: 2 },
82
+ },
83
+ },
84
+ {
85
+ name: "b",
86
+ originalLocation: {
87
+ filePath: "<fixtures>/test/3.css",
88
+ start: { line: 1, column: 1 },
89
+ end: { line: 1, column: 2 },
90
+ },
91
+ },
92
+ {
93
+ name: "c",
94
+ originalLocation: {
95
+ filePath: "<fixtures>/test/4.css",
96
+ start: { line: 1, column: 1 },
97
+ end: { line: 1, column: 2 },
98
+ },
99
+ },
100
+ {
101
+ name: "d",
102
+ originalLocation: {
103
+ filePath: "<fixtures>/test/5-recursive.css",
104
+ start: { line: 1, column: 1 },
105
+ end: { line: 1, column: 2 },
106
+ },
107
+ },
108
+ ],
109
+ }
110
+ `);
111
+ });
112
+ test('does not track other files by `composes`', async () => {
113
+ createFixtures({
114
+ '/test/1.css': dedent `
115
+ .a {
116
+ composes: b from './2.css';
117
+ composes: c from './3.css'; /* non-existent file */
118
+ }
119
+ `,
120
+ '/test/2.css': dedent `
121
+ .b {}
122
+ `,
123
+ });
124
+ const result = await locator.load(getFixturePath('/test/1.css'));
125
+ expect(result).toMatchInlineSnapshot(`
126
+ {
127
+ dependencies: [],
128
+ tokens: [
129
+ {
130
+ name: "a",
131
+ originalLocation: {
132
+ filePath: "<fixtures>/test/1.css",
133
+ start: { line: 1, column: 1 },
134
+ end: { line: 1, column: 2 },
135
+ },
136
+ },
137
+ ],
138
+ }
139
+ `);
140
+ });
141
+ test('tracks other files when `@value` is present', async () => {
142
+ createFixtures({
143
+ '/test/1.css': dedent `
144
+ @value a from './2.css';
145
+ @value b from '3.css';
146
+ @value c from '${getFixturePath('/test/4.css')}';
147
+ `,
148
+ '/test/2.css': dedent `
149
+ @value a: 1;
150
+ `,
151
+ '/test/3.css': dedent `
152
+ @value b: 2;
153
+ `,
154
+ '/test/4.css': dedent `
155
+ @value c: 3;
156
+ `,
157
+ });
158
+ const result = await locator.load(getFixturePath('/test/1.css'));
159
+ expect(result).toMatchInlineSnapshot(`
160
+ {
161
+ dependencies: ["<fixtures>/test/2.css", "<fixtures>/test/3.css", "<fixtures>/test/4.css"],
162
+ tokens: [
163
+ {
164
+ name: "a",
165
+ originalLocation: {
166
+ filePath: "<fixtures>/test/2.css",
167
+ start: { line: 1, column: 8 },
168
+ end: { line: 1, column: 9 },
169
+ },
170
+ },
171
+ {
172
+ name: "b",
173
+ originalLocation: {
174
+ filePath: "<fixtures>/test/3.css",
175
+ start: { line: 1, column: 8 },
176
+ end: { line: 1, column: 9 },
177
+ },
178
+ },
179
+ {
180
+ name: "c",
181
+ originalLocation: {
182
+ filePath: "<fixtures>/test/4.css",
183
+ start: { line: 1, column: 8 },
184
+ end: { line: 1, column: 9 },
185
+ },
186
+ },
187
+ ],
188
+ }
189
+ `);
190
+ });
191
+ test('unique tokens', async () => {
192
+ createFixtures({
193
+ '/test/1.css': dedent `
194
+ /* duplicate import */
195
+ @import './2.css';
196
+ @import '2.css';
197
+ .a {}
198
+ .a {} /* duplicate class selector */
199
+ `,
200
+ '/test/2.css': dedent `
201
+ .a {} /* class selector that duplicates the import source */
202
+ .b {}
203
+ `,
204
+ });
205
+ const result = await locator.load(getFixturePath('/test/1.css'));
206
+ expect(result).toMatchInlineSnapshot(`
207
+ {
208
+ dependencies: ["<fixtures>/test/2.css"],
209
+ tokens: [
210
+ {
211
+ name: "a",
212
+ originalLocation: {
213
+ filePath: "<fixtures>/test/2.css",
214
+ start: { line: 1, column: 1 },
215
+ end: { line: 1, column: 2 },
216
+ },
217
+ },
218
+ {
219
+ name: "b",
220
+ originalLocation: {
221
+ filePath: "<fixtures>/test/2.css",
222
+ start: { line: 2, column: 1 },
223
+ end: { line: 2, column: 2 },
224
+ },
225
+ },
226
+ {
227
+ name: "a",
228
+ originalLocation: {
229
+ filePath: "<fixtures>/test/1.css",
230
+ start: { line: 4, column: 1 },
231
+ end: { line: 4, column: 2 },
232
+ },
233
+ },
234
+ {
235
+ name: "a",
236
+ originalLocation: {
237
+ filePath: "<fixtures>/test/1.css",
238
+ start: { line: 5, column: 1 },
239
+ end: { line: 5, column: 2 },
240
+ },
241
+ },
242
+ ],
243
+ }
244
+ `);
245
+ });
246
+ test('returns the result from the cache when the file has not been modified', async () => {
247
+ createFixtures({
248
+ '/test/1.css': dedent `
249
+ @import './2.css';
250
+ @import './3.css';
251
+ `,
252
+ '/test/2.css': dedent `
253
+ .b {}
254
+ `,
255
+ '/test/3.css': dedent `
256
+ .c {}
257
+ .d {}
258
+ `,
259
+ });
260
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
261
+ const readCSSSpy = jest.spyOn(locator, 'readCSS');
262
+ await locator.load(getFixturePath('/test/1.css'));
263
+ expect(readCSSSpy).toHaveBeenCalledTimes(3);
264
+ expect(readCSSSpy).toHaveBeenNthCalledWith(1, getFixturePath('/test/1.css'));
265
+ expect(readCSSSpy).toHaveBeenNthCalledWith(2, getFixturePath('/test/2.css'));
266
+ expect(readCSSSpy).toHaveBeenNthCalledWith(3, getFixturePath('/test/3.css'));
267
+ readCSSSpy.mockClear();
268
+ // update `/test/2.css`
269
+ sleepSync(1); // wait for the file system to update the mtime
270
+ await writeFile(getFixturePath('/test/2.css'), await readFile(getFixturePath('/test/2.css'), 'utf-8'));
271
+ // `3.css` is not updated, so the cache is used. Therefore, `readFile` is not called.
272
+ await locator.load(getFixturePath('/test/3.css'));
273
+ expect(readCSSSpy).toHaveBeenCalledTimes(0);
274
+ // `1.css` is not updated, but dependencies are updated, so the cache is used. Therefore, `readFile` is called.
275
+ await locator.load(getFixturePath('/test/1.css'));
276
+ expect(readCSSSpy).toHaveBeenCalledTimes(2);
277
+ expect(readCSSSpy).toHaveBeenNthCalledWith(1, getFixturePath('/test/1.css'));
278
+ expect(readCSSSpy).toHaveBeenNthCalledWith(2, getFixturePath('/test/2.css'));
279
+ // ``2.css` is updated, but the cache is already available because it was updated in the previous step. Therefore, `readFile` is not called.
280
+ await locator.load(getFixturePath('/test/2.css'));
281
+ expect(readCSSSpy).toHaveBeenCalledTimes(2);
282
+ });
283
+ describe('supports sourcemap', () => {
284
+ test('restores original locations from sourcemap', async () => {
285
+ const transformer = createDefaultTransformer();
286
+ const locator = new Locator({ transformer });
287
+ createFixtures({
288
+ '/test/1.scss': dedent `
289
+ .nesting {
290
+ dummy: '';
291
+ .nesting_child {
292
+ dummy: '';
293
+ }
294
+ }
295
+ `,
296
+ });
297
+ const result = await locator.load(getFixturePath('/test/1.scss'));
298
+ expect(result).toMatchInlineSnapshot(`
299
+ {
300
+ dependencies: [],
301
+ tokens: [
302
+ {
303
+ name: "nesting",
304
+ originalLocation: {
305
+ filePath: "<fixtures>/test/1.scss",
306
+ start: { line: 1, column: 1 },
307
+ end: { line: 1, column: 8 },
308
+ },
309
+ },
310
+ {
311
+ name: "nesting",
312
+ originalLocation: {
313
+ filePath: "<fixtures>/test/1.scss",
314
+ start: { line: 3, column: 3 },
315
+ end: { line: 3, column: 10 },
316
+ },
317
+ },
318
+ {
319
+ name: "nesting_child",
320
+ originalLocation: {
321
+ filePath: "<fixtures>/test/1.scss",
322
+ start: { line: 3, column: 3 },
323
+ end: { line: 3, column: 16 },
324
+ },
325
+ },
326
+ ],
327
+ }
328
+ `);
329
+ });
330
+ test('treats originalLocation as empty if sourcemap is broken', async () => {
331
+ const uuid = randomUUID();
332
+ createFixtures({
333
+ [`/${uuid}/postcss.config.js`]: dedent `
334
+ module.exports = {
335
+ plugins: [],
336
+ };
337
+ `,
338
+ '/test/1.css': dedent `
339
+ .selector_list_a_1, .selector_list_a_2 {}
340
+ /* In postcss, including newlines in the selector list breaks the sourcemap. */
341
+ .selector_list_b_1,
342
+ .selector_list_b_2 {}
343
+ `,
344
+ });
345
+ const transformer = createDefaultTransformer({ postcssConfig: getFixturePath(`/${uuid}/postcss.config.js`) });
346
+ const locator = new Locator({ transformer });
347
+ const result = await locator.load(getFixturePath('/test/1.css'));
348
+ expect(result).toMatchInlineSnapshot(`
349
+ {
350
+ dependencies: [],
351
+ tokens: [
352
+ {
353
+ name: "selector_list_a_1",
354
+ originalLocation: {
355
+ filePath: "<fixtures>/test/1.css",
356
+ start: { line: 1, column: 1 },
357
+ end: { line: 1, column: 18 },
358
+ },
359
+ },
360
+ {
361
+ name: "selector_list_a_2",
362
+ originalLocation: {
363
+ filePath: "<fixtures>/test/1.css",
364
+ start: { line: 1, column: 1 },
365
+ end: { line: 1, column: 18 },
366
+ },
367
+ },
368
+ { name: "selector_list_b_1", originalLocation: {} },
369
+ { name: "selector_list_b_2", originalLocation: {} },
370
+ ],
371
+ }
372
+ `);
373
+ });
374
+ });
375
+ test('ignores http(s) protocol file', async () => {
376
+ createFixtures({
377
+ '/test/1.css': dedent `
378
+ @import 'http://example.com/path/http.css';
379
+ @import 'https://example.com/path/https.css';
380
+ `,
381
+ });
382
+ const result = await locator.load(getFixturePath('/test/1.css'));
383
+ expect(result.dependencies).toStrictEqual([]);
384
+ });
385
+ test('block concurrent calls to load method', async () => {
386
+ createFixtures({
387
+ '/test/1.css': `.a {}`,
388
+ });
389
+ await expect(async () => {
390
+ await Promise.all([locator.load(getFixturePath('/test/1.css')), locator.load(getFixturePath('/test/1.css'))]);
391
+ }).rejects.toThrowError('Cannot call `Locator#load` concurrently.');
392
+ });
393
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../src/locator/index.test.ts"],"names":[],"mappings":"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"}