mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-07 05:52:57 +00:00
Compare commits
2 Commits
ce5016a992
...
bb1f596bfc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb1f596bfc | ||
|
0c49fd8c34
|
38
flake.nix
38
flake.nix
@@ -4,22 +4,37 @@
|
|||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
};
|
};
|
||||||
outputs = {
|
outputs =
|
||||||
|
{
|
||||||
self,
|
self,
|
||||||
nixpkgs,
|
nixpkgs,
|
||||||
flake-utils,
|
flake-utils,
|
||||||
}: let
|
}:
|
||||||
|
let
|
||||||
aapt2buildToolsVersion = "33.0.2";
|
aapt2buildToolsVersion = "33.0.2";
|
||||||
in
|
in
|
||||||
flake-utils.lib.eachDefaultSystem (system: let
|
flake-utils.lib.eachDefaultSystem (
|
||||||
|
system:
|
||||||
|
let
|
||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
overlays = [
|
overlays = [
|
||||||
(final: prev: rec {
|
(final: prev: rec {
|
||||||
fontMin = prev.python311.withPackages (ps: with ps; [brotli fonttools] ++ (with fonttools.optional-dependencies; [woff]));
|
fontMin = prev.python311.withPackages (
|
||||||
|
ps:
|
||||||
|
with ps;
|
||||||
|
[
|
||||||
|
brotli
|
||||||
|
fonttools
|
||||||
|
]
|
||||||
|
++ (with fonttools.optional-dependencies; [ woff ])
|
||||||
|
);
|
||||||
android = prev.androidenv.composeAndroidPackages {
|
android = prev.androidenv.composeAndroidPackages {
|
||||||
buildToolsVersions = ["30.0.3" aapt2buildToolsVersion];
|
buildToolsVersions = [
|
||||||
platformVersions = ["33"];
|
"34.0.0"
|
||||||
|
aapt2buildToolsVersion
|
||||||
|
];
|
||||||
|
platformVersions = [ "34" ];
|
||||||
};
|
};
|
||||||
cypress = prev.cypress.overrideAttrs (cyPrev: rec {
|
cypress = prev.cypress.overrideAttrs (cyPrev: rec {
|
||||||
version = "13.2.0";
|
version = "13.2.0";
|
||||||
@@ -29,6 +44,7 @@
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
nodejs = prev.nodejs_18;
|
nodejs = prev.nodejs_18;
|
||||||
|
corepack = prev.corepack_18;
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
config = {
|
config = {
|
||||||
@@ -38,7 +54,7 @@
|
|||||||
};
|
};
|
||||||
androidFhs = pkgs.buildFHSUserEnv {
|
androidFhs = pkgs.buildFHSUserEnv {
|
||||||
name = "android-env";
|
name = "android-env";
|
||||||
targetPkgs = pkgs: with pkgs; [];
|
targetPkgs = pkgs: with pkgs; [ ];
|
||||||
runScript = "bash";
|
runScript = "bash";
|
||||||
profile = ''
|
profile = ''
|
||||||
export ALLOW_NINJA_ENV=true
|
export ALLOW_NINJA_ENV=true
|
||||||
@@ -46,9 +62,10 @@
|
|||||||
export LD_LIBRARY_PATH=/usr/lib:/usr/lib32
|
export LD_LIBRARY_PATH=/usr/lib:/usr/lib32
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
devShell = pkgs.mkShell rec {
|
devShell = pkgs.mkShell rec {
|
||||||
nativeBuildInputs = [androidFhs];
|
nativeBuildInputs = [ androidFhs ];
|
||||||
buildInputs = with pkgs; [
|
buildInputs = with pkgs; [
|
||||||
nodejs
|
nodejs
|
||||||
corepack
|
corepack
|
||||||
@@ -67,5 +84,6 @@
|
|||||||
CYPRESS_INSTALL_BINARY = "0";
|
CYPRESS_INSTALL_BINARY = "0";
|
||||||
CYPRESS_RUN_BINARY = "${pkgs.cypress}/bin/Cypress";
|
CYPRESS_RUN_BINARY = "${pkgs.cypress}/bin/Cypress";
|
||||||
};
|
};
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,8 @@ describe('ConfigProvider', () => {
|
|||||||
|
|
||||||
it('should fetch app configuration', async () => {
|
it('should fetch app configuration', async () => {
|
||||||
spyOn(configProvider.client, 'handshake').and.returnValue(Promise.resolve(sampleIndexResponse));
|
spyOn(configProvider.client, 'handshake').and.returnValue(Promise.resolve(sampleIndexResponse));
|
||||||
const result = await configProvider.fetch();
|
await configProvider.fetch();
|
||||||
|
const result = configProvider.config;
|
||||||
expect(result).toEqual(sampleIndexResponse);
|
expect(result).toEqual(sampleIndexResponse);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -110,7 +111,7 @@ describe('ConfigProvider', () => {
|
|||||||
expect(storageProviderSpy.has).toHaveBeenCalled();
|
expect(storageProviderSpy.has).toHaveBeenCalled();
|
||||||
expect(storageProviderSpy.get).toHaveBeenCalledTimes(0);
|
expect(storageProviderSpy.get).toHaveBeenCalledTimes(0);
|
||||||
expect(configProvider.client.handshake).toHaveBeenCalled();
|
expect(configProvider.client.handshake).toHaveBeenCalled();
|
||||||
expect(await configProvider.getValue('name')).toEqual(sampleIndexResponse.app.name);
|
expect(configProvider.getValue('name')).toEqual(sampleIndexResponse.app.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw error on failed initialisation', async () => {
|
it('should throw error on failed initialisation', async () => {
|
||||||
@@ -192,4 +193,31 @@ describe('ConfigProvider', () => {
|
|||||||
|
|
||||||
expect(configProvider.getValue('name')).toEqual(sampleIndexResponse.app.name);
|
expect(configProvider.getValue('name')).toEqual(sampleIndexResponse.app.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should fetch new config from remote on init', async () => {
|
||||||
|
storageProviderSpy.has.and.returnValue(Promise.resolve(true));
|
||||||
|
storageProviderSpy.get.and.returnValue(Promise.resolve(sampleIndexResponse));
|
||||||
|
spyOn(configProvider, 'fetch');
|
||||||
|
await configProvider.init();
|
||||||
|
|
||||||
|
expect(configProvider.fetch).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update the local config with the one from remote', async () => {
|
||||||
|
storageProviderSpy.has.and.returnValue(Promise.resolve(true));
|
||||||
|
storageProviderSpy.get.and.returnValue(Promise.resolve(sampleIndexResponse));
|
||||||
|
const newConfig = structuredClone(sampleIndexResponse);
|
||||||
|
newConfig.app.name = 'New app name';
|
||||||
|
spyOn(configProvider.client, 'handshake').and.returnValue(Promise.resolve(newConfig));
|
||||||
|
await configProvider.init();
|
||||||
|
|
||||||
|
// Validate that the initial configuration is loaded
|
||||||
|
expect(configProvider.getValue('name')).toEqual(sampleIndexResponse.app.name);
|
||||||
|
|
||||||
|
// Fetch the new configuration from the remote
|
||||||
|
await configProvider.fetch();
|
||||||
|
|
||||||
|
// Validate that the new configuration is now set
|
||||||
|
expect(configProvider.getValue('name')).toEqual(newConfig.app.name);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -83,17 +83,20 @@ export class ConfigProvider {
|
|||||||
/**
|
/**
|
||||||
* Fetches configuration from backend
|
* Fetches configuration from backend
|
||||||
*/
|
*/
|
||||||
async fetch(): Promise<SCIndexResponse> {
|
async fetch(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const isOffline = await firstValueFrom(this.internetConnectionService.offline$);
|
const isOffline = await firstValueFrom(this.internetConnectionService.offline$);
|
||||||
if (isOffline) {
|
if (isOffline) {
|
||||||
throw new Error('Device is offline.');
|
throw new Error('Device is offline.');
|
||||||
} else {
|
} else {
|
||||||
return await this.client.handshake(this.scVersion);
|
const fetchedConfig: SCIndexResponse = await this.client.handshake(this.scVersion);
|
||||||
|
await this.set(fetchedConfig);
|
||||||
|
this.logger.log(`Configuration updated from remote`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const error_ = error instanceof Error ? new ConfigFetchError(error.message) : new ConfigFetchError();
|
const error_ = error instanceof Error ? new ConfigFetchError(error.message) : new ConfigFetchError();
|
||||||
throw error_;
|
this.logger.warn(`Failed to fetch remote configuration:`, error_);
|
||||||
|
throw error_; // Rethrow the error to handle it in init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,40 +124,33 @@ export class ConfigProvider {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialises the ConfigProvider
|
* Initialises the ConfigProvider
|
||||||
* @throws ConfigInitError if no configuration could be loaded.
|
* @throws ConfigInitError if no configuration could be loaded both locally and remote.
|
||||||
* @throws WrongConfigVersionInStorage if fetch failed and saved config has wrong SCVersion
|
|
||||||
*/
|
*/
|
||||||
async init(): Promise<void> {
|
async init(): Promise<void> {
|
||||||
let loadError;
|
|
||||||
let fetchError;
|
|
||||||
// load saved configuration
|
|
||||||
try {
|
try {
|
||||||
|
// Attempt to load the configuration from local storage
|
||||||
this.config = await this.loadLocal();
|
this.config = await this.loadLocal();
|
||||||
this.firstSession = false;
|
this.firstSession = false;
|
||||||
this.logger.log(`initialised configuration from storage`);
|
this.logger.log(`initialised configuration from storage`);
|
||||||
|
|
||||||
|
// Check if the stored configuration has the correct version
|
||||||
if (this.config.backend.SCVersion.split('.')[0] !== this.scVersion.split('.')[0]) {
|
if (this.config.backend.SCVersion.split('.')[0] !== this.scVersion.split('.')[0]) {
|
||||||
loadError = new WrongConfigVersionInStorage(this.scVersion, this.config.backend.SCVersion);
|
throw new WrongConfigVersionInStorage(this.scVersion, this.config.backend.SCVersion);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
loadError = error;
|
// Fetch the remote configuration in a non-blocking manner
|
||||||
}
|
void this.fetch();
|
||||||
// fetch remote configuration from backend
|
} catch (loadError) {
|
||||||
|
this.logger.warn(loadError);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const fetchedConfig: SCIndexResponse = await this.fetch();
|
// If local loading fails, immediately try to fetch the configuration from remote
|
||||||
await this.set(fetchedConfig);
|
await this.fetch();
|
||||||
this.logger.log(`initialised configuration from remote`);
|
} catch (fetchError) {
|
||||||
} catch (error) {
|
this.logger.warn(`Failed to fetch remote configuration:`, fetchError);
|
||||||
fetchError = error;
|
// If both local loading and remote fetching fail, throw ConfigInitError
|
||||||
}
|
|
||||||
// check for occurred errors and throw them
|
|
||||||
if (loadError !== undefined && fetchError !== undefined) {
|
|
||||||
throw new ConfigInitError();
|
throw new ConfigInitError();
|
||||||
}
|
}
|
||||||
if (loadError !== undefined) {
|
|
||||||
this.logger.warn(loadError);
|
|
||||||
}
|
|
||||||
if (fetchError !== undefined) {
|
|
||||||
this.logger.warn(fetchError);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user