@@ -106,28 +106,7 @@ export function generateDts(cssModule: CSSModule, options: GenerateDtsOptions):
106106 }
107107}
108108
109- /**
110- * Generate a d.ts file with named exports.
111- * @example
112- * If the CSS module file is:
113- * ```css
114- * @import './a.module.css';
115- * @value local1: string;
116- * @value imported1, imported2 as aliasedImported2 from './b.module.css';
117- * .local2 { color: red }
118- * ```
119- * The d.ts file would be:
120- * ```ts
121- * // @ts -nocheck
122- * export var local1: string;
123- * export var local2: string;
124- * export * from './a.module.css';
125- * export {
126- * imported1,
127- * imported2 as aliasedImported2,
128- * } from './b.module.css';
129- * ```
130- */
109+ /** Generate a d.ts file with named exports. */
131110function generateNamedExportsDts (
132111 localTokens : Token [ ] ,
133112 tokenImporters : TokenImporter [ ] ,
@@ -149,6 +128,25 @@ function generateNamedExportsDts(
149128 let text = `// @ts-nocheck\n` ;
150129
151130 for ( const token of localTokens ) {
131+ /**
132+ * The mapping is created as follows:
133+ * a.module.css:
134+ * 1 | .a_1 { color: red; }
135+ * | ^ mapping.sourceOffsets[0]
136+ * |
137+ * 2 | .a_2 { color: blue; }
138+ * | ^ mapping.sourceOffsets[1]
139+ * |
140+ *
141+ * a.module.css.d.ts:
142+ * 1 | // @ts-nocheck
143+ * 2 | export var a_1: string;
144+ * | ^ mapping.generatedOffsets[0]
145+ * |
146+ * 3 | export var a_2: string;
147+ * | ^ mapping.generatedOffsets[1]
148+ */
149+
152150 text += `export var ` ;
153151 mapping . sourceOffsets . push ( token . loc . start . offset ) ;
154152 mapping . generatedOffsets . push ( text . length ) ;
@@ -157,12 +155,71 @@ function generateNamedExportsDts(
157155 }
158156 for ( const tokenImporter of tokenImporters ) {
159157 if ( tokenImporter . type === 'import' ) {
158+ /**
159+ * The mapping is created as follows:
160+ * a.module.css:
161+ * 1 | @import './b.module.css';
162+ * | ^ mapping.sourceOffsets[0]
163+ * |
164+ * 2 | @import './c.module.css';
165+ * | ^ mapping.sourceOffsets[1]
166+ * |
167+ *
168+ * a.module.css.d.ts:
169+ * 1 | // @ts-nocheck
170+ * 2 | export * from './b.module.css';
171+ * | ^ mapping.generatedOffsets[0]
172+ * |
173+ * 3 | export * from './c.module.css';
174+ * | ^ mapping.generatedOffsets[1]
175+ *
176+ * NOTE: Not only the specifier but also the surrounding quotes are included in the mapping.
177+ */
178+
160179 text += `export * from ` ;
161180 mapping . sourceOffsets . push ( tokenImporter . fromLoc . start . offset - 1 ) ;
162181 mapping . lengths . push ( tokenImporter . from . length + 2 ) ;
163182 mapping . generatedOffsets . push ( text . length ) ;
164183 text += `'${ tokenImporter . from } ';\n` ;
165184 } else {
185+ /**
186+ * The mapping is created as follows:
187+ * a.module.css:
188+ * 1 | @value b_1, b_2 from './b.module.css';
189+ * | ^ ^ ^ mapping.sourceOffsets[2]
190+ * | ^ ^ mapping.sourceOffsets[1]
191+ * | ^ mapping.sourceOffsets[0]
192+ * |
193+ * 2 | @value c_1 as aliased_c_1 from './c.module.css';
194+ * | ^ ^ ^ mapping.sourceOffsets[5]
195+ * | ^ ^ mapping.sourceOffsets[4]
196+ * | ^ mapping.sourceOffsets[3]
197+ * |
198+ *
199+ * a.module.css.d.ts:
200+ * 1 | // @ts-nocheck
201+ * 2 | export {
202+ * 3 | b_1,
203+ * | ^ mapping.generatedOffsets[0]
204+ * |
205+ * 4 | b_2,
206+ * | ^ mapping.generatedOffsets[1]
207+ * |
208+ * 5 | } from './b.module.css';
209+ * | ^ mapping.generatedOffsets[2]
210+ * |
211+ * 6 | export {
212+ * 7 | c_1 as aliased_c_1,
213+ * | ^ ^ mapping.generatedOffsets[4], linkedCodeMapping.sourceOffsets[0]
214+ * | ^ mapping.generatedOffsets[3], linkedCodeMapping.generatedOffsets[0]
215+ * |
216+ * 8 | } from './c.module.css';
217+ * | ^ mapping.generatedOffsets[5]
218+ *
219+ * NOTE: Not only the specifier but also the surrounding quotes are included in the mapping.
220+ * NOTE: linkedCodeMapping is only generated for tokens that have a `localName` (i.e., aliased tokens).
221+ */
222+
166223 text += `export {\n` ;
167224 // eslint-disable-next-line no-loop-func
168225 tokenImporter . values . forEach ( ( value ) => {
@@ -203,29 +260,7 @@ function generateNamedExportsDts(
203260 return { text, mapping, linkedCodeMapping } ;
204261}
205262
206- /**
207- * Generate a d.ts file with a default export.
208- * @example
209- * If the CSS module file is:
210- * ```css
211- * @import './a.module.css';
212- * @value local1: string;
213- * @value imported1, imported2 as aliasedImported2 from './b.module.css';
214- * .local2 { color: red }
215- * ```
216- * The d.ts file would be:
217- * ```ts
218- * // @ts -nocheck
219- * const styles = {
220- * local1: '' as readonly string,
221- * local2: '' as readonly string,
222- * ...(await import('./a.module.css')).default,
223- * imported1: (await import('./b.module.css')).default.imported1,
224- * aliasedImported2: (await import('./b.module.css')).default.imported2,
225- * };
226- * export default styles;
227- * ```
228- */
263+ /** Generate a d.ts file with a default export. */
229264function generateDefaultExportDts (
230265 localTokens : Token [ ] ,
231266 tokenImporters : TokenImporter [ ] ,
@@ -256,6 +291,27 @@ function generateDefaultExportDts(
256291
257292 text += `declare const ${ STYLES_EXPORT_NAME } = {\n` ;
258293 for ( const token of localTokens ) {
294+ /**
295+ * The mapping is created as follows:
296+ * a.module.css:
297+ * 1 | .a_1 { color: red; }
298+ * | ^ mapping.sourceOffsets[0]
299+ * |
300+ * 2 | .a_2 { color: blue; }
301+ * | ^ mapping.sourceOffsets[1]
302+ * |
303+ *
304+ * a.module.css.d.ts:
305+ * 1 | declare const styles = {
306+ * 2 | a_1: '' as readonly string,
307+ * | ^ mapping.generatedOffsets[0]
308+ * |
309+ * 3 | a_2: '' as readonly string,
310+ * | ^ mapping.generatedOffsets[1]
311+ * |
312+ * 4 | };
313+ */
314+
259315 text += ` ` ;
260316 mapping . sourceOffsets . push ( token . loc . start . offset ) ;
261317 mapping . generatedOffsets . push ( text . length ) ;
@@ -264,12 +320,71 @@ function generateDefaultExportDts(
264320 }
265321 for ( const tokenImporter of tokenImporters ) {
266322 if ( tokenImporter . type === 'import' ) {
323+ /**
324+ * The mapping is created as follows:
325+ * a.module.css:
326+ * 1 | @import './b.module.css';
327+ * | ^ mapping.sourceOffsets[0]
328+ * |
329+ * 2 | @import './c.module.css';
330+ * | ^ mapping.sourceOffsets[1]
331+ * |
332+ *
333+ * a.module.css.d.ts:
334+ * 1 | declare const styles = {
335+ * 2 | ...blockErrorType((await import('./b.module.css')).default),
336+ * | ^ mapping.generatedOffsets[0]
337+ * |
338+ * 3 | ...blockErrorType((await import('./c.module.css')).default),
339+ * | ^ mapping.generatedOffsets[1]
340+ * |
341+ * 4 | };
342+ *
343+ * NOTE: Not only the specifier but also the surrounding quotes are included in the mapping.
344+ */
345+
267346 text += ` ...blockErrorType((await import(` ;
268347 mapping . sourceOffsets . push ( tokenImporter . fromLoc . start . offset - 1 ) ;
269348 mapping . lengths . push ( tokenImporter . from . length + 2 ) ;
270349 mapping . generatedOffsets . push ( text . length ) ;
271350 text += `'${ tokenImporter . from } ')).default),\n` ;
272351 } else {
352+ /**
353+ * The mapping is created as follows:
354+ * a.module.css:
355+ * 1 | @value b_1, b_2 from './b.module.css';
356+ * | ^ ^ ^ mapping.sourceOffsets[1]
357+ * | ^ ^ mapping.sourceOffsets[3], mapping.sourceOffsets[4]
358+ * | ^ mapping.sourceOffsets[0], mapping.sourceOffsets[2]
359+ * |
360+ * 2 | @value c_1 as aliased_c_1 from './c.module.css';
361+ * | ^ ^ ^ mapping.sourceOffsets[6]
362+ * | ^ ^ mapping.sourceOffsets[5]
363+ * | ^ mapping.sourceOffsets[7]
364+ * |
365+ *
366+ * a.module.css.d.ts:
367+ * 1 | declare const styles = {
368+ * 2 | b_1: (await import('./b.module.css')).default.b_1,
369+ * | ^ ^ ^ mapping.generatedOffsets[2], linkedCodeMapping.generatedOffsets[0]
370+ * | ^ ^ mapping.generatedOffsets[1]
371+ * | ^ mapping.generatedOffsets[0], linkedCodeMapping.sourceOffsets[0]
372+ * |
373+ * 3 | b_2: (await import('./b.module.css')).default.b_2,
374+ * | ^ ^ mapping.generatedOffsets[4], linkedCodeMapping.generatedOffsets[1]
375+ * | ^ mapping.generatedOffsets[3], linkedCodeMapping.sourceOffsets[1]
376+ * |
377+ * 4 | aliased_c_1: (await import('./c.module.css')).default.c_1,
378+ * | ^ ^ ^ mapping.generatedOffsets[7], linkedCodeMapping.generatedOffsets[2]
379+ * | ^ ^ mapping.generatedOffsets[6]
380+ * | ^ mapping.generatedOffsets[5], linkedCodeMapping.sourceOffsets[2]
381+ * |
382+ * 5 | };
383+ *
384+ * NOTE: Not only the specifier but also the surrounding quotes are included in the mapping.
385+ * TODO: Stop generating unnecessary mappings for tokens that do not have a `localName`.
386+ */
387+
273388 // eslint-disable-next-line no-loop-func
274389 tokenImporter . values . forEach ( ( value , i ) => {
275390 const localName = value . localName ?? value . name ;
0 commit comments