happy-css-modules 3.1.0 → 3.2.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/dist/cli.d.ts +6 -0
- package/dist/cli.js +127 -0
- package/dist/cli.js.map +1 -0
- package/dist/cli.test.d.ts +1 -0
- package/dist/cli.test.js +66 -0
- package/dist/cli.test.js.map +1 -0
- package/dist/config.d.ts +1 -0
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -0
- package/dist/emitter/dts.d.ts +15 -0
- package/dist/emitter/dts.js +134 -0
- package/dist/emitter/dts.js.map +1 -0
- package/dist/emitter/dts.test.d.ts +1 -0
- package/dist/emitter/dts.test.js +206 -0
- package/dist/emitter/dts.test.js.map +1 -0
- package/dist/emitter/file-system.d.ts +6 -0
- package/dist/emitter/file-system.js +26 -0
- package/dist/emitter/file-system.js.map +1 -0
- package/dist/emitter/file-system.test.d.ts +1 -0
- package/dist/emitter/file-system.test.js +34 -0
- package/dist/emitter/file-system.test.js.map +1 -0
- package/dist/emitter/index.d.ts +42 -0
- package/dist/emitter/index.js +49 -0
- package/dist/emitter/index.js.map +1 -0
- package/dist/emitter/index.test.d.ts +1 -0
- package/dist/emitter/index.test.js +76 -0
- package/dist/emitter/index.test.js.map +1 -0
- package/dist/emitter/source-map.d.ts +10 -0
- package/dist/emitter/source-map.js +17 -0
- package/dist/emitter/source-map.js.map +1 -0
- package/dist/emitter/source-map.test.d.ts +1 -0
- package/dist/emitter/source-map.test.js +13 -0
- package/dist/emitter/source-map.test.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/integration-test/go-to-definition.test.d.ts +1 -0
- package/dist/integration-test/go-to-definition.test.js +334 -0
- package/dist/integration-test/go-to-definition.test.js.map +1 -0
- package/dist/locator/index.d.ts +46 -0
- package/dist/locator/index.js +173 -0
- package/dist/locator/index.js.map +1 -0
- package/dist/locator/index.test.d.ts +1 -0
- package/dist/locator/index.test.js +393 -0
- package/dist/locator/index.test.js.map +1 -0
- package/dist/locator/postcss.d.ts +91 -0
- package/dist/locator/postcss.js +241 -0
- package/dist/locator/postcss.js.map +1 -0
- package/dist/locator/postcss.test.d.ts +1 -0
- package/dist/locator/postcss.test.js +256 -0
- package/dist/locator/postcss.test.js.map +1 -0
- package/dist/logger.d.ts +9 -0
- package/dist/logger.js +28 -0
- package/dist/logger.js.map +1 -0
- package/dist/regression-test/issue-168.test.d.ts +1 -0
- package/dist/regression-test/issue-168.test.js +30 -0
- package/dist/regression-test/issue-168.test.js.map +1 -0
- package/dist/resolver/index.d.ts +22 -0
- package/dist/resolver/index.js +44 -0
- package/dist/resolver/index.js.map +1 -0
- package/dist/resolver/index.test.d.ts +1 -0
- package/dist/resolver/index.test.js +16 -0
- package/dist/resolver/index.test.js.map +1 -0
- package/dist/resolver/node-resolver.d.ts +2 -0
- package/dist/resolver/node-resolver.js +6 -0
- package/dist/resolver/node-resolver.js.map +1 -0
- package/dist/resolver/node-resolver.test.d.ts +1 -0
- package/dist/resolver/node-resolver.test.js +25 -0
- package/dist/resolver/node-resolver.test.js.map +1 -0
- package/dist/resolver/relative-resolver.d.ts +2 -0
- package/dist/resolver/relative-resolver.js +5 -0
- package/dist/resolver/relative-resolver.js.map +1 -0
- package/dist/resolver/relative-resolver.test.d.ts +1 -0
- package/dist/resolver/relative-resolver.test.js +12 -0
- package/dist/resolver/relative-resolver.test.js.map +1 -0
- package/dist/resolver/webpack-resolver.d.ts +24 -0
- package/dist/resolver/webpack-resolver.js +91 -0
- package/dist/resolver/webpack-resolver.js.map +1 -0
- package/dist/resolver/webpack-resolver.test.d.ts +1 -0
- package/dist/resolver/webpack-resolver.test.js +89 -0
- package/dist/resolver/webpack-resolver.test.js.map +1 -0
- package/dist/runner.d.ts +78 -0
- package/dist/runner.js +122 -0
- package/dist/runner.js.map +1 -0
- package/dist/runner.test.d.ts +1 -0
- package/dist/runner.test.js +304 -0
- package/dist/runner.test.js.map +1 -0
- package/dist/test-util/jest/resolver.cjs +31 -0
- package/dist/test-util/jest/resolver.cjs.map +1 -0
- package/dist/test-util/jest/resolver.d.cts +16 -0
- package/dist/test-util/tsserver.d.ts +31 -0
- package/dist/test-util/tsserver.js +112 -0
- package/dist/test-util/tsserver.js.map +1 -0
- package/dist/test-util/util.d.ts +29 -0
- package/dist/test-util/util.js +85 -0
- package/dist/test-util/util.js.map +1 -0
- package/dist/transformer/index.d.ts +30 -0
- package/dist/transformer/index.js +25 -0
- package/dist/transformer/index.js.map +1 -0
- package/dist/transformer/index.test.d.ts +1 -0
- package/dist/transformer/index.test.js +66 -0
- package/dist/transformer/index.test.js.map +1 -0
- package/dist/transformer/less-transformer.d.ts +2 -0
- package/dist/transformer/less-transformer.js +45 -0
- package/dist/transformer/less-transformer.js.map +1 -0
- package/dist/transformer/less-transformer.test.d.ts +1 -0
- package/dist/transformer/less-transformer.test.js +134 -0
- package/dist/transformer/less-transformer.test.js.map +1 -0
- package/dist/transformer/postcss-transformer.d.ts +12 -0
- package/dist/transformer/postcss-transformer.js +32 -0
- package/dist/transformer/postcss-transformer.js.map +1 -0
- package/dist/transformer/postcss-transformer.test.d.ts +1 -0
- package/dist/transformer/postcss-transformer.test.js +178 -0
- package/dist/transformer/postcss-transformer.test.js.map +1 -0
- package/dist/transformer/scss-transformer.d.ts +2 -0
- package/dist/transformer/scss-transformer.js +40 -0
- package/dist/transformer/scss-transformer.js.map +1 -0
- package/dist/transformer/scss-transformer.test.d.ts +1 -0
- package/dist/transformer/scss-transformer.test.js +149 -0
- package/dist/transformer/scss-transformer.test.js.map +1 -0
- package/dist/util.d.ts +21 -0
- package/dist/util.js +72 -0
- package/dist/util.js.map +1 -0
- package/dist/util.test.d.ts +1 -0
- package/dist/util.test.js +74 -0
- package/dist/util.test.js.map +1 -0
- package/package.json +1 -1
- package/src/cli.ts +6 -0
- package/src/emitter/dts.test.ts +7 -4
- package/src/emitter/dts.ts +22 -10
- package/src/emitter/index.test.ts +10 -0
- package/src/emitter/index.ts +17 -4
- package/src/emitter/source-map.test.ts +4 -4
- package/src/emitter/source-map.ts +8 -2
- package/src/runner.test.ts +23 -0
- package/src/runner.ts +6 -0
- package/src/library/README.md +0 -3
- package/src/library/source-map/index.ts +0 -26
|
@@ -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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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { type Rule, type AtRule, type Root } from 'postcss';
|
|
2
|
+
import { type ClassName } from 'postcss-selector-parser';
|
|
3
|
+
/** The pair of line number and column number. */
|
|
4
|
+
export type Position = {
|
|
5
|
+
/** The line number in the source file. It is 1-based (compatible with postcss). */
|
|
6
|
+
line: number;
|
|
7
|
+
/** The column number in the source file. It is 1-based (compatible with postcss). */
|
|
8
|
+
column: number;
|
|
9
|
+
};
|
|
10
|
+
/** The original location of class selector. If the original location is not found, all fields are `undefined`. */
|
|
11
|
+
export type Location = {
|
|
12
|
+
filePath: string;
|
|
13
|
+
/** The inclusive starting position of the node's source (compatible with postcss). */
|
|
14
|
+
start: Position;
|
|
15
|
+
/** The inclusive ending position of the node's source (compatible with postcss). */
|
|
16
|
+
end: Position;
|
|
17
|
+
} | {
|
|
18
|
+
filePath: undefined;
|
|
19
|
+
start: undefined;
|
|
20
|
+
end: undefined;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Traverses a local token from the AST and returns its name.
|
|
24
|
+
* @param ast The AST to traverse.
|
|
25
|
+
* @returns The name of the local token.
|
|
26
|
+
*/
|
|
27
|
+
export declare function generateLocalTokenNames(ast: Root): Promise<string[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Get the original location of the class selector.
|
|
30
|
+
* @param rule The rule node that contains the token.
|
|
31
|
+
* @param classSelector The class selector node that contains the token.
|
|
32
|
+
* @returns The original location of the class selector.
|
|
33
|
+
*/
|
|
34
|
+
export declare function getOriginalLocationOfClassSelector(rule: Rule, classSelector: ClassName): Location;
|
|
35
|
+
/**
|
|
36
|
+
* Get the original location of `@value`.
|
|
37
|
+
* @param atValue The `@value` rule.
|
|
38
|
+
* @returns The location of the `@value` rule.
|
|
39
|
+
*/
|
|
40
|
+
export declare function getOriginalLocationOfAtValue(atValue: AtRule, valueDeclaration: ValueDeclaration): Location;
|
|
41
|
+
type CollectNodesResult = {
|
|
42
|
+
atImports: AtRule[];
|
|
43
|
+
atValues: AtRule[];
|
|
44
|
+
classSelectors: {
|
|
45
|
+
rule: Rule;
|
|
46
|
+
classSelector: ClassName;
|
|
47
|
+
}[];
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Collect nodes from the AST.
|
|
51
|
+
* @param ast The AST.
|
|
52
|
+
*/
|
|
53
|
+
export declare function collectNodes(ast: Root): CollectNodesResult;
|
|
54
|
+
/**
|
|
55
|
+
* Parse the `@import` rule.
|
|
56
|
+
* @param atImport The `@import` rule to parse.
|
|
57
|
+
* @returns The imported sheet path.
|
|
58
|
+
*/
|
|
59
|
+
export declare function parseAtImport(atImport: AtRule): string | undefined;
|
|
60
|
+
type ValueDeclaration = {
|
|
61
|
+
type: 'valueDeclaration';
|
|
62
|
+
tokenName: string;
|
|
63
|
+
};
|
|
64
|
+
type ValueImportDeclaration = {
|
|
65
|
+
type: 'valueImportDeclaration';
|
|
66
|
+
imports: {
|
|
67
|
+
importedTokenName: string;
|
|
68
|
+
localTokenName: string;
|
|
69
|
+
}[];
|
|
70
|
+
from: string;
|
|
71
|
+
};
|
|
72
|
+
type ParsedAtValue = ValueDeclaration | ValueImportDeclaration;
|
|
73
|
+
/**
|
|
74
|
+
* Parse the `@value` rule.
|
|
75
|
+
* Forked from https://github.com/css-modules/postcss-modules-values/blob/v4.0.0/src/index.js.
|
|
76
|
+
*
|
|
77
|
+
* @license
|
|
78
|
+
* ISC License (ISC)
|
|
79
|
+
* Copyright (c) 2015, Glen Maddern
|
|
80
|
+
*
|
|
81
|
+
* Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted,
|
|
82
|
+
* provided that the above copyright notice and this permission notice appear in all copies.
|
|
83
|
+
*
|
|
84
|
+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING
|
|
85
|
+
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
86
|
+
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
87
|
+
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
|
88
|
+
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
89
|
+
*/
|
|
90
|
+
export declare function parseAtValue(atValue: AtRule): ParsedAtValue;
|
|
91
|
+
export {};
|