@gxp-dev/tools 2.0.92 → 2.0.93

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.
@@ -29,6 +29,7 @@ const {
29
29
  safeCopyFile,
30
30
  createPackageJson,
31
31
  updateAppManifest,
32
+ ensureBaseFramework,
32
33
  installDependencies,
33
34
  updateExistingProject,
34
35
  ensureMkcertInstalled,
@@ -721,6 +722,7 @@ async function initCommand(argv) {
721
722
  console.log("Updating existing project...")
722
723
  updateExistingProject(projectPath)
723
724
  copyBundleFiles(projectPath, paths, false)
725
+ ensureBaseFramework(projectPath)
724
726
  console.log("✅ Project updated!")
725
727
  return
726
728
  }
@@ -8,6 +8,12 @@
8
8
  const isWin = process.platform === "win32"
9
9
  const exportCmd = isWin ? "set" : "export"
10
10
 
11
+ // Base CSS framework loaded by theme-layouts during development.
12
+ // Versioned here so the same value lands in package.json devDependencies
13
+ // AND the app-manifest's baseFramework field (platform reads the manifest
14
+ // to know which CSS framework to provide for the live plugin).
15
+ const TAILWIND_VERSION = "^4.3.0"
16
+
11
17
  // Required dependencies for GxP projects
12
18
  const REQUIRED_DEPENDENCIES = {
13
19
  dotenv: "^16.4.5",
@@ -23,8 +29,12 @@ const REQUIRED_DEV_DEPENDENCIES = {
23
29
  vitest: "^4.1.5",
24
30
  "@vue/test-utils": "^2.4.6",
25
31
  "happy-dom": "^15.11.0",
32
+ tailwindcss: TAILWIND_VERSION,
33
+ "@tailwindcss/vite": TAILWIND_VERSION,
26
34
  }
27
35
 
36
+ const BASE_FRAMEWORK = `tailwindcss@${TAILWIND_VERSION}`
37
+
28
38
  // Default scripts for package.json
29
39
  const DEFAULT_SCRIPTS = {
30
40
  dev: "gxdev dev --cli",
@@ -131,4 +141,6 @@ module.exports = {
131
141
  DEFAULT_PORTS,
132
142
  PACKAGE_NAME,
133
143
  ENVIRONMENT_URLS,
144
+ TAILWIND_VERSION,
145
+ BASE_FRAMEWORK,
134
146
  }
@@ -11,6 +11,7 @@ const {
11
11
  REQUIRED_DEPENDENCIES,
12
12
  REQUIRED_DEV_DEPENDENCIES,
13
13
  DEFAULT_SCRIPTS,
14
+ BASE_FRAMEWORK,
14
15
  } = require("../constants")
15
16
  const { loadGlobalConfig } = require("./paths")
16
17
 
@@ -89,6 +90,9 @@ function updateAppManifest(projectPath, projectName, description = "") {
89
90
  manifest.description = `GxP Plugin: ${projectName}`
90
91
  }
91
92
 
93
+ // Tell the platform which base CSS framework the layouts load.
94
+ manifest.baseFramework = BASE_FRAMEWORK
95
+
92
96
  // Update strings with project name
93
97
  if (manifest.strings && manifest.strings.default) {
94
98
  manifest.strings.default.welcome_text = `Welcome to ${projectName}`
@@ -101,6 +105,33 @@ function updateAppManifest(projectPath, projectName, description = "") {
101
105
  }
102
106
  }
103
107
 
108
+ /**
109
+ * Ensures app-manifest.json has the current baseFramework value.
110
+ * Used during existing-project updates where the manifest file is not overwritten.
111
+ * @param {string} projectPath - Path to project directory
112
+ */
113
+ function ensureBaseFramework(projectPath) {
114
+ const manifestPath = path.join(projectPath, "app-manifest.json")
115
+ if (!fs.existsSync(manifestPath)) {
116
+ return
117
+ }
118
+
119
+ try {
120
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"))
121
+ if (manifest.baseFramework === BASE_FRAMEWORK) {
122
+ return
123
+ }
124
+ manifest.baseFramework = BASE_FRAMEWORK
125
+ fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, "\t"))
126
+ console.log(`✓ Set baseFramework in app-manifest.json (${BASE_FRAMEWORK})`)
127
+ } catch (error) {
128
+ console.warn(
129
+ "⚠ Could not set baseFramework in app-manifest.json:",
130
+ error.message,
131
+ )
132
+ }
133
+ }
134
+
104
135
  /**
105
136
  * Installs npm dependencies
106
137
  */
@@ -244,6 +275,7 @@ module.exports = {
244
275
  safeCopyFile,
245
276
  createPackageJson,
246
277
  updateAppManifest,
278
+ ensureBaseFramework,
247
279
  installDependencies,
248
280
  updateExistingProject,
249
281
  isImageMagickInstalled,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gxp-dev/tools",
3
- "version": "2.0.92",
3
+ "version": "2.0.93",
4
4
  "description": "Dev tools to create platform plugins",
5
5
  "type": "commonjs",
6
6
  "publishConfig": {
@@ -47,7 +47,7 @@ function getApiConfig() {
47
47
  const projectId = import.meta.env.VITE_API_PROJECT_ID || ""
48
48
  const useHttps = import.meta.env.VITE_USE_HTTPS !== "false"
49
49
  const nodePort = import.meta.env.VITE_NODE_PORT || "3060"
50
- const mockPort = import.meta.env.VITE_SOCKET_IO_PORT || "3061"
50
+ const mockPort = import.meta.env.VITE_SOCKET_IO_PORT || "3069"
51
51
 
52
52
  // Check if we're in development mode (Vite dev server)
53
53
  const isDev = import.meta.env.DEV
@@ -120,6 +120,28 @@ function hasLocalFile(fileName) {
120
120
  * concatenated, objects (resolve.alias, define, etc.) are merged key-by-key,
121
121
  * primitives are overwritten.
122
122
  */
123
+ /**
124
+ * Try to load the `@tailwindcss/vite` plugin from the project's node_modules.
125
+ *
126
+ * Tailwind 4 ships as a dev-only base CSS framework — `tailwindcss` and
127
+ * `@tailwindcss/vite` are declared in the project's devDependencies and
128
+ * imported via `@import "tailwindcss";` inside the theme-layouts (which are
129
+ * dev-only; the production build entry is `src/Plugin.vue`). Loading the
130
+ * Vite plugin here lets that import generate utility CSS without each
131
+ * project having to wire it up in `vite.extend.js`. If the user has removed
132
+ * Tailwind we silently skip — the layouts work without it, just without
133
+ * Tailwind's default styling.
134
+ */
135
+ async function loadTailwindPlugin() {
136
+ try {
137
+ const mod = await import("@tailwindcss/vite")
138
+ const plugin = mod.default ?? mod
139
+ return typeof plugin === "function" ? plugin() : null
140
+ } catch {
141
+ return null
142
+ }
143
+ }
144
+
123
145
  async function loadExtensionConfig(ctx, runtimeConfig) {
124
146
  const candidates = ["vite.extend.js", "vite.extend.mjs"]
125
147
  for (const name of candidates) {
@@ -415,6 +437,12 @@ export default defineConfig(async (ctx) => {
415
437
  // Determine if HTTPS is enabled
416
438
  const useHttps = getHttpsConfig(env) !== undefined
417
439
 
440
+ // Load Tailwind 4 Vite plugin from the project's node_modules if present.
441
+ const tailwindPlugin = await loadTailwindPlugin()
442
+ if (tailwindPlugin) {
443
+ console.log("🎨 Tailwind: @tailwindcss/vite plugin loaded")
444
+ }
445
+
418
446
  // Get API proxy target for non-mock environments
419
447
  const apiProxyTarget = getApiProxyTarget(env)
420
448
  if (apiProxyTarget) {
@@ -448,6 +476,8 @@ export default defineConfig(async (ctx) => {
448
476
  },
449
477
  plugins: [
450
478
  runtimeFilesPlugin,
479
+ // Tailwind 4 Vite plugin (no-op if @tailwindcss/vite isn't installed).
480
+ ...((tailwindPlugin && [tailwindPlugin]) || []),
451
481
  // Source tracker must run BEFORE vue() to transform templates before compilation
452
482
  ...(useSourceTracker ? [gxpSourceTrackerPlugin()] : []),
453
483
  vue(),
@@ -4,6 +4,7 @@
4
4
  "description": "GxToolkit Plugin",
5
5
  "manifest_version": 3,
6
6
  "asset_dir": "/src/public",
7
+ "baseFramework": "tailwindcss@^4.3.0",
7
8
  "configurationFile": "configuration.json",
8
9
  "appInstructionsFile": "app-instructions.md",
9
10
  "defaultStylingFile": "default-styling.css",
@@ -24,7 +24,7 @@ API_ENV=mock
24
24
  # Development server configuration
25
25
  NODE_PORT=3060
26
26
  CLIENT_PORT=3060
27
- SOCKET_IO_PORT=3061
27
+ SOCKET_IO_PORT=3069
28
28
 
29
29
  # Logging configuration
30
30
  NODE_LOG_LEVEL=info
@@ -2,6 +2,16 @@
2
2
  <slot />
3
3
  </template>
4
4
 
5
+ <!--
6
+ Tailwind base/utilities for development only. The layouts wrap the plugin in
7
+ the dev runtime but are NOT part of the production build (build entry is
8
+ src/Plugin.vue), so this CSS never ships in dist/. Remove this block if you
9
+ don't want Tailwind defaults applied while developing.
10
+ -->
11
+ <style>
12
+ @import "tailwindcss";
13
+ </style>
14
+
5
15
  <style scoped></style>
6
16
 
7
17
  <script setup>
@@ -2,6 +2,16 @@
2
2
  <slot />
3
3
  </template>
4
4
 
5
+ <!--
6
+ Tailwind base/utilities for development only. The layouts wrap the plugin in
7
+ the dev runtime but are NOT part of the production build (build entry is
8
+ src/Plugin.vue), so this CSS never ships in dist/. Remove this block if you
9
+ don't want Tailwind defaults applied while developing.
10
+ -->
11
+ <style>
12
+ @import "tailwindcss";
13
+ </style>
14
+
5
15
  <style scoped></style>
6
16
 
7
17
  <script setup>
@@ -2,6 +2,16 @@
2
2
  <slot />
3
3
  </template>
4
4
 
5
+ <!--
6
+ Tailwind base/utilities for development only. The layouts wrap the plugin in
7
+ the dev runtime but are NOT part of the production build (build entry is
8
+ src/Plugin.vue), so this CSS never ships in dist/. Remove this block if you
9
+ don't want Tailwind defaults applied while developing.
10
+ -->
11
+ <style>
12
+ @import "tailwindcss";
13
+ </style>
14
+
5
15
  <style scoped></style>
6
16
 
7
17
  <script setup>