From d2c81202557c9639eb54ba74b3b9dbee359d33ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thea=20Sch=C3=B6bl?= Date: Fri, 8 Dec 2023 13:49:53 +0000 Subject: [PATCH] feat: simplify version history api --- .../backend/config/default/tools/version.js | 22 ++- .../config/f-u/version-history/index.js | 7 +- backend/backend/tsconfig.json | 6 +- backend/proxy/package.json | 4 +- .../app/ios/App/App.xcodeproj/project.pbxproj | 53 +++---- frontend/app/ios/App/Podfile | 2 +- frontend/app/ios/App/Podfile.lock | 131 ++++++++++++++++++ frontend/app/package.json | 4 +- .../app/modules/about/app-version.service.ts | 42 +++--- .../modules/about/release-notes.component.ts | 5 +- .../src/app/modules/about/release-notes.html | 10 +- packages/core/src/config/app.ts | 7 - pnpm-lock.yaml | 64 ++++----- 13 files changed, 240 insertions(+), 117 deletions(-) create mode 100644 frontend/app/ios/App/Podfile.lock diff --git a/backend/backend/config/default/tools/version.js b/backend/backend/config/default/tools/version.js index bb709980..b21b681e 100644 --- a/backend/backend/config/default/tools/version.js +++ b/backend/backend/config/default/tools/version.js @@ -1,5 +1,5 @@ // @ts-check -import {readFile} from 'fs/promises'; +import {readFile, readdir} from 'fs/promises'; /** * @example version(1, import.meta.url) @@ -23,20 +23,14 @@ export async function version(options, base) { } /** - * @param infos {Record} * @param base {string} Base path of the file as `import.meta.url` * @returns {Promise} */ -export async function versions(infos, base) { - return Promise.all( - Object.entries(infos).map(([versionName, published]) => - version( - { - published, - version: versionName, - }, - base, - ), - ), - ).then(it => it.sort(({version: a}, {version: b}) => -a.localeCompare(b, undefined, {numeric: true}))); +export async function versions(base) { + const directory = await readdir(new URL(base)); + const versions = [...new Set(directory.map(it => it.replace(/\.\w+\.md$/, '')))].sort( + (a, b) => -a.localeCompare(b, undefined, {numeric: true}), + ); + + return Promise.all(versions.map(versionName => version({version: versionName}, base))); } diff --git a/backend/backend/config/f-u/version-history/index.js b/backend/backend/config/f-u/version-history/index.js index 6941204c..17c5b102 100644 --- a/backend/backend/config/f-u/version-history/index.js +++ b/backend/backend/config/f-u/version-history/index.js @@ -2,11 +2,6 @@ import {versions} from '../../default/tools/version.js'; /** @type {import('@openstapps/core').SCAppVersionInfo[]} */ -const versionHistory = await versions( - { - '2.4.0': {}, - }, - import.meta.url, -); +const versionHistory = await versions(import.meta.url); export default versionHistory; diff --git a/backend/backend/tsconfig.json b/backend/backend/tsconfig.json index b36e2eac..72ef42e9 100644 --- a/backend/backend/tsconfig.json +++ b/backend/backend/tsconfig.json @@ -3,6 +3,8 @@ "compilerOptions": { "resolveJsonModule": true, "useUnknownInCatchVariables": false, - "allowJs": true - } + "allowJs": true, + "checkJs": true + }, + "exclude": ["app.js", "lib/"] } diff --git a/backend/proxy/package.json b/backend/proxy/package.json index 696e1bf6..69bb6971 100644 --- a/backend/proxy/package.json +++ b/backend/proxy/package.json @@ -50,7 +50,7 @@ "dockerode": "3.3.5", "is-cidr": "4.0.2", "mustache": "4.2.0", - "semver": "7.3.8", + "semver": "7.5.4", "typescript": "5.1.6" }, "devDependencies": { @@ -65,7 +65,7 @@ "@types/mustache": "4.2.2", "@types/node": "18.15.3", "@types/proxyquire": "1.3.28", - "@types/semver": "7.3.13", + "@types/semver": "7.5.6", "@types/sha1": "1.1.3", "@types/sinon": "10.0.14", "@types/sinon-chai": "3.2.9", diff --git a/frontend/app/ios/App/App.xcodeproj/project.pbxproj b/frontend/app/ios/App/App.xcodeproj/project.pbxproj index 3aee6aa2..7a22303a 100644 --- a/frontend/app/ios/App/App.xcodeproj/project.pbxproj +++ b/frontend/app/ios/App/App.xcodeproj/project.pbxproj @@ -14,7 +14,7 @@ 504EC30F1FED79650016851F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30E1FED79650016851F /* Assets.xcassets */; }; 504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC3101FED79650016851F /* LaunchScreen.storyboard */; }; 50B271D11FEDC1A000F3C39B /* public in Resources */ = {isa = PBXBuildFile; fileRef = 50B271D01FEDC1A000F3C39B /* public */; }; - A084ECDBA7D38E1E42DFC39D /* Pods_App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */; }; + 88B0D35EB4B7888A415041EE /* Pods_App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7C462D51B10BE605A8502F2C /* Pods_App.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -27,10 +27,10 @@ 504EC3111FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 504EC3131FED79650016851F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 50B271D01FEDC1A000F3C39B /* public */ = {isa = PBXFileReference; lastKnownFileType = folder; path = public; sourceTree = ""; }; - AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_App.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.release.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.release.xcconfig"; sourceTree = ""; }; + 7C462D51B10BE605A8502F2C /* Pods_App.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_App.framework; sourceTree = BUILT_PRODUCTS_DIR; }; E2D249FB277CB255005492AC /* App.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = App.entitlements; sourceTree = ""; }; - FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.debug.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.debug.xcconfig"; sourceTree = ""; }; + EA601541CA9010D807358964 /* Pods-App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.debug.xcconfig"; path = "Target Support Files/Pods-App/Pods-App.debug.xcconfig"; sourceTree = ""; }; + EB81CB8CD78E2A93A8154B20 /* Pods-App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.release.xcconfig"; path = "Target Support Files/Pods-App/Pods-App.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -38,28 +38,20 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - A084ECDBA7D38E1E42DFC39D /* Pods_App.framework in Frameworks */, + 88B0D35EB4B7888A415041EE /* Pods_App.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 27E2DDA53C4D2A4D1A88CE4A /* Frameworks */ = { - isa = PBXGroup; - children = ( - AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; 504EC2FB1FED79650016851F = { isa = PBXGroup; children = ( 504EC3061FED79650016851F /* App */, 504EC3051FED79650016851F /* Products */, - 7F8756D8B27F46E3366F6CEA /* Pods */, - 27E2DDA53C4D2A4D1A88CE4A /* Frameworks */, + 93DA7B5AF35933F9EF51EE34 /* Pods */, + 819423158BC1FAAD85B02762 /* Frameworks */, ); sourceTree = ""; }; @@ -87,13 +79,22 @@ path = App; sourceTree = ""; }; - 7F8756D8B27F46E3366F6CEA /* Pods */ = { + 819423158BC1FAAD85B02762 /* Frameworks */ = { isa = PBXGroup; children = ( - FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */, - AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */, + 7C462D51B10BE605A8502F2C /* Pods_App.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 93DA7B5AF35933F9EF51EE34 /* Pods */ = { + isa = PBXGroup; + children = ( + EA601541CA9010D807358964 /* Pods-App.debug.xcconfig */, + EB81CB8CD78E2A93A8154B20 /* Pods-App.release.xcconfig */, ); name = Pods; + path = Pods; sourceTree = ""; }; /* End PBXGroup section */ @@ -103,11 +104,11 @@ isa = PBXNativeTarget; buildConfigurationList = 504EC3161FED79650016851F /* Build configuration list for PBXNativeTarget "App" */; buildPhases = ( - 6634F4EFEBD30273BCE97C65 /* [CP] Check Pods Manifest.lock */, + 947055B15D65E7FC3ADB1FEB /* [CP] Check Pods Manifest.lock */, 504EC3001FED79650016851F /* Sources */, 504EC3011FED79650016851F /* Frameworks */, 504EC3021FED79650016851F /* Resources */, - 9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */, + F40DBF7576173B02228B7A71 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -169,16 +170,20 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 6634F4EFEBD30273BCE97C65 /* [CP] Check Pods Manifest.lock */ = { + 947055B15D65E7FC3ADB1FEB /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( "${PODS_PODFILE_DIR_PATH}/Podfile.lock", "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); outputPaths = ( "$(DERIVED_FILE_DIR)/Pods-App-checkManifestLockResult.txt", ); @@ -187,7 +192,7 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */ = { + F40DBF7576173B02228B7A71 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -344,7 +349,7 @@ }; 504EC3171FED79650016851F /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */; + baseConfigurationReference = EA601541CA9010D807358964 /* Pods-App.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = App/App.entitlements; @@ -366,7 +371,7 @@ }; 504EC3181FED79650016851F /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */; + baseConfigurationReference = EB81CB8CD78E2A93A8154B20 /* Pods-App.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = App/App.entitlements; diff --git a/frontend/app/ios/App/Podfile b/frontend/app/ios/App/Podfile index 5dd2ca52..604ef359 100644 --- a/frontend/app/ios/App/Podfile +++ b/frontend/app/ios/App/Podfile @@ -26,7 +26,7 @@ def capacitor_pods pod 'CapacitorShare', :path => '../../../../node_modules/.pnpm/@capacitor+share@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/share' pod 'CapacitorSplashScreen', :path => '../../../../node_modules/.pnpm/@capacitor+splash-screen@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/splash-screen' pod 'TransistorsoftCapacitorBackgroundFetch', :path => '../../../../node_modules/.pnpm/@transistorsoft+capacitor-background-fetch@1.0.2_@capacitor+core@5.5.0/node_modules/@transistorsoft/capacitor-background-fetch' - pod 'CapacitorSecureStoragePlugin', :path => '../../../../node_modules/.pnpm/capacitor-secure-storage-plugin@0.8.1_@capacitor+core@5.5.0/node_modules/capacitor-secure-storage-plugin' + pod 'CapacitorSecureStoragePlugin', :path => '../../../../node_modules/.pnpm/capacitor-secure-storage-plugin@0.9.0_@capacitor+core@5.5.0/node_modules/capacitor-secure-storage-plugin' pod 'CordovaPlugins', :path => '../capacitor-cordova-ios-plugins' end diff --git a/frontend/app/ios/App/Podfile.lock b/frontend/app/ios/App/Podfile.lock new file mode 100644 index 00000000..ef5d9a11 --- /dev/null +++ b/frontend/app/ios/App/Podfile.lock @@ -0,0 +1,131 @@ +PODS: + - Capacitor (5.5.0): + - CapacitorCordova + - CapacitorApp (5.0.6): + - Capacitor + - CapacitorBrowser (5.1.0): + - Capacitor + - CapacitorClipboard (5.0.6): + - Capacitor + - CapacitorCordova (5.5.0) + - CapacitorDevice (5.0.6): + - Capacitor + - CapacitorDialog (5.0.6): + - Capacitor + - CapacitorFilesystem (5.1.4): + - Capacitor + - CapacitorGeolocation (5.0.6): + - Capacitor + - CapacitorHaptics (5.0.6): + - Capacitor + - CapacitorKeyboard (5.0.6): + - Capacitor + - CapacitorLocalNotifications (5.0.6): + - Capacitor + - CapacitorNetwork (5.0.6): + - Capacitor + - CapacitorPreferences (5.0.6): + - Capacitor + - CapacitorSecureStoragePlugin (0.9.0): + - Capacitor + - SwiftKeychainWrapper + - CapacitorShare (5.0.6): + - Capacitor + - CapacitorSplashScreen (5.0.6): + - Capacitor + - CordovaPlugins (5.5.0): + - CapacitorCordova + - SwiftKeychainWrapper (4.0.1) + - TransistorsoftCapacitorBackgroundFetch (1.0.2): + - Capacitor + +DEPENDENCIES: + - "Capacitor (from `../../../../node_modules/.pnpm/@capacitor+ios@5.5.0_@capacitor+core@5.5.0/node_modules/@capacitor/ios`)" + - "CapacitorApp (from `../../../../node_modules/.pnpm/@capacitor+app@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/app`)" + - "CapacitorBrowser (from `../../../../node_modules/.pnpm/@capacitor+browser@5.1.0_@capacitor+core@5.5.0/node_modules/@capacitor/browser`)" + - "CapacitorClipboard (from `../../../../node_modules/.pnpm/@capacitor+clipboard@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/clipboard`)" + - "CapacitorCordova (from `../../../../node_modules/.pnpm/@capacitor+ios@5.5.0_@capacitor+core@5.5.0/node_modules/@capacitor/ios`)" + - "CapacitorDevice (from `../../../../node_modules/.pnpm/@capacitor+device@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/device`)" + - "CapacitorDialog (from `../../../../node_modules/.pnpm/@capacitor+dialog@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/dialog`)" + - "CapacitorFilesystem (from `../../../../node_modules/.pnpm/@capacitor+filesystem@5.1.4_@capacitor+core@5.5.0/node_modules/@capacitor/filesystem`)" + - "CapacitorGeolocation (from `../../../../node_modules/.pnpm/@capacitor+geolocation@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/geolocation`)" + - "CapacitorHaptics (from `../../../../node_modules/.pnpm/@capacitor+haptics@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/haptics`)" + - "CapacitorKeyboard (from `../../../../node_modules/.pnpm/@capacitor+keyboard@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/keyboard`)" + - "CapacitorLocalNotifications (from `../../../../node_modules/.pnpm/@capacitor+local-notifications@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/local-notifications`)" + - "CapacitorNetwork (from `../../../../node_modules/.pnpm/@capacitor+network@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/network`)" + - "CapacitorPreferences (from `../../../../node_modules/.pnpm/@capacitor+preferences@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/preferences`)" + - "CapacitorSecureStoragePlugin (from `../../../../node_modules/.pnpm/capacitor-secure-storage-plugin@0.9.0_@capacitor+core@5.5.0/node_modules/capacitor-secure-storage-plugin`)" + - "CapacitorShare (from `../../../../node_modules/.pnpm/@capacitor+share@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/share`)" + - "CapacitorSplashScreen (from `../../../../node_modules/.pnpm/@capacitor+splash-screen@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/splash-screen`)" + - CordovaPlugins (from `../capacitor-cordova-ios-plugins`) + - "TransistorsoftCapacitorBackgroundFetch (from `../../../../node_modules/.pnpm/@transistorsoft+capacitor-background-fetch@1.0.2_@capacitor+core@5.5.0/node_modules/@transistorsoft/capacitor-background-fetch`)" + +SPEC REPOS: + trunk: + - SwiftKeychainWrapper + +EXTERNAL SOURCES: + Capacitor: + :path: "../../../../node_modules/.pnpm/@capacitor+ios@5.5.0_@capacitor+core@5.5.0/node_modules/@capacitor/ios" + CapacitorApp: + :path: "../../../../node_modules/.pnpm/@capacitor+app@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/app" + CapacitorBrowser: + :path: "../../../../node_modules/.pnpm/@capacitor+browser@5.1.0_@capacitor+core@5.5.0/node_modules/@capacitor/browser" + CapacitorClipboard: + :path: "../../../../node_modules/.pnpm/@capacitor+clipboard@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/clipboard" + CapacitorCordova: + :path: "../../../../node_modules/.pnpm/@capacitor+ios@5.5.0_@capacitor+core@5.5.0/node_modules/@capacitor/ios" + CapacitorDevice: + :path: "../../../../node_modules/.pnpm/@capacitor+device@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/device" + CapacitorDialog: + :path: "../../../../node_modules/.pnpm/@capacitor+dialog@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/dialog" + CapacitorFilesystem: + :path: "../../../../node_modules/.pnpm/@capacitor+filesystem@5.1.4_@capacitor+core@5.5.0/node_modules/@capacitor/filesystem" + CapacitorGeolocation: + :path: "../../../../node_modules/.pnpm/@capacitor+geolocation@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/geolocation" + CapacitorHaptics: + :path: "../../../../node_modules/.pnpm/@capacitor+haptics@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/haptics" + CapacitorKeyboard: + :path: "../../../../node_modules/.pnpm/@capacitor+keyboard@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/keyboard" + CapacitorLocalNotifications: + :path: "../../../../node_modules/.pnpm/@capacitor+local-notifications@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/local-notifications" + CapacitorNetwork: + :path: "../../../../node_modules/.pnpm/@capacitor+network@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/network" + CapacitorPreferences: + :path: "../../../../node_modules/.pnpm/@capacitor+preferences@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/preferences" + CapacitorSecureStoragePlugin: + :path: "../../../../node_modules/.pnpm/capacitor-secure-storage-plugin@0.9.0_@capacitor+core@5.5.0/node_modules/capacitor-secure-storage-plugin" + CapacitorShare: + :path: "../../../../node_modules/.pnpm/@capacitor+share@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/share" + CapacitorSplashScreen: + :path: "../../../../node_modules/.pnpm/@capacitor+splash-screen@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/splash-screen" + CordovaPlugins: + :path: "../capacitor-cordova-ios-plugins" + TransistorsoftCapacitorBackgroundFetch: + :path: "../../../../node_modules/.pnpm/@transistorsoft+capacitor-background-fetch@1.0.2_@capacitor+core@5.5.0/node_modules/@transistorsoft/capacitor-background-fetch" + +SPEC CHECKSUMS: + Capacitor: 57890b363df14d5d2d5d8461aa23e886cb34da2a + CapacitorApp: 024e1b1bea5f883d79f6330d309bc441c88ad04a + CapacitorBrowser: 7a0fb6a1011abfaaf2dfedfd8248f942a8eda3d6 + CapacitorClipboard: 77edf49827ea21da2a9c05c690a4a6a4d07199c4 + CapacitorCordova: 3d3908a3d208a11a75f9df3b18c4405c4de76e1d + CapacitorDevice: 2c968f98a1ec4d22357418c1521e7ddc46c675e6 + CapacitorDialog: 0f3c15dfe9414b83bc64aef4078f1b92bcfead26 + CapacitorFilesystem: af704badfbc69f6f8623d9ed313e5490e3723dcb + CapacitorGeolocation: 7be5f77abc205c0efe319fff8587a7183e7b0240 + CapacitorHaptics: 1fffc1217c7e64a472d7845be50fb0c2f7d4204c + CapacitorKeyboard: b978154b024a5f65e044908e37d15b7de58b9d12 + CapacitorLocalNotifications: c2d8b14794064fd4814b1d6c4ddbac8029afa295 + CapacitorNetwork: d80b3e79bef6ec37640ee2806c19771f07ff2d0c + CapacitorPreferences: f03954bcb0ff09c792909e46bff88e3183c16b10 + CapacitorSecureStoragePlugin: e91d7df060f2495a1acff9583641a6953e3aacba + CapacitorShare: cd41743331cb71d217c029de54b681cbd91e0fcc + CapacitorSplashScreen: 5fa2ab5e46cf5cc530cf16a51c80c7a986579ccd + CordovaPlugins: de5669381702d76ed5b1d442177a6a5fc3252a9d + SwiftKeychainWrapper: 807ba1d63c33a7d0613288512399cd1eda1e470c + TransistorsoftCapacitorBackgroundFetch: 74ca62dae7ec78639eaf3d0d1e24c595ada213dd + +PODFILE CHECKSUM: 073b899f90bacc5049101cb9c562a168757d554e + +COCOAPODS: 1.13.0 diff --git a/frontend/app/package.json b/frontend/app/package.json index 50f1cba3..ad309323 100644 --- a/frontend/app/package.json +++ b/frontend/app/package.json @@ -107,6 +107,7 @@ "ngx-moment": "6.0.2", "opening_hours": "3.8.0", "rxjs": "7.8.1", + "semver": "7.5.4", "swiper": "8.4.5", "tslib": "2.4.1", "zone.js": "0.13.1" @@ -148,6 +149,7 @@ "@types/leaflet": "1.9.0", "@types/leaflet.markercluster": "1.5.1", "@types/node": "18.15.3", + "@types/semver": "7.5.6", "@typescript-eslint/eslint-plugin": "5.60.1", "@typescript-eslint/parser": "5.60.1", "cordova-res": "0.15.4", @@ -156,8 +158,8 @@ "eslint-plugin-jsdoc": "46.4.2", "eslint-plugin-prettier": "4.2.1", "eslint-plugin-unicorn": "47.0.0", - "fontkit": "2.0.2", "fast-deep-equal": "3.1.3", + "fontkit": "2.0.2", "glob": "10.2.7", "http-server": "14.1.1", "is-docker": "2.2.1", diff --git a/frontend/app/src/app/modules/about/app-version.service.ts b/frontend/app/src/app/modules/about/app-version.service.ts index bb3cbb1b..0fd2f5e4 100644 --- a/frontend/app/src/app/modules/about/app-version.service.ts +++ b/frontend/app/src/app/modules/about/app-version.service.ts @@ -6,6 +6,7 @@ import {Capacitor} from '@capacitor/core'; import {ReleaseNotesComponent} from './release-notes.component'; import {SCAppVersionInfo} from '@openstapps/core'; import {App} from '@capacitor/app'; +import {coerce} from 'semver'; export const RELEASE_NOTES_SHOWN_KEY = 'release_notes_shown'; @@ -17,14 +18,6 @@ export class AppVersionService { private modalController: ModalController, ) {} - /** - * Get the release notes of the latest published version - */ - get publishedVersions() { - const platform = Capacitor.getPlatform() as 'android' | 'ios' | 'web'; - return this.config.config.app.versionHistory?.filter(({published}) => published[platform] !== undefined); - } - /** * Get the latest release notes that have not been presented yet */ @@ -32,29 +25,38 @@ export class AppVersionService { if (Capacitor.getPlatform() === 'web') { return; } - const storedVersion = (await this.storage.has(RELEASE_NOTES_SHOWN_KEY)) - ? await this.storage.get(RELEASE_NOTES_SHOWN_KEY) - : ''; - const currentVersion = await App.getInfo().then(info => info.version); - return this.publishedVersions?.find(({version}) => { - const wasNotShown = version.localeCompare(storedVersion, undefined, {numeric: true}) === 1; - const isNotFutureVersion = version.localeCompare(currentVersion, undefined, {numeric: true}) <= 0; - return wasNotShown && isNotFutureVersion; - }); + const storedVersion = coerce( + (await this.storage.has(RELEASE_NOTES_SHOWN_KEY)) + ? await this.storage.get(RELEASE_NOTES_SHOWN_KEY) + : '0.0.0', + )!; + const currentVersion = coerce(await App.getInfo().then(info => info.version))!; + + return this.config.config.app.versionHistory + ?.filter(({version}) => { + const semanticVersion = coerce(version)!; + const wasNotShown = semanticVersion.compare(storedVersion) === 1; + const isNotFutureVersion = semanticVersion.compare(currentVersion) <= 0; + return wasNotShown && isNotFutureVersion; + }) + ?.sort((a, b) => coerce(a.version)!.compare(b.version)); } /** * Present release notes */ - async presentReleaseNotes(version: SCAppVersionInfo) { + async presentReleaseNotes(versions: SCAppVersionInfo[]) { + if (!versions || versions.length === 0) { + return; + } const modal = await this.modalController.create({ component: ReleaseNotesComponent, componentProps: { - versionInfo: version, + versionInfos: versions, }, }); await modal.present(); await modal.onDidDismiss(); - await this.storage.put(RELEASE_NOTES_SHOWN_KEY, version.version); + await this.storage.put(RELEASE_NOTES_SHOWN_KEY, versions[0].version); } } diff --git a/frontend/app/src/app/modules/about/release-notes.component.ts b/frontend/app/src/app/modules/about/release-notes.component.ts index 98d6ace4..cb932e2b 100644 --- a/frontend/app/src/app/modules/about/release-notes.component.ts +++ b/frontend/app/src/app/modules/about/release-notes.component.ts @@ -5,6 +5,7 @@ import {ThingTranslateModule} from '../../translation/thing-translate.module'; import {IonicModule, ModalController} from '@ionic/angular'; import {TranslateModule} from '@ngx-translate/core'; import {UtilModule} from '../../util/util.module'; +import {CommonModule} from '@angular/common'; @Component({ selector: 'stapps-release-notes', @@ -12,10 +13,10 @@ import {UtilModule} from '../../util/util.module'; styleUrls: ['release-notes.scss'], standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, - imports: [UtilModule, MarkdownModule, ThingTranslateModule, IonicModule, TranslateModule], + imports: [UtilModule, MarkdownModule, ThingTranslateModule, IonicModule, TranslateModule, CommonModule], }) export class ReleaseNotesComponent { - @Input() versionInfo: SCAppVersionInfo; + @Input() versionInfos: SCAppVersionInfo[]; constructor(readonly modalController: ModalController) {} } diff --git a/frontend/app/src/app/modules/about/release-notes.html b/frontend/app/src/app/modules/about/release-notes.html index dd50f0bb..757c8b60 100644 --- a/frontend/app/src/app/modules/about/release-notes.html +++ b/frontend/app/src/app/modules/about/release-notes.html @@ -9,8 +9,10 @@ - + + + diff --git a/packages/core/src/config/app.ts b/packages/core/src/config/app.ts index 3b3c1b84..4de3fe93 100644 --- a/packages/core/src/config/app.ts +++ b/packages/core/src/config/app.ts @@ -18,7 +18,6 @@ import {SCMap} from '../general/map.js'; import {SCLanguageSetting, SCSetting, SCUserGroupSetting} from '../things/setting.js'; import {SCAuthorizationProviderType} from './authorization.js'; import {SCFeatureConfiguration} from './feature.js'; -import {SCISO8601Date} from '../general/time.js'; /** * An app configuration menu item @@ -151,12 +150,6 @@ export interface SCAppConfiguration { * Info about app version releases */ export interface SCAppVersionInfo { - /** - * Published date for each platform. - * - * Missing entries mean the version has not been published on that platform yet. - */ - published: Partial>; /** * Version index that increments by one each version */ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 31482930..3febb51e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -273,8 +273,8 @@ importers: specifier: 4.2.0 version: 4.2.0 semver: - specifier: 7.3.8 - version: 7.3.8 + specifier: 7.5.4 + version: 7.5.4 typescript: specifier: 5.1.6 version: 5.1.6 @@ -304,8 +304,8 @@ importers: specifier: 1.3.28 version: 1.3.28 '@types/semver': - specifier: 7.3.13 - version: 7.3.13 + specifier: 7.5.6 + version: 7.5.6 '@types/sinon': specifier: 10.0.14 version: 10.0.14 @@ -881,6 +881,9 @@ importers: rxjs: specifier: 7.8.1 version: 7.8.1 + semver: + specifier: 7.5.4 + version: 7.5.4 swiper: specifier: 8.4.5 version: 8.4.5 @@ -999,6 +1002,9 @@ importers: '@types/node': specifier: 18.15.3 version: 18.15.3 + '@types/semver': + specifier: 7.5.6 + version: 7.5.6 '@typescript-eslint/eslint-plugin': specifier: 5.60.1 version: 5.60.1(@typescript-eslint/parser@5.60.1)(eslint@8.43.0)(typescript@5.1.6) @@ -4991,7 +4997,7 @@ packages: plist: 3.1.0 prompts: 2.4.2 rimraf: 4.4.1 - semver: 7.3.8 + semver: 7.5.4 tar: 6.2.0 tslib: 2.4.1 xml2js: 0.5.0 @@ -6309,7 +6315,7 @@ packages: resolution: {integrity: sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dependencies: - semver: 7.5.3 + semver: 7.5.4 /@npmcli/git@4.1.0: resolution: {integrity: sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==} @@ -6321,7 +6327,7 @@ packages: proc-log: 3.0.0 promise-inflight: 1.0.1 promise-retry: 2.0.1 - semver: 7.5.3 + semver: 7.5.4 which: 3.0.1 transitivePeerDependencies: - bluebird @@ -7256,12 +7262,8 @@ packages: resolution: {integrity: sha512-KQf+QAMWKMrtBMsB8/24w53tEsxllMj6TuA80TT/5igJalLI/zm0L3oXRbIAl4Ohfc85gyHX/jhMwsVkmhLU4A==} dev: true - /@types/semver@7.3.13: - resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==} - - /@types/semver@7.5.4: - resolution: {integrity: sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==} - dev: true + /@types/semver@7.5.6: + resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==} /@types/send@0.17.1: resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==} @@ -7642,13 +7644,13 @@ packages: dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.43.0) '@types/json-schema': 7.0.11 - '@types/semver': 7.3.13 + '@types/semver': 7.5.6 '@typescript-eslint/scope-manager': 5.60.1 '@typescript-eslint/types': 5.60.1 '@typescript-eslint/typescript-estree': 5.60.1(typescript@3.8.3) eslint: 8.43.0 eslint-scope: 5.1.1 - semver: 7.3.8 + semver: 7.5.4 transitivePeerDependencies: - supports-color - typescript @@ -7662,13 +7664,13 @@ packages: dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.43.0) '@types/json-schema': 7.0.11 - '@types/semver': 7.3.13 + '@types/semver': 7.5.6 '@typescript-eslint/scope-manager': 5.60.1 '@typescript-eslint/types': 5.60.1 '@typescript-eslint/typescript-estree': 5.60.1(typescript@5.1.6) eslint: 8.43.0 eslint-scope: 5.1.1 - semver: 7.3.8 + semver: 7.5.4 transitivePeerDependencies: - supports-color - typescript @@ -7681,7 +7683,7 @@ packages: dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.43.0) '@types/json-schema': 7.0.14 - '@types/semver': 7.5.4 + '@types/semver': 7.5.6 '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.1.6) @@ -8732,7 +8734,7 @@ packages: /builtins@5.0.1: resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} dependencies: - semver: 7.3.8 + semver: 7.5.4 dev: true /bundle-require@4.0.1(esbuild@0.17.19): @@ -9777,7 +9779,7 @@ packages: postcss-modules-scope: 3.0.0(postcss@8.4.24) postcss-modules-values: 4.0.0(postcss@8.4.24) postcss-value-parser: 4.2.0 - semver: 7.5.3 + semver: 7.5.4 webpack: 5.86.0(esbuild@0.17.19) dev: true @@ -15014,7 +15016,7 @@ packages: resolution: {integrity: sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA==} engines: {node: '>=10'} dependencies: - semver: 7.3.8 + semver: 7.5.4 dev: true /node-addon-api@3.2.1: @@ -15177,7 +15179,7 @@ packages: dependencies: hosted-git-info: 6.1.1 is-core-module: 2.13.0 - semver: 7.3.8 + semver: 7.5.4 validate-npm-package-license: 3.0.4 dev: true @@ -15206,7 +15208,7 @@ packages: resolution: {integrity: sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dependencies: - semver: 7.5.3 + semver: 7.5.4 dev: true /npm-normalize-package-bin@1.0.1: @@ -15224,7 +15226,7 @@ packages: dependencies: hosted-git-info: 6.1.1 proc-log: 3.0.0 - semver: 7.5.3 + semver: 7.5.4 validate-npm-package-name: 5.0.0 dev: true @@ -15242,7 +15244,7 @@ packages: npm-install-checks: 6.3.0 npm-normalize-package-bin: 3.0.1 npm-package-arg: 10.1.0 - semver: 7.5.3 + semver: 7.5.4 dev: true /npm-registry-fetch@14.0.5: @@ -15961,7 +15963,7 @@ packages: jiti: 1.20.0 klona: 2.0.6 postcss: 8.4.24 - semver: 7.5.3 + semver: 7.5.4 webpack: 5.86.0(esbuild@0.17.19) transitivePeerDependencies: - typescript @@ -17024,13 +17026,6 @@ packages: hasBin: true dev: true - /semver@7.3.8: - resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} - engines: {node: '>=10'} - hasBin: true - dependencies: - lru-cache: 6.0.0 - /semver@7.5.1: resolution: {integrity: sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==} engines: {node: '>=10'} @@ -17045,6 +17040,7 @@ packages: hasBin: true dependencies: lru-cache: 6.0.0 + dev: true /semver@7.5.4: resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} @@ -17150,7 +17146,7 @@ packages: detect-libc: 1.0.3 node-addon-api: 4.3.0 prebuild-install: 7.1.1 - semver: 7.3.8 + semver: 7.5.4 simple-get: 4.0.1 tar-fs: 2.1.1 tunnel-agent: 0.6.0