@flighthq/host-capacitor 0.1.0
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/capacitorApp.d.ts +4 -0
- package/dist/capacitorApp.d.ts.map +1 -0
- package/dist/capacitorApp.js +172 -0
- package/dist/capacitorApp.js.map +1 -0
- package/dist/capacitorClipboard.d.ts +4 -0
- package/dist/capacitorClipboard.d.ts.map +1 -0
- package/dist/capacitorClipboard.js +127 -0
- package/dist/capacitorClipboard.js.map +1 -0
- package/dist/capacitorConnectivity.d.ts +4 -0
- package/dist/capacitorConnectivity.d.ts.map +1 -0
- package/dist/capacitorConnectivity.js +69 -0
- package/dist/capacitorConnectivity.js.map +1 -0
- package/dist/capacitorDevice.d.ts +4 -0
- package/dist/capacitorDevice.d.ts.map +1 -0
- package/dist/capacitorDevice.js +100 -0
- package/dist/capacitorDevice.js.map +1 -0
- package/dist/capacitorDialog.d.ts +4 -0
- package/dist/capacitorDialog.d.ts.map +1 -0
- package/dist/capacitorDialog.js +39 -0
- package/dist/capacitorDialog.js.map +1 -0
- package/dist/capacitorFileSystem.d.ts +4 -0
- package/dist/capacitorFileSystem.d.ts.map +1 -0
- package/dist/capacitorFileSystem.js +216 -0
- package/dist/capacitorFileSystem.js.map +1 -0
- package/dist/capacitorGeolocation.d.ts +4 -0
- package/dist/capacitorGeolocation.d.ts.map +1 -0
- package/dist/capacitorGeolocation.js +104 -0
- package/dist/capacitorGeolocation.js.map +1 -0
- package/dist/capacitorHaptics.d.ts +4 -0
- package/dist/capacitorHaptics.d.ts.map +1 -0
- package/dist/capacitorHaptics.js +56 -0
- package/dist/capacitorHaptics.js.map +1 -0
- package/dist/capacitorKeyboard.d.ts +4 -0
- package/dist/capacitorKeyboard.d.ts.map +1 -0
- package/dist/capacitorKeyboard.js +89 -0
- package/dist/capacitorKeyboard.js.map +1 -0
- package/dist/capacitorModule.d.ts +310 -0
- package/dist/capacitorModule.d.ts.map +1 -0
- package/dist/capacitorModule.js +31 -0
- package/dist/capacitorModule.js.map +1 -0
- package/dist/capacitorNotification.d.ts +4 -0
- package/dist/capacitorNotification.d.ts.map +1 -0
- package/dist/capacitorNotification.js +172 -0
- package/dist/capacitorNotification.js.map +1 -0
- package/dist/capacitorRegister.d.ts +3 -0
- package/dist/capacitorRegister.d.ts.map +1 -0
- package/dist/capacitorRegister.js +52 -0
- package/dist/capacitorRegister.js.map +1 -0
- package/dist/capacitorShare.d.ts +4 -0
- package/dist/capacitorShare.d.ts.map +1 -0
- package/dist/capacitorShare.js +66 -0
- package/dist/capacitorShare.js.map +1 -0
- package/dist/capacitorStatusBar.d.ts +4 -0
- package/dist/capacitorStatusBar.d.ts.map +1 -0
- package/dist/capacitorStatusBar.js +80 -0
- package/dist/capacitorStatusBar.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/package.json +49 -0
- package/src/capacitorApp.test.ts +81 -0
- package/src/capacitorClipboard.test.ts +71 -0
- package/src/capacitorConnectivity.test.ts +64 -0
- package/src/capacitorDevice.test.ts +99 -0
- package/src/capacitorDialog.test.ts +50 -0
- package/src/capacitorFileSystem.test.ts +88 -0
- package/src/capacitorGeolocation.test.ts +75 -0
- package/src/capacitorHaptics.test.ts +75 -0
- package/src/capacitorKeyboard.test.ts +89 -0
- package/src/capacitorNotification.test.ts +95 -0
- package/src/capacitorRegister.test.ts +104 -0
- package/src/capacitorShare.test.ts +68 -0
- package/src/capacitorStatusBar.test.ts +66 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Maps Flight's ShareBackend onto Capacitor's `@capacitor/share`. `share`/`shareWithResult` are async
|
|
2
|
+
// and map directly; a user cancel rejects, resolving false / a dismissed ShareResult rather than
|
|
3
|
+
// throwing. Capacitor's `canShare` is async while the ShareBackend availability probes (isAvailable,
|
|
4
|
+
// canShare) are synchronous, so the adapter prefetches the availability boolean once at construction and
|
|
5
|
+
// the sync probes read it — reporting false until that first probe resolves. Portable ShareFile
|
|
6
|
+
// descriptors carry data URLs, which Capacitor's file-URI `files` field cannot accept, so only
|
|
7
|
+
// title/text/url cross; a content that is only files reports canShare false.
|
|
8
|
+
export function createCapacitorShareBackend(capacitor) {
|
|
9
|
+
const share = capacitor.share;
|
|
10
|
+
// Sync availability probes over async Capacitor: prefetch canShare once and cache the boolean.
|
|
11
|
+
let cachedAvailable = false;
|
|
12
|
+
share
|
|
13
|
+
.canShare()
|
|
14
|
+
.then((result) => {
|
|
15
|
+
cachedAvailable = result.value;
|
|
16
|
+
})
|
|
17
|
+
.catch(() => {
|
|
18
|
+
/* leave false */
|
|
19
|
+
});
|
|
20
|
+
return {
|
|
21
|
+
isAvailable() {
|
|
22
|
+
return cachedAvailable;
|
|
23
|
+
},
|
|
24
|
+
canShare(content) {
|
|
25
|
+
return cachedAvailable && hasShareableText(content);
|
|
26
|
+
},
|
|
27
|
+
async share(content, options) {
|
|
28
|
+
if (!hasShareableText(content))
|
|
29
|
+
return false;
|
|
30
|
+
try {
|
|
31
|
+
await share.share({
|
|
32
|
+
title: content.title,
|
|
33
|
+
text: content.text,
|
|
34
|
+
url: content.url,
|
|
35
|
+
dialogTitle: options?.chooserTitle,
|
|
36
|
+
});
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
async shareWithResult(content, options) {
|
|
44
|
+
if (!hasShareableText(content))
|
|
45
|
+
return { completed: false, activityType: null, dismissed: false };
|
|
46
|
+
try {
|
|
47
|
+
const result = await share.share({
|
|
48
|
+
title: content.title,
|
|
49
|
+
text: content.text,
|
|
50
|
+
url: content.url,
|
|
51
|
+
dialogTitle: options?.chooserTitle,
|
|
52
|
+
});
|
|
53
|
+
return { completed: true, activityType: result.activityType ?? null, dismissed: false };
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// A rejected share is a user dismissal, not a programmer error.
|
|
57
|
+
return { completed: false, activityType: null, dismissed: true };
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// Capacitor's share sheet needs at least one of title/text/url; data-URL files are not expressible.
|
|
63
|
+
function hasShareableText(content) {
|
|
64
|
+
return content.title !== undefined || content.text !== undefined || content.url !== undefined;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=capacitorShare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capacitorShare.js","sourceRoot":"","sources":["../src/capacitorShare.ts"],"names":[],"mappings":"AAIA,sGAAsG;AACtG,iGAAiG;AACjG,qGAAqG;AACrG,yGAAyG;AACzG,gGAAgG;AAChG,+FAA+F;AAC/F,6EAA6E;AAC7E,MAAM,UAAU,2BAA2B,CAAC,SAAuB;IACjE,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;IAC9B,+FAA+F;IAC/F,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,KAAK;SACF,QAAQ,EAAE;SACV,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QACf,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC;IACjC,CAAC,CAAC;SACD,KAAK,CAAC,GAAG,EAAE;QACV,iBAAiB;IACnB,CAAC,CAAC,CAAC;IACL,OAAO;QACL,WAAW;YACT,OAAO,eAAe,CAAC;QACzB,CAAC;QACD,QAAQ,CAAC,OAAO;YACd,OAAO,eAAe,IAAI,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACtD,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO;YAC1B,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC7C,IAAI,CAAC;gBACH,MAAM,KAAK,CAAC,KAAK,CAAC;oBAChB,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,GAAG,EAAE,OAAO,CAAC,GAAG;oBAChB,WAAW,EAAE,OAAO,EAAE,YAAY;iBACnC,CAAC,CAAC;gBACH,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,KAAK,CAAC,eAAe,CAAC,OAAO,EAAE,OAAO;YACpC,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;gBAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;YAClG,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC;oBAC/B,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,GAAG,EAAE,OAAO,CAAC,GAAG;oBAChB,WAAW,EAAE,OAAO,EAAE,YAAY;iBACnC,CAAC,CAAC;gBACH,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;YAC1F,CAAC;YAAC,MAAM,CAAC;gBACP,gEAAgE;gBAChE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;YACnE,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,oGAAoG;AACpG,SAAS,gBAAgB,CAAC,OAA+B;IACvD,OAAO,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,CAAC;AAChG,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capacitorStatusBar.d.ts","sourceRoot":"","sources":["../src/capacitorStatusBar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAiC,MAAM,iBAAiB,CAAC;AAEvF,OAAO,KAAK,EAAE,YAAY,EAAgC,MAAM,mBAAmB,CAAC;AAQpF,wBAAgB,+BAA+B,CAAC,SAAS,EAAE,YAAY,GAAG,gBAAgB,CAyCzF"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Maps Flight's StatusBarBackend onto Capacitor's `@capacitor/status-bar`. The setters are async and fire
|
|
2
|
+
// fire-and-forget: setStyle, setBackgroundColor (a packed RGBA int → a `#RRGGBB` hex string, dropping
|
|
3
|
+
// alpha the plugin ignores), setVisible (→ show/hide), and setOverlaysContent (→ setOverlaysWebView).
|
|
4
|
+
// getInfo is a synchronous snapshot while Capacitor's getInfo is async, so it is served from a value
|
|
5
|
+
// prefetched once at construction (default until it resolves). Capacitor emits no status-bar change
|
|
6
|
+
// event, so subscribe is inert.
|
|
7
|
+
export function createCapacitorStatusBarBackend(capacitor) {
|
|
8
|
+
const statusBar = capacitor.statusBar;
|
|
9
|
+
// Sync getInfo over async Capacitor: prefetch the snapshot once and cache it.
|
|
10
|
+
let cachedInfo = null;
|
|
11
|
+
statusBar
|
|
12
|
+
.getInfo()
|
|
13
|
+
.then((info) => {
|
|
14
|
+
cachedInfo = info;
|
|
15
|
+
})
|
|
16
|
+
.catch(() => {
|
|
17
|
+
/* leave null → defaults */
|
|
18
|
+
});
|
|
19
|
+
return {
|
|
20
|
+
getInfo(out) {
|
|
21
|
+
const info = cachedInfo;
|
|
22
|
+
out.color = info?.color !== undefined ? hexToRgba(info.color) : 0;
|
|
23
|
+
// Capacitor does not report a status-bar height; -1 sentinel per the contract.
|
|
24
|
+
out.height = -1;
|
|
25
|
+
out.overlaysContent = info?.overlays ?? false;
|
|
26
|
+
out.style = info !== null ? toStatusBarStyle(info.style) : 'default';
|
|
27
|
+
out.visible = info?.visible ?? true;
|
|
28
|
+
return out;
|
|
29
|
+
},
|
|
30
|
+
setBackgroundColor(color) {
|
|
31
|
+
statusBar.setBackgroundColor({ color: rgbaToHex(color) }).catch(() => { });
|
|
32
|
+
},
|
|
33
|
+
setOverlaysContent(overlay) {
|
|
34
|
+
statusBar.setOverlaysWebView({ overlay }).catch(() => { });
|
|
35
|
+
},
|
|
36
|
+
setStyle(style) {
|
|
37
|
+
statusBar.setStyle({ style: toCapacitorStyle(style) }).catch(() => { });
|
|
38
|
+
},
|
|
39
|
+
setVisible(visible) {
|
|
40
|
+
if (visible)
|
|
41
|
+
statusBar.show().catch(() => { });
|
|
42
|
+
else
|
|
43
|
+
statusBar.hide().catch(() => { });
|
|
44
|
+
},
|
|
45
|
+
subscribe() {
|
|
46
|
+
// Capacitor emits no status-bar change event; inert unsubscribe.
|
|
47
|
+
return () => { };
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// Flight status-bar style ('light' | 'dark' | 'default') → Capacitor Style ('Light' | 'Dark' | 'Default').
|
|
52
|
+
function toCapacitorStyle(style) {
|
|
53
|
+
if (style === 'light')
|
|
54
|
+
return 'Light';
|
|
55
|
+
if (style === 'dark')
|
|
56
|
+
return 'Dark';
|
|
57
|
+
return 'Default';
|
|
58
|
+
}
|
|
59
|
+
function toStatusBarStyle(style) {
|
|
60
|
+
if (style === 'Light')
|
|
61
|
+
return 'light';
|
|
62
|
+
if (style === 'Dark')
|
|
63
|
+
return 'dark';
|
|
64
|
+
return 'default';
|
|
65
|
+
}
|
|
66
|
+
// A packed RGBA integer (0xRRGGBBAA) → a `#RRGGBB` hex string; Capacitor's color takes no alpha channel.
|
|
67
|
+
function rgbaToHex(color) {
|
|
68
|
+
const rgb = (color >>> 8) & 0xffffff;
|
|
69
|
+
return `#${rgb.toString(16).padStart(6, '0')}`;
|
|
70
|
+
}
|
|
71
|
+
// A `#RRGGBB` (or `#RRGGBBAA`) hex string → a packed RGBA integer (0xRRGGBBAA), opaque when no alpha.
|
|
72
|
+
function hexToRgba(hex) {
|
|
73
|
+
const digits = hex.replace(/^#/, '');
|
|
74
|
+
if (digits.length === 8)
|
|
75
|
+
return Number.parseInt(digits, 16) >>> 0;
|
|
76
|
+
if (digits.length === 6)
|
|
77
|
+
return ((Number.parseInt(digits, 16) << 8) | 0xff) >>> 0;
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=capacitorStatusBar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capacitorStatusBar.js","sourceRoot":"","sources":["../src/capacitorStatusBar.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export * from './capacitorApp';
|
|
2
|
+
export * from './capacitorClipboard';
|
|
3
|
+
export * from './capacitorConnectivity';
|
|
4
|
+
export * from './capacitorDevice';
|
|
5
|
+
export * from './capacitorDialog';
|
|
6
|
+
export * from './capacitorFileSystem';
|
|
7
|
+
export * from './capacitorGeolocation';
|
|
8
|
+
export * from './capacitorHaptics';
|
|
9
|
+
export * from './capacitorKeyboard';
|
|
10
|
+
export * from './capacitorModule';
|
|
11
|
+
export * from './capacitorNotification';
|
|
12
|
+
export * from './capacitorRegister';
|
|
13
|
+
export * from './capacitorShare';
|
|
14
|
+
export * from './capacitorStatusBar';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export * from './capacitorApp';
|
|
2
|
+
export * from './capacitorClipboard';
|
|
3
|
+
export * from './capacitorConnectivity';
|
|
4
|
+
export * from './capacitorDevice';
|
|
5
|
+
export * from './capacitorDialog';
|
|
6
|
+
export * from './capacitorFileSystem';
|
|
7
|
+
export * from './capacitorGeolocation';
|
|
8
|
+
export * from './capacitorHaptics';
|
|
9
|
+
export * from './capacitorKeyboard';
|
|
10
|
+
export * from './capacitorModule';
|
|
11
|
+
export * from './capacitorNotification';
|
|
12
|
+
export * from './capacitorRegister';
|
|
13
|
+
export * from './capacitorShare';
|
|
14
|
+
export * from './capacitorStatusBar';
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flighthq/host-capacitor",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist",
|
|
15
|
+
"src/**/*.test.ts",
|
|
16
|
+
"!dist/**/*.test.js",
|
|
17
|
+
"!dist/**/*.test.d.ts",
|
|
18
|
+
"!dist/**/*.test.js.map",
|
|
19
|
+
"!dist/**/*.test.d.ts.map"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc -b",
|
|
23
|
+
"clean": "tsc -b --clean",
|
|
24
|
+
"test": "vitest run --config vitest.config.ts",
|
|
25
|
+
"test:watch": "vitest --watch --config vitest.config.ts",
|
|
26
|
+
"prepack": "npm run clean && npm run clean:dist && npm run build",
|
|
27
|
+
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@flighthq/app": "0.1.0",
|
|
31
|
+
"@flighthq/clipboard": "0.1.0",
|
|
32
|
+
"@flighthq/connectivity": "0.1.0",
|
|
33
|
+
"@flighthq/device": "0.1.0",
|
|
34
|
+
"@flighthq/dialog": "0.1.0",
|
|
35
|
+
"@flighthq/filesystem": "0.1.0",
|
|
36
|
+
"@flighthq/geolocation": "0.1.0",
|
|
37
|
+
"@flighthq/haptics": "0.1.0",
|
|
38
|
+
"@flighthq/keyboard": "0.1.0",
|
|
39
|
+
"@flighthq/notification": "0.1.0",
|
|
40
|
+
"@flighthq/share": "0.1.0",
|
|
41
|
+
"@flighthq/statusbar": "0.1.0",
|
|
42
|
+
"@flighthq/types": "0.1.0"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"typescript": "^5.3.0"
|
|
46
|
+
},
|
|
47
|
+
"description": "Capacitor (mobile) host backend: registers Capacitor plugin implementations of Flight's app/clipboard/dialog/notification/share/filesystem/geolocation/haptics/connectivity/device/statusbar/keyboard seams over an injected CapacitorApi",
|
|
48
|
+
"sideEffects": false
|
|
49
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { createCapacitorAppBackend } from './capacitorApp';
|
|
2
|
+
import type { CapacitorApi } from './capacitorModule';
|
|
3
|
+
|
|
4
|
+
const flush = async () => {
|
|
5
|
+
await Promise.resolve();
|
|
6
|
+
await Promise.resolve();
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
function fakeCapacitor() {
|
|
10
|
+
const calls: string[] = [];
|
|
11
|
+
const listeners = new Map<string, (payload: unknown) => void>();
|
|
12
|
+
const capacitor = {
|
|
13
|
+
app: {
|
|
14
|
+
async getInfo() {
|
|
15
|
+
return { name: 'FlightApp', id: 'com.flight.app', build: '42', version: '2.3.4' };
|
|
16
|
+
},
|
|
17
|
+
async exitApp() {
|
|
18
|
+
calls.push('exitApp');
|
|
19
|
+
},
|
|
20
|
+
async minimizeApp() {
|
|
21
|
+
calls.push('minimizeApp');
|
|
22
|
+
},
|
|
23
|
+
async addListener(eventName: string, listener: (payload: unknown) => void) {
|
|
24
|
+
listeners.set(eventName, listener);
|
|
25
|
+
return {
|
|
26
|
+
async remove() {
|
|
27
|
+
calls.push(`remove:${eventName}`);
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
} as unknown as CapacitorApi;
|
|
33
|
+
return { capacitor, calls, listeners };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
describe('createCapacitorAppBackend', () => {
|
|
37
|
+
it('serves name and version from the prefetch cache once it resolves', async () => {
|
|
38
|
+
const backend = createCapacitorAppBackend(fakeCapacitor().capacitor);
|
|
39
|
+
// The sync getters read '' until the construction-time prefetch settles.
|
|
40
|
+
expect(backend.getName()).toBe('');
|
|
41
|
+
await flush();
|
|
42
|
+
expect(backend.getName()).toBe('FlightApp');
|
|
43
|
+
expect(backend.getVersion()).toBe('2.3.4');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('fires the process/app control methods', () => {
|
|
47
|
+
const { capacitor, calls } = fakeCapacitor();
|
|
48
|
+
const backend = createCapacitorAppBackend(capacitor);
|
|
49
|
+
backend.quit();
|
|
50
|
+
expect(backend.hideApp()).toBe(true);
|
|
51
|
+
expect(calls).toContain('exitApp');
|
|
52
|
+
expect(calls).toContain('minimizeApp');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('routes activate and open-file through app listeners', async () => {
|
|
56
|
+
const { capacitor, listeners } = fakeCapacitor();
|
|
57
|
+
const backend = createCapacitorAppBackend(capacitor);
|
|
58
|
+
let activated = 0;
|
|
59
|
+
let openedUrl = '';
|
|
60
|
+
backend.subscribeActivate(() => activated++);
|
|
61
|
+
backend.subscribeOpenFile((url) => (openedUrl = url));
|
|
62
|
+
await flush();
|
|
63
|
+
listeners.get('appStateChange')?.({ isActive: false });
|
|
64
|
+
expect(activated).toBe(0);
|
|
65
|
+
listeners.get('appStateChange')?.({ isActive: true });
|
|
66
|
+
expect(activated).toBe(1);
|
|
67
|
+
listeners.get('appUrlOpen')?.({ url: 'flight://open' });
|
|
68
|
+
expect(openedUrl).toBe('flight://open');
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('reports sentinels for the desktop-only surface', () => {
|
|
72
|
+
const backend = createCapacitorAppBackend(fakeCapacitor().capacitor);
|
|
73
|
+
expect(backend.bounceDock()).toBe(-1);
|
|
74
|
+
expect(backend.setBadgeCount(3)).toBe(false);
|
|
75
|
+
expect(backend.setName('X')).toBe(false);
|
|
76
|
+
expect(backend.showApp()).toBe(false);
|
|
77
|
+
expect(backend.getLocale()).toBe('');
|
|
78
|
+
expect(backend.getCommandLine()).toEqual([]);
|
|
79
|
+
expect(typeof backend.subscribeReady(() => {})).toBe('function');
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { createCapacitorClipboardBackend } from './capacitorClipboard';
|
|
2
|
+
import type { CapacitorApi } from './capacitorModule';
|
|
3
|
+
|
|
4
|
+
function fakeCapacitor() {
|
|
5
|
+
const store = { value: '', type: 'text/plain' };
|
|
6
|
+
const calls: string[] = [];
|
|
7
|
+
const capacitor = {
|
|
8
|
+
clipboard: {
|
|
9
|
+
async read() {
|
|
10
|
+
calls.push('read');
|
|
11
|
+
return { value: store.value, type: store.type };
|
|
12
|
+
},
|
|
13
|
+
async write(options: { string?: string; image?: string }) {
|
|
14
|
+
calls.push('write');
|
|
15
|
+
if (options.image !== undefined) {
|
|
16
|
+
store.value = options.image;
|
|
17
|
+
store.type = 'image/png';
|
|
18
|
+
} else {
|
|
19
|
+
store.value = options.string ?? '';
|
|
20
|
+
store.type = 'text/plain';
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
} as unknown as CapacitorApi;
|
|
25
|
+
return { capacitor, store, calls };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
describe('createCapacitorClipboardBackend', () => {
|
|
29
|
+
it('round-trips text through the Capacitor clipboard', async () => {
|
|
30
|
+
const { capacitor, calls } = fakeCapacitor();
|
|
31
|
+
const backend = createCapacitorClipboardBackend(capacitor);
|
|
32
|
+
expect(await backend.writeText('hi')).toBe(true);
|
|
33
|
+
expect(await backend.readText()).toBe('hi');
|
|
34
|
+
expect(await backend.hasText()).toBe(true);
|
|
35
|
+
expect(calls).toContain('write');
|
|
36
|
+
expect(calls).toContain('read');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('round-trips a data-URL image', async () => {
|
|
40
|
+
const backend = createCapacitorClipboardBackend(fakeCapacitor().capacitor);
|
|
41
|
+
expect(await backend.writeImage('data:image/png;base64,AAAA')).toBe(true);
|
|
42
|
+
expect(await backend.readImage()).toBe('data:image/png;base64,AAAA');
|
|
43
|
+
expect(await backend.hasImage()).toBe(true);
|
|
44
|
+
// An image on the clipboard is not text.
|
|
45
|
+
expect(await backend.readText()).toBe('');
|
|
46
|
+
expect(await backend.hasText()).toBe(false);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('reports sentinels for unsupported flavors', async () => {
|
|
50
|
+
const backend = createCapacitorClipboardBackend(fakeCapacitor().capacitor);
|
|
51
|
+
expect(await backend.readHtml()).toBe('');
|
|
52
|
+
expect(await backend.writeHtml('<b/>')).toBe(false);
|
|
53
|
+
expect(await backend.readBookmark()).toBeNull();
|
|
54
|
+
expect(await backend.getFormats()).toEqual([]);
|
|
55
|
+
expect(await backend.readFiles()).toEqual([]);
|
|
56
|
+
expect(backend.getChangeCount()).toBe(-1);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('resolves sentinels when the clipboard read throws', async () => {
|
|
60
|
+
const capacitor = {
|
|
61
|
+
clipboard: {
|
|
62
|
+
async read() {
|
|
63
|
+
throw new Error('denied');
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
} as unknown as CapacitorApi;
|
|
67
|
+
const backend = createCapacitorClipboardBackend(capacitor);
|
|
68
|
+
expect(await backend.readText()).toBe('');
|
|
69
|
+
expect(await backend.hasText()).toBe(false);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { ConnectivityStatus } from '@flighthq/types';
|
|
2
|
+
|
|
3
|
+
import { createCapacitorConnectivityBackend } from './capacitorConnectivity';
|
|
4
|
+
import type { CapacitorApi, CapacitorConnectionStatus } from './capacitorModule';
|
|
5
|
+
|
|
6
|
+
const flush = async () => {
|
|
7
|
+
await Promise.resolve();
|
|
8
|
+
await Promise.resolve();
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
function emptyStatus(): ConnectivityStatus {
|
|
12
|
+
return {
|
|
13
|
+
online: false,
|
|
14
|
+
type: 'unknown',
|
|
15
|
+
downlink: 0,
|
|
16
|
+
downlinkMax: 0,
|
|
17
|
+
effectiveType: 'x',
|
|
18
|
+
rtt: 0,
|
|
19
|
+
saveData: true,
|
|
20
|
+
metered: false,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function fakeCapacitor(initial: CapacitorConnectionStatus = { connected: true, connectionType: 'wifi' }) {
|
|
25
|
+
const listeners: Array<(status: CapacitorConnectionStatus) => void> = [];
|
|
26
|
+
const capacitor = {
|
|
27
|
+
network: {
|
|
28
|
+
async getStatus() {
|
|
29
|
+
return initial;
|
|
30
|
+
},
|
|
31
|
+
async addListener(_eventName: string, listener: (status: CapacitorConnectionStatus) => void) {
|
|
32
|
+
listeners.push(listener);
|
|
33
|
+
return { async remove() {} };
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
} as unknown as CapacitorApi;
|
|
37
|
+
return { capacitor, fire: (status: CapacitorConnectionStatus) => listeners.forEach((l) => l(status)) };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
describe('createCapacitorConnectivityBackend', () => {
|
|
41
|
+
it('fills the out snapshot from the prefetched status', async () => {
|
|
42
|
+
const backend = createCapacitorConnectivityBackend(fakeCapacitor().capacitor);
|
|
43
|
+
await flush();
|
|
44
|
+
const status = backend.getStatus(emptyStatus());
|
|
45
|
+
expect(status.online).toBe(true);
|
|
46
|
+
expect(status.type).toBe('wifi');
|
|
47
|
+
expect(status.downlink).toBe(-1);
|
|
48
|
+
expect(status.metered).toBe(false);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('reflects a networkStatusChange in the mirror and to subscribers', async () => {
|
|
52
|
+
const { capacitor, fire } = fakeCapacitor();
|
|
53
|
+
const backend = createCapacitorConnectivityBackend(capacitor);
|
|
54
|
+
await flush();
|
|
55
|
+
let changes = 0;
|
|
56
|
+
backend.subscribe(() => changes++);
|
|
57
|
+
await flush();
|
|
58
|
+
fire({ connected: true, connectionType: 'cellular' });
|
|
59
|
+
expect(changes).toBe(1);
|
|
60
|
+
const status = backend.getStatus(emptyStatus());
|
|
61
|
+
expect(status.type).toBe('cellular');
|
|
62
|
+
expect(status.metered).toBe(true);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { DeviceCapabilities, DeviceDisplayMetrics, DeviceInfo, SafeAreaInsets } from '@flighthq/types';
|
|
2
|
+
|
|
3
|
+
import { createCapacitorDeviceBackend } from './capacitorDevice';
|
|
4
|
+
import type { CapacitorApi } from './capacitorModule';
|
|
5
|
+
|
|
6
|
+
const flush = async () => {
|
|
7
|
+
await Promise.resolve();
|
|
8
|
+
await Promise.resolve();
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
function fakeCapacitor() {
|
|
12
|
+
const capacitor = {
|
|
13
|
+
device: {
|
|
14
|
+
async getInfo() {
|
|
15
|
+
return {
|
|
16
|
+
model: 'iPhone15,2',
|
|
17
|
+
platform: 'ios',
|
|
18
|
+
operatingSystem: 'ios',
|
|
19
|
+
osVersion: '17.0',
|
|
20
|
+
manufacturer: 'Apple',
|
|
21
|
+
isVirtual: false,
|
|
22
|
+
webViewVersion: '17.0',
|
|
23
|
+
name: "Joe's iPhone",
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
async getId() {
|
|
27
|
+
return { identifier: 'device-uuid' };
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
} as unknown as CapacitorApi;
|
|
31
|
+
return { capacitor };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function blankInfo(): DeviceInfo {
|
|
35
|
+
return {
|
|
36
|
+
arch: 'z',
|
|
37
|
+
availableMemory: 1,
|
|
38
|
+
boardName: 'z',
|
|
39
|
+
colorGamut: 'z',
|
|
40
|
+
cpuCores: 1,
|
|
41
|
+
fontScale: 1,
|
|
42
|
+
formFactor: 'z',
|
|
43
|
+
gpuRenderer: 'z',
|
|
44
|
+
gpuVendor: 'z',
|
|
45
|
+
isHdr: true,
|
|
46
|
+
isJailbroken: true,
|
|
47
|
+
isLowEndDevice: true,
|
|
48
|
+
isRooted: true,
|
|
49
|
+
isVirtual: true,
|
|
50
|
+
manufacturer: 'z',
|
|
51
|
+
marketingName: 'z',
|
|
52
|
+
model: 'z',
|
|
53
|
+
osBuild: 'z',
|
|
54
|
+
osName: 'z',
|
|
55
|
+
osVersion: 'z',
|
|
56
|
+
platformString: 'z',
|
|
57
|
+
productName: 'z',
|
|
58
|
+
supportedAbis: ['z'],
|
|
59
|
+
totalMemory: 1,
|
|
60
|
+
webViewVersion: 'z',
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
describe('createCapacitorDeviceBackend', () => {
|
|
65
|
+
it('fills DeviceInfo from the prefetched Capacitor info once it resolves', async () => {
|
|
66
|
+
const backend = createCapacitorDeviceBackend(fakeCapacitor().capacitor);
|
|
67
|
+
// Sentinels until the construction-time prefetch settles.
|
|
68
|
+
expect(backend.getInfo(blankInfo()).model).toBe('');
|
|
69
|
+
await flush();
|
|
70
|
+
const info = backend.getInfo(blankInfo());
|
|
71
|
+
expect(info.model).toBe('iPhone15,2');
|
|
72
|
+
expect(info.manufacturer).toBe('Apple');
|
|
73
|
+
expect(info.osName).toBe('ios');
|
|
74
|
+
expect(info.marketingName).toBe("Joe's iPhone");
|
|
75
|
+
expect(info.formFactor).toBe('Phone');
|
|
76
|
+
// Unreported fields fall back to sentinels.
|
|
77
|
+
expect(info.arch).toBe('');
|
|
78
|
+
expect(info.totalMemory).toBe(-1);
|
|
79
|
+
expect(backend.getId()).toBe('device-uuid');
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('reports sentinels for metrics, capabilities, and safe-area insets', () => {
|
|
83
|
+
const backend = createCapacitorDeviceBackend(fakeCapacitor().capacitor);
|
|
84
|
+
const metrics: DeviceDisplayMetrics = {
|
|
85
|
+
colorDepth: 1,
|
|
86
|
+
densityDpi: 1,
|
|
87
|
+
logicalHeight: 1,
|
|
88
|
+
logicalWidth: 1,
|
|
89
|
+
physicalHeight: 1,
|
|
90
|
+
physicalWidth: 1,
|
|
91
|
+
pixelRatio: 1,
|
|
92
|
+
};
|
|
93
|
+
expect(backend.getDisplayMetrics(metrics).pixelRatio).toBe(-1);
|
|
94
|
+
const caps: DeviceCapabilities = { hasKeyboard: true, hasMouse: true, hasStylus: true };
|
|
95
|
+
expect(backend.getCapabilities(caps)).toEqual({ hasKeyboard: false, hasMouse: false, hasStylus: false });
|
|
96
|
+
const insets: SafeAreaInsets = { top: 9, right: 9, bottom: 9, left: 9 };
|
|
97
|
+
expect(backend.getSafeAreaInsets(insets)).toEqual({ top: 0, right: 0, bottom: 0, left: 0 });
|
|
98
|
+
});
|
|
99
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createCapacitorDialogBackend } from './capacitorDialog';
|
|
2
|
+
import type { CapacitorApi } from './capacitorModule';
|
|
3
|
+
|
|
4
|
+
function fakeCapacitor(promptResult = { value: 'typed', cancelled: false }) {
|
|
5
|
+
const calls: string[] = [];
|
|
6
|
+
const capacitor = {
|
|
7
|
+
dialog: {
|
|
8
|
+
async alert() {
|
|
9
|
+
calls.push('alert');
|
|
10
|
+
},
|
|
11
|
+
async confirm() {
|
|
12
|
+
calls.push('confirm');
|
|
13
|
+
return { value: true };
|
|
14
|
+
},
|
|
15
|
+
async prompt() {
|
|
16
|
+
calls.push('prompt');
|
|
17
|
+
return promptResult;
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
} as unknown as CapacitorApi;
|
|
21
|
+
return { capacitor, calls };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
describe('createCapacitorDialogBackend', () => {
|
|
25
|
+
it('maps message onto a single-button alert', async () => {
|
|
26
|
+
const { capacitor, calls } = fakeCapacitor();
|
|
27
|
+
const backend = createCapacitorDialogBackend(capacitor);
|
|
28
|
+
const result = await backend.message({ message: 'hello' });
|
|
29
|
+
expect(result).toEqual({ buttonIndex: 0, cancelled: false, checkboxChecked: false });
|
|
30
|
+
expect(calls).toContain('alert');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('maps confirm and prompt', async () => {
|
|
34
|
+
const backend = createCapacitorDialogBackend(fakeCapacitor().capacitor);
|
|
35
|
+
expect(await backend.confirm({ message: 'ok?' })).toBe(true);
|
|
36
|
+
expect(await backend.prompt({ message: 'name?' })).toBe('typed');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('resolves the null sentinel for a cancelled prompt', async () => {
|
|
40
|
+
const backend = createCapacitorDialogBackend(fakeCapacitor({ value: '', cancelled: true }).capacitor);
|
|
41
|
+
expect(await backend.prompt({ message: 'name?' })).toBeNull();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('reports empty results for the absent file picker', async () => {
|
|
45
|
+
const backend = createCapacitorDialogBackend(fakeCapacitor().capacitor);
|
|
46
|
+
expect(await backend.openFile({})).toEqual([]);
|
|
47
|
+
expect(await backend.openDirectory({})).toEqual([]);
|
|
48
|
+
expect(await backend.saveFile({})).toBeNull();
|
|
49
|
+
});
|
|
50
|
+
});
|