@lowdefy/shell 3.23.3 → 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.f01501a75909f38ccc32.js +0 -1
- package/dist/shell/runtime.e50f6c3a5f7c74a0a717.js +0 -1
|
@@ -0,0 +1,90 @@
|
|
|
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 collectPageTypes from './collectPageTypes.js';
|
|
18
|
+
|
|
19
|
+
const page = {
|
|
20
|
+
id: 'page:today',
|
|
21
|
+
type: 'Screen',
|
|
22
|
+
slots: {
|
|
23
|
+
content: {
|
|
24
|
+
blocks: [
|
|
25
|
+
{
|
|
26
|
+
id: 'block:today:tap:0',
|
|
27
|
+
type: 'Button',
|
|
28
|
+
events: {
|
|
29
|
+
onClick: {
|
|
30
|
+
try: [{ id: 'go', type: 'Link', params: 'detail' }],
|
|
31
|
+
catch: [{ id: 'failed', type: 'SetState', params: {} }],
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: 'block:today:box:0',
|
|
37
|
+
type: 'Box',
|
|
38
|
+
slots: { content: { blocks: [{ id: 'block:today:text:0', type: 'Paragraph' }] } },
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const expected = {
|
|
46
|
+
blocks: ['Box', 'Button', 'Paragraph', 'Screen'],
|
|
47
|
+
actions: ['Link', 'SetState'],
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
test('collectPageTypes reads the block and action types of a page', () => {
|
|
51
|
+
expect(collectPageTypes(page)).toEqual(expected);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// The dev server sends page config serialized: an array that carries a config key comes as
|
|
55
|
+
// { '~arr': [...], '~k': key }.
|
|
56
|
+
test('collectPageTypes reads a serialized page as the dev server sends it', () => {
|
|
57
|
+
const serialized = {
|
|
58
|
+
id: 'page:today',
|
|
59
|
+
type: 'Screen',
|
|
60
|
+
slots: {
|
|
61
|
+
content: {
|
|
62
|
+
blocks: {
|
|
63
|
+
'~arr': [
|
|
64
|
+
{
|
|
65
|
+
id: 'block:today:tap:0',
|
|
66
|
+
type: 'Button',
|
|
67
|
+
events: {
|
|
68
|
+
onClick: {
|
|
69
|
+
try: { '~arr': [{ id: 'go', type: 'Link', params: 'detail' }], '~k': 'k2' },
|
|
70
|
+
catch: { '~arr': [{ id: 'failed', type: 'SetState', params: {} }], '~k': 'k3' },
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
id: 'block:today:box:0',
|
|
76
|
+
type: 'Box',
|
|
77
|
+
slots: {
|
|
78
|
+
content: {
|
|
79
|
+
blocks: { '~arr': [{ id: 'block:today:text:0', type: 'Paragraph' }], '~k': 'k4' },
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
'~k': 'k1',
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
expect(collectPageTypes(serialized)).toEqual(expected);
|
|
90
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
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 checkTypeSet from './checkTypeSet.js';
|
|
18
|
+
import collectPageTypes from './collectPageTypes.js';
|
|
19
|
+
|
|
20
|
+
// The types a page needs that this shell lacks. A production root lists the page's type set under
|
|
21
|
+
// its typesKey; a dev root lists none, so the page's own config is read when it has arrived.
|
|
22
|
+
function findMissingPageTypes({ entry, manifest, page, root }) {
|
|
23
|
+
if (entry.typesKey !== undefined) {
|
|
24
|
+
return checkTypeSet({ manifest, typeSet: root.typeSets[entry.typesKey] ?? {} });
|
|
25
|
+
}
|
|
26
|
+
if (page === undefined) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const used = collectPageTypes(page.pageConfig);
|
|
30
|
+
return [
|
|
31
|
+
...used.blocks
|
|
32
|
+
.filter((name) => manifest.blocks[name] === undefined)
|
|
33
|
+
.map((name) => ({ category: 'blocks', type: name })),
|
|
34
|
+
...used.actions
|
|
35
|
+
.filter((name) => manifest.actions[name] === undefined)
|
|
36
|
+
.map((name) => ({ category: 'actions', type: name })),
|
|
37
|
+
];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default findMissingPageTypes;
|
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
function parseVersion(version) {
|
|
18
|
+
const [major = 0, minor = 0, patch = 0] = String(version)
|
|
19
|
+
.split('-')[0]
|
|
20
|
+
.split('.')
|
|
21
|
+
.map((part) => Number.parseInt(part, 10) || 0);
|
|
22
|
+
return [major, minor, patch];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Compares two release versions ("7.4.0") by major, minor and patch: below 0 when a is older than
|
|
26
|
+
// b, 0 when they match, above 0 when a is newer. A prerelease suffix is ignored.
|
|
27
|
+
function compareVersions(a, b) {
|
|
28
|
+
const partsA = parseVersion(a);
|
|
29
|
+
const partsB = parseVersion(b);
|
|
30
|
+
for (let i = 0; i < 3; i += 1) {
|
|
31
|
+
if (partsA[i] !== partsB[i]) {
|
|
32
|
+
return partsA[i] - partsB[i];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return 0;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default compareVersions;
|
|
@@ -0,0 +1,30 @@
|
|
|
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
|
+
import compareVersions from './compareVersions.js';
|
|
20
|
+
|
|
21
|
+
// mobile.minShellVersion blocks every page of an app on a shell older than it: it is for security
|
|
22
|
+
// fixes a server cannot work around.
|
|
23
|
+
function isShellTooOld({ minShellVersion, shellVersion }) {
|
|
24
|
+
if (type.isNone(minShellVersion)) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
return compareVersions(shellVersion, minShellVersion) < 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default isShellTooOld;
|
|
@@ -0,0 +1,21 @@
|
|
|
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
|
+
// Generated by scripts/createShellVersion.mjs from package.json. Do not edit.
|
|
18
|
+
|
|
19
|
+
const shellVersion = '7.2.0';
|
|
20
|
+
|
|
21
|
+
export default shellVersion;
|
|
@@ -0,0 +1,32 @@
|
|
|
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 { execFileSync } from 'child_process';
|
|
18
|
+
import path from 'path';
|
|
19
|
+
|
|
20
|
+
import shellPackage from '../../package.json';
|
|
21
|
+
import shellVersion from './shellVersion.js';
|
|
22
|
+
|
|
23
|
+
// The committed version the bundle carries must be the package's: run
|
|
24
|
+
// `pnpm --filter=@lowdefy/shell shell-version` after changing it. `pnpm release:version` does.
|
|
25
|
+
test('src/version/shellVersion.js matches the @lowdefy/shell package version', () => {
|
|
26
|
+
expect(shellVersion).toBe(shellPackage.version);
|
|
27
|
+
expect(
|
|
28
|
+
execFileSync(process.execPath, [path.join(__dirname, '../../scripts/createShellVersion.mjs')], {
|
|
29
|
+
encoding: 'utf8',
|
|
30
|
+
})
|
|
31
|
+
).toBe(shellVersion);
|
|
32
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
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 callEndpoint from '../native/callEndpoint.js';
|
|
18
|
+
import reportShellError from '../host/reportShellError.js';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Each mobile.widgets source's data, from its endpoint: { [id]: { title, layout, url, count, label,
|
|
22
|
+
* items } }. A count source answers { count, label? }, a list source { items: [{ title, subtitle?
|
|
23
|
+
* }] }. A source whose endpoint fails keeps showing nothing new (it is left out, and the failure is
|
|
24
|
+
* reported). The url a widget
|
|
25
|
+
* opens is the source's path under the shell's scheme.
|
|
26
|
+
*
|
|
27
|
+
* @param {Object} params
|
|
28
|
+
* @param {Object} params.app The open app (currentApp.js).
|
|
29
|
+
*/
|
|
30
|
+
async function fetchWidgetData({ app }) {
|
|
31
|
+
const sources = app.session.getState().root?.widgets ?? [];
|
|
32
|
+
const entries = await Promise.all(
|
|
33
|
+
sources.map(async (source) => {
|
|
34
|
+
try {
|
|
35
|
+
const data = await callEndpoint({ app, endpointId: source.endpointId });
|
|
36
|
+
return [
|
|
37
|
+
source.id,
|
|
38
|
+
{
|
|
39
|
+
title: source.title,
|
|
40
|
+
layout: source.layout,
|
|
41
|
+
url: `${app.shell.scheme}://${(source.path ?? '/').replace(/^\//, '')}`,
|
|
42
|
+
count: data?.count ?? null,
|
|
43
|
+
label: data?.label ?? null,
|
|
44
|
+
items: (data?.items ?? []).slice(0, 6).map((item) => ({
|
|
45
|
+
title: String(item.title ?? ''),
|
|
46
|
+
subtitle: item.subtitle === undefined ? null : String(item.subtitle),
|
|
47
|
+
})),
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
} catch (error) {
|
|
51
|
+
reportShellError({ error, session: app.session });
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
);
|
|
56
|
+
return Object.fromEntries(entries.filter((entry) => entry !== null));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export default fetchWidgetData;
|
|
@@ -0,0 +1,156 @@
|
|
|
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 { Text, VStack, HStack, Spacer } from '@expo/ui/swift-ui';
|
|
18
|
+
import { font, foregroundStyle, lineLimit, widgetURL } from '@expo/ui/swift-ui/modifiers';
|
|
19
|
+
import { createWidget } from 'expo-widgets';
|
|
20
|
+
|
|
21
|
+
import fetchWidgetData from './fetchWidgetData.js';
|
|
22
|
+
import { getCurrentApp } from '../native/currentApp.js';
|
|
23
|
+
|
|
24
|
+
// The two fixed layouts, drawn by the widget extension from the props the app hands them
|
|
25
|
+
// ({ sources }) and the source the person picked when adding the widget (its `source` parameter).
|
|
26
|
+
// They run in the widget's own JavaScript runtime ('widget' directive), so they read nothing but
|
|
27
|
+
// their arguments.
|
|
28
|
+
function CountLayout(props, environment) {
|
|
29
|
+
'widget';
|
|
30
|
+
const sources = props.sources ?? {};
|
|
31
|
+
const source = sources[environment.configuration?.source] ?? sources[Object.keys(sources)[0]];
|
|
32
|
+
if (!source) {
|
|
33
|
+
return <Text>Open the app to load this widget.</Text>;
|
|
34
|
+
}
|
|
35
|
+
if (environment.widgetFamily === 'accessoryInline') {
|
|
36
|
+
return (
|
|
37
|
+
<Text modifiers={[widgetURL(source.url)]}>{`${source.count ?? '–'} ${
|
|
38
|
+
source.label ?? source.title
|
|
39
|
+
}`}</Text>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
return (
|
|
43
|
+
<VStack alignment="leading" modifiers={[widgetURL(source.url)]}>
|
|
44
|
+
<Text
|
|
45
|
+
modifiers={[
|
|
46
|
+
font({ size: 13, weight: 'semibold' }),
|
|
47
|
+
foregroundStyle({ type: 'hierarchical', style: 'secondary' }),
|
|
48
|
+
]}
|
|
49
|
+
>
|
|
50
|
+
{source.title}
|
|
51
|
+
</Text>
|
|
52
|
+
<Spacer />
|
|
53
|
+
<Text modifiers={[font({ size: 40, weight: 'bold' })]}>{String(source.count ?? '–')}</Text>
|
|
54
|
+
{source.label ? (
|
|
55
|
+
<Text
|
|
56
|
+
modifiers={[
|
|
57
|
+
font({ size: 13 }),
|
|
58
|
+
foregroundStyle({ type: 'hierarchical', style: 'secondary' }),
|
|
59
|
+
lineLimit(1),
|
|
60
|
+
]}
|
|
61
|
+
>
|
|
62
|
+
{source.label}
|
|
63
|
+
</Text>
|
|
64
|
+
) : null}
|
|
65
|
+
</VStack>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function ListLayout(props, environment) {
|
|
70
|
+
'widget';
|
|
71
|
+
const sources = props.sources ?? {};
|
|
72
|
+
const source = sources[environment.configuration?.source] ?? sources[Object.keys(sources)[0]];
|
|
73
|
+
if (!source) {
|
|
74
|
+
return <Text>Open the app to load this widget.</Text>;
|
|
75
|
+
}
|
|
76
|
+
const rows = environment.widgetFamily === 'systemLarge' ? 6 : 3;
|
|
77
|
+
return (
|
|
78
|
+
<VStack alignment="leading" spacing={6} modifiers={[widgetURL(source.url)]}>
|
|
79
|
+
<Text
|
|
80
|
+
modifiers={[
|
|
81
|
+
font({ size: 13, weight: 'semibold' }),
|
|
82
|
+
foregroundStyle({ type: 'hierarchical', style: 'secondary' }),
|
|
83
|
+
]}
|
|
84
|
+
>
|
|
85
|
+
{source.title}
|
|
86
|
+
</Text>
|
|
87
|
+
{source.items.slice(0, rows).map((item, index) => (
|
|
88
|
+
<HStack key={index}>
|
|
89
|
+
<VStack alignment="leading" spacing={0}>
|
|
90
|
+
<Text modifiers={[font({ size: 15, weight: 'medium' }), lineLimit(1)]}>
|
|
91
|
+
{item.title}
|
|
92
|
+
</Text>
|
|
93
|
+
{item.subtitle ? (
|
|
94
|
+
<Text
|
|
95
|
+
modifiers={[
|
|
96
|
+
font({ size: 12 }),
|
|
97
|
+
foregroundStyle({ type: 'hierarchical', style: 'secondary' }),
|
|
98
|
+
lineLimit(1),
|
|
99
|
+
]}
|
|
100
|
+
>
|
|
101
|
+
{item.subtitle}
|
|
102
|
+
</Text>
|
|
103
|
+
) : null}
|
|
104
|
+
</VStack>
|
|
105
|
+
<Spacer />
|
|
106
|
+
</HStack>
|
|
107
|
+
))}
|
|
108
|
+
{source.items.length === 0 ? (
|
|
109
|
+
<Text modifiers={[foregroundStyle({ type: 'hierarchical', style: 'secondary' })]}>
|
|
110
|
+
Nothing here.
|
|
111
|
+
</Text>
|
|
112
|
+
) : null}
|
|
113
|
+
<Spacer />
|
|
114
|
+
</VStack>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const countWidget = createWidget('LowdefyCount', CountLayout, { sources: {} });
|
|
119
|
+
const listWidget = createWidget('LowdefyList', ListLayout, { sources: {} });
|
|
120
|
+
|
|
121
|
+
// The sources a person picks from when adding a widget, by layout.
|
|
122
|
+
function setSourceOptions(sources) {
|
|
123
|
+
[
|
|
124
|
+
[countWidget, 'count'],
|
|
125
|
+
[listWidget, 'list'],
|
|
126
|
+
].forEach(([widget, layout]) => {
|
|
127
|
+
widget.setConfigurationParameterEnum(
|
|
128
|
+
'source',
|
|
129
|
+
Object.entries(sources)
|
|
130
|
+
.filter(([, source]) => source.layout === layout)
|
|
131
|
+
.map(([value, source]) => ({ name: source.title, value }))
|
|
132
|
+
);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* The widgets device feature (the widgets extension): RefreshWidgets, and the shell's own refreshes
|
|
138
|
+
* (refreshWidgets.js), fetch every source and hand each layout the sources of its kind.
|
|
139
|
+
*/
|
|
140
|
+
const widgets = {
|
|
141
|
+
async refresh() {
|
|
142
|
+
const sources = await fetchWidgetData({ app: await getCurrentApp() });
|
|
143
|
+
setSourceOptions(sources);
|
|
144
|
+
const pick = (layout) =>
|
|
145
|
+
Object.fromEntries(Object.entries(sources).filter(([, source]) => source.layout === layout));
|
|
146
|
+
countWidget.updateSnapshot({ sources: pick('count') });
|
|
147
|
+
listWidget.updateSnapshot({ sources: pick('list') });
|
|
148
|
+
return { sources: Object.keys(sources).length };
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
// The widgets extension's device features (profiles.js WIDGETS_ENTRY).
|
|
153
|
+
const features = { widgets };
|
|
154
|
+
const hosts = [];
|
|
155
|
+
|
|
156
|
+
export { features, hosts };
|
|
@@ -0,0 +1,31 @@
|
|
|
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 { getDeviceFeature, hasDeviceFeature } from '@lowdefy/blocks-native/device';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Refreshes the Home Screen and Lock Screen widgets from the app's mobile.widgets endpoints: at
|
|
21
|
+
* launch, on resume, on a push with data.refreshWidgets, on background fetch and on RefreshWidgets.
|
|
22
|
+
* A shell without the widgets extension has nothing to refresh.
|
|
23
|
+
*/
|
|
24
|
+
async function refreshWidgets() {
|
|
25
|
+
if (!hasDeviceFeature('widgets')) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
return getDeviceFeature({ feature: 'widgets', action: 'RefreshWidgets' }).refresh();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export default refreshWidgets;
|
|
@@ -0,0 +1,93 @@
|
|
|
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
|
+
const { withPodfile, withRunOnce, withSettingsGradle } = require('expo/config-plugins');
|
|
18
|
+
|
|
19
|
+
function quotedList(names) {
|
|
20
|
+
return `[${names.map((name) => `'${name}'`).join(', ')}]`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Replaces `pattern` once in a native project file, and fails the prebuild when the Expo template no
|
|
24
|
+
// longer has it: a shell that links a module it should not must never build quietly.
|
|
25
|
+
function replaceOnce({ contents, file, pattern, replace }) {
|
|
26
|
+
if (!pattern.test(contents)) {
|
|
27
|
+
throw new Error(
|
|
28
|
+
`Cannot exclude native modules: ${file} no longer matches ${pattern}. Update withExcludedNativeModules.js for this Expo template.`
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
return contents.replace(pattern, replace);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Leaves native modules out of a shell's native projects (getExclusions in shellVariant.js), so a
|
|
36
|
+
* shell carries only its capability profile's modules, and a release shell none of Lowdefy Dev's:
|
|
37
|
+
* - iOS: `use_expo_modules!` and the react-native-config command in the Podfile get `exclude`.
|
|
38
|
+
* - Android: settings.gradle sets `expoAutolinking.exclude` and adds `--exclude` to the
|
|
39
|
+
* react-native-config command.
|
|
40
|
+
* - Each module's config plugin is marked as run, so prebuild does not apply it on its own and
|
|
41
|
+
* add its permissions (NSCameraUsageDescription, NSMotionUsageDescription, CAMERA).
|
|
42
|
+
*
|
|
43
|
+
* @param {Object} config The Expo config.
|
|
44
|
+
* @param {string[]} modules The package names to leave out.
|
|
45
|
+
*/
|
|
46
|
+
function withExcludedNativeModules(config, modules) {
|
|
47
|
+
if (modules.length === 0) {
|
|
48
|
+
return config;
|
|
49
|
+
}
|
|
50
|
+
let result = modules.reduce(
|
|
51
|
+
(current, name) => withRunOnce(current, { plugin: (unchanged) => unchanged, name }),
|
|
52
|
+
config
|
|
53
|
+
);
|
|
54
|
+
result = withPodfile(result, (podfileConfig) => {
|
|
55
|
+
let { contents } = podfileConfig.modResults;
|
|
56
|
+
contents = replaceOnce({
|
|
57
|
+
contents,
|
|
58
|
+
file: 'Podfile',
|
|
59
|
+
pattern: /^(\s*)use_expo_modules!\s*$/m,
|
|
60
|
+
replace: `$1use_expo_modules!(exclude: ${quotedList(modules)})`,
|
|
61
|
+
});
|
|
62
|
+
contents = replaceOnce({
|
|
63
|
+
contents,
|
|
64
|
+
file: 'Podfile',
|
|
65
|
+
pattern: /('react-native-config',\s*'--json',\s*'--platform',\s*'ios')/,
|
|
66
|
+
replace: `$1,\n ${modules.map((name) => `'--exclude', '${name}'`).join(',\n ')}`,
|
|
67
|
+
});
|
|
68
|
+
podfileConfig.modResults.contents = contents;
|
|
69
|
+
return podfileConfig;
|
|
70
|
+
});
|
|
71
|
+
result = withSettingsGradle(result, (settingsConfig) => {
|
|
72
|
+
let { contents } = settingsConfig.modResults;
|
|
73
|
+
contents = replaceOnce({
|
|
74
|
+
contents,
|
|
75
|
+
file: 'settings.gradle',
|
|
76
|
+
pattern: /^expoAutolinking\.useExpoModules\(\)\s*$/m,
|
|
77
|
+
replace: `expoAutolinking.exclude = ${quotedList(modules)}\nexpoAutolinking.useExpoModules()`,
|
|
78
|
+
});
|
|
79
|
+
contents = replaceOnce({
|
|
80
|
+
contents,
|
|
81
|
+
file: 'settings.gradle',
|
|
82
|
+
pattern: /ex\.autolinkLibrariesFromCommand\(expoAutolinking\.rnConfigCommand\)/,
|
|
83
|
+
replace: `ex.autolinkLibrariesFromCommand(expoAutolinking.rnConfigCommand + ${quotedList(
|
|
84
|
+
modules.flatMap((name) => ['--exclude', name])
|
|
85
|
+
)})`,
|
|
86
|
+
});
|
|
87
|
+
settingsConfig.modResults.contents = contents;
|
|
88
|
+
return settingsConfig;
|
|
89
|
+
});
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
module.exports = withExcludedNativeModules;
|
package/dist/location.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.shellDirectory = exports.publicDirectory = void 0;
|
|
7
|
-
|
|
8
|
-
var _path = _interopRequireDefault(require("path"));
|
|
9
|
-
|
|
10
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
-
|
|
12
|
-
/*
|
|
13
|
-
Copyright 2020-2021 Lowdefy, Inc
|
|
14
|
-
|
|
15
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
|
16
|
-
you may not use this file except in compliance with the License.
|
|
17
|
-
You may obtain a copy of the License at
|
|
18
|
-
|
|
19
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
20
|
-
|
|
21
|
-
Unless required by applicable law or agreed to in writing, software
|
|
22
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
|
23
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
24
|
-
See the License for the specific language governing permissions and
|
|
25
|
-
limitations under the License.
|
|
26
|
-
*/
|
|
27
|
-
var publicDirectory = _path.default.resolve(__dirname, 'public');
|
|
28
|
-
|
|
29
|
-
exports.publicDirectory = publicDirectory;
|
|
30
|
-
|
|
31
|
-
var shellDirectory = _path.default.resolve(__dirname, 'shell');
|
|
32
|
-
|
|
33
|
-
exports.shellDirectory = shellDirectory;
|
|
Binary file
|
package/dist/public/icon-32.png
DELETED
|
Binary file
|
package/dist/public/icon-512.png
DELETED
|
Binary file
|
package/dist/public/icon.svg
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
-
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
3
|
-
<svg width="100%" height="100%" viewBox="0 0 94 94" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
|
4
|
-
<g transform="matrix(1,0,0,1,-979.672,-59.6924)">
|
|
5
|
-
<g transform="matrix(1,0,0,1.03297,-38.3284,-294.615)">
|
|
6
|
-
<g transform="matrix(1,0,0,1,952,232)">
|
|
7
|
-
<path d="M160,129.634C160,119.35 151.375,111 140.751,111L85.249,111C74.625,111 66,119.35 66,129.634L66,183.366C66,193.65 74.625,202 85.249,202L140.751,202C151.375,202 160,193.65 160,183.366L160,129.634Z"/>
|
|
8
|
-
</g>
|
|
9
|
-
<g transform="matrix(0.872141,0,0,1,1002.6,346)">
|
|
10
|
-
<rect x="36" y="12" width="36" height="59" style="fill:white;"/>
|
|
11
|
-
</g>
|
|
12
|
-
<g transform="matrix(0.78125,0,0,0.862069,1010.84,356.663)">
|
|
13
|
-
<rect x="77" y="41" width="32" height="29" style="fill:rgb(24,144,255);"/>
|
|
14
|
-
</g>
|
|
15
|
-
</g>
|
|
16
|
-
</g>
|
|
17
|
-
</svg>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|