@lowdefy/shell 3.23.2 → 7.2.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/LICENSE +183 -183
- package/README.md +364 -2
- package/app/(t0,t1,t2,t3,t4)/[...path].js +38 -0
- package/app/(t0,t1,t2,t3,t4)/_layout.js +48 -0
- package/app/(t0,t1,t2,t3,t4)/index.js +38 -0
- package/app/+native-intent.js +39 -0
- package/app/_layout.js +36 -0
- package/app.config.ts +183 -0
- package/appLinks.js +65 -0
- package/applyShellPlugins.js +43 -0
- package/authCallbackIntentFilters.js +46 -0
- package/babel.config.js +25 -0
- package/checkShellConfig.js +172 -0
- package/checkShellPlugins.js +74 -0
- package/getPrivacyManifest.js +39 -0
- package/metro.config.js +73 -0
- package/native/LowdefyAppShortcuts.swift.template +84 -0
- package/native/withAppShortcuts.js +60 -0
- package/native-fingerprint.json +16 -0
- package/package.json +120 -40
- package/profiles.js +607 -0
- package/readShellConfig.js +36 -0
- package/resolveShellPlugins.js +109 -0
- package/runtimeVersion.js +112 -0
- package/scripts/checkReleaseBundle.mjs +358 -0
- package/scripts/createDayjsLocales.mjs +67 -0
- package/scripts/createShellAssets.mjs +54 -0
- package/scripts/createShellVersion.mjs +83 -0
- package/scripts/createTypeManifest.mjs +205 -0
- package/shell.dev.json +11 -0
- package/shellVariant.js +126 -0
- package/src/ShellContext.js +32 -0
- package/src/actions/CopyToClipboard.js +29 -0
- package/src/actions/CopyToClipboard.test.js +33 -0
- package/src/actions/GeolocationCurrentPosition.js +61 -0
- package/src/actions/GeolocationCurrentPosition.test.js +79 -0
- package/src/actions/GetLocalStorage.js +36 -0
- package/src/actions/RemoveLocalStorage.js +31 -0
- package/src/actions/ScrollTo.js +66 -0
- package/src/actions/ScrollTo.test.js +83 -0
- package/src/actions/SetFocus.js +33 -0
- package/src/actions/SetFocus.test.js +49 -0
- package/src/actions/SetLocalStorage.js +34 -0
- package/src/actions/localStorage.test.js +68 -0
- package/src/actions/measureInScrollView.js +36 -0
- package/src/actions/nativeActions.js +41 -0
- package/src/auth/AuthButton.js +44 -0
- package/src/auth/AuthGate.js +57 -0
- package/src/auth/AuthLink.js +43 -0
- package/src/auth/LockScreen.js +67 -0
- package/src/auth/LockScreen.test.js +37 -0
- package/src/auth/SignInScreen.js +268 -0
- package/src/auth/SignInScreen.test.js +187 -0
- package/src/auth/createAppAuth.js +325 -0
- package/src/auth/createAppAuth.test.js +424 -0
- package/src/auth/createAuthApi.js +115 -0
- package/src/auth/createAuthApi.test.js +138 -0
- package/src/auth/createCoreAuth.js +96 -0
- package/src/auth/createCoreAuth.test.js +188 -0
- package/src/auth/createDeviceKey.js +62 -0
- package/src/auth/createDeviceKey.test.js +54 -0
- package/src/auth/createSessionStores.js +45 -0
- package/src/auth/createTokenStore.js +103 -0
- package/src/auth/createTokenStore.test.js +116 -0
- package/src/auth/getAuthSettings.js +24 -0
- package/src/auth/getAuthView.js +39 -0
- package/src/auth/getAuthView.test.js +52 -0
- package/src/auth/getSheetReturnUrl.js +35 -0
- package/src/auth/getTokenStoreOptions.js +46 -0
- package/src/auth/isBackgroundShell.js +26 -0
- package/src/auth/isSheetReturnLink.js +35 -0
- package/src/auth/parseQuery.js +39 -0
- package/src/auth/purgeAppData.js +80 -0
- package/src/auth/purgeAppData.test.js +104 -0
- package/src/auth/shouldLock.js +26 -0
- package/src/auth/signInWithSheet.js +97 -0
- package/src/auth/signInWithSheet.test.js +205 -0
- package/src/auth/styles.js +78 -0
- package/src/auth/unregisterPushToken.js +62 -0
- package/src/auth/unregisterPushToken.test.js +67 -0
- package/src/auth/usesBiometricUnlock.js +23 -0
- package/src/auth/watchSession.js +47 -0
- package/src/auth/withoutCookies.js +26 -0
- package/src/cache/createSqliteCacheStore.js +113 -0
- package/src/cache/createSqliteCacheStore.test.js +93 -0
- package/src/cache/getCacheKey.js +25 -0
- package/src/cache/getLastCacheKeyName.js +22 -0
- package/src/components/AppProvider.js +118 -0
- package/src/components/Frame.js +116 -0
- package/src/components/Frame.test.js +101 -0
- package/src/components/LoadingScreen.js +35 -0
- package/src/components/MenuButton.js +121 -0
- package/src/components/MenuButton.test.js +74 -0
- package/src/components/MessageScreen.js +51 -0
- package/src/components/NavigationTheme.js +33 -0
- package/src/components/NoConnectionBanner.js +51 -0
- package/src/components/NoConnectionBanner.test.js +73 -0
- package/src/components/OtherPageScreen.js +95 -0
- package/src/components/OtherPageScreen.test.js +74 -0
- package/src/components/PageScreen.js +254 -0
- package/src/components/PageScreen.test.js +492 -0
- package/src/components/RouteErrorScreen.js +47 -0
- package/src/components/ShellRoot.js +34 -0
- package/src/components/ShellRoot.test.js +62 -0
- package/src/components/ShellThemeProvider.js +45 -0
- package/src/components/SwitchToTab.js +36 -0
- package/src/components/SwitchToTab.test.js +63 -0
- package/src/components/TabIconImages.js +72 -0
- package/src/components/UpdateScreen.js +40 -0
- package/src/components/getNavigationTheme.js +44 -0
- package/src/components/getNavigationTheme.test.js +41 -0
- package/src/components/styles.js +50 -0
- package/src/components/useSurfaceTokens.js +47 -0
- package/src/config/getAppApiBase.js +34 -0
- package/src/config/getShellConfig.js +37 -0
- package/src/config/getShellConfig.test.js +80 -0
- package/src/createShellApp.js +126 -0
- package/src/dev/DevShell.js +239 -0
- package/src/dev/DevShell.test.js +233 -0
- package/src/dev/connect/ConfirmSheet.js +71 -0
- package/src/dev/connect/ConnectScreen.js +117 -0
- package/src/dev/connect/QrScanner.js +89 -0
- package/src/dev/connection/createDevShellConfig.js +47 -0
- package/src/dev/connection/createDevTransport.js +51 -0
- package/src/dev/connection/createDevTransport.test.js +87 -0
- package/src/dev/connection/createServerList.js +48 -0
- package/src/dev/connection/isLoopbackHost.js +25 -0
- package/src/dev/connection/pairedShellApp.test.js +104 -0
- package/src/dev/connection/parseDevLink.js +66 -0
- package/src/dev/connection/parseDevLink.test.js +97 -0
- package/src/dev/connection/parseQuery.js +33 -0
- package/src/dev/connection/parseServerInput.js +40 -0
- package/src/dev/connection/parseServerUrl.js +45 -0
- package/src/dev/devStyles.js +97 -0
- package/src/dev/index.js +21 -0
- package/src/dev/inject/createDeviceInjections.js +188 -0
- package/src/dev/inject/createDeviceInjections.test.js +224 -0
- package/src/dev/inject/createOfflineFetch.js +35 -0
- package/src/dev/inject/createOfflineFetch.test.js +68 -0
- package/src/dev/inject/injectPush.js +60 -0
- package/src/dev/inject/injectShare.js +55 -0
- package/src/dev/inject/withInjectedDevice.js +98 -0
- package/src/dev/menu/BlockGallery.js +33 -0
- package/src/dev/menu/DevMenu.js +121 -0
- package/src/dev/menu/createLogBuffer.js +83 -0
- package/src/dev/menu/watchShake.js +52 -0
- package/src/dev/menu/watchShake.test.js +61 -0
- package/src/dev/recorder/createNativeRecorder.js +204 -0
- package/src/dev/recorder/createNativeRecorder.test.js +307 -0
- package/src/dev/redirectDevLink.js +30 -0
- package/src/dev/redirectDevLink.test.js +49 -0
- package/src/dev/steps/createStepRunner.js +184 -0
- package/src/dev/steps/createStepRunner.test.js +262 -0
- package/src/dev/steps/findBlock.js +78 -0
- package/src/dev/steps/isContextSettled.js +37 -0
- package/src/dev/steps/waitForSettle.js +39 -0
- package/src/dev/steps/waitUntil.js +40 -0
- package/src/dev/tab/DevTabClient.js +97 -0
- package/src/dev/tab/answerEval.js +39 -0
- package/src/dev/tab/answerInspect.js +45 -0
- package/src/dev/tab/createDevTabClient.js +272 -0
- package/src/dev/tab/createDevTabClient.test.js +317 -0
- package/src/dev/tab/describeTabError.js +35 -0
- package/src/dev/tab/devClientMarker.js +22 -0
- package/src/dev/tab/devClientMarker.test.js +23 -0
- package/src/dev/tab/findPageContext.js +43 -0
- package/src/dev/tab/getShownPage.js +42 -0
- package/src/dev/tab/readEventStream.js +68 -0
- package/src/dev/tab/reloadApp.js +42 -0
- package/src/dev/tab/reloadApp.test.js +115 -0
- package/src/device/DeviceHosts.js +32 -0
- package/src/device/basic/createFilesFeature.js +41 -0
- package/src/device/basic/createHapticsFeature.js +46 -0
- package/src/device/basic/createKeepAwakeFeature.js +37 -0
- package/src/device/basic/createPhotosFeature.js +40 -0
- package/src/device/basic/createRequestQueueFeature.js +37 -0
- package/src/device/basic/createShareFeature.js +63 -0
- package/src/device/basic/createShareFeature.test.js +47 -0
- package/src/device/basic/createSpeechFeature.js +43 -0
- package/src/device/basic/createUploadFeature.js +41 -0
- package/src/device/basic/toImagePickerOptions.js +41 -0
- package/src/device/basic/toPickedFile.js +54 -0
- package/src/device/calendar/index.js +68 -0
- package/src/device/contacts/index.js +67 -0
- package/src/device/createDevice.js +65 -0
- package/src/device/device.js +27 -0
- package/src/device/field/MapView.js +93 -0
- package/src/device/field/ScanCodeSheet.js +86 -0
- package/src/device/field/ScannerView.js +52 -0
- package/src/device/field/createAudioFeature.js +70 -0
- package/src/device/field/createBrightnessFeature.js +40 -0
- package/src/device/field/createCameraFeature.js +56 -0
- package/src/device/field/createDocumentScannerFeature.js +51 -0
- package/src/device/field/createLocationFeature.js +39 -0
- package/src/device/field/createScanRequests.js +55 -0
- package/src/device/field/index.js +39 -0
- package/src/device/field/scanRequests.js +22 -0
- package/src/device/injected.js +60 -0
- package/src/device/injected.test.js +39 -0
- package/src/device/nfc/index.js +89 -0
- package/src/device/nfc/toNfcRecord.js +44 -0
- package/src/device/nfc/toNfcRecord.test.js +48 -0
- package/src/device/tracking/createBacklog.js +63 -0
- package/src/device/tracking/createBacklog.test.js +47 -0
- package/src/device/tracking/index.js +211 -0
- package/src/device/tracking/index.test.js +110 -0
- package/src/host/createDeviceStore.js +32 -0
- package/src/host/createMemoryStore.js +32 -0
- package/src/host/createNetworkStatus.js +94 -0
- package/src/host/createNetworkStatus.test.js +94 -0
- package/src/host/createRouterAdapter.js +33 -0
- package/src/host/createShellFetch.js +62 -0
- package/src/host/createShellFetch.test.js +165 -0
- package/src/host/createShellGlobals.js +62 -0
- package/src/host/createShellHost.js +83 -0
- package/src/host/createShellHost.test.js +36 -0
- package/src/host/getOrigin.js +31 -0
- package/src/host/isNetworkError.js +24 -0
- package/src/host/isOnline.js +22 -0
- package/src/host/networkStatus.js +24 -0
- package/src/host/readServerError.js +45 -0
- package/src/host/readServerError.test.js +85 -0
- package/src/host/reportShellError.js +47 -0
- package/src/host/reportShellError.test.js +79 -0
- package/src/host/withNetworkErrors.js +38 -0
- package/src/host/withNetworkErrors.test.js +61 -0
- package/src/host/withShellHeader.js +25 -0
- package/src/host/withShellHeader.test.js +28 -0
- package/src/js/evaluateJsEntries.js +43 -0
- package/src/js/evaluateJsEntries.test.js +48 -0
- package/src/locale/createShellLocale.js +112 -0
- package/src/locale/createShellLocale.test.js +74 -0
- package/src/locale/dayjsLocales.js +165 -0
- package/src/locale/getDeviceLocales.js +23 -0
- package/src/locale/loadDayjsLocale.js +32 -0
- package/src/locale/resolveActiveLocale.js +46 -0
- package/src/locale/resolveActiveLocale.test.js +40 -0
- package/src/native/backgroundFetch.js +97 -0
- package/src/native/callEndpoint.js +63 -0
- package/src/native/createAppEventTrigger.js +70 -0
- package/src/native/currentApp.js +49 -0
- package/src/native/getPagePath.js +32 -0
- package/src/native/openPath.js +55 -0
- package/src/native/openPath.test.js +39 -0
- package/src/native/parseShellLink.js +38 -0
- package/src/native/parseShellLink.test.js +29 -0
- package/src/native/startAppServices.js +94 -0
- package/src/native/startAppServices.test.js +97 -0
- package/src/native/startShareIn.js +59 -0
- package/src/native/startShortcuts.js +88 -0
- package/src/native/startShortcuts.test.js +59 -0
- package/src/native/toSharePayload.js +47 -0
- package/src/native/toSharePayload.test.js +47 -0
- package/src/native/whenAppReady.js +48 -0
- package/src/navigation/SlotContext.js +24 -0
- package/src/navigation/frameSlots.js +27 -0
- package/src/navigation/getFrame.js +30 -0
- package/src/navigation/getInitialScreenOptions.js +63 -0
- package/src/navigation/getInitialScreenOptions.test.js +66 -0
- package/src/navigation/getPresentation.js +28 -0
- package/src/navigation/getSlotRootPath.js +27 -0
- package/src/navigation/getStackOptions.js +185 -0
- package/src/navigation/getTabHref.js +45 -0
- package/src/navigation/getTabIcons.js +43 -0
- package/src/navigation/isPageUnderHeader.js +46 -0
- package/src/navigation/navigation.test.js +342 -0
- package/src/navigation/toAppLinkPath.js +43 -0
- package/src/navigation/toAppLinkPath.test.js +53 -0
- package/src/navigation/toRouterHref.js +29 -0
- package/src/notifications/createNotificationsFeature.js +61 -0
- package/src/notifications/getCategoryAction.js +31 -0
- package/src/notifications/handleNotificationResponse.js +82 -0
- package/src/notifications/registerPushToken.js +71 -0
- package/src/notifications/startNotifications.js +114 -0
- package/src/notifications/toCategoryActions.js +42 -0
- package/src/notifications/toNotificationEvent.js +36 -0
- package/src/notifications/toScheduleRequest.js +62 -0
- package/src/plugins/appTypes.js +28 -0
- package/src/plugins/prefixTypes.js +28 -0
- package/src/plugins/shellPlugins.json +15 -0
- package/src/plugins/typeManifest.js +789 -0
- package/src/plugins/types.js +64 -0
- package/src/plugins/types.test.js +173 -0
- package/src/polyfills/installGetRandomValues.js +28 -0
- package/src/queue/createRequestQueue.js +198 -0
- package/src/queue/createRequestQueue.test.js +215 -0
- package/src/queue/createSqliteQueueStore.js +121 -0
- package/src/queue/summarizeQueue.js +39 -0
- package/src/session/createAppSession.js +323 -0
- package/src/session/createAppSession.test.js +391 -0
- package/src/session/getPageView.js +59 -0
- package/src/session/getPageView.test.js +137 -0
- package/src/sync/encodePagePath.js +27 -0
- package/src/sync/fetchPage.js +72 -0
- package/src/sync/fetchPage.test.js +84 -0
- package/src/sync/fetchRoot.js +43 -0
- package/src/sync/fetchUser.js +33 -0
- package/src/sync/runLimited.js +36 -0
- package/src/sync/toRootConfig.js +35 -0
- package/src/test/createFakeNetwork.js +40 -0
- package/src/test/createFakeSecureStore.js +40 -0
- package/src/test/createFakeServer.js +98 -0
- package/src/test/createMemoryCacheStore.js +59 -0
- package/src/test/createNetworkError.js +24 -0
- package/src/test/expoImage.js +42 -0
- package/src/test/expoNotifications.js +40 -0
- package/src/test/expoQuickActions.js +22 -0
- package/src/test/expoSpeechRecognition.js +31 -0
- package/src/test/expoTaskManager.js +25 -0
- package/src/test/expoUi.js +55 -0
- package/src/test/expoUiBottomSheet.js +64 -0
- package/src/test/expoUiDateTimePicker.js +26 -0
- package/src/test/expoUiMenu.js +46 -0
- package/src/test/expoUiSegmentedControl.js +47 -0
- package/src/test/expoUiSwiftUi.js +62 -0
- package/src/test/expoUiSwiftUiModifiers.js +23 -0
- package/src/test/expoWebBrowser.js +23 -0
- package/src/test/fixtures.js +98 -0
- package/src/test/nativeModule.js +33 -0
- package/src/test/renderPageScreen.js +109 -0
- package/src/types/checkTypeSet.js +39 -0
- package/src/types/collectPageTypes.js +49 -0
- package/src/types/collectPageTypes.test.js +90 -0
- package/src/types/findMissingPageTypes.js +40 -0
- package/src/version/compareVersions.js +38 -0
- package/src/version/isShellTooOld.js +30 -0
- package/src/version/shellVersion.js +21 -0
- package/src/version/shellVersion.test.js +32 -0
- package/src/widgets/fetchWidgetData.js +59 -0
- package/src/widgets/index.js +156 -0
- package/src/widgets/refreshWidgets.js +31 -0
- package/withExcludedNativeModules.js +93 -0
- package/dist/location.js +0 -33
- package/dist/public/apple-touch-icon.png +0 -0
- package/dist/public/icon-32.png +0 -0
- package/dist/public/icon-512.png +0 -0
- package/dist/public/icon.svg +0 -17
- package/dist/public/logo-dark-theme.png +0 -0
- package/dist/public/logo-light-theme.png +0 -0
- package/dist/public/logo-square-dark-theme.png +0 -0
- package/dist/public/logo-square-light-theme.png +0 -0
- package/dist/public/manifest.webmanifest +0 -16
- package/dist/shell/246.93432ff68186aae6c87b.js +0 -2
- package/dist/shell/246.93432ff68186aae6c87b.js.LICENSE.txt +0 -8
- package/dist/shell/454.b597ca21366afda000af.js +0 -2
- package/dist/shell/454.b597ca21366afda000af.js.LICENSE.txt +0 -14
- package/dist/shell/484.d645e6c09079f45ce044.js +0 -1
- package/dist/shell/706.a66931e02a549fd269bd.js +0 -2
- package/dist/shell/706.a66931e02a549fd269bd.js.LICENSE.txt +0 -8
- package/dist/shell/9.78be8c1b6c3986f404fc.js +0 -2
- package/dist/shell/9.78be8c1b6c3986f404fc.js.LICENSE.txt +0 -45
- package/dist/shell/922.43b7a3ebe22ef05b3049.js +0 -2
- package/dist/shell/922.43b7a3ebe22ef05b3049.js.LICENSE.txt +0 -14
- package/dist/shell/index.html +0 -57
- package/dist/shell/main.bde87d1433f0625faed6.js +0 -1
- package/dist/shell/runtime.1ead93159ba56c05b969.js +0 -1
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { Platform } from 'react-native';
|
|
18
|
+
import * as Notifications from 'expo-notifications';
|
|
19
|
+
|
|
20
|
+
import callEndpoint from '../native/callEndpoint.js';
|
|
21
|
+
import reportShellError from '../host/reportShellError.js';
|
|
22
|
+
|
|
23
|
+
// The Expo push token, for an app that sends through Expo's push service. A shell without an EAS
|
|
24
|
+
// project has none. Without it the native token is still registered, so a failure is reported and
|
|
25
|
+
// the registration goes on.
|
|
26
|
+
async function getExpoToken({ projectId, session }) {
|
|
27
|
+
if (typeof projectId !== 'string') {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const { data } = await Notifications.getExpoPushTokenAsync({ projectId });
|
|
32
|
+
return data;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
reportShellError({ error, session });
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Sends this phone's push token to the app's mobile.notifications.register endpoint, once signed in
|
|
41
|
+
* and allowed to notify: { token (APNs or FCM), expoToken, platform, provider, shellId,
|
|
42
|
+
* appVersion }. The app stores it per user (the endpoint has the caller's session) and sends pushes
|
|
43
|
+
* through APNs, FCM or Expo. Does nothing without a register endpoint or permission.
|
|
44
|
+
*
|
|
45
|
+
* @param {Object} params
|
|
46
|
+
* @param {Object} params.app The open app (currentApp.js).
|
|
47
|
+
* @param {string} [params.token] A new native token (the token listener), else read now.
|
|
48
|
+
*/
|
|
49
|
+
async function registerPushToken({ app, token }) {
|
|
50
|
+
const endpointId = app.session.getState().root?.notifications?.register;
|
|
51
|
+
if (typeof endpointId !== 'string' || app.tokenStore.get() === null) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
const { granted } = await Notifications.getPermissionsAsync();
|
|
55
|
+
if (!granted) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
const nativeToken = token ?? (await Notifications.getDevicePushTokenAsync()).data;
|
|
59
|
+
const registration = {
|
|
60
|
+
token: nativeToken,
|
|
61
|
+
expoToken: await getExpoToken({ projectId: app.shell.easProjectId, session: app.session }),
|
|
62
|
+
platform: Platform.OS,
|
|
63
|
+
provider: Platform.OS === 'ios' ? 'apns' : 'fcm',
|
|
64
|
+
shellId: app.shell.id,
|
|
65
|
+
appVersion: app.shell.version,
|
|
66
|
+
};
|
|
67
|
+
await callEndpoint({ app, endpointId, payload: registration });
|
|
68
|
+
return registration;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export default registerPushToken;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import * as Notifications from 'expo-notifications';
|
|
18
|
+
import { type } from '@lowdefy/helpers';
|
|
19
|
+
|
|
20
|
+
import handleNotificationResponse from './handleNotificationResponse.js';
|
|
21
|
+
import refreshWidgets from '../widgets/refreshWidgets.js';
|
|
22
|
+
import registerPushToken from './registerPushToken.js';
|
|
23
|
+
import reportShellError from '../host/reportShellError.js';
|
|
24
|
+
import toCategoryActions from './toCategoryActions.js';
|
|
25
|
+
import toNotificationEvent from './toNotificationEvent.js';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Notifications for the open app, once its root is held: registers its categories, shows a
|
|
29
|
+
* notification that arrives while it is open as mobile.notifications.foreground says, fires
|
|
30
|
+
* onNotification for it, handles taps and buttons (handleNotificationResponse, also the one that
|
|
31
|
+
* launched the app), and registers the push token once signed in and allowed. A push with
|
|
32
|
+
* `data.refreshWidgets` updates the widgets.
|
|
33
|
+
*
|
|
34
|
+
* @param {Object} params
|
|
35
|
+
* @param {Object} params.app The open app (currentApp.js).
|
|
36
|
+
* @returns {() => void} Stops listening.
|
|
37
|
+
*/
|
|
38
|
+
function startNotifications({ app }) {
|
|
39
|
+
const subscriptions = [];
|
|
40
|
+
let registeredCategories = null;
|
|
41
|
+
// The response that launched the app can also reach the listener: each is handled once.
|
|
42
|
+
const handled = new Set();
|
|
43
|
+
function report(error) {
|
|
44
|
+
reportShellError({ error, session: app.session });
|
|
45
|
+
}
|
|
46
|
+
function respond(response) {
|
|
47
|
+
const key = `${response.notification.request.identifier}:${response.actionIdentifier}`;
|
|
48
|
+
if (handled.has(key)) return;
|
|
49
|
+
handled.add(key);
|
|
50
|
+
// A button's endpoint call and the path it opens need the token and the root.
|
|
51
|
+
app.ready.then(() => handleNotificationResponse({ app, response })).catch(report);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function applyRoot() {
|
|
55
|
+
const notifications = app.session.getState().root?.notifications;
|
|
56
|
+
if (!type.isObject(notifications) || notifications === registeredCategories) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
registeredCategories = notifications;
|
|
60
|
+
notifications.categories.forEach((category) => {
|
|
61
|
+
Notifications.setNotificationCategoryAsync(
|
|
62
|
+
category.id,
|
|
63
|
+
toCategoryActions(category.actions)
|
|
64
|
+
).catch(() => {});
|
|
65
|
+
});
|
|
66
|
+
registerPushToken({ app }).catch(report);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
Notifications.setNotificationHandler({
|
|
70
|
+
handleNotification: async () => {
|
|
71
|
+
const banner = app.session.getState().root?.notifications?.foreground !== 'silent';
|
|
72
|
+
return {
|
|
73
|
+
shouldShowBanner: banner,
|
|
74
|
+
shouldShowList: true,
|
|
75
|
+
shouldPlaySound: banner,
|
|
76
|
+
shouldSetBadge: true,
|
|
77
|
+
};
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
subscriptions.push(
|
|
82
|
+
Notifications.addNotificationReceivedListener((notification) => {
|
|
83
|
+
const event = toNotificationEvent(notification);
|
|
84
|
+
if (event.data.refreshWidgets === true) {
|
|
85
|
+
refreshWidgets({ app }).catch(() => {});
|
|
86
|
+
}
|
|
87
|
+
app.triggerAppEvent({ name: 'onNotification', event: { notification: event } });
|
|
88
|
+
}),
|
|
89
|
+
Notifications.addNotificationResponseReceivedListener(respond),
|
|
90
|
+
Notifications.addPushTokenListener(({ data }) => {
|
|
91
|
+
registerPushToken({ app, token: data }).catch(report);
|
|
92
|
+
})
|
|
93
|
+
);
|
|
94
|
+
const unsubscribe = app.session.subscribe(applyRoot);
|
|
95
|
+
applyRoot();
|
|
96
|
+
// A sign-in after the app opened registers the token for the person who signed in.
|
|
97
|
+
const unsubscribeToken = app.tokenStore.subscribe((token) => {
|
|
98
|
+
if (token !== null) registerPushToken({ app }).catch(report);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
const launching = Notifications.getLastNotificationResponse();
|
|
102
|
+
if (launching !== null) {
|
|
103
|
+
Notifications.clearLastNotificationResponse();
|
|
104
|
+
respond(launching);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return () => {
|
|
108
|
+
unsubscribe();
|
|
109
|
+
unsubscribeToken();
|
|
110
|
+
subscriptions.forEach((subscription) => subscription.remove());
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export default startNotifications;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A mobile.notifications category's actions as expo-notifications registers them. A button that
|
|
19
|
+
* calls an endpoint or snoozes runs without opening the app; the others open it.
|
|
20
|
+
*
|
|
21
|
+
* @param {Object[]} actions The category's actions (getMobileNotifications in the build).
|
|
22
|
+
*/
|
|
23
|
+
function toCategoryActions(actions) {
|
|
24
|
+
return actions.map((action) => ({
|
|
25
|
+
identifier: action.id,
|
|
26
|
+
buttonTitle: action.title,
|
|
27
|
+
textInput:
|
|
28
|
+
action.input === null
|
|
29
|
+
? undefined
|
|
30
|
+
: {
|
|
31
|
+
placeholder: action.input.placeholder ?? '',
|
|
32
|
+
submitButtonTitle: action.input.buttonTitle ?? action.title,
|
|
33
|
+
},
|
|
34
|
+
options: {
|
|
35
|
+
opensAppToForeground: action.endpointId === null && action.snooze === null,
|
|
36
|
+
isDestructive: action.destructive,
|
|
37
|
+
isAuthenticationRequired: action.authenticationRequired,
|
|
38
|
+
},
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default toCategoryActions;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { type } from '@lowdefy/helpers';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A notification as the app's events see it: { id, title, body, data, categoryId, badge }.
|
|
21
|
+
*
|
|
22
|
+
* @param {Object} notification An expo-notifications Notification.
|
|
23
|
+
*/
|
|
24
|
+
function toNotificationEvent(notification) {
|
|
25
|
+
const { content, identifier } = notification.request;
|
|
26
|
+
return {
|
|
27
|
+
id: identifier,
|
|
28
|
+
title: content.title ?? null,
|
|
29
|
+
body: content.body ?? null,
|
|
30
|
+
data: type.isObject(content.data) ? content.data : {},
|
|
31
|
+
categoryId: content.categoryIdentifier ?? null,
|
|
32
|
+
badge: content.badge ?? null,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default toNotificationEvent;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import * as Notifications from 'expo-notifications';
|
|
18
|
+
import { type } from '@lowdefy/helpers';
|
|
19
|
+
|
|
20
|
+
function getTrigger({ at, repeats, seconds }) {
|
|
21
|
+
if (type.isString(at)) {
|
|
22
|
+
const date = new Date(at);
|
|
23
|
+
if (Number.isNaN(date.getTime())) {
|
|
24
|
+
throw new Error(`ScheduleNotification "at" should be an ISO date-time. Received "${at}".`);
|
|
25
|
+
}
|
|
26
|
+
return { type: Notifications.SchedulableTriggerInputTypes.DATE, date };
|
|
27
|
+
}
|
|
28
|
+
if (type.isNumber(seconds)) {
|
|
29
|
+
if (repeats === true && seconds < 60) {
|
|
30
|
+
throw new Error('ScheduleNotification with "repeats" needs "seconds" of 60 or more.');
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
type: Notifications.SchedulableTriggerInputTypes.TIME_INTERVAL,
|
|
34
|
+
seconds: Math.max(1, seconds),
|
|
35
|
+
repeats: repeats === true,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* ScheduleNotification's params as an expo-notifications request: shown now with neither `at` nor
|
|
43
|
+
* `seconds`. `path` goes into data.path, which a tap opens.
|
|
44
|
+
*
|
|
45
|
+
* @param {Object} params ScheduleNotification's params.
|
|
46
|
+
*/
|
|
47
|
+
function toScheduleRequest(params) {
|
|
48
|
+
const { badge, body, categoryId, data, id, path, title } = params;
|
|
49
|
+
return {
|
|
50
|
+
identifier: id,
|
|
51
|
+
content: {
|
|
52
|
+
title,
|
|
53
|
+
body,
|
|
54
|
+
data: { ...(data ?? {}), ...(type.isString(path) ? { path } : {}) },
|
|
55
|
+
categoryIdentifier: categoryId,
|
|
56
|
+
badge,
|
|
57
|
+
},
|
|
58
|
+
trigger: getTrigger(params),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export default toScheduleRequest;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// The native types of the app's shell plugins (shell.json `plugins`), which src/plugins/types.js
|
|
18
|
+
// registers after the built-in types. The shell package ships it empty; `lowdefy mobile config`
|
|
19
|
+
// rewrites it in the copied shell to import each plugin's `./native`, with its typePrefix applied:
|
|
20
|
+
//
|
|
21
|
+
// import * as plugin0 from '@example/lowdefy-printer/native';
|
|
22
|
+
// import prefixTypes from './prefixTypes.js';
|
|
23
|
+
//
|
|
24
|
+
// export default {
|
|
25
|
+
// actions: { ...prefixTypes({ types: plugin0.actions, typePrefix: 'Printer' }) },
|
|
26
|
+
// blocks: { ...prefixTypes({ types: plugin0.blocks, typePrefix: 'Printer' }) },
|
|
27
|
+
// };
|
|
28
|
+
export default { actions: {}, blocks: {} };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// A shell plugin's native types with its typePrefix (shell.json `plugins[].typePrefix`) on each
|
|
18
|
+
// name, as the type manifest names them (scripts/createTypeManifest.mjs).
|
|
19
|
+
function prefixTypes({ types, typePrefix }) {
|
|
20
|
+
return Object.fromEntries(
|
|
21
|
+
Object.entries(types ?? {}).map(([name, implementation]) => [
|
|
22
|
+
`${typePrefix ?? ''}${name}`,
|
|
23
|
+
implementation,
|
|
24
|
+
])
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default prefixTypes;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
[
|
|
2
|
+
{ "category": "actions", "package": "@lowdefy/actions-core" },
|
|
3
|
+
{ "category": "actions", "package": "@lowdefy/blocks-native" },
|
|
4
|
+
{ "category": "blocks", "package": "@lowdefy/blocks-native" },
|
|
5
|
+
{ "category": "operators", "package": "@lowdefy/operators-js" },
|
|
6
|
+
{ "category": "operators", "package": "@lowdefy/operators-change-case" },
|
|
7
|
+
{ "category": "operators", "package": "@lowdefy/operators-cron" },
|
|
8
|
+
{ "category": "operators", "package": "@lowdefy/operators-dayjs" },
|
|
9
|
+
{ "category": "operators", "package": "@lowdefy/operators-diff" },
|
|
10
|
+
{ "category": "operators", "package": "@lowdefy/operators-jsonata" },
|
|
11
|
+
{ "category": "operators", "package": "@lowdefy/operators-mql" },
|
|
12
|
+
{ "category": "operators", "package": "@lowdefy/operators-nunjucks" },
|
|
13
|
+
{ "category": "operators", "package": "@lowdefy/operators-uuid" },
|
|
14
|
+
{ "category": "operators", "package": "@lowdefy/operators-yaml" }
|
|
15
|
+
]
|