webim-plugin 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -37,7 +37,7 @@ Commands:
37
37
 
38
38
  Config (webim-plugin.json):
39
39
  { "entry": "src/index.js", "out": "dist/plugin.js",
40
- "api": "http://localhost:4100/api", "tenant": "root" }
40
+ "api": "https://webim.app/api", "tenant": "root" }
41
41
 
42
42
  Auth (push/dev): WEBIM_TOKEN, or WEBIM_EMAIL + WEBIM_PASSWORD.`;
43
43
 
@@ -45,7 +45,7 @@ Auth (push/dev): WEBIM_TOKEN, or WEBIM_EMAIL + WEBIM_PASSWORD.`;
45
45
  // scaffolding
46
46
 
47
47
  const TEMPLATE_CONFIG = (name) => `${JSON.stringify(
48
- { entry: 'src/index.js', out: 'dist/plugin.js', api: 'http://localhost:4100/api', tenant: 'root' },
48
+ { entry: 'src/index.js', out: 'dist/plugin.js', api: 'https://webim.app/api', tenant: 'root' },
49
49
  null,
50
50
  2
51
51
  )}\n`;
@@ -206,7 +206,9 @@ must have a default in \`props\`.
206
206
 
207
207
  - Everything must land in ONE ES module — \`push\` uploads only the built JS.
208
208
  - \`import\` of \`.css\`/\`.html\` files yields the file content as a STRING
209
- (inject a \`<style>\` tag / parse markup yourself at mount time).
209
+ (inject a \`<style>\` tag / parse markup yourself at mount time). In \`.css\`
210
+ imports the CLI rewrites \`:root\` to \`:host\` — inside a shadow root
211
+ \`:root\` matches nothing, \`:host\` is its exact analogue.
210
212
  - Images and fonts (\`.svg .png .jpg .jpeg .gif .webp .woff .woff2\`) import
211
213
  as \`data:\` URLs.
212
214
  - After bundling, the CLI IMPORTS the bundle in Node.js to validate it.
@@ -226,7 +228,8 @@ must have a default in \`props\`.
226
228
  \`document.head\` (deduplicate first) — \`@font-face\` is inert inside a
227
229
  shadow root.
228
230
  3. If reusing an app's page-level stylesheet, rescope it to a wrapper div
229
- inside the shadow: \`body\`/\`html\`/\`:root\` selectors → the wrapper class,
231
+ inside the shadow: \`body\`/\`html\` selectors → the wrapper class
232
+ (\`:root\` is rewritten to \`:host\` by the build automatically),
230
233
  \`position: fixed\` → \`absolute\`, \`100vw/100vh\` → \`100%\`. Give the
231
234
  wrapper \`position: relative; overflow: hidden\`.
232
235
  4. The same block can be mounted MULTIPLE times on one page: no module-level
@@ -445,7 +448,7 @@ async function wrap(dirArg) {
445
448
 
446
449
  await mkdir(path.dirname(entryFile), { recursive: true });
447
450
  await writeFile(path.join(dir, CONFIG_FILE), `${JSON.stringify(
448
- { entry, out: 'dist/plugin.js', api: 'http://localhost:4100/api', tenant: 'root' },
451
+ { entry, out: 'dist/plugin.js', api: 'https://webim.app/api', tenant: 'root' },
449
452
  null,
450
453
  2
451
454
  )}\n`);
@@ -488,7 +491,7 @@ async function loadConfig() {
488
491
  return {
489
492
  entry: config.entry ?? 'src/index.js',
490
493
  out: config.out ?? 'dist/plugin.js',
491
- api: config.api ?? 'http://localhost:4100/api',
494
+ api: config.api ?? 'https://webim.app/api',
492
495
  tenant: config.tenant ?? ''
493
496
  };
494
497
  }
@@ -497,7 +500,6 @@ async function loadConfig() {
497
500
  // and HTML come in as strings (inject a <style> / parse markup at mount),
498
501
  // images and fonts as data: URLs.
499
502
  const LOADERS = {
500
- '.css': 'text',
501
503
  '.html': 'text',
502
504
  '.svg': 'dataurl',
503
505
  '.png': 'dataurl',
@@ -509,6 +511,31 @@ const LOADERS = {
509
511
  '.woff2': 'dataurl'
510
512
  };
511
513
 
514
+ // .css imports are strings too, but rescoped first: plugins render inside a
515
+ // Shadow DOM, where `:root` matches nothing — its analogue is `:host`, so the
516
+ // rewrite is always safe (same specificity, same "tree root" meaning).
517
+ // `html`/`body` selectors CAN'T be rewritten automatically — the wrapper
518
+ // class they should target is the plugin's own choice — so they only warn.
519
+ const warnedCssFiles = new Set();
520
+ const cssRescopePlugin = {
521
+ name: 'css-rescope',
522
+ setup(build) {
523
+ build.onLoad({ filter: /\.css$/ }, async (args) => {
524
+ const css = await readFile(args.path, 'utf8');
525
+
526
+ if (!warnedCssFiles.has(args.path) && /(^|[\s,}])(html|body)\s*[,{[.:>#]/m.test(css)) {
527
+ warnedCssFiles.add(args.path);
528
+ console.warn(
529
+ `Warning: ${path.relative(process.cwd(), args.path)} styles html/body — those selectors match nothing ` +
530
+ 'inside the shadow root; rescope them to a wrapper class (see WEBIM_PLUGIN.md, Rendering rules).'
531
+ );
532
+ }
533
+
534
+ return { contents: css.replace(/:root\b/g, ':host'), loader: 'text' };
535
+ });
536
+ }
537
+ };
538
+
512
539
  async function bundle(config) {
513
540
  const esbuild = await import('esbuild');
514
541
  const result = await esbuild.build({
@@ -523,7 +550,8 @@ async function bundle(config) {
523
550
  // Modern JSX runtime (React 17+/Vite default): .jsx/.tsx files work
524
551
  // without a manual `import React` in every file.
525
552
  jsx: 'automatic',
526
- loader: LOADERS
553
+ loader: LOADERS,
554
+ plugins: [cssRescopePlugin]
527
555
  });
528
556
 
529
557
  if (result.errors.length) throw new Error(result.errors.map((e) => e.text).join('\n'));
@@ -684,6 +712,7 @@ async function dev() {
684
712
  jsx: 'automatic',
685
713
  loader: LOADERS,
686
714
  plugins: [
715
+ cssRescopePlugin,
687
716
  {
688
717
  name: 'webim-push',
689
718
  setup(buildHook) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webim-plugin",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "CLI for Web-IM builder plugins — scaffold, bundle TS/JSX into the single-module standard, validate, and push to a tenant",
5
5
  "license": "MIT",
6
6
  "author": "Orhan POLAT",