Skip to content

Commit 6016bae

Browse files
committed
fix: update package dependencies and build scripts
- Updated build scripts to use esbuild.mts instead of esbuild.mjs. - Modified linting commands to support both .mjs and .mts file extensions. - Upgraded various dependencies in package.json, including eslint, typescript, and rimraf. - Changed TypeScript target from es2020 to es2022 and updated lib to ES2022. - Updated Cargo.lock and Cargo.toml for wit-bindgen-wasm to use newer versions of dependencies, including wasm-bindgen, anyhow, and web-sys. - Enhanced error handling in getWitBindgenVersionFromWasm function by adding a cause to the thrown error. - Initialized selectedWorld variable as undefined in extension.ts. Signed-off-by: Gordon Smith <GordonJSmith@gmail.com>
1 parent 48eb8cd commit 6016bae

File tree

9 files changed

+609
-942
lines changed

9 files changed

+609
-942
lines changed

.github/copilot-instructions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Build and dev workflows
1818
- Tests: `npm test` runs lint, prettier check, build, package, grammar tests, and unit tests. Quick loops: `npm run test-unit` or `npm run test-grammar`. Update grammar snapshots: `npm run update-snapshot`.
1919
- Verify WASM build: `npm run verify-wasm` checks that the built WASM file exists and is valid.
2020

21-
Bundling details (esbuild.mjs)
21+
Bundling details (esbuild.mts)
2222
- ESM build targeting Node 22 with `external: ["vscode"]`, injects `src/node-polyfills.js`.
2323
- Plugins auto-discover and copy dynamic WASM references and worker JS to `dist/`. `src/wasmUtils.ts` first looks for `dist/wit_bindgen_wasm_bg.wasm` and falls back to module default init. If you introduce new wasm or worker assets referenced via `new URL('file.ext', import.meta.url)`, the plugin will attempt to copy them.
2424

@@ -55,6 +55,6 @@ Key references
5555
- Additional instructions: `.github/instructions/*`
5656
- Entry point: `src/extension.ts`
5757
- Validation: `src/validator.ts`, `src/errorParser.ts`, `src/wasmUtils.ts`
58-
- Build: `esbuild.mjs`, `package.json` scripts
58+
- Build: `esbuild.mts`, `package.json` scripts
5959
- WASM package: `wit-bindgen-wasm/README.md`, `wit-bindgen-wasm/pkg/*`
6060
- Dependencies: `wit-parser` 0.241, `wit-component` 0.241, `wasmparser` 0.241, `wasm-tools` CLI

esbuild.mjs renamed to esbuild.mts

Lines changed: 77 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,40 @@ const WASM_EXTENSIONS = [".wasm"];
2424
const BUILD_TARGET = "node22";
2525
const ENTRY_POINT = "src/extension.ts";
2626

