@kb-labs/studio-plugin-tools 2.119.0-canary.e120bc0ee → 2.119.0

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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":["require"],"mappings":";AAwBO,IAAM,kBAAA,GAAsF;AAAA,EACjG,KAAA,EAAO,EAAE,SAAA,EAAW,IAAA,EAAM,iBAAiB,SAAA,EAAU;AAAA,EACrD,WAAA,EAAa,EAAE,SAAA,EAAW,IAAA,EAAM,iBAAiB,SAAA,EAAU;AAAA,EAC3D,kBAAA,EAAoB,EAAE,SAAA,EAAW,IAAA,EAAM,iBAAiB,QAAA,EAAS;AAAA,EACjE,IAAA,EAAM,EAAE,SAAA,EAAW,IAAA,EAAM,iBAAiB,SAAA,EAAU;AAAA,EACpD,mBAAA,EAAqB,EAAE,SAAA,EAAW,IAAA,EAAM,iBAAiB,QAAA,EAAS;AAAA,EAClE,uBAAA,EAAyB,EAAE,SAAA,EAAW,IAAA,EAAM,iBAAiB,QAAA,EAAS;AAAA,EACtE,OAAA,EAAS,EAAE,SAAA,EAAW,IAAA,EAAM,iBAAiB,QAAA,EAAS;AAAA,EACtD,uBAAA,EAAyB,EAAE,SAAA,EAAW,IAAA,EAAM,iBAAiB,QAAA,EAAS;AAAA,EACtE,2BAAA,EAA6B,EAAE,SAAA,EAAW,IAAA,EAAM,iBAAiB,QAAA,EAAS;AAAA,EAC1E,wBAAA,EAA0B,EAAE,SAAA,EAAW,IAAA,EAAM,iBAAiB,QAAA,EAAS;AAAA,EACvE,yBAAA,EAA2B,EAAE,SAAA,EAAW,IAAA,EAAM,iBAAiB,QAAA,EAAS;AAAA,EACxE,cAAA,EAAgB,EAAE,SAAA,EAAW,IAAA,EAAM,iBAAiB,QAAA;AACtD;AA+BA,eAAe,qBAAqB,OAAA,EAAgD;AAClF,EAAA,MAAM,EAAA,GAAK,MAAM,OAAO,IAAI,CAAA;AAE5B,EAAA,MAAM,YAAA,GAAe,OAAO,YAAoC;AAC9D,IAAA,IAAI;AACF,MAAA,MAAM,YAAA,GAAe,QAAQ,oBAAoB,CAAA;AACjD,MAAA,MAAM,WAAW,IAAA,CAAK,KAAA,CAAM,GAAG,YAAA,CAAa,YAAA,EAAc,MAAM,CAAC,CAAA;AACjE,MAAA,OAAO,SAAS,OAAA,IAAW,IAAA;AAAA,IAC7B,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF,CAAA,GAAG;AAEH,EAAA,IAAI,CAAC,YAAA,EAAc;AAAC,IAAA;AAAA,EAAO;AAE3B,EAAA,MAAM,WAAW,YAAA,CAAa,KAAA,CAAM,GAAG,CAAA,CAAE,EAAA,CAAG,CAAC,CAAA,IAAK,GAAA;AAClD,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,QAAA,EAAU,EAAE,CAAA;AACnC,EAAA,IAAI,SAAS,EAAA,EAAI;AACf,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;;AAAA,yCAAA,EAA2C,YAAY,CAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA,KAYzD;AAAA,EACF;AACF;AAEA,eAAsB,yBAAyB,OAAA,EAAkE;AAC/G,EAAA,MAAM,EAAE,sBAAA,EAAuB,GAAI,MAAM,OAAO,oCAAoC,CAAA;AACpF,EAAA,MAAM,IAAA,GAAO,MAAM,OAAO,MAAM,CAAA;AAChC,EAAA,MAAM,EAAE,aAAA,EAAc,GAAI,MAAM,OAAO,QAAQ,CAAA;AAC/C,EAAA,MAAMA,QAAAA,GAAU,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA;AAE7C,EAAA,MAAM,oBAAA,CAAqBA,SAAQ,OAAO,CAAA;AAE1C,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,YAAA;AACvC,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,cAAA;AACvC,EAAA,MAAM,SAAA,GAAY,QAAQ,GAAA,IAAO,KAAA;AAEjC,EAAA,OAAO;AAAA,IACL,OAAO,EAAC;AAAA,IACR,MAAA,EAAQ;AAAA,MACN,MAAM,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,GAAA,IAAO,SAAS,CAAA;AAAA,MAC3C,UAAA,EAAY,MAAA;AAAA,MACZ,KAAA,EAAO;AAAA,KACT;AAAA,IACA,OAAA,EAAS;AAAA,MACP,UAAA,EAAY,CAAC,MAAA,EAAQ,KAAA,EAAO,QAAQ,KAAK;AAAA,KAC3C;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,KAAA,EAAO;AAAA,QACL;AAAA,UACE,IAAA,EAAM,SAAA;AAAA,UACN,OAAA,EAAS,cAAA;AAAA,UACT,GAAA,EAAK;AAAA,YACH,MAAA,EAAQ,oBAAA;AAAA,YACR,OAAA,EAAS;AAAA,cACP,GAAA,EAAK;AAAA,gBACH,MAAA,EAAQ,EAAE,MAAA,EAAQ,YAAA,EAAc,KAAK,IAAA,EAAK;AAAA,gBAC1C,WAAW,EAAE,KAAA,EAAO,EAAE,OAAA,EAAS,aAAY;AAAE;AAC/C;AACF;AACF,SACF;AAAA,QACA;AAAA,UACE,IAAA,EAAM,gBAAA;AAAA,UACN,GAAA,EAAK;AAAA,YACHA,QAAAA,CAAQ,QAAQ,cAAc,CAAA;AAAA,YAC9B;AAAA,cACE,MAAA,EAAQA,QAAAA,CAAQ,OAAA,CAAQ,YAAY,CAAA;AAAA,cACpC,OAAA,EAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAOP,OAAA,EAAS,EAAE,sBAAA,EAAwB,OAAA;AAAQ;AAC7C;AACF;AACF,SACF;AAAA,QACA;AAAA,UACE,IAAA,EAAM,QAAA;AAAA,UACN,OAAA,EAAS,gBAAA;AAAA,UACT,GAAA,EAAK,CAACA,QAAAA,CAAQ,OAAA,CAAQ,cAAc,CAAA,EAAGA,QAAAA,CAAQ,OAAA,CAAQ,YAAY,CAAC;AAAA;AACtE;AACF,KACF;AAAA,IACA,OAAA,EAAS;AAAA,MACP,IAAI,sBAAA,CAAuB;AAAA,QACzB,MAAM,OAAA,CAAQ,IAAA;AAAA,QACd,QAAA,EAAU,QAAQ,QAAA,IAAY,gBAAA;AAAA,QAC9B,QAAA,EAAU,IAAA;AAAA,QACV,GAAA,EAAK,SAAA,GAAY,EAAE,aAAA,EAAe,MAAK,GAAI,KAAA;AAAA,QAC3C,SAAS,OAAA,CAAQ,OAAA;AAAA,QACjB,MAAA,EAAQ;AAAA,UACN,GAAG,kBAAA;AAAA,UACH,GAAG,OAAA,CAAQ;AAAA;AACb,OACD;AAAA,KACH;AAAA,IACA,YAAA,EAAc;AAAA,MACZ,QAAA,EAAU;AAAA;AACZ,GACF;AACF","file":"index.js","sourcesContent":["/**\n * @kb-labs/studio-plugin-tools\n *\n * Build tooling for plugin Studio pages (Module Federation remotes).\n * Uses Rspack with @module-federation/enhanced for native MF support.\n *\n * @example\n * ```typescript\n * // rspack.studio.config.ts\n * const { createStudioRemoteConfig } = require('@kb-labs/studio-plugin-tools');\n *\n * module.exports = createStudioRemoteConfig({\n * name: 'commitPlugin',\n * exposes: {\n * './CommitOverview': './src/studio/pages/CommitOverview.tsx',\n * },\n * });\n * ```\n */\n\n/**\n * Shared dependencies that match the Studio host.\n * Loaded once by the host — remotes reuse them via MF shared scope.\n */\nexport const STUDIO_SHARED_DEPS: Record<string, { singleton: boolean; requiredVersion: string }> = {\n react: { singleton: true, requiredVersion: '^19.0.0' },\n 'react-dom': { singleton: true, requiredVersion: '^19.0.0' },\n 'react-router-dom': { singleton: true, requiredVersion: '^7.0.0' },\n antd: { singleton: true, requiredVersion: '^5.21.0' },\n '@ant-design/icons': { singleton: true, requiredVersion: '^5.4.0' },\n '@tanstack/react-query': { singleton: true, requiredVersion: '^5.0.0' },\n zustand: { singleton: true, requiredVersion: '^5.0.0' },\n '@kb-labs/studio-hooks': { singleton: true, requiredVersion: '^2.0.0' },\n '@kb-labs/studio-event-bus': { singleton: true, requiredVersion: '^2.0.0' },\n '@kb-labs/studio-ui-kit': { singleton: true, requiredVersion: '^2.0.0' },\n '@kb-labs/studio-ui-core': { singleton: true, requiredVersion: '^2.0.0' },\n '@kb-labs/sdk': { singleton: true, requiredVersion: '^2.0.0' },\n};\n\nexport interface KbStudioRemoteOptions {\n /** Module Federation remote name (must match manifest remoteName) */\n name: string;\n /** Exposed modules: { './PageName': './src/studio/pages/PageName.tsx' } */\n exposes: Record<string, string>;\n /** Override or extend shared deps */\n shared?: Record<string, { singleton?: boolean; requiredVersion?: string }>;\n /** Remote entry filename (default: 'remoteEntry.js') */\n filename?: string;\n /** Output directory (default: 'dist/widgets') */\n outputDir?: string;\n /**\n * Generate TypeScript types for exposed modules (MF v2 dts feature).\n * Studio host picks them up automatically in dev via @mf-types/.\n * Default: true in development, false in production.\n */\n dts?: boolean;\n}\n\n/**\n * Create a complete Rspack config for building a plugin as an MF remote.\n *\n * Returns a full rspack config object — use as default export in rspack.config.mjs.\n * Uses dynamic import internally to avoid CJS/ESM issues.\n */\n/**\n * Validate React version in the calling plugin's node_modules.\n * Studio host uses React 18 — React 19 causes MF element type mismatch at runtime.\n */\nasync function validateReactVersion(resolve: (id: string) => string): Promise<void> {\n const fs = await import('fs');\n\n const reactVersion = await (async (): Promise<string | null> => {\n try {\n const reactPkgPath = resolve('react/package.json');\n const reactPkg = JSON.parse(fs.readFileSync(reactPkgPath, 'utf8')) as { version: string };\n return reactPkg.version ?? null;\n } catch {\n return null;\n }\n })();\n\n if (!reactVersion) {return;}\n\n const majorStr = reactVersion.split('.').at(0) ?? '0';\n const major = parseInt(majorStr, 10);\n if (major >= 20) {\n throw new Error(\n `\\n\\n❌ Studio plugin build failed: React ${reactVersion} detected.\\n\\n` +\n `Studio host runs React 19. When a plugin bundles React 20+, elements may\\n` +\n `use a different internal symbol which React 19 cannot reconcile,\\n` +\n `causing \"Objects are not valid as a React child\" crash at runtime.\\n\\n` +\n `Fix: pin React 19 in your plugin's devDependencies:\\n\\n` +\n ` \"devDependencies\": {\\n` +\n ` \"react\": \"^19.0.0\",\\n` +\n ` \"react-dom\": \"^19.0.0\"\\n` +\n ` }\\n\\n` +\n `Then reinstall and rebuild:\\n\\n` +\n ` pnpm install\\n` +\n ` pnpm build:studio\\n`,\n );\n }\n}\n\nexport async function createStudioRemoteConfig(options: KbStudioRemoteOptions): Promise<Record<string, unknown>> {\n const { ModuleFederationPlugin } = await import('@module-federation/enhanced/rspack');\n const path = await import('path');\n const { createRequire } = await import('module');\n const require = createRequire(import.meta.url);\n\n await validateReactVersion(require.resolve);\n\n const isDev = process.env.NODE_ENV !== 'production';\n const outputDir = options.outputDir ?? 'dist/widgets';\n const enableDts = options.dts ?? isDev;\n\n return {\n entry: {},\n output: {\n path: path.resolve(process.cwd(), outputDir),\n publicPath: 'auto',\n clean: true,\n },\n resolve: {\n extensions: ['.tsx', '.ts', '.jsx', '.js'],\n },\n module: {\n rules: [\n {\n test: /\\.tsx?$/,\n exclude: /node_modules/,\n use: {\n loader: 'builtin:swc-loader',\n options: {\n jsc: {\n parser: { syntax: 'typescript', tsx: true },\n transform: { react: { runtime: 'automatic' } },\n },\n },\n },\n },\n {\n test: /\\.module\\.css$/,\n use: [\n require.resolve('style-loader'),\n {\n loader: require.resolve('css-loader'),\n options: {\n // Explicit rather than relying on css-loader's version-dependent\n // default — keeps class name casing consistent with the Studio\n // host's native Rspack CSS Modules (studio/app/rspack.config.mjs,\n // `exportsConvention: 'as-is'`) and with the tsup CSS Modules\n // plugin used by library packages like ui-kit\n // (infra/devkit/tsup/css-modules-plugin.js).\n modules: { exportLocalsConvention: 'as-is' },\n },\n },\n ],\n },\n {\n test: /\\.css$/,\n exclude: /\\.module\\.css$/,\n use: [require.resolve('style-loader'), require.resolve('css-loader')],\n },\n ],\n },\n plugins: [\n new ModuleFederationPlugin({\n name: options.name,\n filename: options.filename ?? 'remoteEntry.js',\n manifest: true,\n dts: enableDts ? { generateTypes: true } : false,\n exposes: options.exposes,\n shared: {\n ...STUDIO_SHARED_DEPS,\n ...options.shared,\n },\n }),\n ],\n optimization: {\n minimize: true,\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../../home/runner/work/kb-labs/kb-labs/studio/plugin-tools/src/index.ts"],"names":["require"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @kb-labs/studio-plugin-tools\n *\n * Build tooling for plugin Studio pages (Module Federation remotes).\n * Uses Rspack with @module-federation/enhanced for native MF support.\n *\n * @example\n * ```typescript\n * // rspack.studio.config.ts\n * const { createStudioRemoteConfig } = require('@kb-labs/studio-plugin-tools');\n *\n * module.exports = createStudioRemoteConfig({\n * name: 'commitPlugin',\n * exposes: {\n * './CommitOverview': './src/studio/pages/CommitOverview.tsx',\n * },\n * });\n * ```\n */\n\n/**\n * Shared dependencies that match the Studio host.\n * Loaded once by the host — remotes reuse them via MF shared scope.\n */\nexport const STUDIO_SHARED_DEPS: Record<string, { singleton: boolean; requiredVersion: string }> = {\n react: { singleton: true, requiredVersion: '^19.0.0' },\n 'react-dom': { singleton: true, requiredVersion: '^19.0.0' },\n 'react-router-dom': { singleton: true, requiredVersion: '^7.0.0' },\n antd: { singleton: true, requiredVersion: '^5.21.0' },\n '@ant-design/icons': { singleton: true, requiredVersion: '^5.4.0' },\n '@tanstack/react-query': { singleton: true, requiredVersion: '^5.0.0' },\n zustand: { singleton: true, requiredVersion: '^5.0.0' },\n '@kb-labs/studio-hooks': { singleton: true, requiredVersion: '^2.0.0' },\n '@kb-labs/studio-event-bus': { singleton: true, requiredVersion: '^2.0.0' },\n '@kb-labs/studio-ui-kit': { singleton: true, requiredVersion: '^2.0.0' },\n '@kb-labs/studio-ui-core': { singleton: true, requiredVersion: '^2.0.0' },\n '@kb-labs/sdk': { singleton: true, requiredVersion: '^2.0.0' },\n};\n\nexport interface KbStudioRemoteOptions {\n /** Module Federation remote name (must match manifest remoteName) */\n name: string;\n /** Exposed modules: { './PageName': './src/studio/pages/PageName.tsx' } */\n exposes: Record<string, string>;\n /** Override or extend shared deps */\n shared?: Record<string, { singleton?: boolean; requiredVersion?: string }>;\n /** Remote entry filename (default: 'remoteEntry.js') */\n filename?: string;\n /** Output directory (default: 'dist/widgets') */\n outputDir?: string;\n /**\n * Generate TypeScript types for exposed modules (MF v2 dts feature).\n * Studio host picks them up automatically in dev via @mf-types/.\n * Default: true in development, false in production.\n */\n dts?: boolean;\n}\n\n/**\n * Create a complete Rspack config for building a plugin as an MF remote.\n *\n * Returns a full rspack config object — use as default export in rspack.config.mjs.\n * Uses dynamic import internally to avoid CJS/ESM issues.\n */\n/**\n * Validate React version in the calling plugin's node_modules.\n * Studio host uses React 18 — React 19 causes MF element type mismatch at runtime.\n */\nasync function validateReactVersion(resolve: (id: string) => string): Promise<void> {\n const fs = await import('fs');\n\n const reactVersion = await (async (): Promise<string | null> => {\n try {\n const reactPkgPath = resolve('react/package.json');\n const reactPkg = JSON.parse(fs.readFileSync(reactPkgPath, 'utf8')) as { version: string };\n return reactPkg.version ?? null;\n } catch {\n return null;\n }\n })();\n\n if (!reactVersion) {return;}\n\n const majorStr = reactVersion.split('.').at(0) ?? '0';\n const major = parseInt(majorStr, 10);\n if (major >= 20) {\n throw new Error(\n `\\n\\n❌ Studio plugin build failed: React ${reactVersion} detected.\\n\\n` +\n `Studio host runs React 19. When a plugin bundles React 20+, elements may\\n` +\n `use a different internal symbol which React 19 cannot reconcile,\\n` +\n `causing \"Objects are not valid as a React child\" crash at runtime.\\n\\n` +\n `Fix: pin React 19 in your plugin's devDependencies:\\n\\n` +\n ` \"devDependencies\": {\\n` +\n ` \"react\": \"^19.0.0\",\\n` +\n ` \"react-dom\": \"^19.0.0\"\\n` +\n ` }\\n\\n` +\n `Then reinstall and rebuild:\\n\\n` +\n ` pnpm install\\n` +\n ` pnpm build:studio\\n`,\n );\n }\n}\n\nexport async function createStudioRemoteConfig(options: KbStudioRemoteOptions): Promise<Record<string, unknown>> {\n const { ModuleFederationPlugin } = await import('@module-federation/enhanced/rspack');\n const path = await import('path');\n const { createRequire } = await import('module');\n const require = createRequire(import.meta.url);\n\n await validateReactVersion(require.resolve);\n\n const isDev = process.env.NODE_ENV !== 'production';\n const outputDir = options.outputDir ?? 'dist/widgets';\n const enableDts = options.dts ?? isDev;\n\n return {\n entry: {},\n output: {\n path: path.resolve(process.cwd(), outputDir),\n publicPath: 'auto',\n clean: true,\n },\n resolve: {\n extensions: ['.tsx', '.ts', '.jsx', '.js'],\n },\n module: {\n rules: [\n {\n test: /\\.tsx?$/,\n exclude: /node_modules/,\n use: {\n loader: 'builtin:swc-loader',\n options: {\n jsc: {\n parser: { syntax: 'typescript', tsx: true },\n transform: { react: { runtime: 'automatic' } },\n },\n },\n },\n },\n {\n test: /\\.module\\.css$/,\n use: [\n require.resolve('style-loader'),\n {\n loader: require.resolve('css-loader'),\n options: {\n // Explicit rather than relying on css-loader's version-dependent\n // default — keeps class name casing consistent with the Studio\n // host's native Rspack CSS Modules (studio/app/rspack.config.mjs,\n // `exportsConvention: 'as-is'`) and with the tsup CSS Modules\n // plugin used by library packages like ui-kit\n // (infra/devkit/tsup/css-modules-plugin.js).\n modules: { exportLocalsConvention: 'as-is' },\n },\n },\n ],\n },\n {\n test: /\\.css$/,\n exclude: /\\.module\\.css$/,\n use: [require.resolve('style-loader'), require.resolve('css-loader')],\n },\n ],\n },\n plugins: [\n new ModuleFederationPlugin({\n name: options.name,\n filename: options.filename ?? 'remoteEntry.js',\n manifest: true,\n dts: enableDts ? { generateTypes: true } : false,\n exposes: options.exposes,\n shared: {\n ...STUDIO_SHARED_DEPS,\n ...options.shared,\n },\n }),\n ],\n optimization: {\n minimize: true,\n },\n };\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kb-labs/studio-plugin-tools",
3
3
  "description": "Build tooling for plugin Studio pages — Rspack config for Module Federation remotes",
4
- "version": "2.119.0-canary.e120bc0ee",
4
+ "version": "2.119.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -27,10 +27,10 @@
27
27
  "tsup": "^8.5.0",
28
28
  "typescript": "^5.6.3",
29
29
  "vitest": "^3.2.6",
30
- "@kb-labs/devkit": "2.119.0-canary.e120bc0ee"
30
+ "@kb-labs/devkit": "2.119.0"
31
31
  },
32
32
  "engines": {
33
- "node": ">=22.0.0",
33
+ "node": ">=24.0.0",
34
34
  "pnpm": ">=9.0.0"
35
35
  },
36
36
  "peerDependencies": {