@open-mova/cli 0.1.20 → 0.1.22
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/README.md +237 -6
- package/dist/application/android-configuration.d.ts +2 -0
- package/dist/application/android-configuration.js +115 -0
- package/dist/application/configuration-migrations.d.ts +6 -0
- package/dist/application/configuration-migrations.js +103 -0
- package/dist/application/configuration.d.ts +5 -0
- package/dist/application/configuration.js +38 -20
- package/dist/application/core-compatibility.d.ts +3 -0
- package/dist/application/core-compatibility.js +10 -0
- package/dist/application/doctor.d.ts +12 -0
- package/dist/application/doctor.js +304 -0
- package/dist/application/microfrontend-manifest.d.ts +3 -0
- package/dist/application/microfrontend-manifest.js +20 -0
- package/dist/application/microfrontend-profile.js +2 -1
- package/dist/application/microfrontend-update.d.ts +17 -0
- package/dist/application/microfrontend-update.js +117 -0
- package/dist/application/microfrontend.d.ts +1 -0
- package/dist/application/microfrontend.js +14 -3
- package/dist/application/native-capabilities.d.ts +15 -0
- package/dist/application/native-capabilities.js +143 -0
- package/dist/application/project-update.d.ts +8 -0
- package/dist/application/project-update.js +106 -0
- package/dist/application/shell-configuration.d.ts +20 -0
- package/dist/application/shell-configuration.js +52 -1
- package/dist/application/shell-repository.d.ts +1 -1
- package/dist/application/shell-repository.js +14 -7
- package/dist/application/shell-update.d.ts +1 -5
- package/dist/application/shell-update.js +11 -108
- package/dist/cli.js +2 -0
- package/dist/commands/capacitor.js +55 -90
- package/dist/commands/create.js +3 -2
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.js +25 -0
- package/dist/commands/info.js +1 -1
- package/dist/commands/microfrontend.js +40 -1
- package/dist/commands/update.js +13 -4
- package/dist/types.d.ts +7 -1
- package/package.json +7 -3
|
@@ -1,11 +1,51 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
|
-
import { existsSync,
|
|
2
|
+
import { existsSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { readApplicationConfiguration, requireApplicationRoot, } from '../application/configuration.js';
|
|
5
|
+
import { configureAndroidProject } from '../application/android-configuration.js';
|
|
6
|
+
import { diagnoseNativeCapabilities, disableNativeCapabilities, enableNativeCapabilities, listNativeCapabilities, } from '../application/native-capabilities.js';
|
|
5
7
|
import { localBinaryName, npmCommand, useCommandShell } from '../utils/platform.js';
|
|
6
8
|
export function registerCapacitorCommands(program) {
|
|
7
9
|
const capacitor = program.command('cap').description('Prepara la shell para Android o iOS');
|
|
8
|
-
capacitor
|
|
10
|
+
capacitor
|
|
11
|
+
.command('list')
|
|
12
|
+
.description('Lista las capacidades nativas disponibles y habilitadas')
|
|
13
|
+
.action(() => {
|
|
14
|
+
const root = requireApplicationRoot(process.cwd());
|
|
15
|
+
for (const { definition, enabled } of listNativeCapabilities(root)) {
|
|
16
|
+
console.log(`${enabled ? '✓' : '○'} ${definition.name} (${definition.platforms.join(', ')})`);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
capacitor
|
|
20
|
+
.command('enable <capabilities...>')
|
|
21
|
+
.description('Instala y habilita capacidades nativas en la aplicación')
|
|
22
|
+
.action((capabilities) => {
|
|
23
|
+
const root = requireApplicationRoot(process.cwd());
|
|
24
|
+
enableNativeCapabilities(root, capabilities);
|
|
25
|
+
synchronizeExistingNativeProjects(root);
|
|
26
|
+
console.log(`Capacidades habilitadas: ${capabilities.join(', ')}.`);
|
|
27
|
+
});
|
|
28
|
+
capacitor
|
|
29
|
+
.command('disable <capabilities...>')
|
|
30
|
+
.description('Deshabilita capacidades y elimina los plugins que ya no se usan')
|
|
31
|
+
.action((capabilities) => {
|
|
32
|
+
const root = requireApplicationRoot(process.cwd());
|
|
33
|
+
disableNativeCapabilities(root, capabilities);
|
|
34
|
+
synchronizeExistingNativeProjects(root);
|
|
35
|
+
console.log(`Capacidades deshabilitadas: ${capabilities.join(', ')}.`);
|
|
36
|
+
});
|
|
37
|
+
capacitor
|
|
38
|
+
.command('doctor [platform]')
|
|
39
|
+
.description('Muestra requisitos y configuración pendiente de las capacidades')
|
|
40
|
+
.action((platform) => {
|
|
41
|
+
const root = requireApplicationRoot(process.cwd());
|
|
42
|
+
const selectedPlatform = platform ? parsePlatform(platform) : undefined;
|
|
43
|
+
for (const message of diagnoseNativeCapabilities(root, selectedPlatform)) {
|
|
44
|
+
console.log(message);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
capacitor
|
|
48
|
+
.command('add <platform>')
|
|
9
49
|
.description('Crea el proyecto nativo de la plataforma')
|
|
10
50
|
.action((platform) => {
|
|
11
51
|
const selectedPlatform = parsePlatform(platform);
|
|
@@ -14,7 +54,8 @@ export function registerCapacitorCommands(program) {
|
|
|
14
54
|
runCapacitor(root, ['add', selectedPlatform]);
|
|
15
55
|
configureNativePlatform(root, selectedPlatform, readApplicationConfiguration(root));
|
|
16
56
|
});
|
|
17
|
-
capacitor
|
|
57
|
+
capacitor
|
|
58
|
+
.command('sync [platform]')
|
|
18
59
|
.description('Compila la shell y sincroniza sus assets y plugins nativos')
|
|
19
60
|
.action((platform) => {
|
|
20
61
|
const root = requireApplicationRoot(process.cwd());
|
|
@@ -28,7 +69,8 @@ export function registerCapacitorCommands(program) {
|
|
|
28
69
|
configureExistingPlatforms(root, readApplicationConfiguration(root));
|
|
29
70
|
}
|
|
30
71
|
});
|
|
31
|
-
capacitor
|
|
72
|
+
capacitor
|
|
73
|
+
.command('open <platform>')
|
|
32
74
|
.description('Abre el proyecto nativo en Android Studio o Xcode')
|
|
33
75
|
.action((platform) => {
|
|
34
76
|
const root = requireApplicationRoot(process.cwd());
|
|
@@ -77,96 +119,19 @@ function configureExistingPlatforms(root, configuration) {
|
|
|
77
119
|
configureNativePlatform(root, 'android', configuration);
|
|
78
120
|
}
|
|
79
121
|
}
|
|
80
|
-
function
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
function configureGoogleMapsForAndroid(root, configuration) {
|
|
88
|
-
const packageJson = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
|
|
89
|
-
if (!packageJson.dependencies?.['@capacitor/google-maps'])
|
|
90
|
-
return;
|
|
91
|
-
const manifestPath = join(root, 'android', 'app', 'src', 'main', 'AndroidManifest.xml');
|
|
92
|
-
if (!existsSync(manifestPath)) {
|
|
93
|
-
throw new Error('No se encuentra AndroidManifest.xml para configurar Google Maps.');
|
|
94
|
-
}
|
|
95
|
-
const manifest = readFileSync(manifestPath, 'utf8');
|
|
96
|
-
const apiKeyMetadata = 'android:name="com.google.android.geo.API_KEY"';
|
|
97
|
-
if (!manifest.includes(apiKeyMetadata)) {
|
|
98
|
-
const applicationCloseTag = '</application>';
|
|
99
|
-
if (!manifest.includes(applicationCloseTag)) {
|
|
100
|
-
throw new Error('No se ha encontrado el elemento application en AndroidManifest.xml.');
|
|
122
|
+
function synchronizeExistingNativeProjects(root) {
|
|
123
|
+
const platforms = ['android', 'ios'];
|
|
124
|
+
for (const platform of platforms) {
|
|
125
|
+
if (existsSync(join(root, platform))) {
|
|
126
|
+
runCapacitor(root, ['sync', platform]);
|
|
127
|
+
configureNativePlatform(root, platform, readApplicationConfiguration(root));
|
|
101
128
|
}
|
|
102
|
-
const metadata = [
|
|
103
|
-
' <meta-data',
|
|
104
|
-
` ${apiKeyMetadata}`,
|
|
105
|
-
' android:value="@string/open_mova_google_maps_api_key" />',
|
|
106
|
-
].join('\n');
|
|
107
|
-
writeFileSync(manifestPath, manifest.replace(applicationCloseTag, `${metadata}\n ${applicationCloseTag}`), 'utf8');
|
|
108
|
-
}
|
|
109
|
-
const valuesDirectory = join(root, 'android', 'app', 'src', 'main', 'res', 'values');
|
|
110
|
-
mkdirSync(valuesDirectory, { recursive: true });
|
|
111
|
-
const apiKey = process.env.OPEN_MOVA_GOOGLE_MAPS_ANDROID_API_KEY
|
|
112
|
-
?? configuration.native?.googleMaps?.androidApiKey
|
|
113
|
-
// Google Maps aborta la aplicación si falta por completo esta entrada.
|
|
114
|
-
// El valor explícito permite arrancar; Maps seguirá requiriendo una clave real al usarse.
|
|
115
|
-
?? 'OPEN_MOVA_GOOGLE_MAPS_API_KEY_NOT_CONFIGURED';
|
|
116
|
-
const resource = [
|
|
117
|
-
'<?xml version="1.0" encoding="utf-8"?>',
|
|
118
|
-
'<resources>',
|
|
119
|
-
` <string name="open_mova_google_maps_api_key" translatable="false">${escapeXml(apiKey)}</string>`,
|
|
120
|
-
'</resources>',
|
|
121
|
-
'',
|
|
122
|
-
].join('\n');
|
|
123
|
-
writeFileSync(join(valuesDirectory, 'open_mova_google_maps.xml'), resource, 'utf8');
|
|
124
|
-
}
|
|
125
|
-
function escapeXml(value) {
|
|
126
|
-
return value.replace(/[&<>"']/g, (character) => ({
|
|
127
|
-
'&': '&',
|
|
128
|
-
'<': '<',
|
|
129
|
-
'>': '>',
|
|
130
|
-
'"': '"',
|
|
131
|
-
"'": ''',
|
|
132
|
-
})[character] ?? character);
|
|
133
|
-
}
|
|
134
|
-
function configureMinimumAndroidSdk(root) {
|
|
135
|
-
const packageJson = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
|
|
136
|
-
if (!packageJson.dependencies?.['@capacitor/local-llm'])
|
|
137
|
-
return;
|
|
138
|
-
const variablesPath = join(root, 'android', 'variables.gradle');
|
|
139
|
-
if (!existsSync(variablesPath)) {
|
|
140
|
-
throw new Error('No se encuentra android/variables.gradle para configurar Local LLM.');
|
|
141
|
-
}
|
|
142
|
-
const variables = readFileSync(variablesPath, 'utf8');
|
|
143
|
-
const minimumSdkPattern = /minSdkVersion\s*=\s*(\d+)/;
|
|
144
|
-
const currentMinimumSdk = Number(minimumSdkPattern.exec(variables)?.[1]);
|
|
145
|
-
if (!Number.isFinite(currentMinimumSdk)) {
|
|
146
|
-
throw new Error('No se ha encontrado minSdkVersion en android/variables.gradle.');
|
|
147
129
|
}
|
|
148
|
-
if (currentMinimumSdk >= 28)
|
|
149
|
-
return;
|
|
150
|
-
writeFileSync(variablesPath, variables.replace(minimumSdkPattern, 'minSdkVersion = 28'), 'utf8');
|
|
151
130
|
}
|
|
152
|
-
function
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
return;
|
|
156
|
-
const gradlePath = join(root, 'android', 'app', 'build.gradle');
|
|
157
|
-
if (!existsSync(gradlePath)) {
|
|
158
|
-
throw new Error('No se encuentra android/app/build.gradle para configurar Background Runner.');
|
|
159
|
-
}
|
|
160
|
-
const repositoryEntry = "dirs '../../node_modules/@capacitor/background-runner/android/src/main/libs', 'libs'";
|
|
161
|
-
const gradle = readFileSync(gradlePath, 'utf8');
|
|
162
|
-
if (gradle.includes(repositoryEntry))
|
|
163
|
-
return;
|
|
164
|
-
const flatDirectory = /flatDir\s*\{/;
|
|
165
|
-
if (!flatDirectory.test(gradle)) {
|
|
166
|
-
throw new Error('No se ha encontrado el bloque flatDir en android/app/build.gradle.');
|
|
131
|
+
function configureNativePlatform(root, platform, configuration) {
|
|
132
|
+
if (platform === 'android') {
|
|
133
|
+
configureAndroidProject(root, configuration);
|
|
167
134
|
}
|
|
168
|
-
const configuredGradle = gradle.replace(flatDirectory, (match) => `${match}\n ${repositoryEntry}`);
|
|
169
|
-
writeFileSync(gradlePath, configuredGradle, 'utf8');
|
|
170
135
|
}
|
|
171
136
|
function runCapacitor(root, args) {
|
|
172
137
|
if (!existsSync(join(root, 'capacitor.config.ts'))) {
|
package/dist/commands/create.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, mkdtempSync, renameSync, rmSync } from 'node:fs';
|
|
2
2
|
import { dirname, join, resolve } from 'node:path';
|
|
3
3
|
import { createMicrofrontend } from '../application/microfrontend.js';
|
|
4
|
-
import { addMicrofrontend, writeApplicationConfiguration
|
|
4
|
+
import { addMicrofrontend, writeApplicationConfiguration } from '../application/configuration.js';
|
|
5
5
|
import { synchronizeShellConfiguration } from '../application/shell-configuration.js';
|
|
6
6
|
import { configureDownloadedShell, DEMO_MICROFRONTEND_REMOTE_ENTRY, downloadShell, } from '../application/shell-repository.js';
|
|
7
7
|
import { normalizeName } from '../utils/names.js';
|
|
@@ -27,9 +27,10 @@ export function registerCreateCommand(program) {
|
|
|
27
27
|
shellVersion = shell.version;
|
|
28
28
|
configureDownloadedShell(temporaryApplication, applicationName, !options.empty);
|
|
29
29
|
let configuration = {
|
|
30
|
-
schemaVersion:
|
|
30
|
+
schemaVersion: 3,
|
|
31
31
|
name: applicationName,
|
|
32
32
|
shell,
|
|
33
|
+
native: { capabilities: [] },
|
|
33
34
|
microfrontends: [],
|
|
34
35
|
};
|
|
35
36
|
if (!options.empty) {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { inspectDevelopmentEnvironment } from '../application/doctor.js';
|
|
2
|
+
const STATUS_SYMBOL = {
|
|
3
|
+
ok: '✓',
|
|
4
|
+
warning: '!',
|
|
5
|
+
error: '✗',
|
|
6
|
+
};
|
|
7
|
+
export function registerDoctorCommand(program) {
|
|
8
|
+
program
|
|
9
|
+
.command('doctor')
|
|
10
|
+
.description('Comprueba el entorno y la configuración de una aplicación Open Mova')
|
|
11
|
+
.action(() => {
|
|
12
|
+
const report = inspectDevelopmentEnvironment(process.cwd());
|
|
13
|
+
console.log('Diagnóstico de Open Mova');
|
|
14
|
+
for (const check of report.checks) {
|
|
15
|
+
console.log(`${STATUS_SYMBOL[check.status]} ${check.message}`);
|
|
16
|
+
if (check.detail)
|
|
17
|
+
console.log(` ${check.detail}`);
|
|
18
|
+
}
|
|
19
|
+
const errors = report.checks.filter((check) => check.status === 'error').length;
|
|
20
|
+
const warnings = report.checks.filter((check) => check.status === 'warning').length;
|
|
21
|
+
console.log(`Resultado: ${errors} errores, ${warnings} avisos.`);
|
|
22
|
+
if (errors > 0)
|
|
23
|
+
process.exitCode = 1;
|
|
24
|
+
});
|
|
25
|
+
}
|
package/dist/commands/info.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolve } from 'node:path';
|
|
2
|
-
import { findApplicationRoot, readApplicationConfiguration
|
|
2
|
+
import { findApplicationRoot, readApplicationConfiguration } from '../application/configuration.js';
|
|
3
3
|
export function registerInfoCommand(program) {
|
|
4
4
|
program
|
|
5
5
|
.command('info')
|
|
@@ -4,6 +4,7 @@ import { addMicrofrontend, readApplicationConfiguration, requireApplicationRoot,
|
|
|
4
4
|
import { synchronizeShellConfiguration } from '../application/shell-configuration.js';
|
|
5
5
|
import { normalizeName } from '../utils/names.js';
|
|
6
6
|
import { listShellVersions } from '../application/shell-repository.js';
|
|
7
|
+
import { applyMicrofrontendUpdate, createMicrofrontendUpdatePlan, } from '../application/microfrontend-update.js';
|
|
7
8
|
export function registerMicrofrontendCommands(program) {
|
|
8
9
|
const microfrontend = program
|
|
9
10
|
.command('mf')
|
|
@@ -21,7 +22,9 @@ export function registerMicrofrontendCommands(program) {
|
|
|
21
22
|
const applicationRoot = requireApplicationRoot(process.cwd());
|
|
22
23
|
const configuration = readApplicationConfiguration(applicationRoot);
|
|
23
24
|
const normalizedName = normalizeName(name, 'El nombre del microfrontal');
|
|
24
|
-
const templateVersion = options.templateVersion ??
|
|
25
|
+
const templateVersion = options.templateVersion ??
|
|
26
|
+
(options.demo ? configuration.shell?.version : undefined) ??
|
|
27
|
+
listShellVersions()[0];
|
|
25
28
|
if (!templateVersion) {
|
|
26
29
|
throw new Error('No hay tags estables disponibles para crear el microfrontal.');
|
|
27
30
|
}
|
|
@@ -53,6 +56,7 @@ export function registerMicrofrontendCommands(program) {
|
|
|
53
56
|
.option('--remote-entry <url>', 'URL del remoteEntry.json')
|
|
54
57
|
.option('--port <number>', 'puerto de desarrollo para un proyecto local', parsePort)
|
|
55
58
|
.option('--production-remote-entry <url>', 'URL HTTPS del remoto publicado')
|
|
59
|
+
.option('--core-version <range>', 'rango requerido de @open-mova/core')
|
|
56
60
|
.action((sourcePath, options) => {
|
|
57
61
|
const applicationRoot = requireApplicationRoot(process.cwd());
|
|
58
62
|
const configuration = readApplicationConfiguration(applicationRoot);
|
|
@@ -64,6 +68,7 @@ export function registerMicrofrontendCommands(program) {
|
|
|
64
68
|
remoteEntry: options.remoteEntry,
|
|
65
69
|
port: options.port,
|
|
66
70
|
productionRemoteEntry: options.productionRemoteEntry,
|
|
71
|
+
coreVersion: options.coreVersion,
|
|
67
72
|
});
|
|
68
73
|
const updatedConfiguration = addMicrofrontend(configuration, microfrontendConfiguration);
|
|
69
74
|
writeApplicationConfiguration(applicationRoot, updatedConfiguration);
|
|
@@ -71,6 +76,40 @@ export function registerMicrofrontendCommands(program) {
|
|
|
71
76
|
console.log(`Microfrontal "${microfrontendConfiguration.name}" registrado.`);
|
|
72
77
|
console.log(`Ruta pública: /${microfrontendConfiguration.route}`);
|
|
73
78
|
});
|
|
79
|
+
microfrontend
|
|
80
|
+
.command('update <name>')
|
|
81
|
+
.description('Actualiza un microfrontal creado desde la plantilla de Open Mova')
|
|
82
|
+
.option('--check', 'mostrar los cambios sin modificar archivos')
|
|
83
|
+
.option('--to <tag>', 'versión de destino, por ejemplo v0.2.1')
|
|
84
|
+
.action((name, options) => {
|
|
85
|
+
const applicationRoot = requireApplicationRoot(process.cwd());
|
|
86
|
+
const configuration = readApplicationConfiguration(applicationRoot);
|
|
87
|
+
const normalizedName = normalizeName(name, 'El nombre del microfrontal');
|
|
88
|
+
const plan = createMicrofrontendUpdatePlan(applicationRoot, configuration, normalizedName, options.to);
|
|
89
|
+
console.log(`Plantilla actual: ${plan.currentVersion}`);
|
|
90
|
+
console.log(`Plantilla destino: ${plan.target.version}`);
|
|
91
|
+
for (const change of plan.changes)
|
|
92
|
+
console.log(`- ${change}`);
|
|
93
|
+
if (plan.conflicts.length > 0) {
|
|
94
|
+
console.log('Conflictos que no se sobrescribirán:');
|
|
95
|
+
for (const conflict of plan.conflicts)
|
|
96
|
+
console.log(`- ${conflict}`);
|
|
97
|
+
}
|
|
98
|
+
if (options.check)
|
|
99
|
+
return;
|
|
100
|
+
if (plan.conflicts.length > 0) {
|
|
101
|
+
throw new Error('Resuelve los conflictos antes de actualizar el microfrontal.');
|
|
102
|
+
}
|
|
103
|
+
if (plan.changes.length === 0) {
|
|
104
|
+
console.log('El microfrontal ya está actualizado.');
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
applyMicrofrontendUpdate(applicationRoot, configuration, plan);
|
|
108
|
+
console.log(`Microfrontal "${normalizedName}" actualizado a ${plan.target.version}.`);
|
|
109
|
+
if (plan.removePackageLock) {
|
|
110
|
+
console.log(`Ejecuta npm install en ${plan.projectRoot}.`);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
74
113
|
}
|
|
75
114
|
function parsePort(value) {
|
|
76
115
|
const port = Number(value);
|
package/dist/commands/update.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { applyShellUpdate, createShellUpdatePlan
|
|
1
|
+
import { readApplicationConfigurationDocument, requireApplicationRoot, } from '../application/configuration.js';
|
|
2
|
+
import { applyShellUpdate, createShellUpdatePlan } from '../application/shell-update.js';
|
|
3
3
|
export function registerUpdateCommand(program) {
|
|
4
4
|
program
|
|
5
5
|
.command('update')
|
|
@@ -8,20 +8,29 @@ export function registerUpdateCommand(program) {
|
|
|
8
8
|
.option('--to <tag>', 'versión de destino, por ejemplo v0.2.0')
|
|
9
9
|
.action((options) => {
|
|
10
10
|
const applicationRoot = requireApplicationRoot(process.cwd());
|
|
11
|
-
const
|
|
11
|
+
const document = readApplicationConfigurationDocument(applicationRoot);
|
|
12
|
+
const configuration = document.configuration;
|
|
12
13
|
const plan = createShellUpdatePlan(applicationRoot, configuration, options.to);
|
|
13
14
|
printPlan(plan);
|
|
15
|
+
if (document.migrations.length > 0) {
|
|
16
|
+
console.log('Migraciones de mova.config.json:');
|
|
17
|
+
for (const migration of document.migrations)
|
|
18
|
+
console.log(`- ${migration}`);
|
|
19
|
+
}
|
|
14
20
|
if (options.check)
|
|
15
21
|
return;
|
|
16
22
|
if (plan.conflicts.length > 0) {
|
|
17
23
|
throw new Error('Se han detectado archivos modificados. Resuelve los conflictos antes de actualizar.');
|
|
18
24
|
}
|
|
19
|
-
if (plan.changes.length === 0) {
|
|
25
|
+
if (plan.changes.length === 0 && document.migrations.length === 0) {
|
|
20
26
|
console.log('La aplicación ya está actualizada.');
|
|
21
27
|
return;
|
|
22
28
|
}
|
|
23
29
|
applyShellUpdate(applicationRoot, configuration, plan);
|
|
24
30
|
console.log(`Aplicación actualizada a ${plan.target.version}.`);
|
|
31
|
+
if (document.migrations.length > 0) {
|
|
32
|
+
console.log('mova.config.json se ha migrado al esquema actual.');
|
|
33
|
+
}
|
|
25
34
|
if (plan.removePackageLock) {
|
|
26
35
|
console.log('Ejecuta npm install para instalar dependencias y regenerar package-lock.json.');
|
|
27
36
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export interface OpenMovaApplicationConfiguration {
|
|
2
|
-
readonly schemaVersion:
|
|
2
|
+
readonly schemaVersion: 3;
|
|
3
3
|
readonly name: string;
|
|
4
4
|
readonly shell?: {
|
|
5
5
|
readonly repository: string;
|
|
@@ -11,6 +11,8 @@ export interface OpenMovaApplicationConfiguration {
|
|
|
11
11
|
readonly microfrontends: readonly MicrofrontendConfiguration[];
|
|
12
12
|
}
|
|
13
13
|
export interface NativeConfiguration {
|
|
14
|
+
/** Capacidades instaladas y proporcionadas por la shell. */
|
|
15
|
+
readonly capabilities: readonly string[];
|
|
14
16
|
readonly googleMaps?: {
|
|
15
17
|
/** Clave de Android Maps. También puede venir de OPEN_MOVA_GOOGLE_MAPS_ANDROID_API_KEY. */
|
|
16
18
|
readonly androidApiKey?: string;
|
|
@@ -24,6 +26,10 @@ export interface MicrofrontendConfiguration {
|
|
|
24
26
|
readonly developmentRemoteEntry: string;
|
|
25
27
|
readonly productionRemoteEntry?: string;
|
|
26
28
|
readonly sourcePath?: string;
|
|
29
|
+
readonly compatibility: {
|
|
30
|
+
/** Rango de @open-mova/core declarado y publicado por el microfrontal. */
|
|
31
|
+
readonly requiredCoreVersion: string;
|
|
32
|
+
};
|
|
27
33
|
readonly template?: {
|
|
28
34
|
readonly repository: string;
|
|
29
35
|
readonly version: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mova/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.22",
|
|
4
4
|
"description": "CLI para crear y mantener aplicaciones Open Mova",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Open Mova contributors",
|
|
@@ -39,13 +39,17 @@
|
|
|
39
39
|
"scripts": {
|
|
40
40
|
"build": "tsc",
|
|
41
41
|
"start": "tsx src/cli.ts",
|
|
42
|
-
"typecheck": "tsc --noEmit"
|
|
42
|
+
"typecheck": "tsc --noEmit",
|
|
43
|
+
"test": "npm run build && npm run test:unit",
|
|
44
|
+
"test:unit": "node --test test/*.test.mjs"
|
|
43
45
|
},
|
|
44
46
|
"dependencies": {
|
|
45
|
-
"commander": "^14.0.0"
|
|
47
|
+
"commander": "^14.0.0",
|
|
48
|
+
"semver": "^7.8.5"
|
|
46
49
|
},
|
|
47
50
|
"devDependencies": {
|
|
48
51
|
"@types/node": "^24.0.0",
|
|
52
|
+
"@types/semver": "^7.8.0",
|
|
49
53
|
"tsx": "^4.20.0",
|
|
50
54
|
"typescript": "^5.9.3"
|
|
51
55
|
}
|