@nordicsemiconductor/pc-nrfconnect-shared 60.0.0-pre1
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/.github/ISSUE_TEMPLATE/custom.md +10 -0
- package/.husky/pre-push +3 -0
- package/.renovaterc.json +10 -0
- package/Changelog.md +2973 -0
- package/LICENSE +35 -0
- package/README.md +11 -0
- package/azure-pipelines.yml +34 -0
- package/config/eslintrc.js +190 -0
- package/config/jest.config.js +41 -0
- package/config/prettier.config.js +13 -0
- package/config/tsconfig.json +15 -0
- package/fw/bootloader/graviton_bootloader_v1.0.1-[nRF5_SDK_15.0.1-1.alpha_f76d012].zip +0 -0
- package/jest.config.js +7 -0
- package/main/index.ts +32 -0
- package/mocks/deviceLibMock.ts +21 -0
- package/mocks/electronMock.ts +15 -0
- package/mocks/electronStoreMock.ts +19 -0
- package/mocks/emptyMock.ts +7 -0
- package/mocks/fileMock.ts +13 -0
- package/mocks/gaMock.ts +9 -0
- package/mocks/mockTests.test.ts +15 -0
- package/mocks/packageJsonMock.ts +10 -0
- package/mocks/remoteMock.ts +17 -0
- package/package.json +132 -0
- package/scripts/check-app-properties.ts +197 -0
- package/scripts/check-for-typescript.ts +41 -0
- package/scripts/esbuild-bootstrap.js +15 -0
- package/scripts/esbuild-renderer.js +131 -0
- package/scripts/esbuild.js +57 -0
- package/scripts/installHusky.ts +17 -0
- package/scripts/nordic-publish.ts +485 -0
- package/scripts/nrfconnect-license.ts +277 -0
- package/scripts/prepare-shared-release.ts +122 -0
- package/scripts/release-shared.test.ts +132 -0
- package/scripts/release-shared.ts +207 -0
- package/src/About/About.tsx +25 -0
- package/src/About/AboutButton.tsx +28 -0
- package/src/About/ApplicationCard.tsx +83 -0
- package/src/About/DeviceCard.tsx +74 -0
- package/src/About/DocumentationCard.tsx +18 -0
- package/src/About/DocumentationSection.tsx +24 -0
- package/src/About/Section.tsx +21 -0
- package/src/About/ShortcutButton.tsx +41 -0
- package/src/About/SupportCard.tsx +97 -0
- package/src/About/about.scss +40 -0
- package/src/About/documentationSlice.ts +41 -0
- package/src/About/section.scss +15 -0
- package/src/About/shortcutSlice.ts +52 -0
- package/src/Alert/Alert.module.scss +29 -0
- package/src/Alert/Alert.tsx +37 -0
- package/src/App/App.test.tsx +47 -0
- package/src/App/App.tsx +227 -0
- package/src/App/ConnectedToStore.tsx +19 -0
- package/src/App/VisibilityBar.tsx +103 -0
- package/src/App/app.scss +83 -0
- package/src/App/appLayout.ts +95 -0
- package/src/App/shared.scss +49 -0
- package/src/App/visibility-bar.scss +55 -0
- package/src/Button/Button.tsx +66 -0
- package/src/Button/button.module.scss +154 -0
- package/src/Card/Card.tsx +26 -0
- package/src/Card/card.module.scss +28 -0
- package/src/Device/BrokenDeviceDialog/BrokenDeviceDialog.tsx +58 -0
- package/src/Device/BrokenDeviceDialog/broken-device-dialog.scss +18 -0
- package/src/Device/BrokenDeviceDialog/brokenDeviceDialogSlice.tsx +48 -0
- package/src/Device/DeviceSelector/BasicDeviceInfo.tsx +115 -0
- package/src/Device/DeviceSelector/DeviceIcon.tsx +27 -0
- package/src/Device/DeviceSelector/DeviceList/AnimatedList.tsx +62 -0
- package/src/Device/DeviceSelector/DeviceList/BrokenDevice.tsx +34 -0
- package/src/Device/DeviceSelector/DeviceList/Device.tsx +84 -0
- package/src/Device/DeviceSelector/DeviceList/DeviceList.tsx +113 -0
- package/src/Device/DeviceSelector/DeviceList/EditDeviceButtons.tsx +28 -0
- package/src/Device/DeviceSelector/DeviceList/MoreDeviceInfo.tsx +65 -0
- package/src/Device/DeviceSelector/DeviceList/RenameDevice.tsx +22 -0
- package/src/Device/DeviceSelector/DeviceList/broken-device.scss +32 -0
- package/src/Device/DeviceSelector/DeviceList/device-list.scss +64 -0
- package/src/Device/DeviceSelector/DeviceList/device.scss +28 -0
- package/src/Device/DeviceSelector/DeviceList/edit-device-buttons.scss +31 -0
- package/src/Device/DeviceSelector/DeviceList/more-device-info.scss +33 -0
- package/src/Device/DeviceSelector/DeviceList/rename-device.scss +13 -0
- package/src/Device/DeviceSelector/DeviceSelector.test.tsx +342 -0
- package/src/Device/DeviceSelector/DeviceSelector.tsx +173 -0
- package/src/Device/DeviceSelector/Favorite.tsx +49 -0
- package/src/Device/DeviceSelector/SelectDevice.tsx +36 -0
- package/src/Device/DeviceSelector/SelectedDevice.tsx +65 -0
- package/src/Device/DeviceSelector/arrow-down.svg +1 -0
- package/src/Device/DeviceSelector/basic-device-info.scss +62 -0
- package/src/Device/DeviceSelector/device-icon.scss +27 -0
- package/src/Device/DeviceSelector/favorite.scss +17 -0
- package/src/Device/DeviceSelector/select-device.scss +38 -0
- package/src/Device/DeviceSelector/selected-device.scss +57 -0
- package/src/Device/DeviceSetup/DeviceSetupView.tsx +102 -0
- package/src/Device/deviceAutoSelectSlice.ts +144 -0
- package/src/Device/deviceInfo/deviceInfo.ts +254 -0
- package/src/Device/deviceInfo/nRF51-Series-logo.svg +1 -0
- package/src/Device/deviceInfo/nRF52-Series-logo.svg +1 -0
- package/src/Device/deviceInfo/nRF53-Series-logo.svg +1 -0
- package/src/Device/deviceInfo/nRF70-Series_no-background_RGB.svg +36 -0
- package/src/Device/deviceInfo/nRF91-Series-logo.svg +1 -0
- package/src/Device/deviceInfo/ppk-logo.svg +1 -0
- package/src/Device/deviceInfo/unknown-logo.svg +30 -0
- package/src/Device/deviceInfo/unknown-nordic-logo.svg +25 -0
- package/src/Device/deviceLibWrapper.test.ts +97 -0
- package/src/Device/deviceLibWrapper.ts +133 -0
- package/src/Device/deviceLister.test.ts +89 -0
- package/src/Device/deviceLister.ts +396 -0
- package/src/Device/deviceSetup.ts +264 -0
- package/src/Device/deviceSetupSlice.ts +94 -0
- package/src/Device/deviceSlice.ts +248 -0
- package/src/Device/dfu-cc.ts +162 -0
- package/src/Device/initPacket.ts +402 -0
- package/src/Device/jprogOperations.ts +206 -0
- package/src/Device/sdfuOperations.ts +601 -0
- package/src/Dialog/Dialog.test.tsx +134 -0
- package/src/Dialog/Dialog.tsx +236 -0
- package/src/Dialog/dialog.scss +60 -0
- package/src/Dropdown/Dropdown.module.scss +83 -0
- package/src/Dropdown/Dropdown.test.tsx +62 -0
- package/src/Dropdown/Dropdown.tsx +106 -0
- package/src/ErrorBoundary/ErrorBoundary.test.tsx +105 -0
- package/src/ErrorBoundary/ErrorBoundary.tsx +186 -0
- package/src/ErrorBoundary/bug.svg +1 -0
- package/src/ErrorBoundary/error-boundary.scss +102 -0
- package/src/ErrorDialog/ErrorDialog.test.tsx +70 -0
- package/src/ErrorDialog/ErrorDialog.tsx +94 -0
- package/src/ErrorDialog/error.scss +14 -0
- package/src/ErrorDialog/errorDialogSlice.test.ts +64 -0
- package/src/ErrorDialog/errorDialogSlice.ts +80 -0
- package/src/FactoryReset/FactoryResetButton.test.tsx +46 -0
- package/src/FactoryReset/FactoryResetButton.tsx +81 -0
- package/src/InlineInput/InlineInput.tsx +170 -0
- package/src/InlineInput/NumberInlineInput.tsx +107 -0
- package/src/InlineInput/inline-input.scss +38 -0
- package/src/InlineInput/number-inline-input.scss +15 -0
- package/src/Log/LogEntry.tsx +62 -0
- package/src/Log/LogViewer.tsx +54 -0
- package/src/Log/log-entry.scss +30 -0
- package/src/Log/log-viewer.scss +24 -0
- package/src/Log/logSlice.ts +73 -0
- package/src/Log/syncLogToStore.ts +36 -0
- package/src/Logo/Logo.tsx +48 -0
- package/src/Logo/logo.scss +11 -0
- package/src/Logo/nordic-logo-blue-icon-only.png +0 -0
- package/src/Logo/nordic-logo-gray-icon-only.png +0 -0
- package/src/Logo/nordic-logo-white-icon-only.png +0 -0
- package/src/Main/Main.tsx +13 -0
- package/src/Main/main.scss +13 -0
- package/src/MasonryLayout/MasonryLayout.tsx +234 -0
- package/src/MasonryLayout/masonryLayout.module.scss +46 -0
- package/src/NavBar/NavBar.tsx +22 -0
- package/src/NavBar/NavMenu.test.tsx +41 -0
- package/src/NavBar/NavMenu.tsx +53 -0
- package/src/NavBar/NavMenuItem.tsx +41 -0
- package/src/NavBar/nav-bar.scss +26 -0
- package/src/NavBar/nav-menu-item.scss +34 -0
- package/src/OpenApp/openApp.ts +18 -0
- package/src/Panes/FeedbackPane.tsx +149 -0
- package/src/PseudoButton/PseudoButton.tsx +56 -0
- package/src/PseudoButton/pseudo-button.scss +11 -0
- package/src/SerialPort/ConflictingSettingsDialog.tsx +242 -0
- package/src/SerialPort/SerialPort.test.ts +54 -0
- package/src/SerialPort/SerialPort.ts +202 -0
- package/src/Shortcuts/Shortcut-item.scss +33 -0
- package/src/Shortcuts/Shortcut-modal.scss +20 -0
- package/src/Shortcuts/ShortcutItem.tsx +48 -0
- package/src/Shortcuts/ShortcutModal.tsx +67 -0
- package/src/SidePanel/Group.tsx +106 -0
- package/src/SidePanel/SidePanel.tsx +19 -0
- package/src/SidePanel/group.scss +42 -0
- package/src/SidePanel/sidepanel.scss +20 -0
- package/src/Slider/Bar.tsx +24 -0
- package/src/Slider/Factor.test.ts +48 -0
- package/src/Slider/Handle.tsx +121 -0
- package/src/Slider/Slider.test.tsx +25 -0
- package/src/Slider/Slider.tsx +91 -0
- package/src/Slider/Ticks.tsx +54 -0
- package/src/Slider/__snapshots__/Slider.test.tsx.snap +50 -0
- package/src/Slider/bar.scss +24 -0
- package/src/Slider/factor.ts +24 -0
- package/src/Slider/handle.scss +32 -0
- package/src/Slider/percentage.ts +67 -0
- package/src/Slider/range.ts +92 -0
- package/src/Slider/slider.scss +14 -0
- package/src/Slider/ticks.scss +28 -0
- package/src/Slider/variables.scss +16 -0
- package/src/StartStopButton/StartStopButton.tsx +60 -0
- package/src/StartStopButton/play-circle.svg +1 -0
- package/src/StartStopButton/start-stop-button.scss +47 -0
- package/src/StartStopButton/stop-circle.svg +1 -0
- package/src/StateSelector/StateSelector.tsx +64 -0
- package/src/StateSelector/state-selector.scss +38 -0
- package/src/Stepper/Stepper.tsx +139 -0
- package/src/Stepper/stepper.scss +127 -0
- package/src/Toggle/Toggle.tsx +120 -0
- package/src/Toggle/toggle.scss +109 -0
- package/src/bootstrap.scss +14 -0
- package/src/index.ts +146 -0
- package/src/logging/appTransport.test.ts +78 -0
- package/src/logging/appTransport.ts +41 -0
- package/src/logging/describeError.test.ts +38 -0
- package/src/logging/describeError.ts +56 -0
- package/src/logging/index.ts +103 -0
- package/src/logging/logBuffer.test.ts +41 -0
- package/src/logging/logBuffer.ts +24 -0
- package/src/logging/sendInitialLogMessages.ts +64 -0
- package/src/store.ts +60 -0
- package/src/svg.d.ts +15 -0
- package/src/utils/AppTypes.ts +60 -0
- package/src/utils/appDirs.ts +78 -0
- package/src/utils/bleChannels.ts +16 -0
- package/src/utils/classNames.test.ts +29 -0
- package/src/utils/classNames.ts +25 -0
- package/src/utils/colors.scss +46 -0
- package/src/utils/colors.ts +38 -0
- package/src/utils/describeVersion.ts +21 -0
- package/src/utils/environment.ts +6 -0
- package/src/utils/logLibVersions.ts +103 -0
- package/src/utils/open.ts +46 -0
- package/src/utils/packageJson.ts +60 -0
- package/src/utils/persistentStore.ts +144 -0
- package/src/utils/systemReport.ts +160 -0
- package/src/utils/truncateMiddle.test.ts +21 -0
- package/src/utils/truncateMiddle.ts +20 -0
- package/src/utils/usageData.ts +189 -0
- package/src/utils/useHotKey.ts +62 -0
- package/src/utils/useStopwatch.test.tsx +311 -0
- package/src/utils/useStopwatch.ts +140 -0
- package/src/variables.scss +820 -0
- package/styles.scss +88 -0
- package/test/dispatchTo.ts +23 -0
- package/test/index.ts +7 -0
- package/test/jestResolver.js +28 -0
- package/test/setupTests.ts +27 -0
- package/test/testUtil.ts +20 -0
- package/test/testrenderer.tsx +39 -0
- package/tsconfig.json +9 -0
- package/typings/externals.d.ts +31 -0
- package/typings/generated/main/index.d.ts +25 -0
- package/typings/generated/src/About/About.d.ts +4 -0
- package/typings/generated/src/About/AboutButton.d.ts +8 -0
- package/typings/generated/src/About/ApplicationCard.d.ts +3 -0
- package/typings/generated/src/About/DeviceCard.d.ts +3 -0
- package/typings/generated/src/About/DocumentationCard.d.ts +3 -0
- package/typings/generated/src/About/DocumentationSection.d.ts +9 -0
- package/typings/generated/src/About/Section.d.ts +8 -0
- package/typings/generated/src/About/ShortcutButton.d.ts +6 -0
- package/typings/generated/src/About/SupportCard.d.ts +3 -0
- package/typings/generated/src/About/documentationSlice.d.ts +12 -0
- package/typings/generated/src/About/shortcutSlice.d.ts +11 -0
- package/typings/generated/src/Alert/Alert.d.ts +10 -0
- package/typings/generated/src/App/App.d.ts +27 -0
- package/typings/generated/src/App/App.test.d.ts +1 -0
- package/typings/generated/src/App/ConnectedToStore.d.ts +7 -0
- package/typings/generated/src/App/VisibilityBar.d.ts +6 -0
- package/typings/generated/src/App/appLayout.d.ts +17 -0
- package/typings/generated/src/Button/Button.d.ts +13 -0
- package/typings/generated/src/Card/Card.d.ts +7 -0
- package/typings/generated/src/Device/BrokenDeviceDialog/BrokenDeviceDialog.d.ts +4 -0
- package/typings/generated/src/Device/BrokenDeviceDialog/brokenDeviceDialogSlice.d.ts +12 -0
- package/typings/generated/src/Device/DeviceSelector/BasicDeviceInfo.d.ts +11 -0
- package/typings/generated/src/Device/DeviceSelector/DeviceIcon.d.ts +7 -0
- package/typings/generated/src/Device/DeviceSelector/DeviceList/AnimatedList.d.ts +10 -0
- package/typings/generated/src/Device/DeviceSelector/DeviceList/BrokenDevice.d.ts +7 -0
- package/typings/generated/src/Device/DeviceSelector/DeviceList/Device.d.ts +10 -0
- package/typings/generated/src/Device/DeviceSelector/DeviceList/DeviceList.d.ts +10 -0
- package/typings/generated/src/Device/DeviceSelector/DeviceList/EditDeviceButtons.d.ts +9 -0
- package/typings/generated/src/Device/DeviceSelector/DeviceList/MoreDeviceInfo.d.ts +7 -0
- package/typings/generated/src/Device/DeviceSelector/DeviceList/RenameDevice.d.ts +6 -0
- package/typings/generated/src/Device/DeviceSelector/DeviceSelector.d.ts +20 -0
- package/typings/generated/src/Device/DeviceSelector/DeviceSelector.test.d.ts +1 -0
- package/typings/generated/src/Device/DeviceSelector/Favorite.d.ts +9 -0
- package/typings/generated/src/Device/DeviceSelector/SelectDevice.d.ts +8 -0
- package/typings/generated/src/Device/DeviceSelector/SelectedDevice.d.ts +7 -0
- package/typings/generated/src/Device/DeviceSetup/DeviceSetupView.d.ts +3 -0
- package/typings/generated/src/Device/deviceAutoSelectSlice.d.ts +28 -0
- package/typings/generated/src/Device/deviceInfo/deviceInfo.d.ts +18 -0
- package/typings/generated/src/Device/deviceLibWrapper.d.ts +8 -0
- package/typings/generated/src/Device/deviceLibWrapper.test.d.ts +1 -0
- package/typings/generated/src/Device/deviceLister.d.ts +25 -0
- package/typings/generated/src/Device/deviceLister.test.d.ts +2 -0
- package/typings/generated/src/Device/deviceSetup.d.ts +40 -0
- package/typings/generated/src/Device/deviceSetupSlice.d.ts +20 -0
- package/typings/generated/src/Device/deviceSlice.d.ts +30 -0
- package/typings/generated/src/Device/dfu-cc.d.ts +3 -0
- package/typings/generated/src/Device/initPacket.d.ts +109 -0
- package/typings/generated/src/Device/jprogOperations.d.ts +2 -0
- package/typings/generated/src/Device/sdfuOperations.d.ts +14 -0
- package/typings/generated/src/Dialog/Dialog.d.ts +64 -0
- package/typings/generated/src/Dialog/Dialog.test.d.ts +1 -0
- package/typings/generated/src/Dropdown/Dropdown.d.ts +16 -0
- package/typings/generated/src/Dropdown/Dropdown.test.d.ts +1 -0
- package/typings/generated/src/ErrorBoundary/ErrorBoundary.d.ts +26 -0
- package/typings/generated/src/ErrorBoundary/ErrorBoundary.test.d.ts +1 -0
- package/typings/generated/src/ErrorDialog/ErrorDialog.d.ts +4 -0
- package/typings/generated/src/ErrorDialog/ErrorDialog.test.d.ts +1 -0
- package/typings/generated/src/ErrorDialog/errorDialogSlice.d.ts +23 -0
- package/typings/generated/src/ErrorDialog/errorDialogSlice.test.d.ts +1 -0
- package/typings/generated/src/FactoryReset/FactoryResetButton.d.ts +12 -0
- package/typings/generated/src/FactoryReset/FactoryResetButton.test.d.ts +1 -0
- package/typings/generated/src/InlineInput/InlineInput.d.ts +14 -0
- package/typings/generated/src/InlineInput/NumberInlineInput.d.ts +12 -0
- package/typings/generated/src/Log/LogEntry.d.ts +7 -0
- package/typings/generated/src/Log/LogViewer.d.ts +5 -0
- package/typings/generated/src/Log/logSlice.d.ts +12 -0
- package/typings/generated/src/Log/syncLogToStore.d.ts +11 -0
- package/typings/generated/src/Logo/Logo.d.ts +6 -0
- package/typings/generated/src/Main/Main.d.ts +6 -0
- package/typings/generated/src/MasonryLayout/MasonryLayout.d.ts +14 -0
- package/typings/generated/src/NavBar/NavBar.d.ts +6 -0
- package/typings/generated/src/NavBar/NavMenu.d.ts +3 -0
- package/typings/generated/src/NavBar/NavMenu.test.d.ts +1 -0
- package/typings/generated/src/NavBar/NavMenuItem.d.ts +10 -0
- package/typings/generated/src/OpenApp/openApp.d.ts +7 -0
- package/typings/generated/src/Panes/FeedbackPane.d.ts +3 -0
- package/typings/generated/src/PseudoButton/PseudoButton.d.ts +10 -0
- package/typings/generated/src/SerialPort/ConflictingSettingsDialog.d.ts +13 -0
- package/typings/generated/src/SerialPort/SerialPort.d.ts +21 -0
- package/typings/generated/src/SerialPort/SerialPort.test.d.ts +1 -0
- package/typings/generated/src/Shortcuts/ShortcutItem.d.ts +8 -0
- package/typings/generated/src/Shortcuts/ShortcutModal.d.ts +8 -0
- package/typings/generated/src/SidePanel/Group.d.ts +16 -0
- package/typings/generated/src/SidePanel/SidePanel.d.ts +7 -0
- package/typings/generated/src/Slider/Bar.d.ts +7 -0
- package/typings/generated/src/Slider/Factor.test.d.ts +1 -0
- package/typings/generated/src/Slider/Handle.d.ts +13 -0
- package/typings/generated/src/Slider/Slider.d.ts +15 -0
- package/typings/generated/src/Slider/Slider.test.d.ts +1 -0
- package/typings/generated/src/Slider/Ticks.d.ts +12 -0
- package/typings/generated/src/Slider/factor.d.ts +1 -0
- package/typings/generated/src/Slider/percentage.d.ts +4 -0
- package/typings/generated/src/Slider/range.d.ts +13 -0
- package/typings/generated/src/StartStopButton/StartStopButton.d.ts +16 -0
- package/typings/generated/src/StateSelector/StateSelector.d.ts +15 -0
- package/typings/generated/src/Stepper/Stepper.d.ts +26 -0
- package/typings/generated/src/Toggle/Toggle.d.ts +19 -0
- package/typings/generated/src/index.d.ts +69 -0
- package/typings/generated/src/logging/appTransport.d.ts +12 -0
- package/typings/generated/src/logging/appTransport.test.d.ts +1 -0
- package/typings/generated/src/logging/describeError.d.ts +2 -0
- package/typings/generated/src/logging/describeError.test.d.ts +1 -0
- package/typings/generated/src/logging/index.d.ts +9 -0
- package/typings/generated/src/logging/logBuffer.d.ts +9 -0
- package/typings/generated/src/logging/logBuffer.test.d.ts +1 -0
- package/typings/generated/src/logging/sendInitialLogMessages.d.ts +2 -0
- package/typings/generated/src/store.d.ts +65 -0
- package/typings/generated/src/utils/AppTypes.d.ts +49 -0
- package/typings/generated/src/utils/appDirs.d.ts +35 -0
- package/typings/generated/src/utils/bleChannels.d.ts +6 -0
- package/typings/generated/src/utils/classNames.d.ts +17 -0
- package/typings/generated/src/utils/classNames.test.d.ts +1 -0
- package/typings/generated/src/utils/colors.d.ts +31 -0
- package/typings/generated/src/utils/describeVersion.d.ts +3 -0
- package/typings/generated/src/utils/environment.d.ts +1 -0
- package/typings/generated/src/utils/logLibVersions.d.ts +2 -0
- package/typings/generated/src/utils/open.d.ts +15 -0
- package/typings/generated/src/utils/packageJson.d.ts +4 -0
- package/typings/generated/src/utils/persistentStore.d.ts +35 -0
- package/typings/generated/src/utils/systemReport.d.ts +4 -0
- package/typings/generated/src/utils/truncateMiddle.d.ts +2 -0
- package/typings/generated/src/utils/truncateMiddle.test.d.ts +1 -0
- package/typings/generated/src/utils/usageData.d.ts +63 -0
- package/typings/generated/src/utils/useHotKey.d.ts +6 -0
- package/typings/generated/src/utils/useStopwatch.d.ts +22 -0
- package/typings/generated/src/utils/useStopwatch.test.d.ts +1 -0
- package/typings/generated/test/dispatchTo.d.ts +3 -0
- package/typings/generated/test/testrenderer.d.ts +5 -0
- package/typings/nrf-intel-hex.d.ts +58 -0
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
#!/usr/bin/env ts-node
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) 2015 Nordic Semiconductor ASA
|
|
5
|
+
*
|
|
6
|
+
* SPDX-License-Identifier: LicenseRef-Nordic-4-Clause
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { execSync } from 'child_process';
|
|
10
|
+
import { program } from 'commander';
|
|
11
|
+
import fs from 'fs';
|
|
12
|
+
import FtpClient from 'ftp';
|
|
13
|
+
import semver from 'semver';
|
|
14
|
+
import calculateShasum from 'shasum';
|
|
15
|
+
|
|
16
|
+
import { AppInfo, PackageJson, SourceJson } from '../src/utils/AppTypes';
|
|
17
|
+
import checkAppProperties from './check-app-properties';
|
|
18
|
+
|
|
19
|
+
interface LegacyAppInfo {
|
|
20
|
+
['dist-tags']?: {
|
|
21
|
+
latest?: string;
|
|
22
|
+
};
|
|
23
|
+
versions?: {
|
|
24
|
+
[version: string]: {
|
|
25
|
+
dist: {
|
|
26
|
+
tarball: string;
|
|
27
|
+
shasum: string;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface App {
|
|
34
|
+
filename: string;
|
|
35
|
+
name: string;
|
|
36
|
+
version: string;
|
|
37
|
+
shasum: string;
|
|
38
|
+
sourceUrl: string;
|
|
39
|
+
appInfoName: string;
|
|
40
|
+
releaseNotesFilename: string;
|
|
41
|
+
iconFilename: string;
|
|
42
|
+
isOfficial: boolean;
|
|
43
|
+
packageJson: PackageJson;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const client = new FtpClient();
|
|
47
|
+
|
|
48
|
+
const hasMessage = (error: unknown): error is { message: unknown } =>
|
|
49
|
+
error != null && typeof error === 'object' && 'message' in error;
|
|
50
|
+
|
|
51
|
+
const errorAsString = (error: unknown) =>
|
|
52
|
+
hasMessage(error) ? error.message : String(error);
|
|
53
|
+
|
|
54
|
+
const getSourceDir = (deployOfficial: boolean, sourceName: string) => {
|
|
55
|
+
const repoDirOfficial = '/.pc-tools/nrfconnect-apps';
|
|
56
|
+
|
|
57
|
+
if (process.env.REPO_DIR) return process.env.REPO_DIR;
|
|
58
|
+
if (deployOfficial) return repoDirOfficial;
|
|
59
|
+
|
|
60
|
+
return `${repoDirOfficial}/${sourceName}`;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const getSourceUrl = (deployOfficial: boolean, sourceName: string) => {
|
|
64
|
+
const repoUrlOfficial =
|
|
65
|
+
'https://developer.nordicsemi.com/.pc-tools/nrfconnect-apps';
|
|
66
|
+
|
|
67
|
+
if (process.env.REPO_URL) return process.env.REPO_URL;
|
|
68
|
+
if (deployOfficial) return repoUrlOfficial;
|
|
69
|
+
|
|
70
|
+
return `${repoUrlOfficial}/${sourceName}`;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
interface Options {
|
|
74
|
+
doPack: boolean;
|
|
75
|
+
doCreateSource: boolean;
|
|
76
|
+
deployOfficial: boolean;
|
|
77
|
+
sourceDir: string;
|
|
78
|
+
sourceUrl: string;
|
|
79
|
+
sourceName?: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const parseOptions = (): Options => {
|
|
83
|
+
program
|
|
84
|
+
.description('Publish to nordic repository')
|
|
85
|
+
.requiredOption(
|
|
86
|
+
'-s, --source <source>',
|
|
87
|
+
'Specify the source to publish (e.g. official).'
|
|
88
|
+
)
|
|
89
|
+
.option(
|
|
90
|
+
'-n, --no-pack',
|
|
91
|
+
'Publish existing .tgz file at the root directory without npm pack.'
|
|
92
|
+
)
|
|
93
|
+
.option(
|
|
94
|
+
'--create-source <source name>',
|
|
95
|
+
'Do not fail if the source specifiec with --source does not yet ' +
|
|
96
|
+
'exist but instead create a new source with this name ' +
|
|
97
|
+
'(e.g. "Release Test").'
|
|
98
|
+
)
|
|
99
|
+
.parse();
|
|
100
|
+
|
|
101
|
+
const options = program.opts();
|
|
102
|
+
|
|
103
|
+
const deployOfficial = options.source === 'official';
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
doPack: options.pack,
|
|
107
|
+
doCreateSource: options.createSource != null,
|
|
108
|
+
sourceName: options.createSource,
|
|
109
|
+
deployOfficial,
|
|
110
|
+
sourceDir: getSourceDir(deployOfficial, options.source),
|
|
111
|
+
sourceUrl: getSourceUrl(deployOfficial, options.source),
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const readPackageJson = (): PackageJson =>
|
|
116
|
+
JSON.parse(fs.readFileSync('./package.json', 'utf-8'));
|
|
117
|
+
|
|
118
|
+
const packPackage = () => {
|
|
119
|
+
console.log('Packing current package');
|
|
120
|
+
execSync('npm pack');
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const ensurePackageExists = (filename: string) => {
|
|
124
|
+
if (!fs.existsSync(filename)) {
|
|
125
|
+
throw new Error(`Package \`${filename}\` to publish is not found`);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const getShasum = (filePath: string) => {
|
|
130
|
+
try {
|
|
131
|
+
return calculateShasum(fs.readFileSync(filePath));
|
|
132
|
+
} catch (error) {
|
|
133
|
+
throw new Error(
|
|
134
|
+
`Unable to read file when verifying shasum: ${filePath}. \nError: ${errorAsString(
|
|
135
|
+
error
|
|
136
|
+
)}`
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const packOrReadPackage = (options: Options): App => {
|
|
142
|
+
const packageJson = readPackageJson();
|
|
143
|
+
const { name, version } = packageJson;
|
|
144
|
+
const filename = `${name}-${version}.tgz`;
|
|
145
|
+
|
|
146
|
+
if (options.doPack) {
|
|
147
|
+
packPackage();
|
|
148
|
+
} else {
|
|
149
|
+
ensurePackageExists(filename);
|
|
150
|
+
}
|
|
151
|
+
const shasum = getShasum(filename);
|
|
152
|
+
|
|
153
|
+
console.log(`Package name: ${name} version: ${version}`);
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
name,
|
|
157
|
+
version,
|
|
158
|
+
filename,
|
|
159
|
+
shasum,
|
|
160
|
+
sourceUrl: options.sourceUrl,
|
|
161
|
+
isOfficial: options.deployOfficial,
|
|
162
|
+
appInfoName: `${name}.json`,
|
|
163
|
+
releaseNotesFilename: `${name}-Changelog.md`,
|
|
164
|
+
iconFilename: `${name}.svg`,
|
|
165
|
+
packageJson,
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const connect = (config: {
|
|
170
|
+
host: string;
|
|
171
|
+
port: number;
|
|
172
|
+
user: string;
|
|
173
|
+
password: string;
|
|
174
|
+
}) =>
|
|
175
|
+
new Promise<void>((resolve, reject) => {
|
|
176
|
+
console.log(
|
|
177
|
+
`Connecting to ftp://${config.user}@${config.host}:${config.port}`
|
|
178
|
+
);
|
|
179
|
+
client.once('error', err => {
|
|
180
|
+
client.removeAllListeners('ready');
|
|
181
|
+
reject(err);
|
|
182
|
+
});
|
|
183
|
+
client.once('ready', () => {
|
|
184
|
+
client.removeAllListeners('error');
|
|
185
|
+
resolve();
|
|
186
|
+
});
|
|
187
|
+
client.connect(config);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
const createSourceDirectory = (dir: string) =>
|
|
191
|
+
new Promise<void>((resolve, reject) => {
|
|
192
|
+
console.log(`Creating source directory ${dir}`);
|
|
193
|
+
client.mkdir(dir, true, err => {
|
|
194
|
+
if (err) {
|
|
195
|
+
reject(new Error(`Failed to create source directory.`));
|
|
196
|
+
} else {
|
|
197
|
+
resolve();
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
const changeWorkingDirectory = (dir: string) =>
|
|
203
|
+
new Promise<void>((resolve, reject) => {
|
|
204
|
+
console.log(`Changing to directory ${dir}`);
|
|
205
|
+
client.cwd(dir, err => {
|
|
206
|
+
if (err) {
|
|
207
|
+
reject(
|
|
208
|
+
new Error(
|
|
209
|
+
'\nError: Failed to change to directory. ' +
|
|
210
|
+
'Check whether it exists on the FTP server.\n' +
|
|
211
|
+
'If you want to create a new source, use the ' +
|
|
212
|
+
'--create-source option.'
|
|
213
|
+
)
|
|
214
|
+
);
|
|
215
|
+
} else {
|
|
216
|
+
resolve();
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
const downloadFileContent = (filename: string) =>
|
|
222
|
+
new Promise<string>((resolve, reject) => {
|
|
223
|
+
console.log(`Downloading file ${filename}`);
|
|
224
|
+
let data = '';
|
|
225
|
+
client.get(filename, (err, stream) => {
|
|
226
|
+
if (err) return reject(err);
|
|
227
|
+
stream.once('close', () => resolve(data));
|
|
228
|
+
stream.on('data', chunk => {
|
|
229
|
+
data += chunk;
|
|
230
|
+
});
|
|
231
|
+
return undefined;
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
const downloadLegacyAppInfo = async (name: string): Promise<LegacyAppInfo> => {
|
|
236
|
+
try {
|
|
237
|
+
const content = await downloadFileContent(name);
|
|
238
|
+
return JSON.parse(content);
|
|
239
|
+
} catch (error) {
|
|
240
|
+
console.log(
|
|
241
|
+
`App info file will be created from scratch due to: ${errorAsString(
|
|
242
|
+
error
|
|
243
|
+
)}`
|
|
244
|
+
);
|
|
245
|
+
return {};
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
const updateLegacyAppInfo = (appInfo: LegacyAppInfo, app: App) => {
|
|
250
|
+
const latest = appInfo['dist-tags']?.latest;
|
|
251
|
+
if (latest != null) {
|
|
252
|
+
console.log(`Latest published version ${latest}`);
|
|
253
|
+
|
|
254
|
+
if (semver.lte(app.version, latest) && app.isOfficial) {
|
|
255
|
+
throw new Error(
|
|
256
|
+
'Current package version cannot be published, bump it higher'
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return {
|
|
262
|
+
...appInfo,
|
|
263
|
+
'dist-tags': {
|
|
264
|
+
...appInfo['dist-tags'],
|
|
265
|
+
latest: app.version,
|
|
266
|
+
},
|
|
267
|
+
versions: {
|
|
268
|
+
...appInfo.versions,
|
|
269
|
+
[app.version]: {
|
|
270
|
+
dist: {
|
|
271
|
+
tarball: `${app.sourceUrl}/${app.filename}`,
|
|
272
|
+
shasum: app.shasum,
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
type UploadLocalFile = (localFileName: string, remote: string) => Promise<void>;
|
|
280
|
+
type UploadBufferContent = (content: Buffer, remote: string) => Promise<void>;
|
|
281
|
+
|
|
282
|
+
const uploadFile: UploadLocalFile & UploadBufferContent = (
|
|
283
|
+
local: string | Buffer,
|
|
284
|
+
remote: string
|
|
285
|
+
) =>
|
|
286
|
+
new Promise<void>((resolve, reject) => {
|
|
287
|
+
console.log(`Uploading file ${remote}`);
|
|
288
|
+
client.put(local, remote, err => (err ? reject(err) : resolve()));
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
const getUpdatedLegacyAppInfo = async (app: App) => {
|
|
292
|
+
const appInfo = await downloadLegacyAppInfo(app.name);
|
|
293
|
+
return updateLegacyAppInfo(appInfo, app);
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
const createBlankSourceJson = async (name: string) => {
|
|
297
|
+
try {
|
|
298
|
+
await downloadFileContent('source.json');
|
|
299
|
+
} catch {
|
|
300
|
+
// Expected that the download throws an exception,
|
|
301
|
+
// because the file is supposed to not exist yet
|
|
302
|
+
return {
|
|
303
|
+
name,
|
|
304
|
+
apps: [],
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
throw new Error(
|
|
309
|
+
'`--create-source` given, but a `source.json` already exists on the server.'
|
|
310
|
+
);
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
const downloadSourceJson = async () => {
|
|
314
|
+
let sourceJsonContent;
|
|
315
|
+
try {
|
|
316
|
+
sourceJsonContent = await downloadFileContent('source.json');
|
|
317
|
+
const sourceJson = <SourceJson>JSON.parse(sourceJsonContent);
|
|
318
|
+
if (
|
|
319
|
+
sourceJson == null ||
|
|
320
|
+
typeof sourceJson !== 'object' ||
|
|
321
|
+
sourceJson.name == null ||
|
|
322
|
+
(sourceJson.apps !== undefined && !Array.isArray(sourceJson.apps))
|
|
323
|
+
) {
|
|
324
|
+
throw new Error(
|
|
325
|
+
'`source.json` does not have the expected content.'
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return sourceJson;
|
|
330
|
+
} catch (error) {
|
|
331
|
+
const message = 'Unable to read `source.json` on the server.\nError: ';
|
|
332
|
+
const caughtError = errorAsString(error);
|
|
333
|
+
const maybeSourceJsonContent =
|
|
334
|
+
sourceJsonContent == null
|
|
335
|
+
? ''
|
|
336
|
+
: `Content: \`${sourceJsonContent}\``;
|
|
337
|
+
|
|
338
|
+
throw new Error(message + caughtError + maybeSourceJsonContent);
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
const getUpdatedSourceJson = async (
|
|
343
|
+
app: App,
|
|
344
|
+
options: Options
|
|
345
|
+
): Promise<SourceJson> => {
|
|
346
|
+
const sourceJson = await (options.doCreateSource
|
|
347
|
+
? createBlankSourceJson(options.sourceName!) // eslint-disable-line @typescript-eslint/no-non-null-assertion -- Can never be null because of the control flow
|
|
348
|
+
: downloadSourceJson());
|
|
349
|
+
return {
|
|
350
|
+
name: sourceJson.name,
|
|
351
|
+
apps: [
|
|
352
|
+
...new Set(sourceJson.apps).add(
|
|
353
|
+
`${app.sourceUrl}/${app.appInfoName}`
|
|
354
|
+
),
|
|
355
|
+
].sort(),
|
|
356
|
+
};
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
const downloadExistingVersions = async (app: App) => {
|
|
360
|
+
try {
|
|
361
|
+
const appInfoContent = await downloadFileContent(app.appInfoName);
|
|
362
|
+
return (JSON.parse(appInfoContent) as AppInfo).versions;
|
|
363
|
+
} catch (error) {
|
|
364
|
+
console.log(
|
|
365
|
+
`No previous app versions found due to: ${errorAsString(error)}`
|
|
366
|
+
);
|
|
367
|
+
|
|
368
|
+
return {};
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
const failBecauseOfMissingProperty = () => {
|
|
373
|
+
throw new Error(
|
|
374
|
+
'This must never happen, because the properties were already checked before'
|
|
375
|
+
);
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
const getUpdatedAppInfo = async (app: App): Promise<AppInfo> => {
|
|
379
|
+
const versions = await downloadExistingVersions(app);
|
|
380
|
+
|
|
381
|
+
const { name, displayName, description, homepage, version } =
|
|
382
|
+
app.packageJson;
|
|
383
|
+
|
|
384
|
+
return {
|
|
385
|
+
name,
|
|
386
|
+
displayName: displayName ?? failBecauseOfMissingProperty(),
|
|
387
|
+
description: description ?? failBecauseOfMissingProperty(),
|
|
388
|
+
homepage,
|
|
389
|
+
iconUrl: `${app.sourceUrl}/${app.iconFilename}`,
|
|
390
|
+
releaseNotesUrl: `${app.sourceUrl}/${app.releaseNotesFilename}`,
|
|
391
|
+
latestVersion: version,
|
|
392
|
+
versions: {
|
|
393
|
+
...versions,
|
|
394
|
+
[version]: {
|
|
395
|
+
tarballUrl: `${app.sourceUrl}/${app.filename}`,
|
|
396
|
+
shasum: app.shasum,
|
|
397
|
+
},
|
|
398
|
+
},
|
|
399
|
+
};
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
const uploadLegacyAppInfo = (app: App, appInfo: LegacyAppInfo) =>
|
|
403
|
+
uploadFile(Buffer.from(JSON.stringify(appInfo, undefined, 2)), app.name);
|
|
404
|
+
|
|
405
|
+
const uploadSourceJson = (sourceJson: SourceJson) =>
|
|
406
|
+
uploadFile(
|
|
407
|
+
Buffer.from(JSON.stringify(sourceJson, undefined, 2)),
|
|
408
|
+
'source.json'
|
|
409
|
+
);
|
|
410
|
+
|
|
411
|
+
const uploadAppInfo = (app: App, appInfo: AppInfo) =>
|
|
412
|
+
uploadFile(
|
|
413
|
+
Buffer.from(JSON.stringify(appInfo, undefined, 2)),
|
|
414
|
+
app.appInfoName
|
|
415
|
+
);
|
|
416
|
+
|
|
417
|
+
const uploadPackage = (app: App) => uploadFile(app.filename, app.filename);
|
|
418
|
+
|
|
419
|
+
const uploadChangelog = (app: App) => {
|
|
420
|
+
const changelogFilename = 'Changelog.md';
|
|
421
|
+
if (!fs.existsSync(changelogFilename)) {
|
|
422
|
+
const errorMsg = `There should be a changelog called "${changelogFilename}". Please provide it!`;
|
|
423
|
+
return Promise.reject(new Error(errorMsg));
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
return uploadFile(changelogFilename, app.releaseNotesFilename);
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
const uploadIcon = (app: App) => {
|
|
430
|
+
const localIconFilename = 'resources/icon.svg';
|
|
431
|
+
if (!fs.existsSync(localIconFilename)) {
|
|
432
|
+
const errorMsg = `There must be an icon called "${localIconFilename}". Please provide it!`;
|
|
433
|
+
return Promise.reject(new Error(errorMsg));
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
return uploadFile(localIconFilename, app.iconFilename);
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
const main = async () => {
|
|
440
|
+
try {
|
|
441
|
+
/*
|
|
442
|
+
* To use this script REPO_HOST, REPO_USER and REPO_PASS will need to be set
|
|
443
|
+
*/
|
|
444
|
+
const config = {
|
|
445
|
+
host: process.env.REPO_HOST || 'localhost',
|
|
446
|
+
port: Number(process.env.REPO_PORT) || 21,
|
|
447
|
+
user: process.env.REPO_USER || 'anonymous',
|
|
448
|
+
password: process.env.REPO_PASS || 'anonymous@',
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
const options = parseOptions();
|
|
452
|
+
|
|
453
|
+
checkAppProperties({
|
|
454
|
+
checkChangelogHasCurrentEntry: options.deployOfficial,
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
const app = packOrReadPackage(options);
|
|
458
|
+
|
|
459
|
+
await connect(config);
|
|
460
|
+
if (options.doCreateSource) {
|
|
461
|
+
await createSourceDirectory(options.sourceDir);
|
|
462
|
+
}
|
|
463
|
+
await changeWorkingDirectory(options.sourceDir);
|
|
464
|
+
|
|
465
|
+
const legacyAppInfo = await getUpdatedLegacyAppInfo(app);
|
|
466
|
+
const sourceJson = await getUpdatedSourceJson(app, options);
|
|
467
|
+
const appInfo = await getUpdatedAppInfo(app);
|
|
468
|
+
|
|
469
|
+
await uploadChangelog(app);
|
|
470
|
+
await uploadIcon(app);
|
|
471
|
+
await uploadPackage(app);
|
|
472
|
+
await uploadLegacyAppInfo(app, legacyAppInfo);
|
|
473
|
+
await uploadAppInfo(app, appInfo);
|
|
474
|
+
await uploadSourceJson(sourceJson);
|
|
475
|
+
|
|
476
|
+
console.log('Done');
|
|
477
|
+
} catch (error) {
|
|
478
|
+
console.error(errorAsString(error));
|
|
479
|
+
process.exitCode = 1;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
client.end();
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
main();
|