27+
/**
28+
* Options for the copyFiles utility function
29+
*/
30+
interface CopyFilesOptions {
31+
srcDir: string;
32+
destDir: string;
33+
files: string[] | string;
34+
logPrefix?: string;
35+
skipIfExists?: boolean;
36+
warnIfMissing?: boolean;
37+
}
38+
39+
/**
40+
* Parsed information from a package.json file
41+
*/
42+
interface PackageInfo {
43+
name: string;
44+
version: string;
45+
files: string[];
46+
dependencies: Record<string, string>;
47+
peerDependencies: Record<string, string>;
48+
optionalDependencies: Record<string, string>;
49+
}
50+
2751
/**
2852
* Safely reads a directory and returns files or empty array on error
2953
* @param {string} dirPath - Directory path to read
3054
* @returns {string[]} Array of filenames or empty array
3155
*/
32-
function safeReadDir(dirPath) {
56+
function safeReadDir(dirPath: string): string[] {
3357
try {
3458
return fs.readdirSync(dirPath);
3559
} catch (error) {
36-
console.warn(`⚠️ Could not read directory ${dirPath}: ${error.message}`);
60+
console.warn(`⚠️ Could not read directory ${dirPath}: ${(error as Error).message}`);
3761
return [];
3862
}
3963
}
@@ -43,11 +67,11 @@ function safeReadDir(dirPath) {
4367
* @param {string} filePath - Path to check
4468
* @returns {boolean} True if path exists
4569
*/
46-
function safeExists(filePath) {
70+
function safeExists(filePath: string): boolean {
4771
try {
4872
return fs.existsSync(filePath);
4973
} catch (error) {
50-
console.warn(`⚠️ Could not check existence of ${filePath}: ${error.message}`);
74+
console.warn(`⚠️ Could not check existence of ${filePath}: ${(error as Error).message}`);
5175
return false;
5276
}
5377
}
@@ -56,13 +80,13 @@ function safeExists(filePath) {
5680
* Clean the dist directory before building
5781
* @param {string} distPath - Path to the dist directory
5882
*/
59-
function cleanDistDirectory(distPath) {
83+
function cleanDistDirectory(distPath: string): void {
6084
if (safeExists(distPath)) {
6185
try {
6286
fs.rmSync(distPath, { recursive: true, force: true });
6387
console.log("🧹 Cleaned dist directory");
6488
} catch (error) {
65-
console.warn(`⚠️ Could not clean dist directory: ${error.message}`);
89+
console.warn(`⚠️ Could not clean dist directory: ${(error as Error).message}`);
6690
}
6791
}
6892
}
@@ -78,7 +102,7 @@ function cleanDistDirectory(distPath) {
78102
* @param {boolean} [options.warnIfMissing] - Log warning if source file doesn't exist
79103
* @returns {number} Number of files successfully copied
80104
*/
81-
function copyFiles(options) {
105+
function copyFiles(options: CopyFilesOptions): number {
82106
const { srcDir, destDir, files, logPrefix = "", skipIfExists = false, warnIfMissing = true } = options;
83107

84108
if (!safeExists(srcDir)) {
@@ -92,11 +116,11 @@ function copyFiles(options) {
92116
try {
93117
fs.mkdirSync(destDir, { recursive: true });
94118
} catch (error) {
95-
console.error(`❌ Failed to create destination directory ${destDir}: ${error.message}`);
119+
console.error(`❌ Failed to create destination directory ${destDir}: ${(error as Error).message}`);
96120
return 0;
97121
}
98122

99-
let filesToCopy = [];
123+
let filesToCopy;
100124
let copiedCount = 0;
101125

102126
try {
@@ -130,11 +154,11 @@ function copyFiles(options) {
130154
console.log(`✅ Copied ${file}${logPrefix ? ` ${logPrefix}` : ""} to ${path.basename(destDir)}/`);
131155
copiedCount++;
132156
} catch (error) {
133-
console.error(`❌ Failed to copy ${file}: ${error.message}`);
157+
console.error(`❌ Failed to copy ${file}: ${(error as Error).message}`);
134158
}
135159
});
136160
} catch (error) {
137-
console.error(`❌ Error processing files in ${srcDir}: ${error.message}`);
161+
console.error(`❌ Error processing files in ${srcDir}: ${(error as Error).message}`);
138162
}
139163

140164
return copiedCount;
@@ -145,25 +169,27 @@ function copyFiles(options) {
145169
* @param {string} packagePath - Path to the package directory
146170
* @returns {Object} Package information including files to copy
147171
*/
148-
function readPackageInfo(packagePath) {
172+
function readPackageInfo(packagePath: string): PackageInfo | null {
149173
const packageJsonPath = path.join(packagePath, "package.json");
150174

151175
if (!safeExists(packageJsonPath)) {
152176
return null;
153177
}
154178

155179
try {
156-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
157-
const filesSection = packageJson.files || [];
180+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")) as Record<string, unknown>;
181+
const filesSection = (packageJson.files as string[]) || [];
158182

159183
return {
160-
name: packageJson.name,
161-
version: packageJson.version,
184+
name: packageJson.name as string,
185+
version: packageJson.version as string,
162186
files: filesSection,
163-
dependencies: packageJson.dependencies || {},
187+
dependencies: (packageJson.dependencies as Record<string, string>) || {},
188+
peerDependencies: (packageJson.peerDependencies as Record<string, string>) || {},
189+
optionalDependencies: (packageJson.optionalDependencies as Record<string, string>) || {},
164190
};
165191
} catch (error) {
166-
console.warn(`Warning: Could not read package.json at ${packageJsonPath}: ${error.message}`);
192+
console.warn(`Warning: Could not read package.json at ${packageJsonPath}: ${(error as Error).message}`);
167193
return null;
168194
}
169195
}
@@ -175,7 +201,7 @@ function readPackageInfo(packagePath) {
175201
* @param {string} subDir - Subdirectory to check (e.g., 'lib', 'obj')
176202
* @returns {string[]} Array of WASM files found
177203
*/
178-
function getWasmFilesFromPackage(packageDir, filesSpec, subDir) {
204+
function getWasmFilesFromPackage(packageDir: string, filesSpec: string[], subDir: string): string[] {
179205
const targetDir = path.join(packageDir, subDir);
180206

181207
if (!safeExists(targetDir)) {
@@ -189,13 +215,13 @@ function getWasmFilesFromPackage(packageDir, filesSpec, subDir) {
189215
// If package has files specification, filter based on that
190216
if (filesSpec && filesSpec.length > 0) {
191217
const relevantSpecs = filesSpec.filter(
192-
(spec) => spec.includes(subDir) && (spec.includes("*.wasm") || spec.includes("*.core*.wasm"))
218+
(spec: string) => spec.includes(subDir) && (spec.includes("*.wasm") || spec.includes("*.core*.wasm"))
193219
);
194220

195221
if (relevantSpecs.length > 0) {
196222
// Use the files specification to determine which files to include
197223
return wasmFiles.filter((file) => {
198-
return relevantSpecs.some((spec) => {
224+
return relevantSpecs.some((spec: string) => {
199225
if (spec.includes("*.core*.wasm")) {
200226
return file.includes(".core") && file.endsWith(".wasm");
201227
}
@@ -211,7 +237,7 @@ function getWasmFilesFromPackage(packageDir, filesSpec, subDir) {
211237
// Default: return all WASM files
212238
return wasmFiles;
213239
} catch (error) {
214-
console.warn(`⚠️ Could not read directory ${targetDir}: ${error.message}`);
240+
console.warn(`⚠️ Could not read directory ${targetDir}: ${(error as Error).message}`);
215241
return [];
216242
}
217243
}
@@ -221,13 +247,13 @@ function getWasmFilesFromPackage(packageDir, filesSpec, subDir) {
221247
* @param {string[]|undefined} filesSpec - Files specification from package.json
222248
* @returns {string[]} Array of directory names to search for WASM files
223249
*/
224-
function getWasmDirectoriesFromFiles(filesSpec) {
250+
function getWasmDirectoriesFromFiles(filesSpec: string[] | undefined): string[] {
225251
if (!filesSpec || !Array.isArray(filesSpec)) {
226252
// Fallback to standard directories if no files specification
227253
return [];
228254
}
229255

230-
const directories = new Set();
256+
const directories = new Set<string>();
231257

232258
filesSpec.forEach((filePattern) => {
233259
if (typeof filePattern === "string") {
@@ -255,7 +281,7 @@ function getWasmDirectoriesFromFiles(filesSpec) {
255281
* @param {string} packageName - Package name (e.g., "@bytecodealliance/jco")
256282
* @returns {string[]} Array of path segments for the package directory
257283
*/
258-
function packageNameToPath(packageName) {
284+
function packageNameToPath(packageName: string): string[] {
259285
return packageName.startsWith("@") ? packageName.split("/") : [packageName];
260286
}
261287

@@ -269,7 +295,14 @@ function packageNameToPath(packageName) {
269295
* @param {boolean} [isNested=false] - Whether this is a nested dependency (affects file copying behavior)
270296
*/
271297
// eslint-disable-next-line @typescript-eslint/no-unused-vars
272-
function processPackageForWasm(packageName, packageDir, distDir, processedPaths, nodeModulesDir, isNested = false) {
298+
function processPackageForWasm(
299+
packageName: string,
300+
packageDir: string,
301+
distDir: string,
302+
processedPaths: Set<string>,
303+
nodeModulesDir: string,
304+
isNested = false
305+
): void {
273306
if (processedPaths.has(packageDir)) {
274307
return;
275308
}
@@ -343,14 +376,14 @@ function processPackageForWasm(packageName, packageDir, distDir, processedPaths,
343376
function createResourceDiscoveryPlugin() {
344377
return {
345378
name: "resource-discovery",
346-
setup(build) {
379+
setup(build: esbuild.PluginBuild) {
347380
// Hook into the build start
348381
build.onStart(() => {
349382
console.log("🔨 [watch] build started");
350383
});
351384

352385
// Hook into build end for comprehensive logging
353-
build.onEnd((result) => {
386+
build.onEnd((result: esbuild.BuildResult) => {
354387
if (result.errors.length > 0) {
355388
console.log("❌ Build completed with errors:");
356389
result.errors.forEach(({ text, location }) => {
@@ -385,15 +418,15 @@ function createResourceDiscoveryPlugin() {
385418
* @returns {import('esbuild').Plugin} An esbuild plugin
386419
*/
387420
function createWasmDiscoveryPlugin() {
388-
const discoveredWasmFiles = new Set();
421+
const discoveredWasmFiles = new Set<string>();
389422
const nodeModulesDir = path.join(process.cwd(), "node_modules");
390423
const distDir = path.join(process.cwd(), "dist");
391424

392425
return {
393426
name: "wasm-discovery",
394-
setup(build) {
427+
setup(build: esbuild.PluginBuild) {
395428
// Hook into build end to analyze the output and discover WASM references
396-
build.onEnd(async (result) => {
429+
build.onEnd(async (result: esbuild.BuildResult) => {
397430
if (result.errors.length > 0) return;
398431

399432
// Analyze the main bundle for dynamic WASM references
@@ -441,7 +474,9 @@ function createWasmDiscoveryPlugin() {
441474
fs.copyFileSync(srcPath, destPath);
442475
console.log(`✅ Copied dynamically referenced WASM: ${wasmFileName}`);
443476
} catch (error) {
444-
console.error(`❌ Failed to copy ${wasmFileName}: ${error.message}`);
477+
console.error(
478+
`❌ Failed to copy ${wasmFileName}: ${(error as Error).message}`
479+
);
445480
}
446481
}
447482
} else {
@@ -450,7 +485,7 @@ function createWasmDiscoveryPlugin() {
450485
}
451486
}
452487
} catch (error) {
453-
console.warn(`⚠️ Could not analyze bundle for WASM references: ${error.message}`);
488+
console.warn(`⚠️ Could not analyze bundle for WASM references: ${(error as Error).message}`);
454489
}
455490
}
456491
});
@@ -464,7 +499,7 @@ function createWasmDiscoveryPlugin() {
464499
* @param {string} nodeModulesDir - Path to node_modules directory
465500
* @returns {Promise<string[]>} Array of paths where the file was found
466501
*/
467-
async function findWasmFileInNodeModules(wasmFileName, nodeModulesDir) {
502+
async function findWasmFileInNodeModules(wasmFileName: string, nodeModulesDir: string): Promise<string[]> {
468503
const foundPaths = [];
469504

470505
try {
@@ -489,7 +524,7 @@ async function findWasmFileInNodeModules(wasmFileName, nodeModulesDir) {
489524
}
490525
}
491526
} catch (error) {
492-
console.warn(`⚠️ Error searching for WASM file ${wasmFileName}: ${error.message}`);
527+
console.warn(`⚠️ Error searching for WASM file ${wasmFileName}: ${(error as Error).message}`);
493528
}
494529

495530
return foundPaths;
@@ -501,7 +536,7 @@ async function findWasmFileInNodeModules(wasmFileName, nodeModulesDir) {
501536
* @param {string} wasmFileName - WASM file name to find
502537
* @returns {Promise<string[]>} Array of paths where the file was found
503538
*/
504-
async function searchForWasmInPackage(packageDir, wasmFileName) {
539+
async function searchForWasmInPackage(packageDir: string, wasmFileName: string): Promise<string[]> {
505540
const foundPaths = [];
506541

507542
// Common directories where WASM files might be located
@@ -525,7 +560,7 @@ async function searchForWasmInPackage(packageDir, wasmFileName) {
525560
* @param {string} nodeModulesDir - Path to node_modules directory
526561
* @returns {string[]} Array of paths where the file was found
527562
*/
528-
async function findJsFileInNodeModules(fileName, nodeModulesDir) {
563+
async function findJsFileInNodeModules(fileName: string, nodeModulesDir: string): Promise<string[]> {
529564
const foundPaths = [];
530565

531566
try {
@@ -550,7 +585,7 @@ async function findJsFileInNodeModules(fileName, nodeModulesDir) {
550585
}
551586
}
552587
} catch (error) {
553-
console.warn(`⚠️ Error searching for JS file ${fileName}: ${error.message}`);
588+
console.warn(`⚠️ Error searching for JS file ${fileName}: ${(error as Error).message}`);
554589
}
555590

556591
return foundPaths;
@@ -562,7 +597,7 @@ async function findJsFileInNodeModules(fileName, nodeModulesDir) {
562597
* @param {string} fileName - JS file name to find
563598
* @returns {Promise<string[]>} Array of paths where the file was found
564599
*/
565-
async function searchForJsInPackage(packageDir, fileName) {
600+
async function searchForJsInPackage(packageDir: string, fileName: string): Promise<string[]> {
566601
const foundPaths = [];
567602

568603
// Common directories where JS files might be located
@@ -587,7 +622,7 @@ async function searchForJsInPackage(packageDir, fileName) {
587622
* @param {string} fileName - File name to find
588623
* @returns {Promise<string[]>} Array of paths where the file was found
589624
*/
590-
async function searchRecursively(dir, fileName) {
625+
async function searchRecursively(dir: string, fileName: string): Promise<string[]> {
591626
const foundPaths = [];
592627

593628
try {
@@ -628,7 +663,7 @@ async function searchRecursively(dir, fileName) {
628663
* @param {boolean} [requireImportMeta=false] - Whether to require import.meta.url in the pattern
629664
* @returns {RegExp} Compiled regex pattern with global flag
630665
*/
631-
function createUrlRegex(extension, requireImportMeta = false) {
666+
function createUrlRegex(extension: string, requireImportMeta = false): RegExp {
632667
const importMetaPart = requireImportMeta ? "[^)]*import\\.meta\\.url" : "[^)]*";
633668
return new RegExp(`new URL\\(['"](?:\\.\\/)?([^'"]+\\.${extension})['"]${importMetaPart}\\)`, "g");
634669
}
@@ -681,7 +716,7 @@ async function discoverEntryPoints() {
681716
}
682717
}
683718
} catch (error) {
684-
console.warn(`⚠️ Could not perform preliminary analysis: ${error.message}`);
719+
console.warn(`⚠️ Could not perform preliminary analysis: ${(error as Error).message}`);
685720
console.warn("🔄 Falling back to main entry point only");
686721
}
687722

0 commit comments

Comments
 (0)