zova-cli-set-front 1.2.122 → 1.2.124

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 CHANGED
@@ -10,7 +10,8 @@ import { createRequire, isBuiltin } from 'node:module';
10
10
  import { camelToKebab, toUpperCaseFirstChar, toLowerCaseFirstChar, skipPrefix, stringToCapitalize, replaceTemplate } from '@cabloy/word-utils';
11
11
  import fse from 'fs-extra';
12
12
  import { build as build$1 } from 'tsdown';
13
- import { createConfigUtils, saveJSONFile as saveJSONFile$1 } from 'zova-vite';
13
+ import { createConfigUtils, resolveZovaViteContext, generateEntryFiles, saveJSONFile as saveJSONFile$1 } from 'zova-vite';
14
+ import { lstat, readFile, writeFile } from 'node:fs/promises';
14
15
  import ts from 'typescript';
15
16
  import yaml from 'yaml';
16
17
  import fs from 'node:fs';
@@ -151,6 +152,85 @@ class CliBinBuildModule extends BeanCliBase {
151
152
  }
152
153
  }
153
154
 
155
+ async function resolveRestBuildPaths(projectPath, flavor, runtimeDir, env = process.env) {
156
+ const isolatedKeys = ['ZOVA_ISOLATED', 'ZOVA_RUNTIME_DIR', 'ZOVA_QUASAR_ROOT', 'ZOVA_QUASAR_CACHE', 'ZOVA_QUASAR_CONFIG_DIR', 'ZOVA_REST_DIR', 'ZOVA_REST_TSCONFIG', 'ZOVA_REST_OUTDIR'];
157
+ const isolated = env.ZOVA_ISOLATED === 'true';
158
+ if (isolatedKeys.some(key => env[key] !== undefined)) {
159
+ if (!isolated || isolatedKeys.some(key => !env[key])) {
160
+ throw new Error('Incomplete isolated REST build environment');
161
+ }
162
+ }
163
+ if (!isolated) {
164
+ return {
165
+ isolated,
166
+ runtimeDir,
167
+ srcDir: path.join(projectPath, '.zova-rest'),
168
+ outDir: path.join(projectPath, 'dist', `rest-${flavor}`),
169
+ tsconfigPath: path.join(projectPath, 'tsconfig.rest.json')
170
+ };
171
+ }
172
+ if (!/^[a-z0-9][\w-]*$/i.test(flavor)) {
173
+ throw new Error('Invalid isolated REST flavor');
174
+ }
175
+ const match = /^\.zova-build-([a-z0-9][\w-]*)$/i.exec(runtimeDir);
176
+ if (!match) throw new Error('Isolated REST requires a run-specific Zova runtime directory');
177
+ const id = match[1];
178
+ const restDir = `.zova-rest-build-${id}`;
179
+ const quasarDir = `.quasar-build-${id}`;
180
+ if (env.ZOVA_RUNTIME_DIR !== runtimeDir || env.ZOVA_QUASAR_ROOT !== path.join(projectPath, quasarDir) || env.ZOVA_QUASAR_CACHE !== path.join(projectPath, quasarDir, 'cache') || env.ZOVA_QUASAR_CONFIG_DIR !== path.join(projectPath, quasarDir, 'config') || env.ZOVA_REST_DIR !== restDir || env.ZOVA_REST_TSCONFIG !== `.tsconfig.rest-build-${id}.json`) {
181
+ throw new Error('Isolated REST paths must belong to the selected build run');
182
+ }
183
+ const outputRoot = path.join(projectPath, quasarDir, 'output');
184
+ const outDir = env.ZOVA_REST_OUTDIR;
185
+ if (!outDir || !path.isAbsolute(outDir) || path.dirname(path.resolve(outDir)) !== outputRoot || path.basename(outDir) !== `rest-${flavor}`) {
186
+ throw new Error('Isolated REST output must be the selected run output directory');
187
+ }
188
+ // Validate every existing component before removing entry/output content. The
189
+ // outer runner owns these roots and alone removes them after child drainage.
190
+ for (const relative of [runtimeDir, restDir, quasarDir, `${quasarDir}/output`, `${quasarDir}/output/rest-${flavor}`, `${restDir}/entry`, `.tsconfig.rest-build-${id}.json`]) {
191
+ try {
192
+ const stat = await lstat(path.join(projectPath, relative));
193
+ if (stat.isSymbolicLink()) throw new Error(`Isolated REST path cannot be a symlink: ${relative}`);
194
+ if (relative.endsWith('.json')) {
195
+ if (!stat.isFile() || stat.nlink !== 1) {
196
+ throw new Error('Isolated REST tsconfig must be a single-link regular file');
197
+ }
198
+ } else if (!stat.isDirectory()) {
199
+ throw new Error(`Isolated REST path must be a directory: ${relative}`);
200
+ }
201
+ } catch (error) {
202
+ if (error.code !== 'ENOENT') throw error;
203
+ if ([runtimeDir, restDir, quasarDir].includes(relative)) {
204
+ throw new Error(`Isolated REST root is missing: ${relative}`);
205
+ }
206
+ }
207
+ }
208
+ return {
209
+ isolated,
210
+ runtimeDir,
211
+ srcDir: path.join(projectPath, restDir, 'entry'),
212
+ outDir,
213
+ tsconfigPath: path.join(projectPath, `.tsconfig.rest-build-${id}.json`)
214
+ };
215
+ }
216
+ async function writeIsolatedRestTsconfig(projectPath, paths) {
217
+ const basePath = path.join(projectPath, 'tsconfig.rest.json');
218
+ const base = JSON.parse(await readFile(basePath, 'utf8'));
219
+ const configDir = path.dirname(paths.tsconfigPath);
220
+ const relative = target => path.relative(configDir, target).replaceAll('\\', '/');
221
+ const include = (Array.isArray(base.include) ? base.include : []).filter(item => !/^\.?\/?\.zova-rest(?:\/|$)/.test(item)).map(item => relative(path.resolve(projectPath, item)));
222
+ include.push(`${relative(paths.srcDir)}/**/*`);
223
+ await writeFile(paths.tsconfigPath, JSON.stringify({
224
+ extends: `./${relative(basePath)}`,
225
+ // rolldown-plugin-dts supplies dirname(tsconfig) as tsgo's rootDir.
226
+ // Keep this owned config beside the project config, not inside entry/.
227
+ compilerOptions: {
228
+ rootDir: '.'
229
+ },
230
+ include
231
+ }, null, 2));
232
+ }
233
+
154
234
  function extractRestDependencies(content) {
155
235
  const source = ts.createSourceFile('index.d.mts', content, ts.ScriptTarget.Latest);
156
236
  // createSourceFile exposes syntax diagnostics at runtime, but not in its public return type.
@@ -416,11 +496,42 @@ class CliBinBuildRest extends BeanCliBase {
416
496
  const bundleName = `zova-rest-${camelToKebab(flavor)}`;
417
497
  const bundleNameCopy = `${camelToKebab(flavor)}`;
418
498
  //
419
- const srcDir = path.join(projectPath, '.zova-rest');
420
- const outDir = path.join(projectPath, 'dist', `rest-${flavor}`);
499
+ const {
500
+ runtimeDir
501
+ } = resolveZovaViteContext({
502
+ appDir: projectPath
503
+ });
504
+ const paths = await resolveRestBuildPaths(path.resolve(projectPath), flavor, runtimeDir);
505
+ const {
506
+ isolated,
507
+ srcDir,
508
+ outDir,
509
+ tsconfigPath
510
+ } = paths;
511
+ if (!isolated) {
512
+ const manifest = await loadJSONFile(path.join(projectPath, 'package.json'));
513
+ if (Object.hasOwn(manifest.scripts ?? {}, 'build:isolated')) {
514
+ const hook = manifest.scripts['build:isolated'];
515
+ if (typeof hook !== 'string' || !hook.trim()) {
516
+ throw new Error('The application build:isolated script must be a non-empty string');
517
+ }
518
+ if (!/^[a-z0-9][\w-]*$/i.test(flavor)) {
519
+ throw new Error('Invalid isolated REST flavor');
520
+ }
521
+ await this.helper.spawnCmd({
522
+ cmd: 'npm',
523
+ args: ['run', 'build:isolated', '--', '--operation', 'rest', flavor],
524
+ options: {
525
+ cwd: projectPath
526
+ }
527
+ });
528
+ return;
529
+ }
530
+ }
421
531
  await rimraf(srcDir);
422
532
  await fse.ensureDir(srcDir);
423
533
  await rimraf(outDir);
534
+ if (isolated) await writeIsolatedRestTsconfig(path.resolve(projectPath), paths);
424
535
  // context
425
536
  const context = {
426
537
  projectPath,
@@ -428,15 +539,17 @@ class CliBinBuildRest extends BeanCliBase {
428
539
  bundleName,
429
540
  bundleNameCopy,
430
541
  srcDir,
431
- outDir
542
+ outDir,
543
+ tsconfigPath,
544
+ isolated
432
545
  };
433
546
  //
434
- await this._prepareResources(context);
547
+ await this._prepareResources(context, runtimeDir);
435
548
  await this._build(context);
436
549
  //
437
- await rimraf(srcDir);
550
+ if (!isolated) await rimraf(srcDir);
438
551
  }
439
- async _prepareResources(context) {
552
+ async _prepareResources(context, runtimeDir) {
440
553
  const {
441
554
  projectPath,
442
555
  flavor,
@@ -456,13 +569,16 @@ class CliBinBuildRest extends BeanCliBase {
456
569
  };
457
570
  const configOptions = {
458
571
  appDir: projectPath,
459
- runtimeDir: '.zova'
572
+ runtimeDir
460
573
  };
461
574
  const configUtils = createConfigUtils(configMeta, configOptions);
462
575
  // env
463
576
  const env = configUtils.loadEnvs();
464
577
  // modulesMeta
465
578
  const modulesMeta = await configUtils.loadModulesMeta();
579
+ if (context.isolated) {
580
+ await generateEntryFiles(configMeta, configOptions, modulesMeta, env);
581
+ }
466
582
  // Modules
467
583
  const modules = [];
468
584
  const bundleModules = [];
@@ -495,7 +611,8 @@ class CliBinBuildRest extends BeanCliBase {
495
611
  }
496
612
  async _buildTs({
497
613
  srcDir,
498
- outDir
614
+ outDir,
615
+ tsconfigPath
499
616
  }) {
500
617
  // entry
501
618
  const entry = path.join(srcDir, 'index.ts');
@@ -504,7 +621,7 @@ class CliBinBuildRest extends BeanCliBase {
504
621
  entry: [entry],
505
622
  format: ['esm'],
506
623
  outDir,
507
- tsconfig: 'tsconfig.rest.json',
624
+ tsconfig: tsconfigPath,
508
625
  dts: false,
509
626
  plugins: [svgResolverPlugin()],
510
627
  deps: {
@@ -522,6 +639,7 @@ class CliBinBuildRest extends BeanCliBase {
522
639
  async _buildDts({
523
640
  srcDir,
524
641
  outDir,
642
+ tsconfigPath,
525
643
  bundleModules,
526
644
  sideEffectImportModuleNames
527
645
  }) {
@@ -532,7 +650,7 @@ class CliBinBuildRest extends BeanCliBase {
532
650
  entry: [entry],
533
651
  format: ['esm'],
534
652
  outDir,
535
- tsconfig: 'tsconfig.rest.json',
653
+ tsconfig: tsconfigPath,
536
654
  clean: false,
537
655
  checks: {
538
656
  namespaceConflict: false
@@ -541,7 +659,7 @@ class CliBinBuildRest extends BeanCliBase {
541
659
  resolver: 'oxc',
542
660
  generator: 'tsgo',
543
661
  eager: true,
544
- tsconfig: 'tsconfig.rest.json',
662
+ tsconfig: tsconfigPath,
545
663
  emitDtsOnly: true
546
664
  },
547
665
  plugins: [svgResolverPlugin()],
@@ -587,10 +705,12 @@ class CliBinBuildRest extends BeanCliBase {
587
705
  await saveJSONFile$1(path.join(outDir, 'package.json'), pkgContent);
588
706
  // await fse.copyFile(path.join(srcDir, 'package.json'), path.join(outDir, 'package.json'));
589
707
  // release
590
- const outReleasesDir = path.join(projectPath, 'dist-releases', `rest-${flavor}-${process.env.APP_VERSION}`);
591
- await fse.copy(outDir, outReleasesDir);
592
- // copy
593
- _copyToTarget(outDir, process.env.BUILD_REST_COPY_DIST, bundleNameCopy, projectPath);
708
+ if (!buildContext.isolated) {
709
+ const outReleasesDir = path.join(projectPath, 'dist-releases', `rest-${flavor}-${process.env.APP_VERSION}`);
710
+ await fse.copy(outDir, outReleasesDir);
711
+ // copy
712
+ _copyToTarget(outDir, process.env.BUILD_REST_COPY_DIST, bundleNameCopy, projectPath);
713
+ }
594
714
  }
595
715
  }
596
716
  function _copyToTarget(outDir, target, bundleNameCopy, projectPath) {
@@ -21,6 +21,8 @@ interface IBinBuildRestContext {
21
21
  bundleNameCopy: string;
22
22
  srcDir: string;
23
23
  outDir: string;
24
+ tsconfigPath: string;
25
+ isolated: boolean;
24
26
  bundleModules?: string[];
25
27
  sideEffectImportModuleNames?: string[];
26
28
  moduleRoots?: string[];
@@ -28,9 +30,9 @@ interface IBinBuildRestContext {
28
30
  }
29
31
  export declare class CliBinBuildRest extends BeanCliBase {
30
32
  execute(): Promise<void>;
31
- _prepareResources(context: IBinBuildRestContext): Promise<void>;
32
- _buildTs({ srcDir, outDir }: IBinBuildRestContext): Promise<void>;
33
- _buildDts({ srcDir, outDir, bundleModules, sideEffectImportModuleNames, }: IBinBuildRestContext): Promise<void>;
33
+ _prepareResources(context: IBinBuildRestContext, runtimeDir: string): Promise<void>;
34
+ _buildTs({ srcDir, outDir, tsconfigPath }: IBinBuildRestContext): Promise<void>;
35
+ _buildDts({ srcDir, outDir, tsconfigPath, bundleModules, sideEffectImportModuleNames, }: IBinBuildRestContext): Promise<void>;
34
36
  _injectDtsImports(outDir: string, sideEffectImportModuleNames: string[]): Promise<void>;
35
37
  _build(buildContext: IBinBuildRestContext): Promise<void>;
36
38
  }
@@ -0,0 +1,9 @@
1
+ export interface RestBuildPaths {
2
+ isolated: boolean;
3
+ runtimeDir: string;
4
+ srcDir: string;
5
+ outDir: string;
6
+ tsconfigPath: string;
7
+ }
8
+ export declare function resolveRestBuildPaths(projectPath: string, flavor: string, runtimeDir: string, env?: Record<string, string | undefined>): Promise<RestBuildPaths>;
9
+ export declare function writeIsolatedRestTsconfig(projectPath: string, paths: RestBuildPaths): Promise<void>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "zova-cli-set-front",
3
- "version": "1.2.122",
4
- "gitHead": "b0a4dbbda3b804afdfacf0792ad37a6e45724349",
3
+ "version": "1.2.124",
4
+ "gitHead": "d1a9a68c5d48db9bc82945c17984dabbec724d8c",
5
5
  "description": "zova cli-set-front",
6
6
  "keywords": [
7
7
  "framework",
@@ -36,7 +36,7 @@
36
36
  "@babel/plugin-proposal-decorators": "^7.29.0",
37
37
  "@babel/plugin-transform-class-properties": "^7.28.6",
38
38
  "@babel/plugin-transform-typescript": "^7.28.6",
39
- "@cabloy/cli": "^3.1.31",
39
+ "@cabloy/cli": "^3.1.32",
40
40
  "@cabloy/extend": "^3.2.8",
41
41
  "@cabloy/module-info": "^2.0.3",
42
42
  "@cabloy/openapi-typescript": "^7.9.2",
@@ -47,7 +47,7 @@
47
47
  "@typescript/native-preview": "npm:typescript@7.0.2",
48
48
  "@vitejs/plugin-vue-jsx": "^5.1.5",
49
49
  "babel-plugin-transform-typescript-metadata": "^0.4.0",
50
- "babel-plugin-zova-bean-module": "^1.2.15",
50
+ "babel-plugin-zova-bean-module": "^1.2.17",
51
51
  "babel-plugin-zova-bean-use": "^1.1.15",
52
52
  "babel-plugin-zova-behavior": "^1.1.16",
53
53
  "babel-plugin-zova-component": "^1.1.15",
@@ -65,7 +65,7 @@
65
65
  "vite": "^8.3.4",
66
66
  "yaml": "^2.8.3",
67
67
  "zova-openapi": "^1.1.17",
68
- "zova-vite": "^1.1.53"
68
+ "zova-vite": "^1.1.55"
69
69
  },
70
70
  "engines": {
71
71
  "node": ">=24.11.0"