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.
Files changed (138) hide show
  1. package/dist/cli.d.ts +6 -0
  2. package/dist/cli.js +127 -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 +15 -0
  11. package/dist/emitter/dts.js +134 -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 +206 -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 +42 -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 +76 -0
  27. package/dist/emitter/index.test.js.map +1 -0
  28. package/dist/emitter/source-map.d.ts +10 -0
  29. package/dist/emitter/source-map.js +17 -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/locator/index.d.ts +46 -0
  41. package/dist/locator/index.js +173 -0
  42. package/dist/locator/index.js.map +1 -0
  43. package/dist/locator/index.test.d.ts +1 -0
  44. package/dist/locator/index.test.js +393 -0
  45. package/dist/locator/index.test.js.map +1 -0
  46. package/dist/locator/postcss.d.ts +91 -0
  47. package/dist/locator/postcss.js +241 -0
  48. package/dist/locator/postcss.js.map +1 -0
  49. package/dist/locator/postcss.test.d.ts +1 -0
  50. package/dist/locator/postcss.test.js +256 -0
  51. package/dist/locator/postcss.test.js.map +1 -0
  52. package/dist/logger.d.ts +9 -0
  53. package/dist/logger.js +28 -0
  54. package/dist/logger.js.map +1 -0
  55. package/dist/regression-test/issue-168.test.d.ts +1 -0
  56. package/dist/regression-test/issue-168.test.js +30 -0
  57. package/dist/regression-test/issue-168.test.js.map +1 -0
  58. package/dist/resolver/index.d.ts +22 -0
  59. package/dist/resolver/index.js +44 -0
  60. package/dist/resolver/index.js.map +1 -0
  61. package/dist/resolver/index.test.d.ts +1 -0
  62. package/dist/resolver/index.test.js +16 -0
  63. package/dist/resolver/index.test.js.map +1 -0
  64. package/dist/resolver/node-resolver.d.ts +2 -0
  65. package/dist/resolver/node-resolver.js +6 -0
  66. package/dist/resolver/node-resolver.js.map +1 -0
  67. package/dist/resolver/node-resolver.test.d.ts +1 -0
  68. package/dist/resolver/node-resolver.test.js +25 -0
  69. package/dist/resolver/node-resolver.test.js.map +1 -0
  70. package/dist/resolver/relative-resolver.d.ts +2 -0
  71. package/dist/resolver/relative-resolver.js +5 -0
  72. package/dist/resolver/relative-resolver.js.map +1 -0
  73. package/dist/resolver/relative-resolver.test.d.ts +1 -0
  74. package/dist/resolver/relative-resolver.test.js +12 -0
  75. package/dist/resolver/relative-resolver.test.js.map +1 -0
  76. package/dist/resolver/webpack-resolver.d.ts +24 -0
  77. package/dist/resolver/webpack-resolver.js +91 -0
  78. package/dist/resolver/webpack-resolver.js.map +1 -0
  79. package/dist/resolver/webpack-resolver.test.d.ts +1 -0
  80. package/dist/resolver/webpack-resolver.test.js +89 -0
  81. package/dist/resolver/webpack-resolver.test.js.map +1 -0
  82. package/dist/runner.d.ts +78 -0
  83. package/dist/runner.js +122 -0
  84. package/dist/runner.js.map +1 -0
  85. package/dist/runner.test.d.ts +1 -0
  86. package/dist/runner.test.js +304 -0
  87. package/dist/runner.test.js.map +1 -0
  88. package/dist/test-util/jest/resolver.cjs +31 -0
  89. package/dist/test-util/jest/resolver.cjs.map +1 -0
  90. package/dist/test-util/jest/resolver.d.cts +16 -0
  91. package/dist/test-util/tsserver.d.ts +31 -0
  92. package/dist/test-util/tsserver.js +112 -0
  93. package/dist/test-util/tsserver.js.map +1 -0
  94. package/dist/test-util/util.d.ts +29 -0
  95. package/dist/test-util/util.js +85 -0
  96. package/dist/test-util/util.js.map +1 -0
  97. package/dist/transformer/index.d.ts +30 -0
  98. package/dist/transformer/index.js +25 -0
  99. package/dist/transformer/index.js.map +1 -0
  100. package/dist/transformer/index.test.d.ts +1 -0
  101. package/dist/transformer/index.test.js +66 -0
  102. package/dist/transformer/index.test.js.map +1 -0
  103. package/dist/transformer/less-transformer.d.ts +2 -0
  104. package/dist/transformer/less-transformer.js +45 -0
  105. package/dist/transformer/less-transformer.js.map +1 -0
  106. package/dist/transformer/less-transformer.test.d.ts +1 -0
  107. package/dist/transformer/less-transformer.test.js +134 -0
  108. package/dist/transformer/less-transformer.test.js.map +1 -0
  109. package/dist/transformer/postcss-transformer.d.ts +12 -0
  110. package/dist/transformer/postcss-transformer.js +32 -0
  111. package/dist/transformer/postcss-transformer.js.map +1 -0
  112. package/dist/transformer/postcss-transformer.test.d.ts +1 -0
  113. package/dist/transformer/postcss-transformer.test.js +178 -0
  114. package/dist/transformer/postcss-transformer.test.js.map +1 -0
  115. package/dist/transformer/scss-transformer.d.ts +2 -0
  116. package/dist/transformer/scss-transformer.js +40 -0
  117. package/dist/transformer/scss-transformer.js.map +1 -0
  118. package/dist/transformer/scss-transformer.test.d.ts +1 -0
  119. package/dist/transformer/scss-transformer.test.js +149 -0
  120. package/dist/transformer/scss-transformer.test.js.map +1 -0
  121. package/dist/util.d.ts +21 -0
  122. package/dist/util.js +72 -0
  123. package/dist/util.js.map +1 -0
  124. package/dist/util.test.d.ts +1 -0
  125. package/dist/util.test.js +74 -0
  126. package/dist/util.test.js.map +1 -0
  127. package/package.json +1 -1
  128. package/src/cli.ts +6 -0
  129. package/src/emitter/dts.test.ts +7 -4
  130. package/src/emitter/dts.ts +22 -10
  131. package/src/emitter/index.test.ts +10 -0
  132. package/src/emitter/index.ts +17 -4
  133. package/src/emitter/source-map.test.ts +4 -4
  134. package/src/emitter/source-map.ts +8 -2
  135. package/src/runner.test.ts +23 -0
  136. package/src/runner.ts +6 -0
  137. package/src/library/README.md +0 -3
  138. package/src/library/source-map/index.ts +0 -26
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/test-util/util.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ import type { StrictlyResolver } from '../locator/index.js';
3
+ import type { PostcssTransformerOptions } from './postcss-transformer.js';
4
+ /**
5
+ * The value returned from the transformer.
6
+ * `false` means to skip transpiling on that file.
7
+ */
8
+ export type TransformResult = {
9
+ /** The transformed code. */
10
+ css: string;
11
+ /** The source map from the transformed code to the original code. */
12
+ map: string | object;
13
+ dependencies: (string | URL)[];
14
+ } | false;
15
+ export type TransformerOptions = {
16
+ /** The path of the file to transform. */
17
+ from: string;
18
+ /** The function to resolve the path of the imported file. */
19
+ resolver: StrictlyResolver;
20
+ /**
21
+ * Whether the specifier should be ignored.
22
+ * For example, specifiers starting with `http://` or `https://` should be ignored.
23
+ */
24
+ isIgnoredSpecifier: (specifier: string) => boolean;
25
+ };
26
+ /** The function to transform source code. */
27
+ export type Transformer = (source: string, options: TransformerOptions) => TransformResult | Promise<TransformResult>;
28
+ export declare const handleImportError: (packageName: string) => (e: unknown) => never;
29
+ export type DefaultTransformerOptions = PostcssTransformerOptions;
30
+ export declare const createDefaultTransformer: (defaultTransformerOptions?: DefaultTransformerOptions) => Transformer;
@@ -0,0 +1,25 @@
1
+ import { createLessTransformer } from './less-transformer.js';
2
+ import { createPostcssTransformer } from './postcss-transformer.js';
3
+ import { createScssTransformer } from './scss-transformer.js';
4
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars -- TODO: pass `e` to Error's cause option
5
+ export const handleImportError = (packageName) => (e) => {
6
+ throw new Error(`${packageName} import failed. Did you forget to \`npm install -D ${packageName}\`?`);
7
+ };
8
+ export const createDefaultTransformer = (defaultTransformerOptions) => {
9
+ const scssTransformer = createScssTransformer();
10
+ const lessTransformer = createLessTransformer();
11
+ const postcssTransformer = createPostcssTransformer(defaultTransformerOptions);
12
+ return async (source, options) => {
13
+ if (options.from.endsWith('.scss')) {
14
+ return scssTransformer(source, options);
15
+ }
16
+ else if (options.from.endsWith('.less')) {
17
+ return lessTransformer(source, options);
18
+ }
19
+ else {
20
+ // TODO: Support multi-stage transformations by sass and less.
21
+ return postcssTransformer(source, options);
22
+ }
23
+ };
24
+ };
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/transformer/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AA+B9D,uGAAuG;AACvG,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,WAAmB,EAAE,EAAE,CAAC,CAAC,CAAU,EAAE,EAAE;IACvE,MAAM,IAAI,KAAK,CAAC,GAAG,WAAW,sDAAsD,WAAW,KAAK,CAAC,CAAC;AACxG,CAAC,CAAC;AAIF,MAAM,CAAC,MAAM,wBAAwB,GAA2E,CAC9G,yBAAyB,EACzB,EAAE;IACF,MAAM,eAAe,GAAG,qBAAqB,EAAE,CAAC;IAChD,MAAM,eAAe,GAAG,qBAAqB,EAAE,CAAC;IAChD,MAAM,kBAAkB,GAAG,wBAAwB,CAAC,yBAAyB,CAAC,CAAC;IAC/E,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;QAC/B,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACnC,OAAO,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC1C,CAAC;aAAM,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1C,OAAO,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,8DAA8D;YAC9D,OAAO,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,66 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { createRequire } from 'node:module';
3
+ import dedent from 'dedent';
4
+ import { Locator } from '../locator/index.js';
5
+ import { createFixtures, getFixturePath } from '../test-util/util.js';
6
+ import { createDefaultTransformer } from './index.js';
7
+ const require = createRequire(import.meta.url);
8
+ const cwd = getFixturePath('/');
9
+ const locator = new Locator({ transformer: createDefaultTransformer({ cwd }) });
10
+ test('processes .scss with scss transformer', async () => {
11
+ createFixtures({
12
+ '/test/1.scss': dedent `
13
+ .a {
14
+ // scss feature test (nesting)
15
+ .a_1 { dummy: ''; }
16
+ }
17
+ `,
18
+ });
19
+ const result = await locator.load(getFixturePath('/test/1.scss'));
20
+ expect(result.tokens.map((token) => token.name)).toStrictEqual(['a', 'a_1']);
21
+ });
22
+ test('processes .less with less transformer', async () => {
23
+ createFixtures({
24
+ '/test/1.less': dedent `
25
+ .a {
26
+ // less feature test (nesting)
27
+ .a_1 { dummy: ''; }
28
+ }
29
+ `,
30
+ });
31
+ const result = await locator.load(getFixturePath('/test/1.less'));
32
+ expect(result.tokens.map((token) => token.name)).toStrictEqual(['a', 'a_1']);
33
+ });
34
+ test('processes .css with postcss transformer if postcssrc is found', async () => {
35
+ // if postcssrc is not found
36
+ const locator1 = new Locator({ transformer: createDefaultTransformer() });
37
+ createFixtures({
38
+ '/test/1.css': dedent `
39
+ $prefix: foo;
40
+ .$(prefix)_bar {}
41
+ `,
42
+ });
43
+ const result1 = await locator1.load(getFixturePath('/test/1.css'));
44
+ expect(result1.tokens.map((token) => token.name)).toStrictEqual(['$(prefix)']);
45
+ // if postcssrc is found
46
+ const uuid = randomUUID();
47
+ const locator2 = new Locator({
48
+ transformer: createDefaultTransformer({ cwd, postcssConfig: `${uuid}/postcss.config.js` }),
49
+ });
50
+ createFixtures({
51
+ [`/${uuid}/postcss.config.js`]: dedent `
52
+ module.exports = {
53
+ plugins: [
54
+ require('${require.resolve('postcss-simple-vars')}'),
55
+ ],
56
+ };
57
+ `,
58
+ '/test/1.css': dedent `
59
+ $prefix: foo;
60
+ .$(prefix)_bar {}
61
+ `,
62
+ });
63
+ const result2 = await locator2.load(getFixturePath('/test/1.css'));
64
+ expect(result2.tokens.map((token) => token.name)).toStrictEqual(['foo_bar']);
65
+ });
66
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../src/transformer/index.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAEtD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;AAChC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,EAAE,WAAW,EAAE,wBAAwB,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;AAEhF,IAAI,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;IACvD,cAAc,CAAC;QACb,cAAc,EAAE,MAAM,CAAA;;;;;KAKrB;KACF,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC;IAClE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AAC/E,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;IACvD,cAAc,CAAC;QACb,cAAc,EAAE,MAAM,CAAA;;;;;KAKrB;KACF,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC;IAClE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AAC/E,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;IAC/E,4BAA4B;IAC5B,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAC,EAAE,WAAW,EAAE,wBAAwB,EAAE,EAAE,CAAC,CAAC;IAC1E,cAAc,CAAC;QACb,aAAa,EAAE,MAAM,CAAA;;;KAGpB;KACF,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC,CAAC;IACnE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IAE/E,wBAAwB;IACxB,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;IAC1B,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAC;QAC3B,WAAW,EAAE,wBAAwB,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG,IAAI,oBAAoB,EAAE,CAAC;KAC3F,CAAC,CAAC;IACH,cAAc,CAAC;QACb,CAAC,IAAI,IAAI,oBAAoB,CAAC,EAAE,MAAM,CAAA;;;mBAGvB,OAAO,CAAC,OAAO,CAAC,qBAAqB,CAAC;;;KAGpD;QACD,aAAa,EAAE,MAAM,CAAA;;;KAGpB;KACF,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC,CAAC;IACnE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AAC/E,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { Transformer } from '../index.js';
2
+ export declare const createLessTransformer: () => Transformer;
@@ -0,0 +1,45 @@
1
+ import { handleImportError } from './index.js';
2
+ // eslint-disable-next-line @typescript-eslint/naming-convention
3
+ function createLessPluginResolver(Less, options) {
4
+ class ResolverFileManager extends Less.FileManager {
5
+ constructor(options) {
6
+ super();
7
+ this.options = options;
8
+ }
9
+ supports() {
10
+ return true;
11
+ }
12
+ async loadFile(filename, currentDirectory, options, environment) {
13
+ // The http/https file is treated as an empty file.
14
+ if (this.options.isIgnoredSpecifier(filename))
15
+ return { contents: '', filename };
16
+ const resolved = await this.options.resolver(filename, { request: currentDirectory });
17
+ return super.loadFile(resolved, currentDirectory, options, environment);
18
+ }
19
+ }
20
+ class LessPluginResolver {
21
+ constructor(options) {
22
+ this.minVersion = [2, 1, 1];
23
+ this.options = options;
24
+ }
25
+ install(less, pluginManager) {
26
+ pluginManager.addFileManager(new ResolverFileManager(this.options));
27
+ }
28
+ }
29
+ return new LessPluginResolver(options);
30
+ }
31
+ export const createLessTransformer = () => {
32
+ let less;
33
+ return async (source, options) => {
34
+ // eslint-disable-next-line require-atomic-updates
35
+ less ??= (await import('less').catch(handleImportError('less'))).default;
36
+ const result = await less.render(source, {
37
+ filename: options.from,
38
+ sourceMap: {},
39
+ plugins: [createLessPluginResolver(less, options)],
40
+ syncImport: false, // Don't use `Less.FileManager#loadFileSync`.
41
+ });
42
+ return { css: result.css, map: result.map, dependencies: result.imports };
43
+ };
44
+ };
45
+ //# sourceMappingURL=less-transformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"less-transformer.js","sourceRoot":"","sources":["../../src/transformer/less-transformer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,gEAAgE;AAChE,SAAS,wBAAwB,CAAC,IAA2B,EAAE,OAA2B;IACxF,MAAM,mBAAoB,SAAQ,IAAI,CAAC,WAAW;QAEhD,YAAY,OAA2B;YACrC,KAAK,EAAE,CAAC;YACR,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACzB,CAAC;QACe,QAAQ;YACtB,OAAO,IAAI,CAAC;QACd,CAAC;QACe,KAAK,CAAC,QAAQ,CAC5B,QAAgB,EAChB,gBAAwB,EACxB,OAA6B,EAC7B,WAA6B;YAE7B,mDAAmD;YACnD,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,QAAQ,CAAC;gBAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;YAEjF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC;YACtF,OAAO,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;QAC1E,CAAC;KACF;IAED,MAAM,kBAAkB;QAEtB,YAAY,OAA2B;YAMhC,eAAU,GAA6B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YALtD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACzB,CAAC;QACM,OAAO,CAAC,IAAgB,EAAE,aAAiC;YAChE,aAAa,CAAC,cAAc,CAAC,IAAI,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACtE,CAAC;KAEF;IAED,OAAO,IAAI,kBAAkB,CAAC,OAAO,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAsB,GAAG,EAAE;IAC3D,IAAI,IAA2B,CAAC;IAChC,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;QAC/B,kDAAkD;QAClD,IAAI,KAAK,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACzE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;YACvC,QAAQ,EAAE,OAAO,CAAC,IAAI;YACtB,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,CAAC,wBAAwB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAClD,UAAU,EAAE,KAAK,EAAE,6CAA6C;SACjE,CAAC,CAAC;QACH,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,YAAY,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IAC5E,CAAC,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,134 @@
1
+ import { jest } from '@jest/globals';
2
+ import dedent from 'dedent';
3
+ import { Locator } from '../locator/index.js';
4
+ import { createFixtures, getFixturePath } from '../test-util/util.js';
5
+ import { createLessTransformer } from './less-transformer.js';
6
+ const locator = new Locator({ transformer: createLessTransformer() });
7
+ const loadSpy = jest.spyOn(locator, 'load');
8
+ afterEach(() => {
9
+ loadSpy.mockClear();
10
+ });
11
+ test('handles less features', async () => {
12
+ createFixtures({
13
+ '/test/1.less': dedent `
14
+ @import './2.less'; // less feature test (@use)
15
+ .a_1 { dummy: ''; }
16
+ .a_2 {
17
+ dummy: '';
18
+ // less feature test (nesting)
19
+ .a_2_1 { dummy: ''; }
20
+ &_2 { dummy: ''; }
21
+ .b_1();
22
+ .b_2();
23
+ }
24
+ `,
25
+ '/test/2.less': dedent `
26
+ .b_1 { dummy: ''; }
27
+ .b_2() { dummy: ''; }
28
+ `,
29
+ '/test/3.less': dedent `
30
+ .c { dummy: ''; }
31
+ `,
32
+ });
33
+ const result = await locator.load(getFixturePath('/test/1.less'));
34
+ // FIXME: The end position of 'a_2_2' is incorrect.
35
+ expect(result).toMatchInlineSnapshot(`
36
+ {
37
+ dependencies: ["<fixtures>/test/2.less"],
38
+ tokens: [
39
+ {
40
+ name: "b_1",
41
+ originalLocation: {
42
+ filePath: "<fixtures>/test/2.less",
43
+ start: { line: 1, column: 1 },
44
+ end: { line: 1, column: 4 },
45
+ },
46
+ },
47
+ {
48
+ name: "a_1",
49
+ originalLocation: {
50
+ filePath: "<fixtures>/test/1.less",
51
+ start: { line: 2, column: 1 },
52
+ end: { line: 2, column: 4 },
53
+ },
54
+ },
55
+ {
56
+ name: "a_2",
57
+ originalLocation: {
58
+ filePath: "<fixtures>/test/1.less",
59
+ start: { line: 3, column: 1 },
60
+ end: { line: 3, column: 4 },
61
+ },
62
+ },
63
+ {
64
+ name: "a_2_1",
65
+ originalLocation: {
66
+ filePath: "<fixtures>/test/1.less",
67
+ start: { line: 6, column: 3 },
68
+ end: { line: 6, column: 8 },
69
+ },
70
+ },
71
+ {
72
+ name: "a_2_2",
73
+ originalLocation: {
74
+ filePath: "<fixtures>/test/1.less",
75
+ start: { line: 7, column: 3 },
76
+ end: { line: 7, column: 8 },
77
+ },
78
+ },
79
+ ],
80
+ }
81
+ `);
82
+ });
83
+ test('tracks dependencies that have been pre-bundled by less compiler', async () => {
84
+ createFixtures({
85
+ '/test/1.less': dedent `
86
+ @import './2.less';
87
+ @import './3.less';
88
+ `,
89
+ '/test/2.less': dedent `
90
+ `,
91
+ '/test/3.less': dedent `
92
+ @import './4.less';
93
+ `,
94
+ '/test/4.less': dedent `
95
+ `,
96
+ });
97
+ const result = await locator.load(getFixturePath('/test/1.less'));
98
+ // The files imported using @import are pre-bundled by the compiler.
99
+ // Therefore, `Locator#load` is not called to process other files.
100
+ expect(loadSpy).toBeCalledTimes(1);
101
+ expect(loadSpy).toHaveBeenNthCalledWith(1, getFixturePath('/test/1.less'));
102
+ // The files pre-bundled by the compiler are also included in `result.dependencies`
103
+ // eslint-disable-next-line @typescript-eslint/require-array-sort-compare
104
+ expect(result.dependencies.sort()).toStrictEqual(
105
+ // eslint-disable-next-line @typescript-eslint/require-array-sort-compare
106
+ ['/test/2.less', '/test/3.less', '/test/4.less'].map(getFixturePath).sort());
107
+ });
108
+ test('resolves specifier using resolver', async () => {
109
+ createFixtures({
110
+ '/test/1.less': dedent `
111
+ @import 'package-1';
112
+ @import 'package-2';
113
+ `,
114
+ '/node_modules/package-1/index.css': `.a {}`,
115
+ '/node_modules/package-2/index.less': `.a {}`,
116
+ });
117
+ const result = await locator.load(getFixturePath('/test/1.less'));
118
+ // eslint-disable-next-line @typescript-eslint/require-array-sort-compare
119
+ expect(result.dependencies.sort()).toStrictEqual(
120
+ // eslint-disable-next-line @typescript-eslint/require-array-sort-compare
121
+ [getFixturePath('/node_modules/package-1/index.css'), getFixturePath('/node_modules/package-2/index.less')].sort());
122
+ });
123
+ test('ignores http(s) protocol file', async () => {
124
+ createFixtures({
125
+ '/test/1.less': dedent `
126
+ @import 'http://example.com/path/http.css';
127
+ @import 'https://example.com/path/https.css';
128
+ @import 'https://example.com/path/less.less';
129
+ `,
130
+ });
131
+ const result = await locator.load(getFixturePath('/test/1.less'));
132
+ expect(result.dependencies).toStrictEqual([]);
133
+ });
134
+ //# sourceMappingURL=less-transformer.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"less-transformer.test.js","sourceRoot":"","sources":["../../src/transformer/less-transformer.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { Transformer } from '../index.js';
2
+ export type PostcssTransformerOptions = {
3
+ cwd?: string | undefined;
4
+ /**
5
+ * The option compatible with postcss's `--config`. It is a relative or absolute path.
6
+ * @example '.'
7
+ * @example 'postcss.config.js'
8
+ * @example '/home/user/repository/src'
9
+ */
10
+ postcssConfig?: string | undefined;
11
+ };
12
+ export declare const createPostcssTransformer: (postcssTransformerOptions?: PostcssTransformerOptions) => Transformer;
@@ -0,0 +1,32 @@
1
+ import { createRequire } from 'node:module';
2
+ import { resolve } from 'node:path';
3
+ import postcss from 'postcss';
4
+ const require = createRequire(import.meta.url);
5
+ const postcssrc = require('postcss-load-config');
6
+ function isDependencyMessage(message) {
7
+ return message.type === 'dependency';
8
+ }
9
+ export const createPostcssTransformer = (postcssTransformerOptions) => {
10
+ const cwd = postcssTransformerOptions?.cwd ?? process.cwd();
11
+ const configSearchPath = postcssTransformerOptions?.postcssConfig
12
+ ? resolve(cwd, postcssTransformerOptions?.postcssConfig)
13
+ : cwd;
14
+ return async (source, options) => {
15
+ // NOTE: postcss-load-config cache the configuration file so is is not reloaded.
16
+ const postcssConfig = await postcssrc({ cwd }, configSearchPath).catch((e) => {
17
+ if (e instanceof Error && e.message.includes('No PostCSS Config found'))
18
+ return undefined;
19
+ throw e;
20
+ });
21
+ if (postcssConfig === undefined)
22
+ return false;
23
+ const result = await postcss.default(postcssConfig.plugins).process(source, {
24
+ ...postcssConfig.options,
25
+ from: options.from,
26
+ map: { inline: false, absolute: true },
27
+ });
28
+ const dependencies = result.messages.filter(isDependencyMessage).map((message) => message.file);
29
+ return { css: result.css, map: result.map, dependencies };
30
+ };
31
+ };
32
+ //# sourceMappingURL=postcss-transformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postcss-transformer.js","sourceRoot":"","sources":["../../src/transformer/postcss-transformer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,OAAyB,MAAM,SAAS,CAAC;AAIhD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C,MAAM,SAAS,GAAyC,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAQvF,SAAS,mBAAmB,CAAC,OAAgB;IAC3C,OAAO,OAAO,CAAC,IAAI,KAAK,YAAY,CAAC;AACvC,CAAC;AAaD,MAAM,CAAC,MAAM,wBAAwB,GAA2E,CAC9G,yBAAyB,EACzB,EAAE;IACF,MAAM,GAAG,GAAG,yBAAyB,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC5D,MAAM,gBAAgB,GAAG,yBAAyB,EAAE,aAAa;QAC/D,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,yBAAyB,EAAE,aAAa,CAAC;QACxD,CAAC,CAAC,GAAG,CAAC;IACR,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;QAC/B,gFAAgF;QAChF,MAAM,aAAa,GAAuB,MAAM,SAAS,CAAC,EAAE,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;YAC/F,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAC;gBAAE,OAAO,SAAS,CAAC;YAC1F,MAAM,CAAC,CAAC;QACV,CAAC,CAAC,CAAC;QACH,IAAI,aAAa,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QAE9C,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE;YAC1E,GAAG,aAAa,CAAC,OAAO;YACxB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE;SACvC,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAEhG,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,YAAY,EAAE,CAAC;IAC5D,CAAC,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,178 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { createRequire } from 'node:module';
3
+ import { jest } from '@jest/globals';
4
+ import dedent from 'dedent';
5
+ import { Locator } from '../locator/index.js';
6
+ import { createFixtures, getFixturePath } from '../test-util/util.js';
7
+ import { createPostcssTransformer } from './postcss-transformer.js';
8
+ const cwd = getFixturePath('/');
9
+ const require = createRequire(import.meta.url);
10
+ // NOTE: postcss-load-config caches the configuration file using the path as a key.
11
+ // Therefore, change the path for each test case so that a new configuration file is always used.
12
+ test('handles postcss features', async () => {
13
+ const uuid = randomUUID();
14
+ const locator = new Locator({
15
+ transformer: createPostcssTransformer({
16
+ cwd,
17
+ postcssConfig: `${uuid}/postcss.config.js`,
18
+ }),
19
+ });
20
+ createFixtures({
21
+ [`/${uuid}/postcss.config.js`]: dedent `
22
+ module.exports = {
23
+ plugins: [
24
+ require('${require.resolve('postcss-simple-vars')}'),
25
+ ],
26
+ };
27
+ `,
28
+ '/test/1.css': dedent `
29
+ $prefix: foo;
30
+ .$(prefix)_bar {}
31
+ `,
32
+ });
33
+ const result = await locator.load(getFixturePath('/test/1.css'));
34
+ expect(result).toMatchInlineSnapshot(`
35
+ {
36
+ dependencies: [],
37
+ tokens: [
38
+ {
39
+ name: "foo_bar",
40
+ originalLocation: {
41
+ filePath: "<fixtures>/test/1.css",
42
+ start: { line: 2, column: 1 },
43
+ end: { line: 2, column: 8 },
44
+ },
45
+ },
46
+ ],
47
+ }
48
+ `);
49
+ });
50
+ test('tracks dependencies that have been pre-bundled by postcss compiler', async () => {
51
+ const uuid = randomUUID();
52
+ const locator = new Locator({
53
+ transformer: createPostcssTransformer({
54
+ cwd,
55
+ postcssConfig: `${uuid}/postcss.config.js`,
56
+ }),
57
+ });
58
+ const loadSpy = jest.spyOn(locator, 'load');
59
+ createFixtures({
60
+ [`/${uuid}/postcss.config.js`]: dedent `
61
+ module.exports = {
62
+ plugins: [
63
+ require('${require.resolve('postcss-import')}'),
64
+ ],
65
+ };
66
+ `,
67
+ '/test/1.css': dedent `
68
+ @import './2.css';
69
+ @import './3.css';
70
+ `,
71
+ '/test/2.css': ``,
72
+ '/test/3.css': `@import './4.css'`,
73
+ '/test/4.css': ``,
74
+ });
75
+ const result = await locator.load(getFixturePath('/test/1.css'));
76
+ // The files imported using @import are pre-bundled by the compiler.
77
+ // Therefore, `Locator#load` is not called to process other files.
78
+ expect(loadSpy).toBeCalledTimes(1);
79
+ expect(loadSpy).toHaveBeenNthCalledWith(1, getFixturePath('/test/1.css'));
80
+ // The files pre-bundled by the compiler are also included in `result.dependencies`
81
+ expect(result.dependencies).toStrictEqual(['/test/2.css', '/test/3.css', '/test/4.css'].map(getFixturePath));
82
+ });
83
+ test('resolves specifier using resolver', async () => {
84
+ const uuid = randomUUID();
85
+ const locator = new Locator({
86
+ transformer: createPostcssTransformer({
87
+ cwd,
88
+ postcssConfig: `${uuid}/postcss.config.js`,
89
+ }),
90
+ });
91
+ createFixtures({
92
+ [`/${uuid}/postcss.config.js`]: dedent `
93
+ module.exports = {
94
+ plugins: [
95
+ // When using postcss-import, the resolver of happy-css-modules is ignored.
96
+ // Therefore, we test here without postcss-import.
97
+ // require('${require.resolve('postcss-import')}'),
98
+ ],
99
+ };
100
+ `,
101
+ '/test/1.css': dedent `
102
+ @import 'package';
103
+ `,
104
+ '/node_modules/package/index.css': `.a {}`,
105
+ });
106
+ const result = await locator.load(getFixturePath('/test/1.css'));
107
+ expect(result.dependencies).toStrictEqual(['/node_modules/package/index.css'].map(getFixturePath));
108
+ });
109
+ test('ignores http(s) protocol file', async () => {
110
+ const uuid = randomUUID();
111
+ const locator = new Locator({
112
+ transformer: createPostcssTransformer({
113
+ cwd,
114
+ postcssConfig: `${uuid}/postcss.config.js`,
115
+ }),
116
+ });
117
+ createFixtures({
118
+ [`/${uuid}/postcss.config.js`]: dedent `
119
+ module.exports = {
120
+ plugins: [
121
+ // When using postcss-import, the resolver of happy-css-modules is ignored.
122
+ // Therefore, we test here without postcss-import.
123
+ // require('${require.resolve('postcss-import')}'),
124
+ ],
125
+ };
126
+ `,
127
+ '/test/1.css': dedent `
128
+ @import 'http://example.com/path/http.css';
129
+ @import 'https://example.com/path/https.css';
130
+ `,
131
+ });
132
+ const result = await locator.load(getFixturePath('/test/1.css'));
133
+ expect(result.dependencies).toStrictEqual([]);
134
+ });
135
+ test('returns false if postcssrc is not found', async () => {
136
+ const uuid = randomUUID();
137
+ const transformer = createPostcssTransformer({
138
+ cwd,
139
+ postcssConfig: `${uuid}/postcss.config.js`,
140
+ });
141
+ createFixtures({
142
+ '/test/1.css': dedent `
143
+ @import 'http://example.com/path/http.css';
144
+ @import 'https://example.com/path/https.css';
145
+ `,
146
+ });
147
+ expect(await transformer('', {
148
+ from: getFixturePath('/test/1.css'),
149
+ isIgnoredSpecifier: () => false,
150
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
151
+ resolver: jest.fn(),
152
+ })).toBe(false);
153
+ });
154
+ test('searches config from cwd if postcssConfig option is missing', async () => {
155
+ const uuid = randomUUID();
156
+ const cwd = `/${uuid}`;
157
+ const locator = new Locator({
158
+ transformer: createPostcssTransformer({
159
+ cwd: getFixturePath(cwd),
160
+ }),
161
+ });
162
+ createFixtures({
163
+ [`/${uuid}/postcss.config.js`]: dedent `
164
+ module.exports = {
165
+ plugins: [
166
+ require('${require.resolve('postcss-simple-vars')}'),
167
+ ],
168
+ };
169
+ `,
170
+ '/test/1.css': dedent `
171
+ $prefix: foo;
172
+ .$(prefix)_bar {}
173
+ `,
174
+ });
175
+ const result = await locator.load(getFixturePath('/test/1.css'));
176
+ expect(result.tokens.map((token) => token.name)).toStrictEqual(['foo_bar']);
177
+ });
178
+ //# sourceMappingURL=postcss-transformer.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postcss-transformer.test.js","sourceRoot":"","sources":["../../src/transformer/postcss-transformer.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { Transformer } from './index.js';
2
+ export declare const createScssTransformer: () => Transformer;
@@ -0,0 +1,40 @@
1
+ // NOTE: The workaround for using sass's modern API. happy-css-modules used to use this API.
2
+ // However, due to the implementation of custom resolvers, we have switched to the legacy API.
3
+ // Therefore, the workaround is now disabled. See
4
+ // https://github.com/mizdra/happy-css-modules/issues/65#issuecomment-1229471950 for more information.
5
+ import { handleImportError } from './index.js';
6
+ // For some reason, `util.promisify` does not work. Therefore, use the original promisify.
7
+ function promisifySassRender(sass) {
8
+ return async (options) => {
9
+ return new Promise((resolve, reject) => {
10
+ sass.render(options, (exception, result) => {
11
+ if (exception)
12
+ reject(exception);
13
+ else
14
+ resolve(result);
15
+ });
16
+ });
17
+ };
18
+ }
19
+ export const createScssTransformer = () => {
20
+ let sass;
21
+ return async (source, options) => {
22
+ // eslint-disable-next-line require-atomic-updates
23
+ sass ??= await import('sass').catch(handleImportError('sass'));
24
+ const render = promisifySassRender(sass);
25
+ const result = await render({
26
+ data: source,
27
+ file: options.from,
28
+ outFile: 'DUMMY', // Required for sourcemap output.
29
+ sourceMap: true,
30
+ importer: (url, prev, done) => {
31
+ options
32
+ .resolver(url, { request: prev })
33
+ .then((resolved) => done({ file: resolved }))
34
+ .catch((e) => done(e));
35
+ },
36
+ });
37
+ return { css: result.css.toString(), map: result.map.toString(), dependencies: result.stats.includedFiles };
38
+ };
39
+ };
40
+ //# sourceMappingURL=scss-transformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scss-transformer.js","sourceRoot":"","sources":["../../src/transformer/scss-transformer.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,8FAA8F;AAC9F,iDAAiD;AACjD,sGAAsG;AAItG,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,0FAA0F;AAC1F,SAAS,mBAAmB,CAAC,IAA2B;IACtD,OAAO,KAAK,EAAE,OAA+B,EAAE,EAAE;QAC/C,OAAO,IAAI,OAAO,CAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACnD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE;gBACzC,IAAI,SAAS;oBAAE,MAAM,CAAC,SAAS,CAAC,CAAC;;oBAC5B,OAAO,CAAC,MAAO,CAAC,CAAC;YACxB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAsB,GAAG,EAAE;IAC3D,IAAI,IAA2B,CAAC;IAChC,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;QAC/B,kDAAkD;QAClD,IAAI,KAAK,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC;YAC1B,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,OAAO,EAAE,OAAO,EAAE,iCAAiC;YACnD,SAAS,EAAE,IAAI;YACf,QAAQ,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;gBAC5B,OAAO;qBACJ,QAAQ,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;qBAChC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;qBAC5C,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3B,CAAC;SACF,CAAC,CAAC;QACH,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,GAAI,CAAC,QAAQ,EAAE,EAAE,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;IAC/G,CAAC,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};