Skip to content

Commit

Permalink
Feat/cli/appmanager/refactoring-commands (#2450)
Browse files Browse the repository at this point in the history
* fix(cli): improving docs and types

* feat(cli): refactoring and error handling in commands using apps-service

* fix: lint fixes

* fix(cli): todo in getEndpointUrl, and not using default import in dev-proxy
  • Loading branch information
eikeland committed Sep 30, 2024
1 parent 8440d7c commit e9f9fb6
Show file tree
Hide file tree
Showing 21 changed files with 616 additions and 421 deletions.
4 changes: 1 addition & 3 deletions cookbooks/app-react/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
import { mergeAppConfigs, defineAppConfig } from '@equinor/fusion-framework-cli';
export default defineAppConfig((_nev, { base }) =>
mergeAppConfigs(base, {
environment: {
scope: 'foobar',
},
environment: {},
endpoints: {
api: {
url: 'https://foo.bars',
Expand Down
6 changes: 3 additions & 3 deletions packages/cli/docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ Commands:

Options:

```sh
-h, --help display help for command
```
| Option | Description |
|----------|-----------------------|
| -h, --help | display help for command |

Example:

Expand Down
65 changes: 41 additions & 24 deletions packages/cli/docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,27 @@ import { mergeAppConfigs, defineAppConfig } from '@equinor/fusion-framework-cli'
export default defineAppConfig((_env, { base }) =>
mergeAppConfigs(base, {
environment: {
endpoints: {
api: {
url: 'https://foo.bar',
scopes: ['default']
}
}
fish: 'they can fly?',
shrimp: {
type: 'crustation',
desc: 'cockroach of the sea'
}
},
endpoints: {
api: {
url: 'https://foo.bar',
scopes: ['default'],
},
},
}),
);
```

You can configure framework services in the `src/config.ts` file.

> this is the configuration used by the application to configure framework services and modules
```ts
// src/config.ts
import type { AppModuleInitiator } from '@equinor/fusion-framework-react-app';
export const configure: AppModuleInitiator = (configurator, { env }) => {
Expand All @@ -40,16 +51,17 @@ export const configure: AppModuleInitiator = (configurator, { env }) => {

By default the CLI will create a manifest on best effort from `package.json`

You can override defaults with mergeManifests

```ts
// app.manifest.config.ts
// app.manifest.config.ts should be of type AppManifestExport
import { defineAppManifest, mergeManifests } from '@equinor/fusion-framework-cli';

export default defineAppManifest((env, { base }) => {
return mergeManifests(
base,
{
/** override name from package.json */
"appKey": "my-key",
entryPoint: 'index.js'
}
)
});
Expand All @@ -59,21 +71,28 @@ export default defineAppManifest((env, { base }) => {

<!-- TODO: add migration tip -->

When uploading resources used within the application, the need to be defined in the manifest.
If the archive contains a file that isn't whitelisted by default it's possible to allow it by adding it's extension to the allowedExtensions array.

**Default allowed extensions**:

- .md
- .js
- .json
- .map

> [!NOTE]
> A new application service is under construction, which supports dynamic resources.
> Since resources will be deprecated in the future, so the CLI will not auto generate it from the `package.json` attribute
> [!IMPORTANT]
> Resources are now deprecated, so the CLI will no longer auto generate it from the `package.json` attribute
##### app.manifest.config.ts

__app.manifest.config.ts__
```ts
import { defineAppManifest } from '@equinor/fusion-framework-cli';
export default defineAppManifest((env, { base }) => {
return {
...base,
resources: [
'static/foo.png',
'static/bar.svg',
allowedExtensions: [
'.png',
'.svg',
],
};
});
Expand All @@ -82,24 +101,22 @@ export default defineAppManifest((env, { base }) => {
By default [Vite](https://vitejs.dev/config/shared-options.html#publicdir) will copy the `public` folder, simply move the resources to the public folder

for more advance, override the application vite config in `app.vite.config.ts`

```ts
/** @type {import('vite').UserConfig} */
export default {
publicDir: 'resources'
}
```


> [!IMPORTANT]
> Resources will be removed in future version of Fusion, the will come an migration guide of how to include static content
## Vite

the cli will look for a `app.vite.config.{ts,js,json}` [Vite Configuration](https://vitejs.dev/config/)

> [!IMPORTANT]
> in most cases developers do not need to alter the base vite configuration, __this is only a option as a last resort__.
> in most cases developers do not need to alter the base vite configuration, **this is only a option as a last resort**.
> [!CAUTION]
> adding a `vite.config` to the base of your project will override Fusion Framework CLI base config, __NOT RECOMMENDED__
vite.config

> [!CAUTION]
> adding a `vite.config` to the base of your project will override Fusion Framework CLI base config, **NOT RECOMMENDED**
2 changes: 1 addition & 1 deletion packages/cli/src/bin/create-dev-serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { loadPackage } from './utils/load-package.js';
import { Spinner } from './utils/spinner.js';
import { chalk, formatPath } from './utils/format.js';
import { loadAppManifest } from './utils/load-manifest.js';
import proxyRequestLogger from './utils/proxy-request-logger.js';
import { proxyRequestLogger } from './utils/proxy-request-logger.js';

export const createDevServer = async (options: {
portal: string;
Expand Down
86 changes: 74 additions & 12 deletions packages/cli/src/bin/create-export-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,19 @@ import semverValid from 'semver/functions/valid.js';
import { chalk, formatPath } from './utils/format.js';
import { Spinner } from './utils/spinner.js';

import { loadPackage } from './utils/load-package.js';
import { loadAppConfig } from './utils/load-app-config.js';
import { publishAppConfig, validateToken, type FusionEnv } from './utils/app-api.js';
import {
getEndpointUrl,
loadAppConfig,
loadPackage,
isAppRegistered,
requireToken,
publishAppConfig,
} from './utils/index.js';
import type { FusionEnv } from './utils/index.js';

import { ConfigExecuterEnv } from '../lib/utils/config.js';
import { resolveAppKey } from '../lib/app-package.js';
import { exit } from 'node:process';

export const createExportConfig = async (options: {
command?: ConfigExecuterEnv['command'];
Expand Down Expand Up @@ -55,13 +63,9 @@ export const createExportConfig = async (options: {
}

if (publish) {
spinner.info('Publishing config');

const validToken = validateToken();
if (!validToken) {
return;
}
spinner.info('Preparing to publishing config');

/* Make sure version is valid */
const version = publish === 'current' ? pkg.packageJson.version : publish;
if (!version || (!semverValid(version) && !['latest', 'preview'].includes(version))) {
spinner.fail(
Expand All @@ -70,12 +74,70 @@ export const createExportConfig = async (options: {
chalk.redBright(version),
'',
);
return;
exit(1);
}

/** make sure user has a valid token */
try {
spinner.info('Validating FUSION_TOKEN');

// make sure token exist
requireToken();

// call service discovery with token, will throw error if failed
await getEndpointUrl('apps', env, '');

spinner.succeed('Found valid FUSION_TOKEN');
} catch (e) {
const err = e as Error;
spinner.fail(chalk.bgRed(err.message));
exit(1);
}

const published = await publishAppConfig(appKey, version, config, env, service);
if (published) {
try {
spinner.info('Verifying that App is registered');

const state = { endpoint: '' };
try {
state.endpoint = await getEndpointUrl(`apps/${appKey}`, env, service);
} catch (e) {
const err = e as Error;
throw new Error(
`Could not get endpoint from service discovery while verifying app. service-discovery status: ${err.message}`,
);
}

await isAppRegistered(state.endpoint, appKey);
spinner.succeed(`${appKey} is registered`);
} catch (e) {
const err = e as Error;
spinner.fail('🙅‍♂️', chalk.bgRed(err.message));
exit(1);
}

try {
spinner.info(`Publishing config to "${appKey}@${version}"`);

const state = { endpoint: '' };
try {
state.endpoint = await getEndpointUrl(
`apps/${appKey}/builds/${version}/config`,
env,
service,
);
} catch (e) {
const err = e as Error;
throw new Error(
`Could not get endpoint from service discovery while publishig config. service-discovery status: ${err.message}`,
);
}

await publishAppConfig(state.endpoint, appKey, config);
spinner.succeed('✅', 'Published config to version', chalk.yellowBright(version));
} catch (e) {
const err = e as Error;
spinner.fail('🙅‍♂️', chalk.bgRed(err.message));
exit(1);
}
}

Expand Down
Loading

0 comments on commit e9f9fb6

Please sign in to comment.