Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/cli/appmanager/refactoring-commands #2450

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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