plusui-native 0.2.106 → 0.2.107

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.
@@ -1,275 +1,288 @@
1
- import { mkdir, readdir, readFile, writeFile, copyFile, stat } from 'fs/promises';
2
- import { join, dirname, resolve } from 'path';
3
- import { existsSync } from 'fs';
4
- import { fileURLToPath } from 'url';
5
- import { EnvironmentDoctor } from '../src/doctor/index.js';
6
- import chalk from 'chalk';
7
- import { spawn } from 'child_process';
8
- import { execSync } from 'child_process';
9
-
10
- const __filename = fileURLToPath(import.meta.url);
11
- const __dirname = dirname(__filename);
12
-
13
- export class TemplateManager {
14
- constructor() {
15
- this.templatesDir = __dirname;
16
- this.cliPackageJson = null;
17
- }
18
-
19
- async loadCliVersion() {
20
- if (!this.cliPackageJson) {
21
- const packageJsonPath = join(this.templatesDir, '..', 'package.json');
22
- const content = await readFile(packageJsonPath, 'utf8');
23
- this.cliPackageJson = JSON.parse(content);
24
- }
25
- return this.cliPackageJson.version;
26
- }
27
-
28
- async loadCliPackageJson() {
29
- if (!this.cliPackageJson) {
30
- const packageJsonPath = join(this.templatesDir, '..', 'package.json');
31
- const content = await readFile(packageJsonPath, 'utf8');
32
- this.cliPackageJson = JSON.parse(content);
33
- }
34
- return this.cliPackageJson;
35
- }
36
-
37
- getLatestPublishedVersion(packageName) {
38
- try {
39
- const version = execSync(`npm view ${packageName} version`, {
40
- encoding: 'utf8',
41
- stdio: ['pipe', 'pipe', 'ignore']
42
- }).trim();
43
- return version || null;
44
- } catch {
45
- return null;
46
- }
47
- }
48
-
49
- toCompatibleRange(version) {
50
- if (!version) {
51
- return null;
52
- }
53
- return version.startsWith('^') || version.startsWith('~') ? version : `^${version}`;
54
- }
55
-
56
- async resolveTemplatePackageVersions() {
57
- const cliPkg = await this.loadCliPackageJson();
58
- const cliVersion = cliPkg.version;
59
- const [major, minor] = cliVersion.split('.');
60
-
61
- const fallbackCliRange = `^${major}.${minor}.0`;
62
- const fallbackToolsRange = `^${major}.1.0`;
63
-
64
- const publishedCli = this.getLatestPublishedVersion('plusui-native');
65
- const publishedCore = this.getLatestPublishedVersion('plusui-native-core');
66
- const publishedBuilder = this.getLatestPublishedVersion('plusui-native-builder');
67
- const publishedConnect = this.getLatestPublishedVersion('plusui-native-connect');
68
-
69
- const cliDependencyBuilder = cliPkg.dependencies?.['plusui-native-builder'] || null;
70
- const cliDependencyConnect = cliPkg.dependencies?.['plusui-native-connect'] || null;
71
-
72
- return {
73
- cli: this.toCompatibleRange(publishedCli) || fallbackCliRange,
74
- core: this.toCompatibleRange(publishedCore) || fallbackToolsRange,
75
- builder: this.toCompatibleRange(publishedBuilder) || cliDependencyBuilder || fallbackToolsRange,
76
- connect: this.toCompatibleRange(publishedConnect) || cliDependencyConnect || fallbackToolsRange
77
- };
78
- }
79
-
80
- async create(projectName, options = {}) {
81
- const template = options.template || 'react';
82
- const templatePath = join(this.templatesDir, template);
83
-
84
- // Determine target path and actual project name
85
- let targetDirName = projectName;
86
- let projectPath = resolve(projectName);
87
-
88
- if (projectName === '.') {
89
- targetDirName = require('path').basename(process.cwd());
90
- projectPath = process.cwd();
91
- }
92
-
93
- console.log(chalk.bold(`\nCreating PlusUI project: ${targetDirName}\n`));
94
-
95
- // 1. Check environment first
96
- console.log(chalk.blue('Checking environment...'));
97
- const doctor = new EnvironmentDoctor();
98
- const quickCheck = await doctor.quickCheck();
99
-
100
- if (!quickCheck.ready) {
101
- console.log(chalk.red('\n✗ Environment not ready!\n'));
102
- console.log(chalk.yellow('Run: plusui doctor --fix\n'));
103
- throw new Error('Environment check failed');
104
- }
105
-
106
- console.log(chalk.green('✓ Environment ready\n'));
107
-
108
- // 2. Create project directory
109
- console.log(chalk.blue('Creating project structure...'));
110
-
111
- if (projectName !== '.') {
112
- if (existsSync(projectPath)) {
113
- throw new Error(`Directory ${projectName} already exists`);
114
- }
115
- await mkdir(projectPath, { recursive: true });
116
- } else {
117
- // Warn but proceed if using current directory
118
- console.log(chalk.yellow(`Initializing in current directory...`));
119
- }
120
-
121
- // 3. Resolve package versions for generated app dependencies
122
- const resolvedVersions = await this.resolveTemplatePackageVersions();
123
-
124
- // 4. Prepare template variables
125
- const variables = {
126
- PROJECT_NAME: targetDirName,
127
- PROJECT_NAME_LOWER: targetDirName.toLowerCase(),
128
- PROJECT_VERSION: '0.1.0',
129
- PLUSUI_CLI_VERSION: resolvedVersions.cli,
130
- PLUSUI_CORE_VERSION: resolvedVersions.core,
131
- PLUSUI_BUILDER_VERSION: resolvedVersions.builder,
132
- PLUSUI_CONNECT_VERSION: resolvedVersions.connect
133
- };
134
-
135
- console.log(chalk.dim(`Using versions: core=${variables.PLUSUI_CORE_VERSION}, builder=${variables.PLUSUI_BUILDER_VERSION}, connect=${variables.PLUSUI_CONNECT_VERSION}`));
136
-
137
- // 5. Copy template files
138
- await this.copyTemplate(templatePath, projectPath, variables);
139
-
140
- // 5. Copy base files
141
- const basePath = join(this.templatesDir, 'base');
142
- await this.copyTemplate(basePath, projectPath, variables, true);
143
-
144
- console.log(chalk.green('✓ Project structure created\n'));
145
-
146
- // 6. Install npm dependencies
147
- console.log(chalk.blue('Installing dependencies...'));
148
- await this.runNpmInstall(projectPath);
149
- console.log(chalk.green('✓ Dependencies installed\n'));
150
-
151
- // 7. Start dev server in the created project immediately
152
- process.chdir(projectPath);
153
- console.log(chalk.green(`✓ Changed directory to: ${projectPath}`));
154
- console.log(chalk.blue('Starting development server...'));
155
- await this.runPlusuiDev(projectPath);
156
-
157
- return { success: true, path: projectPath };
158
- }
159
-
160
- async copyTemplate(templatePath, destPath, variables, skipSubdirs = false) {
161
- if (!existsSync(templatePath)) {
162
- return;
163
- }
164
-
165
- const entries = await readdir(templatePath, { withFileTypes: true });
166
-
167
- for (const entry of entries) {
168
- const srcPath = join(templatePath, entry.name);
169
- const destName = entry.name.replace('.template', '');
170
- const destFilePath = join(destPath, destName);
171
-
172
- if (entry.isDirectory()) {
173
- if (!skipSubdirs) {
174
- await mkdir(destFilePath, { recursive: true });
175
- await this.copyTemplate(srcPath, destFilePath, variables, false);
176
- }
177
- } else {
178
- // Ensure parent directory exists
179
- await mkdir(dirname(destFilePath), { recursive: true });
180
-
181
- // Read file content
182
- let content = await readFile(srcPath, 'utf8');
183
-
184
- // Replace variables
185
- content = this.replaceVariables(content, variables);
186
-
187
- // Write to destination
188
- await writeFile(destFilePath, content, 'utf8');
189
- }
190
- }
191
- }
192
-
193
- replaceVariables(content, variables) {
194
- let result = content;
195
-
196
- for (const [key, value] of Object.entries(variables)) {
197
- // Replace without spaces (e.g. {{PROJECT_NAME}})
198
- result = result.split(`{{${key}}}`).join(value);
199
- // Replace with spaces (e.g. {{ PROJECT_NAME }})
200
- result = result.split(`{{ ${key} }}`).join(value);
201
- }
202
-
203
- return result;
204
- }
205
-
206
- async runNpmInstall(projectPath) {
207
- return new Promise((resolve, reject) => {
208
- const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
209
-
210
- // Install root dependencies
211
- const rootProc = spawn(npm, ['install'], {
212
- cwd: projectPath,
213
- stdio: 'inherit',
214
- shell: true
215
- });
216
-
217
- rootProc.on('close', (code) => {
218
- if (code !== 0) {
219
- reject(new Error(`npm install failed with code ${code}`));
220
- return;
221
- }
222
-
223
- // Install frontend dependencies
224
- const frontendPath = join(projectPath, 'frontend');
225
- if (existsSync(join(frontendPath, 'package.json'))) {
226
- const frontendProc = spawn(npm, ['install'], {
227
- cwd: frontendPath,
228
- stdio: 'inherit',
229
- shell: true
230
- });
231
-
232
- frontendProc.on('close', (feCode) => {
233
- if (feCode === 0) {
234
- resolve();
235
- } else {
236
- reject(new Error(`frontend npm install failed with code ${feCode}`));
237
- }
238
- });
239
-
240
- frontendProc.on('error', reject);
241
- } else {
242
- resolve();
243
- }
244
- });
245
-
246
- rootProc.on('error', reject);
247
- });
248
- }
249
-
250
- async runPlusuiDev(projectPath) {
251
- return new Promise((resolve, reject) => {
252
- const plusuiCmd = process.platform === 'win32' ? 'plusui.cmd' : 'plusui';
253
-
254
- const devProc = spawn(plusuiCmd, ['dev'], {
255
- cwd: projectPath,
256
- stdio: 'inherit',
257
- shell: true,
258
- });
259
-
260
- devProc.on('close', (code, signal) => {
261
- // Normal shutdown via Ctrl+C should not be treated as an error.
262
- if (signal === 'SIGINT' || code === 0 || code === null) {
263
- resolve();
264
- return;
265
- }
266
- reject(new Error(`plusui dev exited with code ${code}`));
267
- });
268
-
269
- devProc.on('error', reject);
270
- });
271
- }
272
-
273
- }
274
-
275
-
1
+ import { mkdir, readdir, readFile, writeFile, copyFile, stat } from 'fs/promises';
2
+ import { join, dirname, resolve } from 'path';
3
+ import { existsSync } from 'fs';
4
+ import { fileURLToPath } from 'url';
5
+ import { EnvironmentDoctor } from '../src/doctor/index.js';
6
+ import chalk from 'chalk';
7
+ import { spawn } from 'child_process';
8
+ import { execSync } from 'child_process';
9
+
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = dirname(__filename);
12
+
13
+ export class TemplateManager {
14
+ constructor() {
15
+ this.templatesDir = __dirname;
16
+ this.cliPackageJson = null;
17
+ }
18
+
19
+ async loadCliVersion() {
20
+ if (!this.cliPackageJson) {
21
+ const packageJsonPath = join(this.templatesDir, '..', 'package.json');
22
+ const content = await readFile(packageJsonPath, 'utf8');
23
+ this.cliPackageJson = JSON.parse(content);
24
+ }
25
+ return this.cliPackageJson.version;
26
+ }
27
+
28
+ async loadCliPackageJson() {
29
+ if (!this.cliPackageJson) {
30
+ const packageJsonPath = join(this.templatesDir, '..', 'package.json');
31
+ const content = await readFile(packageJsonPath, 'utf8');
32
+ this.cliPackageJson = JSON.parse(content);
33
+ }
34
+ return this.cliPackageJson;
35
+ }
36
+
37
+ getLatestPublishedVersion(packageName) {
38
+ try {
39
+ const version = execSync(`npm view ${packageName} version`, {
40
+ encoding: 'utf8',
41
+ stdio: ['pipe', 'pipe', 'ignore']
42
+ }).trim();
43
+ return version || null;
44
+ } catch {
45
+ return null;
46
+ }
47
+ }
48
+
49
+ toCompatibleRange(version) {
50
+ if (!version) {
51
+ return null;
52
+ }
53
+ return version.startsWith('^') || version.startsWith('~') ? version : `^${version}`;
54
+ }
55
+
56
+ async resolveTemplatePackageVersions() {
57
+ const cliPkg = await this.loadCliPackageJson();
58
+ const cliVersion = cliPkg.version;
59
+ const [major, minor] = cliVersion.split('.');
60
+
61
+ const fallbackCliRange = `^${major}.${minor}.0`;
62
+ const fallbackToolsRange = `^${major}.1.0`;
63
+
64
+ const publishedCli = this.getLatestPublishedVersion('plusui-native');
65
+ const publishedCore = this.getLatestPublishedVersion('plusui-native-core');
66
+ const publishedBuilder = this.getLatestPublishedVersion('plusui-native-builder');
67
+ const publishedConnect = this.getLatestPublishedVersion('plusui-native-connect');
68
+
69
+ const cliDependencyBuilder = cliPkg.dependencies?.['plusui-native-builder'] || null;
70
+ const cliDependencyConnect = cliPkg.dependencies?.['plusui-native-connect'] || null;
71
+
72
+ return {
73
+ cli: this.toCompatibleRange(publishedCli) || fallbackCliRange,
74
+ core: this.toCompatibleRange(publishedCore) || fallbackToolsRange,
75
+ builder: this.toCompatibleRange(publishedBuilder) || cliDependencyBuilder || fallbackToolsRange,
76
+ connect: this.toCompatibleRange(publishedConnect) || cliDependencyConnect || fallbackToolsRange
77
+ };
78
+ }
79
+
80
+ async create(projectName, options = {}) {
81
+ // Validate and sanitize project name
82
+ const invalidChars = projectName.replace(/[a-zA-Z0-9_-]/g, '');
83
+ if (invalidChars.length > 0) {
84
+ console.log(chalk.yellow(`\nWarning: Project name contains invalid characters: ${invalidChars}`));
85
+ console.log(chalk.yellow('Only lowercase letters, numbers, hyphens, and underscores are allowed.'));
86
+ projectName = projectName.toLowerCase().replace(/[^a-z0-9_-]/g, '-');
87
+ console.log(chalk.green(`Using sanitized name: ${projectName}\n`));
88
+ }
89
+
90
+ if (/^[0-9]/.test(projectName)) {
91
+ throw new Error('Project name cannot start with a number');
92
+ }
93
+
94
+ const template = options.template || 'react';
95
+ const templatePath = join(this.templatesDir, template);
96
+
97
+ // Determine target path and actual project name
98
+ let targetDirName = projectName;
99
+ let projectPath = resolve(projectName);
100
+
101
+ if (projectName === '.') {
102
+ targetDirName = require('path').basename(process.cwd());
103
+ projectPath = process.cwd();
104
+ }
105
+
106
+ console.log(chalk.bold(`\nCreating PlusUI project: ${targetDirName}\n`));
107
+
108
+ // 1. Check environment first
109
+ console.log(chalk.blue('Checking environment...'));
110
+ const doctor = new EnvironmentDoctor();
111
+ const quickCheck = await doctor.quickCheck();
112
+
113
+ if (!quickCheck.ready) {
114
+ console.log(chalk.red('\n✗ Environment not ready!\n'));
115
+ console.log(chalk.yellow('Run: plusui doctor --fix\n'));
116
+ throw new Error('Environment check failed');
117
+ }
118
+
119
+ console.log(chalk.green('✓ Environment ready\n'));
120
+
121
+ // 2. Create project directory
122
+ console.log(chalk.blue('Creating project structure...'));
123
+
124
+ if (projectName !== '.') {
125
+ if (existsSync(projectPath)) {
126
+ throw new Error(`Directory ${projectName} already exists`);
127
+ }
128
+ await mkdir(projectPath, { recursive: true });
129
+ } else {
130
+ // Warn but proceed if using current directory
131
+ console.log(chalk.yellow(`Initializing in current directory...`));
132
+ }
133
+
134
+ // 3. Resolve package versions for generated app dependencies
135
+ const resolvedVersions = await this.resolveTemplatePackageVersions();
136
+
137
+ // 4. Prepare template variables
138
+ const variables = {
139
+ PROJECT_NAME: targetDirName,
140
+ PROJECT_NAME_LOWER: targetDirName.toLowerCase(),
141
+ PROJECT_VERSION: '0.1.0',
142
+ PLUSUI_CLI_VERSION: resolvedVersions.cli,
143
+ PLUSUI_CORE_VERSION: resolvedVersions.core,
144
+ PLUSUI_BUILDER_VERSION: resolvedVersions.builder,
145
+ PLUSUI_CONNECT_VERSION: resolvedVersions.connect
146
+ };
147
+
148
+ console.log(chalk.dim(`Using versions: core=${variables.PLUSUI_CORE_VERSION}, builder=${variables.PLUSUI_BUILDER_VERSION}, connect=${variables.PLUSUI_CONNECT_VERSION}`));
149
+
150
+ // 5. Copy template files
151
+ await this.copyTemplate(templatePath, projectPath, variables);
152
+
153
+ // 5. Copy base files
154
+ const basePath = join(this.templatesDir, 'base');
155
+ await this.copyTemplate(basePath, projectPath, variables, true);
156
+
157
+ console.log(chalk.green('✓ Project structure created\n'));
158
+
159
+ // 6. Install npm dependencies
160
+ console.log(chalk.blue('Installing dependencies...'));
161
+ await this.runNpmInstall(projectPath);
162
+ console.log(chalk.green('✓ Dependencies installed\n'));
163
+
164
+ // 7. Start dev server in the created project immediately
165
+ process.chdir(projectPath);
166
+ console.log(chalk.green(`✓ Changed directory to: ${projectPath}`));
167
+ console.log(chalk.blue('Starting development server...'));
168
+ await this.runPlusuiDev(projectPath);
169
+
170
+ return { success: true, path: projectPath };
171
+ }
172
+
173
+ async copyTemplate(templatePath, destPath, variables, skipSubdirs = false) {
174
+ if (!existsSync(templatePath)) {
175
+ return;
176
+ }
177
+
178
+ const entries = await readdir(templatePath, { withFileTypes: true });
179
+
180
+ for (const entry of entries) {
181
+ const srcPath = join(templatePath, entry.name);
182
+ const destName = entry.name.replace('.template', '');
183
+ const destFilePath = join(destPath, destName);
184
+
185
+ if (entry.isDirectory()) {
186
+ if (!skipSubdirs) {
187
+ await mkdir(destFilePath, { recursive: true });
188
+ await this.copyTemplate(srcPath, destFilePath, variables, false);
189
+ }
190
+ } else {
191
+ // Ensure parent directory exists
192
+ await mkdir(dirname(destFilePath), { recursive: true });
193
+
194
+ // Read file content
195
+ let content = await readFile(srcPath, 'utf8');
196
+
197
+ // Replace variables
198
+ content = this.replaceVariables(content, variables);
199
+
200
+ // Write to destination
201
+ await writeFile(destFilePath, content, 'utf8');
202
+ }
203
+ }
204
+ }
205
+
206
+ replaceVariables(content, variables) {
207
+ let result = content;
208
+
209
+ for (const [key, value] of Object.entries(variables)) {
210
+ // Replace without spaces (e.g. {{PROJECT_NAME}})
211
+ result = result.split(`{{${key}}}`).join(value);
212
+ // Replace with spaces (e.g. {{ PROJECT_NAME }})
213
+ result = result.split(`{{ ${key} }}`).join(value);
214
+ }
215
+
216
+ return result;
217
+ }
218
+
219
+ async runNpmInstall(projectPath) {
220
+ return new Promise((resolve, reject) => {
221
+ const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
222
+
223
+ // Install root dependencies
224
+ const rootProc = spawn(npm, ['install'], {
225
+ cwd: projectPath,
226
+ stdio: 'inherit',
227
+ shell: true
228
+ });
229
+
230
+ rootProc.on('close', (code) => {
231
+ if (code !== 0) {
232
+ reject(new Error(`npm install failed with code ${code}`));
233
+ return;
234
+ }
235
+
236
+ // Install frontend dependencies
237
+ const frontendPath = join(projectPath, 'frontend');
238
+ if (existsSync(join(frontendPath, 'package.json'))) {
239
+ const frontendProc = spawn(npm, ['install'], {
240
+ cwd: frontendPath,
241
+ stdio: 'inherit',
242
+ shell: true
243
+ });
244
+
245
+ frontendProc.on('close', (feCode) => {
246
+ if (feCode === 0) {
247
+ resolve();
248
+ } else {
249
+ reject(new Error(`frontend npm install failed with code ${feCode}`));
250
+ }
251
+ });
252
+
253
+ frontendProc.on('error', reject);
254
+ } else {
255
+ resolve();
256
+ }
257
+ });
258
+
259
+ rootProc.on('error', reject);
260
+ });
261
+ }
262
+
263
+ async runPlusuiDev(projectPath) {
264
+ return new Promise((resolve, reject) => {
265
+ const plusuiCmd = process.platform === 'win32' ? 'plusui.cmd' : 'plusui';
266
+
267
+ const devProc = spawn(plusuiCmd, ['dev'], {
268
+ cwd: projectPath,
269
+ stdio: 'inherit',
270
+ shell: true,
271
+ });
272
+
273
+ devProc.on('close', (code, signal) => {
274
+ // Normal shutdown via Ctrl+C should not be treated as an error.
275
+ if (signal === 'SIGINT' || code === 0 || code === null) {
276
+ resolve();
277
+ return;
278
+ }
279
+ reject(new Error(`plusui dev exited with code ${code}`));
280
+ });
281
+
282
+ devProc.on('error', reject);
283
+ });
284
+ }
285
+
286
+ }
287
+
288
+
@@ -31,6 +31,6 @@ export default defineConfig({
31
31
  },
32
32
  server: {
33
33
  port: 5173,
34
- strictPort: true,
34
+ strictPort: false,
35
35
  },
36
36
  });
