Skip to content

Commit 8f3485b

Browse files
claude: Allow bundle.outputFile to be just a filename
Refactored output path resolution to support three modes: 1. Just filename (no path separators): { "bundle": { "outputFile": "julia-engine.js" } } → Infers directory from _extension.yml location → Result: _extensions/julia-engine/julia-engine.js 2. Full path (has path separators): { "bundle": { "outputFile": "_extensions/custom/out.js" } } → Uses path as-is → Result: _extensions/custom/out.js 3. Omitted: { "bundle": {} } → Infers both filename (from entry point) and directory → Result: _extensions/julia-engine/julia-engine.js Implementation changes: - Split into two focused functions: - inferFilename(entryPoint): derives "foo.js" from "src/foo.ts" - inferOutputPath(outputFilename): finds _extension.yml and joins with filename - Updated bundle() to detect filename-only vs full-path - Each function has single responsibility, no coupling This provides flexibility while maintaining convention over configuration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 532a9b8 commit 8f3485b

File tree

1 file changed

+29
-9
lines changed
  • src/command/dev-call/build-ts-extension

1 file changed

+29
-9
lines changed

src/command/dev-call/build-ts-extension/cmd.ts

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,15 @@ async function autoDetectEntryPoint(
156156
Deno.exit(1);
157157
}
158158

159-
function inferOutputPath(entryPoint: string): string {
160-
// Get the base name without extension
159+
function inferFilename(entryPoint: string): string {
160+
// Get the base name without extension, add .js
161161
const fileName = basename(entryPoint, extname(entryPoint));
162+
return `${fileName}.js`;
163+
}
164+
165+
function inferOutputPath(outputFilename: string): string {
166+
// Derive extension name from filename for error messages
167+
const extensionName = basename(outputFilename, extname(outputFilename));
162168

163169
// Find the extension directory by looking for _extension.yml
164170
const extensionsDir = "_extensions";
@@ -169,8 +175,8 @@ function inferOutputPath(entryPoint: string): string {
169175
"Extension projects must have an _extensions/ directory with _extension.yml.",
170176
);
171177
error("Create the extension structure:");
172-
error(` mkdir -p _extensions/${fileName}`);
173-
error(` touch _extensions/${fileName}/_extension.yml`);
178+
error(` mkdir -p _extensions/${extensionName}`);
179+
error(` touch _extensions/${extensionName}/_extension.yml`);
174180
Deno.exit(1);
175181
}
176182

@@ -187,7 +193,7 @@ function inferOutputPath(entryPoint: string): string {
187193
"Extension projects must have _extension.yml in a subdirectory of _extensions/.",
188194
);
189195
error("Create the extension metadata:");
190-
error(` touch _extensions/${fileName}/_extension.yml`);
196+
error(` touch _extensions/${extensionName}/_extension.yml`);
191197
Deno.exit(1);
192198
}
193199

@@ -205,15 +211,15 @@ function inferOutputPath(entryPoint: string): string {
205211
error(" {");
206212
error(' "bundle": {');
207213
error(
208-
` "outputFile": "${extensionYmlFiles[0]}/${fileName}.js"`,
214+
` "outputFile": "${extensionYmlFiles[0]}/${outputFilename}"`,
209215
);
210216
error(" }");
211217
error(" }");
212218
Deno.exit(1);
213219
}
214220

215221
// Use the single extension directory found
216-
return join(extensionYmlFiles[0], `${fileName}.js`);
222+
return join(extensionYmlFiles[0], outputFilename);
217223
}
218224

219225
async function bundle(
@@ -227,8 +233,22 @@ async function bundle(
227233
architectureToolsPath("deno");
228234

229235
// Determine output path
230-
const outputPath = config.bundle?.outputFile ||
231-
inferOutputPath(entryPoint);
236+
let outputPath: string;
237+
if (config.bundle?.outputFile) {
238+
const specifiedOutput = config.bundle.outputFile;
239+
// Check if it's just a filename (no path separators)
240+
if (!specifiedOutput.includes("/") && !specifiedOutput.includes("\\")) {
241+
// Just filename - infer directory from _extension.yml
242+
outputPath = inferOutputPath(specifiedOutput);
243+
} else {
244+
// Full path specified - use as-is
245+
outputPath = specifiedOutput;
246+
}
247+
} else {
248+
// Nothing specified - infer both directory and filename
249+
const filename = inferFilename(entryPoint);
250+
outputPath = inferOutputPath(filename);
251+
}
232252

233253
// Ensure output directory exists
234254
const outputDir = dirname(outputPath);

0 commit comments

Comments
 (0)