11import { callback as callbackPlugin } from '@semantic-ui/esbuild-callback' ;
22import { SpecReader } from '@semantic-ui/specs' ;
3- import { asyncEach , each } from '@semantic-ui/utils' ;
4- import { readFileSync , writeFileSync } from 'fs' ;
3+ import { asyncEach } from '@semantic-ui/utils' ;
4+ import { writeFileSync } from 'fs' ;
55import { dirname , resolve } from 'path' ;
66import glob from 'tiny-glob' ;
77import { pathToFileURL } from 'url' ;
@@ -54,49 +54,28 @@ export const buildUIDeps = async ({
5454 outdir : 'src' ,
5555 } ) ;
5656
57- // External glob needed for proper negation support
58- // Support both .json (legacy) and .spec.js (new) during transition
59- const jsonFiles = await glob ( 'src/primitives/**/specs/*.json' ) ;
57+ // Get all .spec.js source files
6058 const specJsFiles = await glob ( 'src/primitives/**/specs/*.spec.js' ) ;
61-
62- const allFiles = [ ...jsonFiles , ...specJsFiles ] ;
63- // Exclude all generated files (*.component.js, *.component.json, *.spec.json)
64- const entryPoints = allFiles . filter ( path =>
65- ! path . endsWith ( '.component.json' )
66- && ! path . endsWith ( '.component.js' )
67- && ! path . endsWith ( '.spec.json' ) // Generated JSON from .spec.js
68- ) ;
59+ const entryPoints = specJsFiles ;
6960
7061 const createComponentSpecs = async ( ) => {
7162 await asyncEach ( entryPoints , async ( entryPath ) => {
7263 try {
73- let spec ;
74- const isJsSpec = entryPath . endsWith ( '.spec.js' ) ;
75-
76- if ( isJsSpec ) {
77- // Load JS module with cache busting for watch mode
78- const specModule = await import ( `${ pathToFileURL ( entryPath ) . href } ?t=${ Date . now ( ) } ` ) ;
79- spec = specModule . default ;
64+ // Load JS module with cache busting for watch mode
65+ const specModule = await import ( `${ pathToFileURL ( entryPath ) . href } ?t=${ Date . now ( ) } ` ) ;
66+ const spec = specModule . default ;
8067
81- // Validate JS specs are pure data
82- validateSpec ( spec , entryPath ) ;
68+ // Validate JS specs are pure data
69+ validateSpec ( spec , entryPath ) ;
8370
84- // Generate JSON snapshot for machine readability (LLMs, tooling)
85- const jsonPath = entryPath . replace ( '.spec.js' , '.spec.json' ) ;
86- const jsonContent = `${ JSON . stringify ( spec , null , 2 ) } \n` ;
87- writeFileSync ( jsonPath , jsonContent ) ;
88- }
89- else {
90- // Legacy JSON loading
91- const contents = readFileSync ( entryPath , 'utf8' ) ;
92- spec = JSON . parse ( contents ) ;
93- }
71+ // Generate JSON snapshot for machine readability (LLMs, tooling)
72+ const jsonPath = entryPath . replace ( '.spec.js' , '.spec.json' ) ;
73+ const jsonContent = `${ JSON . stringify ( spec , null , 2 ) } \n` ;
74+ writeFileSync ( jsonPath , jsonContent ) ;
9475
95- // Generate component spec JS directly
76+ // Generate component spec JS
9677 const componentSpecJS = await generateComponentSpecJS ( spec , false , { } , entryPath ) ;
97- const componentJSPath = isJsSpec
98- ? entryPath . replace ( '.spec.js' , '.component.js' )
99- : entryPath . replace ( '.json' , '.component.js' ) ;
78+ const componentJSPath = entryPath . replace ( '.spec.js' , '.component.js' ) ;
10079 writeFileSync ( componentJSPath , componentSpecJS ) ;
10180
10281 // Generate plural variant if supported
@@ -114,67 +93,24 @@ export const buildUIDeps = async ({
11493 } ) ;
11594 } ;
11695
117- // Convert raw spec JSON to JS modules to avoid ESM JSON import compatibility issues
118- // Note: .spec.js files don't need conversion - they're already JS modules
119- const generateJSExportsFromSpecs = async ( ) => {
120- await createComponentSpecs ( ) ;
121-
122- // Only process legacy JSON spec files (not .spec.js/json or .component.js)
123- const rawSpecFiles = await glob ( 'src/primitives/*/specs/*.json' ) ;
124- const filteredRawSpecs = rawSpecFiles . filter ( path =>
125- ! path . endsWith ( '.component.json' )
126- && ! path . endsWith ( '.spec.json' )
127- ) ;
128-
129- each ( filteredRawSpecs , ( jsonFile ) => {
130- try {
131- const jsonContent = readFileSync ( jsonFile , 'utf-8' ) ;
132- const spec = JSON . parse ( jsonContent ) ;
133- const jsContent = `// Auto-generated from ${ jsonFile . split ( '/' ) . pop ( ) } \nexport default ${
134- JSON . stringify ( spec , null , 2 )
135- } ;\n`;
136- const jsFile = jsonFile . replace ( '.json' , '.js' ) ;
137- writeFileSync ( jsFile , jsContent ) ;
138- }
139- catch ( error ) {
140- console . error ( `Error processing ${ jsonFile } :` , error . message ) ;
141- }
142- } ) ;
143- } ;
144-
145- const generateJSExports = generateJSExportsFromSpecs ( ) ;
146-
14796 // Set up a separate esbuild watcher for spec files
14897 let specWatcher ;
14998 if ( watch ) {
150- // Get all spec files to watch (legacy .json and source .spec.js)
151- const jsonSpecFiles = await glob ( 'src/primitives/**/specs/*.json' ) ;
152- const jsSpecFiles = await glob ( 'src/primitives/**/specs/*.spec.js' ) ;
153-
154- // Exclude all generated files from watch
155- const watchedFiles = [ ...jsonSpecFiles , ...jsSpecFiles ] . filter (
156- path =>
157- ! path . endsWith ( '.component.json' )
158- && ! path . endsWith ( '.component.js' )
159- && ! path . endsWith ( '.spec.json' ) , // Don't watch generated JSON
160- ) ;
161-
162- // Use esbuild to watch the spec files by treating them as entry points
99+ // Use esbuild to watch the .spec.js files by treating them as entry points
163100 // with a plugin that rebuilds our component specs
164- if ( watchedFiles . length > 0 ) {
101+ if ( entryPoints . length > 0 ) {
165102 specWatcher = build ( {
166103 watch,
167104 write : false , // Don't write output, just watch
168105 logLevel : 'silent' , // Suppress esbuild's own logs
169- entryPoints : watchedFiles ,
106+ entryPoints,
170107 outdir : '.temp-watch' , // Required by esbuild when multiple entry points
171108 plugins : [
172109 callbackPlugin ( {
173110 onComplete : async ( result , { isRebuild } ) => {
174111 if ( isRebuild ) {
175112 try {
176113 await createComponentSpecs ( ) ;
177- await generateJSExportsFromSpecs ( ) ;
178114 }
179115 catch ( error ) {
180116 // nothing
@@ -190,7 +126,6 @@ export const buildUIDeps = async ({
190126 return await Promise . all ( [
191127 cssComponentBundle ,
192128 createComponentSpecs ( ) ,
193- generateJSExports ,
194129 specWatcher ,
195130 ] . filter ( Boolean ) ) ;
196131} ;
0 commit comments