Skip to content

feat(cli): flatten asset paths and set publicPath for server-compatib…#82

Open
mpfilbin wants to merge 1 commit into
mainfrom
mpf/support_bundle_assets
Open

feat(cli): flatten asset paths and set publicPath for server-compatib…#82
mpfilbin wants to merge 1 commit into
mainfrom
mpf/support_bundle_assets

Conversation

@mpfilbin
Copy link
Copy Markdown
Collaborator

@mpfilbin mpfilbin commented May 14, 2026

The backend server is adding a new endpoint GET /api/v1/app/:name/:filename that serves all plugin files (JS, CSS, and binary assets) using a single-segment filename. This PR makes two changes to the CLI bundler to support it.

First, it flattens asset output from an assets/ subdirectory to the ZIP root, so asset filenames are single-segment paths the new endpoint can serve.

Second, it sets esbuild's publicPath option to /api/v1/app/{slug}/ so asset URLs embedded in bundled JS and CSS output are absolute paths rather than import.meta.url-relative strings. The relative form breaks when the host app loads the plugin in a context where import.meta.url doesn't resolve to the expected origin.

Summary

  • Flattens bundled assets to the ZIP root (was assets/[name]-[hash], now [name]-[hash]) so filenames are single-segment paths compatible with the new GET
    /api/v1/app/:name/:filename server endpoint
  • Sets esbuild publicPath to /api/v1/app/{slug}/ so asset references embedded in bundled JS and CSS output are absolute paths rather than import.meta.url-relative strings,
    which break when the host app loads the plugin without the correct import.meta.url context

Test Plan

  • Run just test — all 272 tests pass
  • Publish a plugin with image assets and verify images load correctly at /api/v1/app/{name}/{asset-hash}.png
  • Verify CSS url() references resolve to absolute API paths in the bundled output

Copilot AI review requested due to automatic review settings May 14, 2026 18:02
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the CLI bundling pipeline to align plugin ZIP contents and in-bundle asset URLs with the backend’s new single-segment file serving endpoint (GET /api/v1/app/:name/:filename), so images/fonts referenced from JS/CSS resolve correctly when hosted by the server.

Changes:

  • Flatten emitted asset paths from assets/[name]-[hash] to [name]-[hash] so assets land at the ZIP root.
  • Set esbuild publicPath to /api/v1/app/{slug}/ (via a new slug parameter) so JS/CSS embed absolute asset URLs instead of import.meta.url-relative URLs.
  • Update CLI commands, tests, and README to match the new bundling/packaging behavior.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/build/index.ts Updates deprecated build shim’s internal interface for the new bundlePlugin(cwd, slug) signature.
README.md Adjusts documentation to reflect assets being placed at the archive root.
cli/tests/commands/everywhere/publish.test.ts Updates expectations for bundlePlugin being called with a slug.
cli/tests/build/packager.test.ts Updates zip assertions for flattened asset paths.
cli/tests/build/bundler.test.ts Updates bundler tests for slug parameter and absolute /api/v1/app/{slug}/... asset URLs.
cli/src/commands/everywhere/publish.ts Passes slug into bundling so emitted URLs match server routes.
cli/src/commands/everywhere/install.ts Computes slug before bundling and passes it through.
cli/src/commands/everywhere/build.ts Computes slug before bundling and passes it through.
cli/src/build/bundler.ts Flattens assetNames and conditionally sets esbuild publicPath based on slug.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/build/index.ts
Comment on lines 71 to 75
export async function bundlePlugin(cwd: string): Promise<string> {
warnDeprecated();
const cliBuild = await loadCliBuildModule();
const bundle = await cliBuild.bundlePlugin(cwd);
const bundle = await cliBuild.bundlePlugin(cwd, '');
return bundle.js;
…le URLs

Assets are now placed at the ZIP root instead of an assets/ subdirectory,
matching the single-segment GET /api/v1/app/:name/:filename server endpoint.

esbuild's publicPath is set to /api/v1/app/{slug}/ so asset references
embedded in bundled JS and CSS output are absolute paths rather than
import.meta.url-relative strings, which break when the host app loads
the plugin without the correct import.meta.url context.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@mpfilbin mpfilbin force-pushed the mpf/support_bundle_assets branch from f5ce1e1 to ad2fdf7 Compare May 14, 2026 20:06
@mpfilbin
Copy link
Copy Markdown
Collaborator Author

@copilot and you please re-review these changes?

Copy link
Copy Markdown

Copilot AI commented May 14, 2026

@copilot and you please re-review these changes?

The concern raised by the previous review — that the shim was calling bundlePlugin(cwd, '') which would suppress publicPath — was already addressed in commit ad2fdf7. The shim now reads package.json to derive the slug before delegating to the CLI's bundlePlugin:

let slug = '';
try {
  const pkg = JSON.parse(await readFile(join(cwd, 'package.json'), 'utf8')) as { name?: unknown };
  if (typeof pkg.name === 'string') slug = toSlug(pkg.name);
} catch {
  // package.json unreadable — fall back to no publicPath
}
const bundle = await cliBuild.bundlePlugin(cwd, slug);

All 43 relevant tests (bundler, packager, publish, shim) pass with this change.

Copy link
Copy Markdown
Collaborator

@jheddings jheddings left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants