@open-mova/core 0.2.0 → 0.2.2

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 CHANGED
@@ -57,25 +57,6 @@ npm run build
57
57
  El paquete se identifica como `@open-mova/core`. Cuando se añada una pieza
58
58
  pública, debe exportarse desde `src/index.ts`.
59
59
 
60
- La shell proporciona el token `NATIVE_CAPABILITIES` y el MF accede a él por DI:
61
-
62
- ```ts
63
- import { injectNativeCapabilities } from '@open-mova/core';
64
-
65
- const native = injectNativeCapabilities(); // Dentro de un contexto de inyección Angular.
66
- const device = await native.device.getInfo();
67
- const photo = await native.camera.takePhoto();
68
- const selected = await native.camera.choosePhoto();
69
- ```
70
-
71
- `photo.webPath` sirve para mostrar la imagen; `photo.uri` puede existir en
72
- móvil. `choosePhoto()` devuelve `undefined` si la galería devuelve una lista
73
- vacía; cancelar el diálogo puede rechazar la promesa según la plataforma.
74
- Angular muestra un error de provider ausente si la shell no ofrece el contrato.
75
- Los MF que usan capacidades nativas dependen de `@open-mova/core` desde npm.
76
- Shell y MF deben compartir una sola instancia de core mediante Native
77
- Federation.
78
-
79
60
  ## Capacidades nativas
80
61
 
81
62
  Cada plugin oficial se representa como una capacidad con tres operaciones
@@ -83,28 +64,25 @@ comunes:
83
64
 
84
65
  - `isAvailable()` comprueba si el plugin está disponible en la plataforma.
85
66
  - `invoke(nombre, opciones)` ejecuta una operación del plugin.
86
- - `subscribe(evento, listener)` registra un evento y devuelve un handle con
67
+ - `subscribe(evento, listener, contexto?)` registra un evento y devuelve un handle con
87
68
  `remove()` para cancelarlo.
88
69
 
89
- Los nombres de capacidad están en camelCase y no dependen del nombre del
90
- paquete npm. Por ejemplo, un MF puede consultar conectividad así:
91
-
92
- ```ts
93
- const native = injectNativeCapabilities();
94
-
95
- if (native.network.isAvailable()) {
96
- const status = await native.network.invoke('getStatus');
97
- }
98
- ```
70
+ `NATIVE_CAPABILITY_API` contiene la lista completa y versionada de operaciones
71
+ y eventos soportados. El microfrontal de demostración la reutiliza para que su
72
+ referencia interactiva no pueda quedarse desactualizada respecto al contrato.
73
+ El tercer argumento de `subscribe()` solo es necesario en capacidades con
74
+ instancias, como Google Maps, donde se pasa `{ id: 'mapa-principal' }`.
99
75
 
100
- El contrato expone: `actionSheet`, `app`, `appLauncher`, `backgroundRunner`,
76
+ El contrato expone una capacidad por cada plugin oficial soportado:
77
+ `actionSheet`, `app`, `appLauncher`, `backgroundRunner`,
101
78
  `barcodeScanner`, `browser`, `calendar`, `camera`, `clipboard`, `contacts`,
102
79
  `cookies`, `device`, `dialog`, `fileTransfer`, `fileViewer`, `filesystem`,
103
80
  `geolocation`, `googleMaps`, `haptics`, `healthFitness`, `http`,
104
81
  `inAppBrowser`, `keyboard`, `localLlm`, `localNotifications`, `motion`,
105
82
  `network`, `preferences`, `privacyScreen`, `pushNotifications`,
106
83
  `screenOrientation`, `screenReader`, `share`, `splashScreen`, `statusBar`,
107
- `systemBars`, `textZoom` y `toast`.
84
+ `systemBars`, `textZoom` y `toast`. La lista completa de métodos y eventos de
85
+ cada capacidad se encuentra en `NATIVE_CAPABILITY_API`.
108
86
 
109
87
  Las opciones y el resultado no exponen tipos de Capacitor. Esto evita que el MF
110
88
  se acople a su versión; algunas operaciones avanzadas pueden requerir valores
@@ -0,0 +1,23 @@
1
+ /** Versión del paquete que implementa este contrato en tiempo de ejecución. */
2
+ export declare const OPEN_MOVA_CORE_VERSION = "0.2.1";
3
+ /** Versión del formato del manifiesto publicado por cada microfrontal. */
4
+ export declare const MICROFRONTEND_MANIFEST_SCHEMA_VERSION = 1;
5
+ export interface OpenMovaMicrofrontendManifest {
6
+ readonly schemaVersion: typeof MICROFRONTEND_MANIFEST_SCHEMA_VERSION;
7
+ readonly name: string;
8
+ readonly remoteName: string;
9
+ readonly core: {
10
+ readonly requiredVersion: string;
11
+ };
12
+ }
13
+ export interface CompatibilityResult {
14
+ readonly compatible: boolean;
15
+ readonly reason?: string;
16
+ }
17
+ /**
18
+ * Comprueba los rangos que genera Open Mova: versión exacta, caret y tilde.
19
+ * Mantener el formato acotado permite usarlo también en el navegador sin
20
+ * incorporar un segundo motor completo de semver al runtime compartido.
21
+ */
22
+ export declare function checkCoreCompatibility(requiredVersion: string, availableVersion?: string): CompatibilityResult;
23
+ export declare function parseMicrofrontendManifest(value: unknown): OpenMovaMicrofrontendManifest;
@@ -0,0 +1,94 @@
1
+ /** Versión del paquete que implementa este contrato en tiempo de ejecución. */
2
+ export const OPEN_MOVA_CORE_VERSION = '0.2.1';
3
+ /** Versión del formato del manifiesto publicado por cada microfrontal. */
4
+ export const MICROFRONTEND_MANIFEST_SCHEMA_VERSION = 1;
5
+ /**
6
+ * Comprueba los rangos que genera Open Mova: versión exacta, caret y tilde.
7
+ * Mantener el formato acotado permite usarlo también en el navegador sin
8
+ * incorporar un segundo motor completo de semver al runtime compartido.
9
+ */
10
+ export function checkCoreCompatibility(requiredVersion, availableVersion = OPEN_MOVA_CORE_VERSION) {
11
+ const range = parseSupportedRange(requiredVersion);
12
+ const available = parseVersion(availableVersion);
13
+ if (!range || !available) {
14
+ return {
15
+ compatible: false,
16
+ reason: `No se puede interpretar el rango ${requiredVersion} o la versión ${availableVersion}.`,
17
+ };
18
+ }
19
+ const minimumComparison = compareVersions(available, range.minimum);
20
+ const compatible = minimumComparison >= 0 && isBelowUpperBound(available, range);
21
+ return compatible
22
+ ? { compatible: true }
23
+ : {
24
+ compatible: false,
25
+ reason: `Requiere @open-mova/core ${requiredVersion}, pero la shell proporciona ${availableVersion}.`,
26
+ };
27
+ }
28
+ export function parseMicrofrontendManifest(value) {
29
+ if (!isRecord(value) || value.schemaVersion !== MICROFRONTEND_MANIFEST_SCHEMA_VERSION) {
30
+ throw new Error('El manifiesto del microfrontal tiene una versión no compatible.');
31
+ }
32
+ if (typeof value.name !== 'string' ||
33
+ typeof value.remoteName !== 'string' ||
34
+ !isRecord(value.core) ||
35
+ typeof value.core.requiredVersion !== 'string') {
36
+ throw new Error('El manifiesto del microfrontal está incompleto.');
37
+ }
38
+ return {
39
+ schemaVersion: MICROFRONTEND_MANIFEST_SCHEMA_VERSION,
40
+ name: value.name,
41
+ remoteName: value.remoteName,
42
+ core: { requiredVersion: value.core.requiredVersion },
43
+ };
44
+ }
45
+ function parseSupportedRange(value) {
46
+ if (value.trim() === '*') {
47
+ return {
48
+ operator: 'caret',
49
+ minimum: { major: 0, minor: 0, patch: 0 },
50
+ };
51
+ }
52
+ const match = value.trim().match(/^(\^|~)?(\d+)\.(\d+)\.(\d+)$/);
53
+ if (!match)
54
+ return undefined;
55
+ return {
56
+ operator: match[1] === '^' ? 'caret' : match[1] === '~' ? 'tilde' : 'exact',
57
+ minimum: {
58
+ major: Number(match[2]),
59
+ minor: Number(match[3]),
60
+ patch: Number(match[4]),
61
+ },
62
+ };
63
+ }
64
+ function parseVersion(value) {
65
+ const match = value.trim().match(/^v?(\d+)\.(\d+)\.(\d+)$/);
66
+ return match
67
+ ? { major: Number(match[1]), minor: Number(match[2]), patch: Number(match[3]) }
68
+ : undefined;
69
+ }
70
+ function isBelowUpperBound(version, range) {
71
+ if (range.operator === 'caret' &&
72
+ range.minimum.major === 0 &&
73
+ range.minimum.minor === 0 &&
74
+ range.minimum.patch === 0) {
75
+ return true;
76
+ }
77
+ if (range.operator === 'exact')
78
+ return compareVersions(version, range.minimum) === 0;
79
+ if (range.operator === 'tilde') {
80
+ return version.major === range.minimum.major && version.minor === range.minimum.minor;
81
+ }
82
+ if (range.minimum.major > 0)
83
+ return version.major === range.minimum.major;
84
+ if (range.minimum.minor > 0) {
85
+ return version.major === 0 && version.minor === range.minimum.minor;
86
+ }
87
+ return compareVersions(version, range.minimum) === 0;
88
+ }
89
+ function compareVersions(first, second) {
90
+ return first.major - second.major || first.minor - second.minor || first.patch - second.patch;
91
+ }
92
+ function isRecord(value) {
93
+ return typeof value === 'object' && value !== null;
94
+ }
package/dist/index.d.ts CHANGED
@@ -1,2 +1,4 @@
1
- export type { ActionSheetCapability, AppCapability, AppLauncherCapability, BackgroundRunnerCapability, BarcodeScannerCapability, BrowserCapability, CameraCapability, CalendarCapability, ClipboardCapability, ContactsCapability, CookiesCapability, DeviceCapability, DeviceDetails, DialogCapability, FileTransferCapability, FileViewerCapability, FilesystemCapability, GeolocationCapability, GoogleMapsCapability, HapticsCapability, HealthFitnessCapability, HttpCapability, InAppBrowserCapability, KeyboardCapability, LocalLlmCapability, LocalNotificationsCapability, MotionCapability, NativeCapabilities, NativeOptions, NativePluginCapability, NativeSubscription, NetworkCapability, PhotoResult, PreferencesCapability, PrivacyScreenCapability, PushNotificationsCapability, ScreenOrientationCapability, ScreenReaderCapability, ShareCapability, SplashScreenCapability, StatusBarCapability, SystemBarsCapability, TextZoomCapability, ToastCapability, } from './native.js';
2
- export { NATIVE_CAPABILITIES, injectNativeCapabilities } from './native.js';
1
+ export { checkCoreCompatibility, MICROFRONTEND_MANIFEST_SCHEMA_VERSION, OPEN_MOVA_CORE_VERSION, parseMicrofrontendManifest, } from './compatibility.js';
2
+ export type { CompatibilityResult, OpenMovaMicrofrontendManifest } from './compatibility.js';
3
+ export type { ActionSheetCapability, AppCapability, AppLauncherCapability, BackgroundRunnerCapability, BarcodeScannerCapability, BrowserCapability, CameraCapability, CalendarCapability, ClipboardCapability, ContactsCapability, CookiesCapability, DeviceCapability, DeviceDetails, DialogCapability, FileTransferCapability, FileViewerCapability, FilesystemCapability, GeolocationCapability, GoogleMapsCapability, HapticsCapability, HealthFitnessCapability, HttpCapability, InAppBrowserCapability, KeyboardCapability, LocalLlmCapability, LocalNotificationsCapability, MotionCapability, NativeCapabilities, NativeCapabilityName, NativeEvent, NativeOptions, NativeOperation, NativePluginCapability, NativeSubscription, NetworkCapability, PhotoResult, PreferencesCapability, PrivacyScreenCapability, PushNotificationsCapability, ScreenOrientationCapability, ScreenReaderCapability, ShareCapability, SplashScreenCapability, StatusBarCapability, SystemBarsCapability, TextZoomCapability, ToastCapability, } from './native.js';
4
+ export { NATIVE_CAPABILITIES, NATIVE_CAPABILITY_API, injectNativeCapabilities } from './native.js';
package/dist/index.js CHANGED
@@ -1 +1,2 @@
1
- export { NATIVE_CAPABILITIES, injectNativeCapabilities } from './native.js';
1
+ export { checkCoreCompatibility, MICROFRONTEND_MANIFEST_SCHEMA_VERSION, OPEN_MOVA_CORE_VERSION, parseMicrofrontendManifest, } from './compatibility.js';
2
+ export { NATIVE_CAPABILITIES, NATIVE_CAPABILITY_API, injectNativeCapabilities } from './native.js';
package/dist/native.d.ts CHANGED
@@ -1,115 +1,269 @@
1
1
  import { InjectionToken } from '@angular/core';
2
2
  /**
3
- * Options passed across the framework boundary. Some official plugins need
4
- * platform values such as Date, Blob or an element reference, so this cannot
5
- * be restricted to JSON alone.
3
+ * Superficie oficial que Open Mova expone para cada plugin de Capacitor.
4
+ * La demo consume también este catálogo para no mantener una segunda lista.
6
5
  */
6
+ export declare const NATIVE_CAPABILITY_API: {
7
+ readonly actionSheet: {
8
+ readonly operations: readonly ["showActions"];
9
+ readonly events: readonly [];
10
+ };
11
+ readonly app: {
12
+ readonly operations: readonly ["exitApp", "getInfo", "getState", "getLaunchUrl", "minimizeApp", "getAppLanguage", "toggleBackButtonHandler", "removeAllListeners"];
13
+ readonly events: readonly ["appStateChange", "pause", "resume", "appUrlOpen", "appRestoredResult", "backButton"];
14
+ };
15
+ readonly appLauncher: {
16
+ readonly operations: readonly ["canOpenUrl", "openUrl"];
17
+ readonly events: readonly [];
18
+ };
19
+ readonly backgroundRunner: {
20
+ readonly operations: readonly ["checkPermissions", "requestPermissions", "dispatchEvent", "removeNotificationListeners"];
21
+ readonly events: readonly ["backgroundRunnerNotificationReceived"];
22
+ };
23
+ readonly barcodeScanner: {
24
+ readonly operations: readonly ["scanBarcode"];
25
+ readonly events: readonly [];
26
+ };
27
+ readonly browser: {
28
+ readonly operations: readonly ["open", "close", "removeAllListeners"];
29
+ readonly events: readonly ["browserFinished", "browserPageLoaded"];
30
+ };
31
+ readonly calendar: {
32
+ readonly operations: readonly ["checkPermissions", "requestPermissions", "createEvent", "createEventInteractively", "modifyEvent", "findEvents", "deleteEvent", "listCalendars", "createCalendar", "deleteCalendar", "openCalendar"];
33
+ readonly events: readonly [];
34
+ };
35
+ readonly camera: {
36
+ readonly operations: readonly ["takePhoto", "recordVideo", "playVideo", "chooseFromGallery", "editPhoto", "editURIPhoto", "pickLimitedLibraryPhotos", "getLimitedLibraryPhotos", "checkPermissions", "requestPermissions", "getPhoto", "pickImages"];
37
+ readonly events: readonly [];
38
+ };
39
+ readonly clipboard: {
40
+ readonly operations: readonly ["write", "read"];
41
+ readonly events: readonly [];
42
+ };
43
+ readonly contacts: {
44
+ readonly operations: readonly ["find", "save", "remove", "pickContact"];
45
+ readonly events: readonly [];
46
+ };
47
+ readonly cookies: {
48
+ readonly operations: readonly ["getCookies", "setCookie", "deleteCookie", "clearCookies", "clearAllCookies"];
49
+ readonly events: readonly [];
50
+ };
51
+ readonly device: {
52
+ readonly operations: readonly ["getId", "getInfo", "getBatteryInfo", "getLanguageCode", "getLanguageTag"];
53
+ readonly events: readonly [];
54
+ };
55
+ readonly dialog: {
56
+ readonly operations: readonly ["alert", "prompt", "confirm"];
57
+ readonly events: readonly [];
58
+ };
59
+ readonly fileTransfer: {
60
+ readonly operations: readonly ["downloadFile", "uploadFile", "removeAllListeners"];
61
+ readonly events: readonly ["progress"];
62
+ };
63
+ readonly fileViewer: {
64
+ readonly operations: readonly ["openDocumentFromLocalPath", "openDocumentFromResources", "openDocumentFromUrl", "previewMediaContentFromLocalPath", "previewMediaContentFromResources", "previewMediaContentFromUrl"];
65
+ readonly events: readonly [];
66
+ };
67
+ readonly filesystem: {
68
+ readonly operations: readonly ["checkPermissions", "requestPermissions", "readFile", "readFileInChunks", "writeFile", "appendFile", "deleteFile", "mkdir", "rmdir", "readdir", "getUri", "stat", "rename", "copy", "downloadFile", "removeAllListeners"];
69
+ readonly events: readonly ["progress"];
70
+ };
71
+ readonly geolocation: {
72
+ readonly operations: readonly ["getCurrentPosition", "watchPosition", "clearWatch", "checkPermissions", "requestPermissions"];
73
+ readonly events: readonly [];
74
+ };
75
+ readonly googleMaps: {
76
+ readonly operations: readonly ["create", "enableTouch", "disableTouch", "enableClustering", "disableClustering", "addTileOverlay", "removeTileOverlay", "addMarker", "addMarkers", "removeMarker", "removeMarkers", "addPolygons", "removePolygons", "addCircles", "removeCircles", "addPolylines", "removePolylines", "destroy", "setCamera", "getMapType", "setMapType", "enableIndoorMaps", "enableTrafficLayer", "enableAccessibilityElements", "enableCurrentLocation", "setPadding", "getMapBounds", "fitBounds", "removeAllMapListeners"];
77
+ readonly events: readonly ["boundsChanged", "cameraIdle", "cameraMoveStarted", "clusterClick", "clusterInfoWindowClick", "infoWindowClick", "mapClick", "markerClick", "polygonClick", "circleClick", "polylineClick", "markerDragStart", "markerDrag", "markerDragEnd", "myLocationButtonClick", "myLocationClick"];
78
+ };
79
+ readonly haptics: {
80
+ readonly operations: readonly ["impact", "notification", "vibrate", "selectionStart", "selectionChanged", "selectionEnd"];
81
+ readonly events: readonly [];
82
+ };
83
+ readonly healthFitness: {
84
+ readonly operations: readonly ["requestHealthPermissions", "getData", "getWorkoutData", "writeData", "getLastRecord", "setBackgroundJob", "deleteBackgroundJob", "listBackgroundJobs", "updateBackgroundJob", "disconnectFromHealthConnect", "openHealthConnect"];
85
+ readonly events: readonly [];
86
+ };
87
+ readonly http: {
88
+ readonly operations: readonly ["request", "get", "post", "put", "patch", "delete"];
89
+ readonly events: readonly [];
90
+ };
91
+ readonly inAppBrowser: {
92
+ readonly operations: readonly ["openInWebView", "openInSystemBrowser", "openInExternalBrowser", "close", "removeAllListeners"];
93
+ readonly events: readonly ["browserPageLoaded", "browserPageNavigationCompleted", "browserClosed"];
94
+ };
95
+ readonly keyboard: {
96
+ readonly operations: readonly ["show", "hide", "setAccessoryBarVisible", "setScroll", "setStyle", "setResizeMode", "getResizeMode", "removeAllListeners"];
97
+ readonly events: readonly ["keyboardWillShow", "keyboardDidShow", "keyboardWillHide", "keyboardDidHide"];
98
+ };
99
+ readonly localLlm: {
100
+ readonly operations: readonly ["systemAvailability", "download", "prompt", "endSession", "generateImage", "warmup", "removeAllListeners"];
101
+ readonly events: readonly ["systemAvailabilityChange"];
102
+ };
103
+ readonly localNotifications: {
104
+ readonly operations: readonly ["schedule", "update", "getPending", "registerActionTypes", "cancel", "cancelAll", "areEnabled", "getDeliveredNotifications", "removeDeliveredNotifications", "removeDeliveredNotificationsById", "removeAllDeliveredNotifications", "getByIds", "getAll", "createChannel", "deleteChannel", "listChannels", "checkPermissions", "requestPermissions", "changeExactNotificationSetting", "checkExactNotificationSetting", "removeAllListeners"];
105
+ readonly events: readonly ["localNotificationReceived", "localNotificationActionPerformed"];
106
+ };
107
+ readonly motion: {
108
+ readonly operations: readonly ["removeAllListeners"];
109
+ readonly events: readonly ["accel", "orientation"];
110
+ };
111
+ readonly network: {
112
+ readonly operations: readonly ["getStatus", "removeAllListeners"];
113
+ readonly events: readonly ["networkStatusChange"];
114
+ };
115
+ readonly preferences: {
116
+ readonly operations: readonly ["configure", "get", "set", "remove", "clear", "keys", "migrate", "removeOld"];
117
+ readonly events: readonly [];
118
+ };
119
+ readonly privacyScreen: {
120
+ readonly operations: readonly ["enable", "disable", "isEnabled"];
121
+ readonly events: readonly [];
122
+ };
123
+ readonly pushNotifications: {
124
+ readonly operations: readonly ["register", "unregister", "getDeliveredNotifications", "removeDeliveredNotifications", "removeAllDeliveredNotifications", "createChannel", "deleteChannel", "listChannels", "checkPermissions", "requestPermissions", "removeAllListeners"];
125
+ readonly events: readonly ["registration", "registrationError", "pushNotificationReceived", "pushNotificationActionPerformed"];
126
+ };
127
+ readonly screenOrientation: {
128
+ readonly operations: readonly ["orientation", "lock", "unlock", "removeAllListeners"];
129
+ readonly events: readonly ["screenOrientationChange"];
130
+ };
131
+ readonly screenReader: {
132
+ readonly operations: readonly ["isEnabled", "speak", "removeAllListeners"];
133
+ readonly events: readonly ["stateChange"];
134
+ };
135
+ readonly share: {
136
+ readonly operations: readonly ["canShare", "share"];
137
+ readonly events: readonly [];
138
+ };
139
+ readonly splashScreen: {
140
+ readonly operations: readonly ["show", "hide"];
141
+ readonly events: readonly [];
142
+ };
143
+ readonly statusBar: {
144
+ readonly operations: readonly ["setStyle", "setBackgroundColor", "show", "hide", "getInfo", "setOverlaysWebView"];
145
+ readonly events: readonly ["statusBarVisibilityChanged", "statusBarOverlayChanged"];
146
+ };
147
+ readonly systemBars: {
148
+ readonly operations: readonly ["setStyle", "show", "hide", "setAnimation"];
149
+ readonly events: readonly [];
150
+ };
151
+ readonly textZoom: {
152
+ readonly operations: readonly ["get", "getPreferred", "set"];
153
+ readonly events: readonly [];
154
+ };
155
+ readonly toast: {
156
+ readonly operations: readonly ["show"];
157
+ readonly events: readonly [];
158
+ };
159
+ };
160
+ export type NativeCapabilityName = keyof typeof NATIVE_CAPABILITY_API;
161
+ export type NativeOperation<TName extends NativeCapabilityName> = (typeof NATIVE_CAPABILITY_API)[TName]['operations'][number];
162
+ export type NativeEvent<TName extends NativeCapabilityName> = (typeof NATIVE_CAPABILITY_API)[TName]['events'][number];
163
+ /** Options passed across the shell boundary, including non-JSON native values. */
7
164
  export type NativeOptions = Readonly<Record<string, unknown>>;
8
165
  export interface NativeSubscription {
9
166
  remove(): Promise<void>;
10
167
  }
11
- /**
12
- * Base contract shared by every plugin capability. Capacitor stays private to
13
- * the shell, so this public API can be versioned independently.
14
- */
168
+ /** Capacitor stays private to the shell behind this stable public contract. */
15
169
  export interface NativePluginCapability<TOperation extends string = string, TEvent extends string = never> {
16
170
  isAvailable(): boolean;
17
171
  invoke<TResult = unknown>(operation: TOperation, options?: NativeOptions): Promise<TResult>;
18
- subscribe(event: TEvent, listener: (payload: unknown) => void): Promise<NativeSubscription>;
172
+ subscribe(event: TEvent, listener: (payload: unknown) => void, options?: NativeOptions): Promise<NativeSubscription>;
19
173
  }
20
- type ExtensibleOperation<TKnown extends string> = TKnown | (string & {});
174
+ type Capability<TName extends NativeCapabilityName> = NativePluginCapability<NativeOperation<TName>, NativeEvent<TName>>;
21
175
  export interface DeviceDetails {
22
176
  readonly model: string;
23
177
  readonly platform: 'ios' | 'android' | 'web';
24
178
  readonly osVersion: string;
25
179
  }
26
- export interface DeviceCapability extends NativePluginCapability<ExtensibleOperation<'getId' | 'getInfo' | 'getBatteryInfo' | 'getLanguageCode' | 'getLanguageTag'>> {
180
+ export interface DeviceCapability extends Capability<'device'> {
27
181
  getInfo(): Promise<DeviceDetails>;
28
182
  }
29
183
  export interface PhotoResult {
30
184
  readonly webPath?: string;
31
185
  readonly uri?: string;
32
186
  }
33
- export interface CameraCapability extends NativePluginCapability<ExtensibleOperation<'takePhoto' | 'recordVideo' | 'playVideo' | 'chooseFromGallery' | 'editPhoto' | 'editURIPhoto' | 'pickLimitedLibraryPhotos' | 'getLimitedLibraryPhotos' | 'checkPermissions' | 'requestPermissions' | 'getPhoto' | 'pickImages'>> {
187
+ export interface CameraCapability extends Capability<'camera'> {
34
188
  takePhoto(): Promise<PhotoResult>;
35
189
  choosePhoto(): Promise<PhotoResult | undefined>;
36
190
  }
37
- export interface ActionSheetCapability extends NativePluginCapability<ExtensibleOperation<'showActions'>> {
191
+ export interface ActionSheetCapability extends Capability<'actionSheet'> {
38
192
  }
39
- export interface AppLauncherCapability extends NativePluginCapability<ExtensibleOperation<'canOpenUrl' | 'openUrl'>> {
193
+ export interface AppCapability extends Capability<'app'> {
40
194
  }
41
- export interface AppCapability extends NativePluginCapability<ExtensibleOperation<'exitApp' | 'getInfo' | 'getState' | 'getLaunchUrl' | 'minimizeApp' | 'getAppLanguage' | 'toggleBackButtonHandler' | 'removeAllListeners'>, 'appStateChange' | 'pause' | 'resume' | 'appUrlOpen' | 'appRestoredResult' | 'backButton'> {
195
+ export interface AppLauncherCapability extends Capability<'appLauncher'> {
42
196
  }
43
- export interface BackgroundRunnerCapability extends NativePluginCapability<ExtensibleOperation<'checkPermissions' | 'requestPermissions' | 'removeNotificationListeners'>, 'backgroundRunnerNotificationReceived'> {
197
+ export interface BackgroundRunnerCapability extends Capability<'backgroundRunner'> {
44
198
  }
45
- export interface BarcodeScannerCapability extends NativePluginCapability<ExtensibleOperation<'scanBarcode'>> {
199
+ export interface BarcodeScannerCapability extends Capability<'barcodeScanner'> {
46
200
  }
47
- export interface BrowserCapability extends NativePluginCapability<ExtensibleOperation<'open' | 'close' | 'removeAllListeners'>, 'browserFinished' | 'browserPageLoaded'> {
201
+ export interface BrowserCapability extends Capability<'browser'> {
48
202
  }
49
- export interface CalendarCapability extends NativePluginCapability<ExtensibleOperation<'checkPermissions' | 'requestPermissions' | 'createEvent' | 'createEventInteractively' | 'modifyEvent' | 'findEvents' | 'deleteEvent' | 'listCalendars' | 'createCalendar' | 'deleteCalendar' | 'openCalendar'>> {
203
+ export interface CalendarCapability extends Capability<'calendar'> {
50
204
  }
51
- export interface ClipboardCapability extends NativePluginCapability<ExtensibleOperation<'write' | 'read'>> {
205
+ export interface ClipboardCapability extends Capability<'clipboard'> {
52
206
  }
53
- export interface ContactsCapability extends NativePluginCapability<ExtensibleOperation<'find' | 'save' | 'remove' | 'pickContact'>> {
207
+ export interface ContactsCapability extends Capability<'contacts'> {
54
208
  }
55
209
  /** Cookies is bundled in @capacitor/core. */
56
- export interface CookiesCapability extends NativePluginCapability<ExtensibleOperation<'getCookies' | 'setCookie' | 'deleteCookie' | 'clearCookies' | 'clearAllCookies'>> {
210
+ export interface CookiesCapability extends Capability<'cookies'> {
57
211
  }
58
- export interface DialogCapability extends NativePluginCapability<ExtensibleOperation<'alert' | 'prompt' | 'confirm'>> {
212
+ export interface DialogCapability extends Capability<'dialog'> {
59
213
  }
60
- export interface FileTransferCapability extends NativePluginCapability<ExtensibleOperation<'downloadFile' | 'uploadFile' | 'removeAllListeners'>, 'progress'> {
214
+ export interface FileTransferCapability extends Capability<'fileTransfer'> {
61
215
  }
62
- export interface FileViewerCapability extends NativePluginCapability<ExtensibleOperation<'openDocumentFromLocalPath' | 'openDocumentFromResources' | 'openDocumentFromUrl' | 'previewMediaContentFromLocalPath' | 'previewMediaContentFromResources' | 'previewMediaContentFromUrl'>> {
216
+ export interface FileViewerCapability extends Capability<'fileViewer'> {
63
217
  }
64
- export interface FilesystemCapability extends NativePluginCapability<ExtensibleOperation<'checkPermissions' | 'requestPermissions' | 'readFile' | 'writeFile' | 'appendFile' | 'deleteFile' | 'mkdir' | 'rmdir' | 'readdir' | 'getUri' | 'stat' | 'rename' | 'copy' | 'downloadFile'>, 'progress'> {
218
+ export interface FilesystemCapability extends Capability<'filesystem'> {
65
219
  }
66
- export interface GeolocationCapability extends NativePluginCapability<ExtensibleOperation<'getCurrentPosition' | 'watchPosition' | 'clearWatch' | 'checkPermissions' | 'requestPermissions'>> {
220
+ export interface GeolocationCapability extends Capability<'geolocation'> {
67
221
  }
68
- /** Google Maps creates stateful map instances behind this same capability boundary. */
69
- export interface GoogleMapsCapability extends NativePluginCapability<ExtensibleOperation<'create' | 'destroy' | 'setCamera' | 'addMarker' | 'addMarkers' | 'removeMarker' | 'removeMarkers'>> {
222
+ /** Google Maps keeps stateful map instances inside the shell. */
223
+ export interface GoogleMapsCapability extends Capability<'googleMaps'> {
70
224
  }
71
- export interface HapticsCapability extends NativePluginCapability<ExtensibleOperation<'impact' | 'notification' | 'vibrate' | 'selectionStart' | 'selectionChanged' | 'selectionEnd'>> {
225
+ export interface HapticsCapability extends Capability<'haptics'> {
72
226
  }
73
- export interface HealthFitnessCapability extends NativePluginCapability<ExtensibleOperation<'isAvailable' | 'requestAuthorization' | 'checkAuthorization' | 'query' | 'save' | 'delete' | 'setBackgroundJob' | 'disableBackgroundJob'>> {
227
+ export interface HealthFitnessCapability extends Capability<'healthFitness'> {
74
228
  }
75
229
  /** HTTP is bundled in @capacitor/core. */
76
- export interface HttpCapability extends NativePluginCapability<ExtensibleOperation<'request' | 'get' | 'post' | 'put' | 'patch' | 'delete' | 'setCookie' | 'clearCookies' | 'deleteCookie' | 'clearAllCookies'>> {
230
+ export interface HttpCapability extends Capability<'http'> {
77
231
  }
78
- export interface InAppBrowserCapability extends NativePluginCapability<ExtensibleOperation<'openInWebView' | 'openInSystemBrowser' | 'openInExternalBrowser' | 'close' | 'removeAllListeners'>, 'browserPageLoaded' | 'browserPageNavigationCompleted' | 'browserClosed' | 'urlChange'> {
232
+ export interface InAppBrowserCapability extends Capability<'inAppBrowser'> {
79
233
  }
80
- export interface KeyboardCapability extends NativePluginCapability<ExtensibleOperation<'show' | 'hide' | 'setAccessoryBarVisible' | 'setScroll' | 'setResizeMode' | 'getResizeMode' | 'removeAllListeners'>, 'keyboardWillShow' | 'keyboardDidShow' | 'keyboardWillHide' | 'keyboardDidHide'> {
234
+ export interface KeyboardCapability extends Capability<'keyboard'> {
81
235
  }
82
236
  /** Experimental Capacitor plugin. Always call isAvailable before invoking it. */
83
- export interface LocalLlmCapability extends NativePluginCapability<ExtensibleOperation<'systemAvailability' | 'download' | 'prompt' | 'endSession' | 'generateImage' | 'warmup' | 'removeAllListeners'>, 'systemAvailabilityChange'> {
237
+ export interface LocalLlmCapability extends Capability<'localLlm'> {
84
238
  }
85
- export interface LocalNotificationsCapability extends NativePluginCapability<ExtensibleOperation<'schedule' | 'update' | 'getPending' | 'registerActionTypes' | 'cancel' | 'cancelAll' | 'areEnabled' | 'getDeliveredNotifications' | 'removeDeliveredNotifications' | 'removeDeliveredNotificationsById' | 'removeAllDeliveredNotifications' | 'getByIds' | 'getAll' | 'createChannel' | 'deleteChannel' | 'listChannels' | 'checkPermissions' | 'requestPermissions' | 'changeExactNotificationSetting' | 'checkExactNotificationSetting' | 'removeAllListeners'>, 'localNotificationReceived' | 'localNotificationActionPerformed'> {
239
+ export interface LocalNotificationsCapability extends Capability<'localNotifications'> {
86
240
  }
87
- export interface MotionCapability extends NativePluginCapability<ExtensibleOperation<'removeAllListeners'>, 'accel' | 'orientation'> {
241
+ export interface MotionCapability extends Capability<'motion'> {
88
242
  }
89
- export interface NetworkCapability extends NativePluginCapability<ExtensibleOperation<'getStatus' | 'removeAllListeners'>, 'networkStatusChange'> {
243
+ export interface NetworkCapability extends Capability<'network'> {
90
244
  }
91
- export interface PreferencesCapability extends NativePluginCapability<ExtensibleOperation<'configure' | 'get' | 'set' | 'remove' | 'clear' | 'keys' | 'migrate' | 'removeOld'>> {
245
+ export interface PreferencesCapability extends Capability<'preferences'> {
92
246
  }
93
- export interface PrivacyScreenCapability extends NativePluginCapability<ExtensibleOperation<'enable' | 'disable' | 'isEnabled'>> {
247
+ export interface PrivacyScreenCapability extends Capability<'privacyScreen'> {
94
248
  }
95
- export interface PushNotificationsCapability extends NativePluginCapability<ExtensibleOperation<'register' | 'unregister' | 'getDeliveredNotifications' | 'removeDeliveredNotifications' | 'removeAllDeliveredNotifications' | 'createChannel' | 'deleteChannel' | 'listChannels' | 'checkPermissions' | 'requestPermissions' | 'removeAllListeners'>, 'registration' | 'registrationError' | 'pushNotificationReceived' | 'pushNotificationActionPerformed'> {
249
+ export interface PushNotificationsCapability extends Capability<'pushNotifications'> {
96
250
  }
97
- export interface ScreenOrientationCapability extends NativePluginCapability<ExtensibleOperation<'orientation' | 'lock' | 'unlock' | 'removeAllListeners'>, 'screenOrientationChange'> {
251
+ export interface ScreenOrientationCapability extends Capability<'screenOrientation'> {
98
252
  }
99
- export interface ScreenReaderCapability extends NativePluginCapability<ExtensibleOperation<'isEnabled' | 'speak' | 'removeAllListeners'>, 'stateChange'> {
253
+ export interface ScreenReaderCapability extends Capability<'screenReader'> {
100
254
  }
101
- export interface ShareCapability extends NativePluginCapability<ExtensibleOperation<'canShare' | 'share'>> {
255
+ export interface ShareCapability extends Capability<'share'> {
102
256
  }
103
- export interface SplashScreenCapability extends NativePluginCapability<ExtensibleOperation<'show' | 'hide'>> {
257
+ export interface SplashScreenCapability extends Capability<'splashScreen'> {
104
258
  }
105
- export interface StatusBarCapability extends NativePluginCapability<ExtensibleOperation<'setStyle' | 'setBackgroundColor' | 'show' | 'hide' | 'getInfo' | 'setOverlaysWebView'>, 'statusBarVisibilityChanged' | 'statusBarOverlayChanged'> {
259
+ export interface StatusBarCapability extends Capability<'statusBar'> {
106
260
  }
107
261
  /** System Bars is bundled in @capacitor/core and supersedes Status Bar for edge-to-edge layouts. */
108
- export interface SystemBarsCapability extends NativePluginCapability<ExtensibleOperation<'setStyle' | 'show' | 'hide' | 'setAnimation'>> {
262
+ export interface SystemBarsCapability extends Capability<'systemBars'> {
109
263
  }
110
- export interface TextZoomCapability extends NativePluginCapability<ExtensibleOperation<'get' | 'getPreferred' | 'set'>> {
264
+ export interface TextZoomCapability extends Capability<'textZoom'> {
111
265
  }
112
- export interface ToastCapability extends NativePluginCapability<ExtensibleOperation<'show'>> {
266
+ export interface ToastCapability extends Capability<'toast'> {
113
267
  }
114
268
  export interface NativeCapabilities {
115
269
  /** Version 1 remains compatible with the original Device and Camera contract. */
package/dist/native.js CHANGED
@@ -1,4 +1,314 @@
1
1
  import { InjectionToken, inject } from '@angular/core';
2
+ /**
3
+ * Superficie oficial que Open Mova expone para cada plugin de Capacitor.
4
+ * La demo consume también este catálogo para no mantener una segunda lista.
5
+ */
6
+ export const NATIVE_CAPABILITY_API = {
7
+ actionSheet: { operations: ['showActions'], events: [] },
8
+ app: {
9
+ operations: [
10
+ 'exitApp',
11
+ 'getInfo',
12
+ 'getState',
13
+ 'getLaunchUrl',
14
+ 'minimizeApp',
15
+ 'getAppLanguage',
16
+ 'toggleBackButtonHandler',
17
+ 'removeAllListeners',
18
+ ],
19
+ events: ['appStateChange', 'pause', 'resume', 'appUrlOpen', 'appRestoredResult', 'backButton'],
20
+ },
21
+ appLauncher: { operations: ['canOpenUrl', 'openUrl'], events: [] },
22
+ backgroundRunner: {
23
+ operations: [
24
+ 'checkPermissions',
25
+ 'requestPermissions',
26
+ 'dispatchEvent',
27
+ 'removeNotificationListeners',
28
+ ],
29
+ events: ['backgroundRunnerNotificationReceived'],
30
+ },
31
+ barcodeScanner: { operations: ['scanBarcode'], events: [] },
32
+ browser: {
33
+ operations: ['open', 'close', 'removeAllListeners'],
34
+ events: ['browserFinished', 'browserPageLoaded'],
35
+ },
36
+ calendar: {
37
+ operations: [
38
+ 'checkPermissions',
39
+ 'requestPermissions',
40
+ 'createEvent',
41
+ 'createEventInteractively',
42
+ 'modifyEvent',
43
+ 'findEvents',
44
+ 'deleteEvent',
45
+ 'listCalendars',
46
+ 'createCalendar',
47
+ 'deleteCalendar',
48
+ 'openCalendar',
49
+ ],
50
+ events: [],
51
+ },
52
+ camera: {
53
+ operations: [
54
+ 'takePhoto',
55
+ 'recordVideo',
56
+ 'playVideo',
57
+ 'chooseFromGallery',
58
+ 'editPhoto',
59
+ 'editURIPhoto',
60
+ 'pickLimitedLibraryPhotos',
61
+ 'getLimitedLibraryPhotos',
62
+ 'checkPermissions',
63
+ 'requestPermissions',
64
+ 'getPhoto',
65
+ 'pickImages',
66
+ ],
67
+ events: [],
68
+ },
69
+ clipboard: { operations: ['write', 'read'], events: [] },
70
+ contacts: { operations: ['find', 'save', 'remove', 'pickContact'], events: [] },
71
+ cookies: {
72
+ operations: ['getCookies', 'setCookie', 'deleteCookie', 'clearCookies', 'clearAllCookies'],
73
+ events: [],
74
+ },
75
+ device: {
76
+ operations: ['getId', 'getInfo', 'getBatteryInfo', 'getLanguageCode', 'getLanguageTag'],
77
+ events: [],
78
+ },
79
+ dialog: { operations: ['alert', 'prompt', 'confirm'], events: [] },
80
+ fileTransfer: {
81
+ operations: ['downloadFile', 'uploadFile', 'removeAllListeners'],
82
+ events: ['progress'],
83
+ },
84
+ fileViewer: {
85
+ operations: [
86
+ 'openDocumentFromLocalPath',
87
+ 'openDocumentFromResources',
88
+ 'openDocumentFromUrl',
89
+ 'previewMediaContentFromLocalPath',
90
+ 'previewMediaContentFromResources',
91
+ 'previewMediaContentFromUrl',
92
+ ],
93
+ events: [],
94
+ },
95
+ filesystem: {
96
+ operations: [
97
+ 'checkPermissions',
98
+ 'requestPermissions',
99
+ 'readFile',
100
+ 'readFileInChunks',
101
+ 'writeFile',
102
+ 'appendFile',
103
+ 'deleteFile',
104
+ 'mkdir',
105
+ 'rmdir',
106
+ 'readdir',
107
+ 'getUri',
108
+ 'stat',
109
+ 'rename',
110
+ 'copy',
111
+ 'downloadFile',
112
+ 'removeAllListeners',
113
+ ],
114
+ events: ['progress'],
115
+ },
116
+ geolocation: {
117
+ operations: [
118
+ 'getCurrentPosition',
119
+ 'watchPosition',
120
+ 'clearWatch',
121
+ 'checkPermissions',
122
+ 'requestPermissions',
123
+ ],
124
+ events: [],
125
+ },
126
+ googleMaps: {
127
+ operations: [
128
+ 'create',
129
+ 'enableTouch',
130
+ 'disableTouch',
131
+ 'enableClustering',
132
+ 'disableClustering',
133
+ 'addTileOverlay',
134
+ 'removeTileOverlay',
135
+ 'addMarker',
136
+ 'addMarkers',
137
+ 'removeMarker',
138
+ 'removeMarkers',
139
+ 'addPolygons',
140
+ 'removePolygons',
141
+ 'addCircles',
142
+ 'removeCircles',
143
+ 'addPolylines',
144
+ 'removePolylines',
145
+ 'destroy',
146
+ 'setCamera',
147
+ 'getMapType',
148
+ 'setMapType',
149
+ 'enableIndoorMaps',
150
+ 'enableTrafficLayer',
151
+ 'enableAccessibilityElements',
152
+ 'enableCurrentLocation',
153
+ 'setPadding',
154
+ 'getMapBounds',
155
+ 'fitBounds',
156
+ 'removeAllMapListeners',
157
+ ],
158
+ events: [
159
+ 'boundsChanged',
160
+ 'cameraIdle',
161
+ 'cameraMoveStarted',
162
+ 'clusterClick',
163
+ 'clusterInfoWindowClick',
164
+ 'infoWindowClick',
165
+ 'mapClick',
166
+ 'markerClick',
167
+ 'polygonClick',
168
+ 'circleClick',
169
+ 'polylineClick',
170
+ 'markerDragStart',
171
+ 'markerDrag',
172
+ 'markerDragEnd',
173
+ 'myLocationButtonClick',
174
+ 'myLocationClick',
175
+ ],
176
+ },
177
+ haptics: {
178
+ operations: [
179
+ 'impact',
180
+ 'notification',
181
+ 'vibrate',
182
+ 'selectionStart',
183
+ 'selectionChanged',
184
+ 'selectionEnd',
185
+ ],
186
+ events: [],
187
+ },
188
+ healthFitness: {
189
+ operations: [
190
+ 'requestHealthPermissions',
191
+ 'getData',
192
+ 'getWorkoutData',
193
+ 'writeData',
194
+ 'getLastRecord',
195
+ 'setBackgroundJob',
196
+ 'deleteBackgroundJob',
197
+ 'listBackgroundJobs',
198
+ 'updateBackgroundJob',
199
+ 'disconnectFromHealthConnect',
200
+ 'openHealthConnect',
201
+ ],
202
+ events: [],
203
+ },
204
+ http: { operations: ['request', 'get', 'post', 'put', 'patch', 'delete'], events: [] },
205
+ inAppBrowser: {
206
+ operations: [
207
+ 'openInWebView',
208
+ 'openInSystemBrowser',
209
+ 'openInExternalBrowser',
210
+ 'close',
211
+ 'removeAllListeners',
212
+ ],
213
+ events: ['browserPageLoaded', 'browserPageNavigationCompleted', 'browserClosed'],
214
+ },
215
+ keyboard: {
216
+ operations: [
217
+ 'show',
218
+ 'hide',
219
+ 'setAccessoryBarVisible',
220
+ 'setScroll',
221
+ 'setStyle',
222
+ 'setResizeMode',
223
+ 'getResizeMode',
224
+ 'removeAllListeners',
225
+ ],
226
+ events: ['keyboardWillShow', 'keyboardDidShow', 'keyboardWillHide', 'keyboardDidHide'],
227
+ },
228
+ localLlm: {
229
+ operations: [
230
+ 'systemAvailability',
231
+ 'download',
232
+ 'prompt',
233
+ 'endSession',
234
+ 'generateImage',
235
+ 'warmup',
236
+ 'removeAllListeners',
237
+ ],
238
+ events: ['systemAvailabilityChange'],
239
+ },
240
+ localNotifications: {
241
+ operations: [
242
+ 'schedule',
243
+ 'update',
244
+ 'getPending',
245
+ 'registerActionTypes',
246
+ 'cancel',
247
+ 'cancelAll',
248
+ 'areEnabled',
249
+ 'getDeliveredNotifications',
250
+ 'removeDeliveredNotifications',
251
+ 'removeDeliveredNotificationsById',
252
+ 'removeAllDeliveredNotifications',
253
+ 'getByIds',
254
+ 'getAll',
255
+ 'createChannel',
256
+ 'deleteChannel',
257
+ 'listChannels',
258
+ 'checkPermissions',
259
+ 'requestPermissions',
260
+ 'changeExactNotificationSetting',
261
+ 'checkExactNotificationSetting',
262
+ 'removeAllListeners',
263
+ ],
264
+ events: ['localNotificationReceived', 'localNotificationActionPerformed'],
265
+ },
266
+ motion: { operations: ['removeAllListeners'], events: ['accel', 'orientation'] },
267
+ network: { operations: ['getStatus', 'removeAllListeners'], events: ['networkStatusChange'] },
268
+ preferences: {
269
+ operations: ['configure', 'get', 'set', 'remove', 'clear', 'keys', 'migrate', 'removeOld'],
270
+ events: [],
271
+ },
272
+ privacyScreen: { operations: ['enable', 'disable', 'isEnabled'], events: [] },
273
+ pushNotifications: {
274
+ operations: [
275
+ 'register',
276
+ 'unregister',
277
+ 'getDeliveredNotifications',
278
+ 'removeDeliveredNotifications',
279
+ 'removeAllDeliveredNotifications',
280
+ 'createChannel',
281
+ 'deleteChannel',
282
+ 'listChannels',
283
+ 'checkPermissions',
284
+ 'requestPermissions',
285
+ 'removeAllListeners',
286
+ ],
287
+ events: [
288
+ 'registration',
289
+ 'registrationError',
290
+ 'pushNotificationReceived',
291
+ 'pushNotificationActionPerformed',
292
+ ],
293
+ },
294
+ screenOrientation: {
295
+ operations: ['orientation', 'lock', 'unlock', 'removeAllListeners'],
296
+ events: ['screenOrientationChange'],
297
+ },
298
+ screenReader: {
299
+ operations: ['isEnabled', 'speak', 'removeAllListeners'],
300
+ events: ['stateChange'],
301
+ },
302
+ share: { operations: ['canShare', 'share'], events: [] },
303
+ splashScreen: { operations: ['show', 'hide'], events: [] },
304
+ statusBar: {
305
+ operations: ['setStyle', 'setBackgroundColor', 'show', 'hide', 'getInfo', 'setOverlaysWebView'],
306
+ events: ['statusBarVisibilityChanged', 'statusBarOverlayChanged'],
307
+ },
308
+ systemBars: { operations: ['setStyle', 'show', 'hide', 'setAnimation'], events: [] },
309
+ textZoom: { operations: ['get', 'getPreferred', 'set'], events: [] },
310
+ toast: { operations: ['show'], events: [] },
311
+ };
2
312
  // Shell y remotos deben compartir una sola instancia de este token.
3
313
  export const NATIVE_CAPABILITIES = new InjectionToken('Open Mova native capabilities');
4
314
  export function injectNativeCapabilities() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mova/core",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Contratos y utilidades Angular compartidas de Open Mova",
5
5
  "license": "MIT",
6
6
  "author": "Open Mova contributors",
@@ -42,7 +42,9 @@
42
42
  },
43
43
  "scripts": {
44
44
  "build": "tsc -p tsconfig.json",
45
- "typecheck": "tsc -p tsconfig.json --noEmit"
45
+ "typecheck": "tsc -p tsconfig.json --noEmit",
46
+ "test": "npm run build && npm run test:unit",
47
+ "test:unit": "node --test test/*.test.mjs"
46
48
  },
47
49
  "peerDependencies": {
48
50
  "@angular/core": "^21.2.23"