@@ -23,7 +23,6 @@ using json = nlohmann::json;
23
23
  struct AppConfig {
24
24
  std::string name = "{{PROJECT_NAME}}";
25
25
  std::string version = "0.1.0";
26
- bool showWhenFrontendReady = true; // Hides blank webview until React mounts
27
26
  } appConfig;
28
27
 
29
28
  struct WindowConfig {
@@ -38,6 +37,7 @@ struct WindowConfig {
38
37
  bool devTools = true;
39
38
  bool scrollbars = false;
40
39
  bool fileDrop = true; // Enable file drop from OS to webview
40
+ bool tray = true; // Enable system tray
41
41
  std::string route = "/"; // Starting route
42
42
  int devServerPort = 5173;
43
43
  } windowConfig;
@@ -80,30 +80,28 @@ int main() {
80
80
  .skipTaskbar(!windowConfig.showInTaskbar)
81
81
  .scrollbars(windowConfig.scrollbars)
82
82
  .fileDrop(windowConfig.fileDrop)
83
+ .tray(windowConfig.tray)
83
84
  .centered(true)
84
85
  .build();
85
86
 
86
87
  // Icon from embedded assets
87
88
  #ifdef ASSET_ICON_PNG
88
89
  mainWindow.setIconFromMemory(ASSET_ICON_PNG, ASSET_ICON_PNG_LEN);
90
+ mainWindow.setTrayIconFromMemory(ASSET_ICON_PNG, ASSET_ICON_PNG_LEN);
89
91
  #endif
90
92
 
91
- // Hide until frontend signals it's ready (no blank flash)
92
- if (appConfig.showWhenFrontendReady) {
93
- mainWindow.hide();
94
- }
95
-
96
93
  // Wire up connect system (for custom frontend ↔ backend communication)
97
94
  // Run `plusui connect` after adding custom connect methods
98
95
  static Connect conn;
99
96
  bindConnect(mainWindow, conn);
100
97
 
101
- // Load frontend
98
+ // Load frontend then show.
102
99
  #ifdef PLUSUI_DEV_MODE
103
100
  mainWindow.navigate("http://localhost:" + std::to_string(windowConfig.devServerPort) + windowConfig.route);
104
101
  #else
105
102
  mainWindow.loadFile("frontend/dist/index.html" + (windowConfig.route == "/" ? "" : "#" + windowConfig.route));
106
103
  #endif
104
+ mainWindow.show();
107
105
 
108
106
  App runtime;
109
107
  runtime.run();
@@ -31,6 +31,6 @@ export default defineConfig({
31
31
  },
32
32
  server: {
33
33
  port: 5173,
34
- strictPort: true,
34
+ strictPort: false,
35
35
  },
36
36
  });