diff --git a/apps/trading/project.json b/apps/trading/project.json
index ed4bf4925..450ce3d01 100644
--- a/apps/trading/project.json
+++ b/apps/trading/project.json
@@ -4,7 +4,7 @@
"projectType": "application",
"targets": {
"build": {
- "executor": "@nrwl/next:build",
+ "executor": "./tools/executors/next:build",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
@@ -19,7 +19,7 @@
}
},
"serve": {
- "executor": "@nrwl/next:server",
+ "executor": "./tools/executors/next:serve",
"options": {
"buildTarget": "trading:build",
"dev": true
diff --git a/libs/environment/src/hooks/use-environment.spec.tsx b/libs/environment/src/hooks/use-environment.spec.tsx
index af42f19a5..78ce13216 100644
--- a/libs/environment/src/hooks/use-environment.spec.tsx
+++ b/libs/environment/src/hooks/use-environment.spec.tsx
@@ -40,6 +40,10 @@ const mockEnvironmentState: EnvironmentState = {
},
ETHEREUM_PROVIDER_URL: 'https://ether.provider',
ETHERSCAN_URL: 'https://etherscan.url',
+ GIT_BRANCH: 'test',
+ GIT_ORIGIN_URL: 'https://github.com/test/repo',
+ GIT_COMMIT_HASH: 'abcde01234',
+ GITHUB_FEEDBACK_URL: 'https://github.com/test/feedback',
};
beforeEach(() => {
@@ -59,6 +63,11 @@ beforeEach(() => {
process.env['NX_VEGA_NETWORKS'] = JSON.stringify(
mockEnvironmentState.VEGA_NETWORKS
);
+ process.env['NX_GIT_BRANCH'] = mockEnvironmentState.GIT_BRANCH;
+ process.env['NX_GIT_ORIGIN_URL'] = mockEnvironmentState.GIT_ORIGIN_URL;
+ process.env['NX_GIT_COMMIT_HASH'] = mockEnvironmentState.GIT_COMMIT_HASH;
+ process.env['NX_GITHUB_FEEDBACK_URL'] =
+ mockEnvironmentState.GITHUB_FEEDBACK_URL;
});
afterAll(() => {
diff --git a/libs/environment/src/utils/compile-environment.ts b/libs/environment/src/utils/compile-environment.ts
index ecd91d909..4346dcac9 100644
--- a/libs/environment/src/utils/compile-environment.ts
+++ b/libs/environment/src/utils/compile-environment.ts
@@ -58,6 +58,14 @@ const getBundledEnvironmentValue = (key: EnvKey) => {
return process.env['NX_ETHERSCAN_URL'];
case 'VEGA_NETWORKS':
return process.env['NX_VEGA_NETWORKS'];
+ case 'GIT_BRANCH':
+ return process.env['NX_GIT_BRANCH'];
+ case 'GIT_COMMIT_HASH':
+ return process.env['NX_GIT_COMMIT_HASH'];
+ case 'GIT_ORIGIN_URL':
+ return process.env['NX_GIT_ORIGIN_URL'];
+ case 'GITHUB_FEEDBACK_URL':
+ return process.env['NX_GITHUB_FEEDBACK_URL'];
case 'VEGA_EXPLORER_URL':
return process.env['NX_VEGA_EXPLORER_URL'];
}
diff --git a/libs/environment/src/utils/validate-environment.ts b/libs/environment/src/utils/validate-environment.ts
index 44c89d8d1..05979410e 100644
--- a/libs/environment/src/utils/validate-environment.ts
+++ b/libs/environment/src/utils/validate-environment.ts
@@ -23,6 +23,10 @@ const schemaObject = {
ETHERSCAN_URL: z.string().url({
message: 'The NX_ETHERSCAN_URL environment variable must be a valid url',
}),
+ GIT_BRANCH: z.string(),
+ GIT_COMMIT_HASH: z.string(),
+ GIT_ORIGIN_URL: z.string(),
+ GITHUB_FEEDBACK_URL: z.optional(z.string()),
VEGA_ENV: z.nativeEnum(Networks),
VEGA_NETWORKS: z
.object(
diff --git a/libs/network-info/.babelrc b/libs/network-info/.babelrc
new file mode 100644
index 000000000..ccae900be
--- /dev/null
+++ b/libs/network-info/.babelrc
@@ -0,0 +1,12 @@
+{
+ "presets": [
+ [
+ "@nrwl/react/babel",
+ {
+ "runtime": "automatic",
+ "useBuiltIns": "usage"
+ }
+ ]
+ ],
+ "plugins": []
+}
diff --git a/libs/network-info/.eslintrc.json b/libs/network-info/.eslintrc.json
new file mode 100644
index 000000000..734ddacee
--- /dev/null
+++ b/libs/network-info/.eslintrc.json
@@ -0,0 +1,18 @@
+{
+ "extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"],
+ "ignorePatterns": ["!**/*"],
+ "overrides": [
+ {
+ "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
+ "rules": {}
+ },
+ {
+ "files": ["*.ts", "*.tsx"],
+ "rules": {}
+ },
+ {
+ "files": ["*.js", "*.jsx"],
+ "rules": {}
+ }
+ ]
+}
diff --git a/libs/network-info/README.md b/libs/network-info/README.md
new file mode 100644
index 000000000..b4bdc4883
--- /dev/null
+++ b/libs/network-info/README.md
@@ -0,0 +1,21 @@
+# network-info
+
+This library was generated with [Nx](https://nx.dev).
+
+## Prerequisites
+
+The environment variables needed to be present for any app consuming this library.
+
+`NX_VEGA_URL` OR `NX_VEGA_CONFIG_URL` - either the network configuration url or a url to a node to directly connect to
+
+`NX_VEGA_NETWORKS` - JSON object with key-value pairs for environments and their deployed URLs
+
+`NX_GITHUB_FEEDBACK_URL` - the repository's feedback URL to point to
+
+`NX_ETHEREUM_PROVIDER_URL` - the Ethereum provider url
+
+For examples, see Block Explorer's .env files [here](../../apps/explorer)
+
+## Running unit tests
+
+Run `nx test network-info` to execute the unit tests via [Jest](https://jestjs.io).
diff --git a/libs/network-info/jest.config.js b/libs/network-info/jest.config.js
new file mode 100644
index 000000000..9688b5a6c
--- /dev/null
+++ b/libs/network-info/jest.config.js
@@ -0,0 +1,9 @@
+module.exports = {
+ displayName: 'network-info',
+ preset: '../../jest.preset.js',
+ transform: {
+ '^.+\\.[tj]sx?$': 'babel-jest',
+ },
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
+ coverageDirectory: '../../coverage/libs/network-info',
+};
diff --git a/libs/network-info/package.json b/libs/network-info/package.json
new file mode 100644
index 000000000..79ecb86c3
--- /dev/null
+++ b/libs/network-info/package.json
@@ -0,0 +1,4 @@
+{
+ "name": "@vegaprotocol/network-info",
+ "version": "0.0.1"
+}
diff --git a/libs/network-info/project.json b/libs/network-info/project.json
new file mode 100644
index 000000000..d3013199c
--- /dev/null
+++ b/libs/network-info/project.json
@@ -0,0 +1,43 @@
+{
+ "root": "libs/network-info",
+ "sourceRoot": "libs/network-info/src",
+ "projectType": "library",
+ "tags": [],
+ "targets": {
+ "build": {
+ "executor": "@nrwl/web:rollup",
+ "outputs": ["{options.outputPath}"],
+ "options": {
+ "outputPath": "dist/libs/network-info",
+ "tsConfig": "libs/network-info/tsconfig.lib.json",
+ "project": "libs/network-info/package.json",
+ "entryFile": "libs/network-info/src/index.ts",
+ "external": ["react/jsx-runtime"],
+ "rollupConfig": "@nrwl/react/plugins/bundle-rollup",
+ "compiler": "babel",
+ "assets": [
+ {
+ "glob": "libs/network-info/README.md",
+ "input": ".",
+ "output": "."
+ }
+ ]
+ }
+ },
+ "lint": {
+ "executor": "@nrwl/linter:eslint",
+ "outputs": ["{options.outputFile}"],
+ "options": {
+ "lintFilePatterns": ["libs/network-info/**/*.{ts,tsx,js,jsx}"]
+ }
+ },
+ "test": {
+ "executor": "@nrwl/jest:jest",
+ "outputs": ["coverage/libs/network-info"],
+ "options": {
+ "jestConfig": "libs/network-info/jest.config.js",
+ "passWithNoTests": true
+ }
+ }
+ }
+}
diff --git a/libs/network-info/src/index.ts b/libs/network-info/src/index.ts
new file mode 100644
index 000000000..719b96534
--- /dev/null
+++ b/libs/network-info/src/index.ts
@@ -0,0 +1 @@
+export * from './network-info';
diff --git a/libs/network-info/src/network-info.tsx b/libs/network-info/src/network-info.tsx
new file mode 100644
index 000000000..e7dfd1a46
--- /dev/null
+++ b/libs/network-info/src/network-info.tsx
@@ -0,0 +1,87 @@
+import { useState } from 'react';
+import { t } from '@vegaprotocol/react-helpers';
+import { Link, Lozenge } from '@vegaprotocol/ui-toolkit';
+import {
+ useEnvironment,
+ NetworkSwitcherDialog,
+} from '@vegaprotocol/environment';
+
+const getFeedbackLinks = (gitOriginUrl?: string) =>
+ [
+ {
+ name: 'Github',
+ url: gitOriginUrl,
+ },
+ ].filter((link) => !!link.url);
+
+export const NetworkInfo = () => {
+ const [isNetworkConfigOpen, setNetworkConfigOpen] = useState(false);
+ const {
+ VEGA_URL,
+ VEGA_NETWORKS,
+ GIT_COMMIT_HASH,
+ GIT_ORIGIN_URL,
+ GITHUB_FEEDBACK_URL,
+ ETHEREUM_PROVIDER_URL,
+ } = useEnvironment();
+ const feedbackLinks = getFeedbackLinks(GITHUB_FEEDBACK_URL);
+
+ return (
+ <>
+
+
+ {t('Reading network data from')}{' '}
+
+ {VEGA_URL}
+
+ . setNetworkConfigOpen(true)}>{t('Edit')}
+
+
+ {t('Reading Ethereum data from')}{' '}
+
+ {ETHEREUM_PROVIDER_URL}
+
+ .{' '}
+
+ {GIT_COMMIT_HASH && GIT_ORIGIN_URL && (
+
+ {t('Version/commit hash')}:{' '}
+
+ {GIT_COMMIT_HASH}
+
+
+ )}
+ {feedbackLinks.length > 0 && (
+
+ {t('Known issues and feedback on')}{' '}
+ {feedbackLinks.map(({ name, url }, index) => (
+ <>
+
+ {name}
+
+ {feedbackLinks.length > 1 &&
+ index < feedbackLinks.length - 2 &&
+ ','}
+ {feedbackLinks.length > 1 &&
+ index === feedbackLinks.length - 1 &&
+ `, ${t('and')} `}
+ >
+ ))}
+
+ )}
+
+
{
+ if (VEGA_NETWORKS[network]) {
+ window.location.href = VEGA_NETWORKS[network] as string;
+ }
+ }}
+ />
+ >
+ );
+};
diff --git a/libs/network-info/tsconfig.json b/libs/network-info/tsconfig.json
new file mode 100644
index 000000000..1eabf319c
--- /dev/null
+++ b/libs/network-info/tsconfig.json
@@ -0,0 +1,25 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "jsx": "react-jsx",
+ "allowJs": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "forceConsistentCasingInFileNames": true,
+ "strict": true,
+ "noImplicitOverride": true,
+ "noPropertyAccessFromIndexSignature": false,
+ "noImplicitReturns": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "files": [],
+ "include": [],
+ "references": [
+ {
+ "path": "./tsconfig.lib.json"
+ },
+ {
+ "path": "./tsconfig.spec.json"
+ }
+ ]
+}
diff --git a/libs/network-info/tsconfig.lib.json b/libs/network-info/tsconfig.lib.json
new file mode 100644
index 000000000..252904bb7
--- /dev/null
+++ b/libs/network-info/tsconfig.lib.json
@@ -0,0 +1,22 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../../dist/out-tsc",
+ "types": ["node"]
+ },
+ "files": [
+ "../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
+ "../../node_modules/@nrwl/react/typings/image.d.ts"
+ ],
+ "exclude": [
+ "**/*.spec.ts",
+ "**/*.test.ts",
+ "**/*.spec.tsx",
+ "**/*.test.tsx",
+ "**/*.spec.js",
+ "**/*.test.js",
+ "**/*.spec.jsx",
+ "**/*.test.jsx"
+ ],
+ "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
+}
diff --git a/libs/network-info/tsconfig.spec.json b/libs/network-info/tsconfig.spec.json
new file mode 100644
index 000000000..67f149c4c
--- /dev/null
+++ b/libs/network-info/tsconfig.spec.json
@@ -0,0 +1,19 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../../dist/out-tsc",
+ "module": "commonjs",
+ "types": ["jest", "node"]
+ },
+ "include": [
+ "**/*.test.ts",
+ "**/*.spec.ts",
+ "**/*.test.tsx",
+ "**/*.spec.tsx",
+ "**/*.test.js",
+ "**/*.spec.js",
+ "**/*.test.jsx",
+ "**/*.spec.jsx",
+ "**/*.d.ts"
+ ]
+}
diff --git a/libs/smart-contracts/package.json b/libs/smart-contracts/package.json
index 7532b2f9a..391e95da1 100644
--- a/libs/smart-contracts/package.json
+++ b/libs/smart-contracts/package.json
@@ -1,5 +1,4 @@
{
"name": "@vegaprotocol/smart-contracts",
- "version": "0.0.1",
- "type": "commonjs"
+ "version": "0.0.1"
}
diff --git a/libs/ui-toolkit/src/components/lozenge/lozenge.stories.tsx b/libs/ui-toolkit/src/components/lozenge/lozenge.stories.tsx
index 8b921ee2c..dfe59301b 100644
--- a/libs/ui-toolkit/src/components/lozenge/lozenge.stories.tsx
+++ b/libs/ui-toolkit/src/components/lozenge/lozenge.stories.tsx
@@ -11,6 +11,11 @@ const Template: Story = (args) => lozenge;
export const Default = Template.bind({});
+export const None = Template.bind({});
+None.args = {
+ variant: Intent.None,
+};
+
export const Primary = Template.bind({});
Primary.args = {
variant: Intent.Primary,
diff --git a/libs/ui-toolkit/src/components/lozenge/lozenge.tsx b/libs/ui-toolkit/src/components/lozenge/lozenge.tsx
index 5f0b398ca..6e991fb37 100644
--- a/libs/ui-toolkit/src/components/lozenge/lozenge.tsx
+++ b/libs/ui-toolkit/src/components/lozenge/lozenge.tsx
@@ -1,7 +1,7 @@
import type { ReactNode } from 'react';
import classNames from 'classnames';
import { getIntentTextAndBackground } from '../../utils/intent';
-import { Intent } from '../../utils/intent';
+import type { Intent } from '../../utils/intent';
interface LozengeProps {
children: ReactNode;
@@ -10,7 +10,7 @@ interface LozengeProps {
}
const getLozengeClasses = (
- variant: LozengeProps['variant'],
+ variant?: LozengeProps['variant'],
className?: string
) => {
return classNames(
@@ -20,11 +20,7 @@ const getLozengeClasses = (
);
};
-export const Lozenge = ({
- children,
- variant = Intent.None,
- className,
-}: LozengeProps) => {
+export const Lozenge = ({ children, variant, className }: LozengeProps) => {
return (
{children}
);
diff --git a/libs/ui-toolkit/src/utils/intent.tsx b/libs/ui-toolkit/src/utils/intent.tsx
index d634847ec..d135b0aee 100644
--- a/libs/ui-toolkit/src/utils/intent.tsx
+++ b/libs/ui-toolkit/src/utils/intent.tsx
@@ -28,7 +28,7 @@ export const getIntentBorder = (intent = Intent.None) => {
};
};
-export const getIntentTextAndBackground = (intent = Intent.None) => {
+export const getIntentTextAndBackground = (intent?: Intent) => {
return {
'bg-black text-white dark:bg-white dark:text-black': intent === Intent.None,
'bg-vega-pink text-black dark:bg-vega-yellow dark:text-black-normal':
diff --git a/tools/executors/next/build/impl.ts b/tools/executors/next/build/impl.ts
new file mode 100644
index 000000000..2675a0d11
--- /dev/null
+++ b/tools/executors/next/build/impl.ts
@@ -0,0 +1,18 @@
+import type { ExecutorContext } from '@nrwl/devkit';
+import setup from '../../../utils/setup-environment';
+import nextBuildExecutor from '@nrwl/next/src/executors/build/build.impl';
+import { NextBuildBuilderOptions } from '@nrwl/next/src/utils/types';
+
+type Schema = NextBuildBuilderOptions & {
+ env?: string;
+};
+
+export default async function build(
+ options: Schema,
+ context: ExecutorContext
+): Promise> {
+ const { env, ...nextOptions } = options;
+ await setup(env, context, 'tools/executors/next/build');
+
+ return await nextBuildExecutor(nextOptions, context);
+}
diff --git a/tools/executors/next/build/schema.json b/tools/executors/next/build/schema.json
new file mode 100644
index 000000000..2810e3c5f
--- /dev/null
+++ b/tools/executors/next/build/schema.json
@@ -0,0 +1,50 @@
+{
+ "cli": "nx",
+ "id": "build",
+ "description": "Serves an app using @nrwl/next:build",
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "Target environment to run the application in. This assumes an .env file present in the project's root in the following format: .env.{envName}"
+ },
+ "root": {
+ "description": "The source root",
+ "type": "string"
+ },
+ "outputPath": {
+ "type": "string",
+ "description": "The output path of the generated files."
+ },
+ "fileReplacements": {
+ "description": "Replace files with other files in the build.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "replace": {
+ "type": "string",
+ "description": "The file to be replaced."
+ },
+ "with": {
+ "type": "string",
+ "description": "The file to replace with."
+ }
+ },
+ "additionalProperties": false,
+ "required": ["replace", "with"]
+ },
+ "default": []
+ },
+ "nextConfig": {
+ "description": "Path (relative to workspace root) to a function which takes phase, config, and builder options, and returns the resulting config. This is an advanced option and should not be used with a normal Next.js config file (i.e. `next.config.js`).",
+ "type": "string"
+ },
+ "buildLibsFromSource": {
+ "type": "boolean",
+ "description": "Read buildable libraries from source instead of building them separately.",
+ "default": true
+ }
+ },
+ "required": ["root", "outputPath"]
+}
diff --git a/tools/executors/next/executor.json b/tools/executors/next/executor.json
new file mode 100644
index 000000000..cd82d63bd
--- /dev/null
+++ b/tools/executors/next/executor.json
@@ -0,0 +1,14 @@
+{
+ "executors": {
+ "serve": {
+ "implementation": "./serve/impl",
+ "schema": "./serve/schema.json",
+ "description": "Starts a next server with an optional explicit environment."
+ },
+ "build": {
+ "implementation": "./build/impl",
+ "schema": "./build/schema.json",
+ "description": "Starts a next server with an optional explicit environment."
+ }
+ }
+}
diff --git a/tools/executors/serve/package.json b/tools/executors/next/package.json
similarity index 100%
rename from tools/executors/serve/package.json
rename to tools/executors/next/package.json
diff --git a/tools/executors/next/serve/impl.ts b/tools/executors/next/serve/impl.ts
new file mode 100644
index 000000000..34d1ab3c8
--- /dev/null
+++ b/tools/executors/next/serve/impl.ts
@@ -0,0 +1,18 @@
+import type { ExecutorContext } from '@nrwl/devkit';
+import setup from '../../../utils/setup-environment';
+import nextServerExecutor from '@nrwl/next/src/executors/server/server.impl';
+import { NextServeBuilderOptions } from '@nrwl/next/src/utils/types';
+
+type Schema = NextServeBuilderOptions & {
+ env?: string;
+};
+
+export default async function* serve(
+ options: Schema,
+ context: ExecutorContext
+): ReturnType {
+ const { env, ...nextOptions } = options;
+ await setup(env, context, 'tools/executors/next/serve');
+
+ return yield* nextServerExecutor(nextOptions, context);
+}
diff --git a/tools/executors/next/serve/schema.json b/tools/executors/next/serve/schema.json
new file mode 100644
index 000000000..a07c69386
--- /dev/null
+++ b/tools/executors/next/serve/schema.json
@@ -0,0 +1,54 @@
+{
+ "cli": "nx",
+ "id": "serve",
+ "description": "Serves an app using @nrwl/next:server",
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "Target environment to run the application in. This assumes an .env file present in the project's root in the following format: .env.{envName}"
+ },
+ "dev": {
+ "type": "boolean",
+ "description": "Serve the application in the dev mode.",
+ "default": true
+ },
+ "buildTarget": {
+ "type": "string",
+ "description": "Target which builds the application."
+ },
+ "port": {
+ "type": "number",
+ "description": "Port to listen on.",
+ "default": 4200
+ },
+ "staticMarkup": {
+ "type": "boolean",
+ "description": "Static markup.",
+ "default": false
+ },
+ "quiet": {
+ "type": "boolean",
+ "description": "Hide error messages containing server information.",
+ "default": false
+ },
+ "customServerPath": {
+ "type": "string",
+ "description": "Use a custom server script."
+ },
+ "hostname": {
+ "type": "string",
+ "description": "Hostname on which the application is served."
+ },
+ "proxyConfig": {
+ "type": "string",
+ "description": "Path to the proxy configuration file."
+ },
+ "buildLibsFromSource": {
+ "type": "boolean",
+ "description": "Read buildable libraries from source instead of building them separately.",
+ "default": true
+ }
+ },
+ "required": ["buildTarget"]
+}
diff --git a/tools/executors/serve/tsconfig.json b/tools/executors/next/tsconfig.json
similarity index 83%
rename from tools/executors/serve/tsconfig.json
rename to tools/executors/next/tsconfig.json
index 6d5259d33..1cfd7884b 100644
--- a/tools/executors/serve/tsconfig.json
+++ b/tools/executors/next/tsconfig.json
@@ -8,6 +8,6 @@
"sourceMap": false,
"inlineSourceMap": true
},
- "include": ["impl.ts"],
+ "include": ["build/impl.ts", "serve/impl.ts"],
"exclude": ["node_modules"]
}
diff --git a/tools/executors/serve/executor.json b/tools/executors/serve/executor.json
deleted file mode 100644
index 26d70afc8..000000000
--- a/tools/executors/serve/executor.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "executors": {
- "serve": {
- "implementation": "./impl",
- "schema": "./schema.json",
- "description": "Starts a dev-server with an optional explicit environment."
- }
- }
-}
diff --git a/tools/executors/webpack/build/impl.ts b/tools/executors/webpack/build/impl.ts
new file mode 100644
index 000000000..2c00c7911
--- /dev/null
+++ b/tools/executors/webpack/build/impl.ts
@@ -0,0 +1,19 @@
+import type { ExecutorContext } from '@nrwl/devkit';
+import setup from '../../../utils/setup-environment';
+import webpackBuildExecutor, {
+ WebWebpackExecutorOptions,
+} from '@nrwl/web/src/executors/webpack/webpack.impl';
+
+type Schema = WebWebpackExecutorOptions & {
+ env?: string;
+};
+
+export default async function* build(
+ options: Schema,
+ context: ExecutorContext
+): ReturnType {
+ const { env, ...buildOptions } = options;
+ await setup(env, context, 'tools/executors/webpack/build');
+
+ return yield* webpackBuildExecutor(buildOptions, context);
+}
diff --git a/tools/executors/webpack/build/schema.json b/tools/executors/webpack/build/schema.json
new file mode 100644
index 000000000..95ed12fac
--- /dev/null
+++ b/tools/executors/webpack/build/schema.json
@@ -0,0 +1,359 @@
+{
+ "cli": "nx",
+ "id": "build",
+ "description": "Serves an app using @nrwl/web:webpack",
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "Target environment to run the application in. This assumes an .env file present in the project's root in the following format: .env.{envName}"
+ },
+ "crossOrigin": {
+ "type": "string",
+ "description": "The `crossorigin` attribute to use for generated javascript script tags. One of 'none' | 'anonymous' | 'use-credentials'."
+ },
+ "main": {
+ "type": "string",
+ "description": "The name of the main entry-point file."
+ },
+ "tsConfig": {
+ "type": "string",
+ "description": "The name of the Typescript configuration file."
+ },
+ "compiler": {
+ "type": "string",
+ "description": "The compiler to use.",
+ "enum": ["babel", "swc"],
+ "default": "babel"
+ },
+ "outputPath": {
+ "type": "string",
+ "description": "The output path of the generated files."
+ },
+ "deleteOutputPath": {
+ "type": "boolean",
+ "description": "Delete the output path before building.",
+ "default": true
+ },
+ "watch": {
+ "type": "boolean",
+ "description": "Enable re-building when files change.",
+ "default": false
+ },
+ "baseHref": {
+ "type": "string",
+ "description": "Base url for the application being built."
+ },
+ "deployUrl": {
+ "type": "string",
+ "description": "URL where the application will be deployed."
+ },
+ "vendorChunk": {
+ "type": "boolean",
+ "description": "Use a separate bundle containing only vendor libraries.",
+ "default": true
+ },
+ "commonChunk": {
+ "type": "boolean",
+ "description": "Use a separate bundle containing code used across multiple bundles.",
+ "default": true
+ },
+ "runtimeChunk": {
+ "type": "boolean",
+ "description": "Use a separate bundle containing the runtime.",
+ "default": true
+ },
+ "sourceMap": {
+ "description": "Output sourcemaps. Use 'hidden' for use with error reporting tools without generating sourcemap comment.",
+ "default": true,
+ "oneOf": [
+ {
+ "type": "boolean"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "progress": {
+ "type": "boolean",
+ "description": "Log progress to the console while building.",
+ "default": false
+ },
+ "assets": {
+ "type": "array",
+ "description": "List of static application assets.",
+ "default": [],
+ "items": {
+ "$ref": "#/definitions/assetPattern"
+ }
+ },
+ "index": {
+ "type": "string",
+ "description": "HTML File which will be contain the application."
+ },
+ "scripts": {
+ "type": "array",
+ "description": "External Scripts which will be included before the main application entry.",
+ "items": {
+ "$ref": "#/definitions/extraEntryPoint"
+ },
+ "default": []
+ },
+ "styles": {
+ "type": "array",
+ "description": "External Styles which will be included with the application",
+ "items": {
+ "$ref": "#/definitions/extraEntryPoint"
+ },
+ "default": []
+ },
+ "budgets": {
+ "description": "Budget thresholds to ensure parts of your application stay within boundaries which you set.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/budget"
+ },
+ "default": []
+ },
+ "namedChunks": {
+ "type": "boolean",
+ "description": "Names the produced bundles according to their entry file.",
+ "default": true
+ },
+ "outputHashing": {
+ "type": "string",
+ "description": "Define the output filename cache-busting hashing mode.",
+ "default": "none",
+ "enum": ["none", "all", "media", "bundles"]
+ },
+ "stylePreprocessorOptions": {
+ "description": "Options to pass to style preprocessors.",
+ "type": "object",
+ "properties": {
+ "includePaths": {
+ "description": "Paths to include. Paths will be resolved to project root.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": []
+ }
+ },
+ "additionalProperties": false
+ },
+ "optimization": {
+ "description": "Enables optimization of the build output.",
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "scripts": {
+ "type": "boolean",
+ "description": "Enables optimization of the scripts output.",
+ "default": true
+ },
+ "styles": {
+ "type": "boolean",
+ "description": "Enables optimization of the styles output.",
+ "default": true
+ }
+ },
+ "additionalProperties": false
+ },
+ {
+ "type": "boolean"
+ }
+ ]
+ },
+ "extractCss": {
+ "type": "boolean",
+ "description": "Extract CSS into a `.css` file.",
+ "default": false
+ },
+ "es2015Polyfills": {
+ "description": "Conditional polyfills loaded in browsers which do not support `ES2015`.",
+ "type": "string"
+ },
+ "subresourceIntegrity": {
+ "type": "boolean",
+ "description": "Enables the use of subresource integrity validation.",
+ "default": false
+ },
+ "polyfills": {
+ "type": "string",
+ "description": "Polyfills to load before application"
+ },
+ "verbose": {
+ "type": "boolean",
+ "description": "Emits verbose output",
+ "default": false
+ },
+ "statsJson": {
+ "type": "boolean",
+ "description": "Generates a 'stats.json' file which can be analyzed using tools such as: 'webpack-bundle-analyzer' or ``.",
+ "default": false
+ },
+ "extractLicenses": {
+ "type": "boolean",
+ "description": "Extract all licenses in a separate file, in the case of production builds only.",
+ "default": false
+ },
+ "memoryLimit": {
+ "type": "number",
+ "description": "Memory limit for type checking service process in `MB`.",
+ "default": 2048
+ },
+ "maxWorkers": {
+ "type": "number",
+ "description": "Number of workers to use for type checking.",
+ "default": 2
+ },
+ "fileReplacements": {
+ "description": "Replace files with other files in the build.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "replace": {
+ "type": "string",
+ "description": "The file to be replaced."
+ },
+ "with": {
+ "type": "string",
+ "description": "The file to replace with."
+ }
+ },
+ "additionalProperties": false,
+ "required": ["replace", "with"]
+ },
+ "default": []
+ },
+ "buildLibsFromSource": {
+ "type": "boolean",
+ "description": "Read buildable libraries from source instead of building them separately.",
+ "default": true
+ },
+ "generateIndexHtml": {
+ "type": "boolean",
+ "description": "Generates `index.html` file to the output path. This can be turned off if using a webpack plugin to generate HTML such as `html-webpack-plugin`.",
+ "default": true
+ },
+ "postcssConfig": {
+ "type": "string",
+ "description": "Set a path to PostCSS config that applies to the app and all libs. Defaults to `undefined`, which auto-detects postcss.config.js files in each `app`/`lib` directory."
+ },
+ "webpackConfig": {
+ "type": "string",
+ "description": "Path to a function which takes a webpack config, some context and returns the resulting webpack config. See https://nx.dev/guides/customize-webpack"
+ }
+ },
+ "required": ["tsConfig", "main", "index"],
+ "definitions": {
+ "assetPattern": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "glob": {
+ "type": "string",
+ "description": "The pattern to match."
+ },
+ "input": {
+ "type": "string",
+ "description": "The input directory path in which to apply 'glob'. Defaults to the project root."
+ },
+ "ignore": {
+ "description": "An array of globs to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "output": {
+ "type": "string",
+ "description": "Absolute path within the output."
+ }
+ },
+ "additionalProperties": false,
+ "required": ["glob", "input", "output"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "budget": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "The type of budget.",
+ "enum": ["all", "allScript", "any", "anyScript", "bundle", "initial"]
+ },
+ "name": {
+ "type": "string",
+ "description": "The name of the bundle."
+ },
+ "baseline": {
+ "type": "string",
+ "description": "The baseline size for comparison."
+ },
+ "maximumWarning": {
+ "type": "string",
+ "description": "The maximum threshold for warning relative to the baseline."
+ },
+ "maximumError": {
+ "type": "string",
+ "description": "The maximum threshold for error relative to the baseline."
+ },
+ "minimumWarning": {
+ "type": "string",
+ "description": "The minimum threshold for warning relative to the baseline."
+ },
+ "minimumError": {
+ "type": "string",
+ "description": "The minimum threshold for error relative to the baseline."
+ },
+ "warning": {
+ "type": "string",
+ "description": "The threshold for warning relative to the baseline (min & max)."
+ },
+ "error": {
+ "type": "string",
+ "description": "The threshold for error relative to the baseline (min & max)."
+ }
+ },
+ "additionalProperties": false,
+ "required": ["type"]
+ },
+ "extraEntryPoint": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "input": {
+ "type": "string",
+ "description": "The file to include."
+ },
+ "bundleName": {
+ "type": "string",
+ "description": "The bundle name for this extra entry point."
+ },
+ "inject": {
+ "type": "boolean",
+ "description": "If the bundle will be referenced in the HTML file.",
+ "default": true
+ }
+ },
+ "additionalProperties": false,
+ "required": ["input"]
+ },
+ {
+ "type": "string",
+ "description": "The file to include."
+ }
+ ]
+ }
+ }
+}
diff --git a/tools/executors/webpack/executor.json b/tools/executors/webpack/executor.json
new file mode 100644
index 000000000..829a071c5
--- /dev/null
+++ b/tools/executors/webpack/executor.json
@@ -0,0 +1,14 @@
+{
+ "executors": {
+ "serve": {
+ "implementation": "./serve/impl",
+ "schema": "./serve/schema.json",
+ "description": "Starts a dev-server with an optional explicit environment."
+ },
+ "build": {
+ "implementation": "./build/impl",
+ "schema": "./build/schema.json",
+ "description": "Starts a dev-server with an optional explicit environment."
+ }
+ }
+}
diff --git a/tools/executors/webpack/package.json b/tools/executors/webpack/package.json
new file mode 100644
index 000000000..712554f04
--- /dev/null
+++ b/tools/executors/webpack/package.json
@@ -0,0 +1,3 @@
+{
+ "executors": "./executor.json"
+}
diff --git a/tools/executors/webpack/serve/impl.ts b/tools/executors/webpack/serve/impl.ts
new file mode 100644
index 000000000..b3f0250a6
--- /dev/null
+++ b/tools/executors/webpack/serve/impl.ts
@@ -0,0 +1,19 @@
+import type { ExecutorContext } from '@nrwl/devkit';
+import setup from '../../../utils/setup-environment';
+import devServerExecutor, {
+ WebDevServerOptions,
+} from '@nrwl/web/src/executors/dev-server/dev-server.impl';
+
+type Schema = WebDevServerOptions & {
+ env?: string;
+};
+
+export default async function* serve(
+ options: Schema,
+ context: ExecutorContext
+): ReturnType {
+ const { env, ...serverOptions } = options;
+ await setup(env, context, 'tools/executors/webpack/serve');
+
+ return yield* devServerExecutor(serverOptions, context);
+}
diff --git a/tools/executors/serve/schema.json b/tools/executors/webpack/serve/schema.json
similarity index 100%
rename from tools/executors/serve/schema.json
rename to tools/executors/webpack/serve/schema.json
diff --git a/tools/executors/webpack/tsconfig.json b/tools/executors/webpack/tsconfig.json
new file mode 100644
index 000000000..1cfd7884b
--- /dev/null
+++ b/tools/executors/webpack/tsconfig.json
@@ -0,0 +1,13 @@
+{
+ "extends": "../../../tsconfig.base.json",
+ "compilerOptions": {
+ "module": "commonjs",
+ "target": "es5",
+ "types": ["node"],
+ "importHelpers": false,
+ "sourceMap": false,
+ "inlineSourceMap": true
+ },
+ "include": ["build/impl.ts", "serve/impl.ts"],
+ "exclude": ["node_modules"]
+}
diff --git a/tools/executors/serve/impl.ts b/tools/utils/setup-environment.ts
similarity index 65%
rename from tools/executors/serve/impl.ts
rename to tools/utils/setup-environment.ts
index 72dcf4334..d66f9140f 100644
--- a/tools/executors/serve/impl.ts
+++ b/tools/utils/setup-environment.ts
@@ -1,28 +1,33 @@
import * as fs from 'fs';
import * as path from 'path';
-import * as dotenv from 'dotenv';
+import { execSync } from 'child_process';
import * as log from 'npmlog';
+import * as dotenv from 'dotenv';
import type { ExecutorContext } from '@nrwl/devkit';
-import devServerExecutor, {
- WebDevServerOptions,
-} from '@nrwl/web/src/executors/dev-server/dev-server.impl';
-type Schema = WebDevServerOptions & {
- env?: string;
-};
-
-const LOGGER_SCOPE = 'tools/executors/serve';
+process.env['NX_GIT_COMMIT_HASH'] = execSync('git rev-parse HEAD')
+ .toString()
+ .replace(/[\r\n]/gm, '');
+process.env['NX_GIT_BRANCH'] = execSync('git rev-parse --abbrev-ref HEAD')
+ .toString()
+ .replace(/[\r\n]/gm, '');
+process.env['NX_GIT_ORIGIN_URL'] = execSync('git remote get-url origin')
+ .toString()
+ .replace('ssh://git@', 'https://')
+ .replace('.git', '')
+ .replace(/[\r\n]/gm, '');
const logEnvData = (
envMap: Record,
envFiles: string[],
env?: string,
- defaultEnvFile?: string
+ defaultEnvFile?: string,
+ loggerScope?: string
) => {
if (env && !envMap[env]) {
- log.warn(LOGGER_SCOPE, `No environment called "${env}" found.`);
+ log.warn(loggerScope, `No environment called "${env}" found.`);
log.info(
- LOGGER_SCOPE,
+ loggerScope,
envFiles.length > 0
? `You can create a new environment by putting an ".env.${env}" file in your project root, or you can use the following available ones: ${envFiles.join(
', '
@@ -33,14 +38,14 @@ const logEnvData = (
if (!envMap[env]) {
log.info(
- LOGGER_SCOPE,
+ loggerScope,
defaultEnvFile
? `Using "${defaultEnvFile}" as the default project environment.`
: 'Serving the project only using the environment variables scoped to your CLI.'
);
} else {
log.info(
- LOGGER_SCOPE,
+ loggerScope,
`Using "${envMap[env]}" as the default project environment.`
);
}
@@ -52,7 +57,7 @@ const getDefaultEnvFile = (envMap: Record) => {
return envMap['local'] || envMap['.env'];
};
-const getEnvFile = (env: string, envFiles: string[]) => {
+const getEnvFile = (env: string, envFiles: string[], loggerScope?: string) => {
const envMap = envFiles.reduce(
(acc, filename) => ({
...acc,
@@ -62,28 +67,28 @@ const getEnvFile = (env: string, envFiles: string[]) => {
);
const defaultEnvFile = getDefaultEnvFile(envMap);
- logEnvData(envMap, envFiles, env, defaultEnvFile);
+ logEnvData(envMap, envFiles, env, defaultEnvFile, loggerScope);
return envMap[env] || defaultEnvFile;
};
-export default async function* serve(
- options: Schema,
- context: ExecutorContext
-): ReturnType {
- const { env, ...dsOptions } = options;
+export default async function setup(
+ env: string,
+ context: ExecutorContext,
+ loggerScope?: string
+) {
const { root } = context.workspace.projects[context.projectName];
const workspacePath = path.join(context.cwd, root);
const files = await fs.promises.readdir(workspacePath);
+
const envFile = getEnvFile(
env,
- files.filter((f) => f.startsWith('.env'))
+ files.filter((f) => f.startsWith('.env')),
+ loggerScope
);
if (env && envFile) {
dotenv.config({ path: path.join(workspacePath, envFile), override: true });
}
-
- return yield* devServerExecutor(dsOptions, context);
}
diff --git a/tsconfig.base.json b/tsconfig.base.json
index c3bdf503e..5dd625fe4 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -25,6 +25,7 @@
"@vegaprotocol/fills": ["libs/fills/src/index.ts"],
"@vegaprotocol/market-depth": ["libs/market-depth/src/index.ts"],
"@vegaprotocol/market-list": ["libs/market-list/src/index.ts"],
+ "@vegaprotocol/network-info": ["libs/network-info/src/index.ts"],
"@vegaprotocol/network-stats": ["libs/network-stats/src/index.ts"],
"@vegaprotocol/order-list": ["libs/order-list/src/index.ts"],
"@vegaprotocol/positions": ["libs/positions/src/index.ts"],
diff --git a/workspace.json b/workspace.json
index 38526f4b7..d74749e3d 100644
--- a/workspace.json
+++ b/workspace.json
@@ -12,6 +12,7 @@
"fills": "libs/fills",
"market-depth": "libs/market-depth",
"market-list": "libs/market-list",
+ "network-info": "libs/network-info",
"network-stats": "libs/network-stats",
"order-list": "libs/order-list",
"positions": "libs/positions",