@madgex/fert 6.0.2 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/cli.js +1 -0
- package/bin/commands/configs.js +1 -0
- package/bin/commands/dev-server.js +13 -3
- package/bin/utils/configs.js +15 -4
- package/bin/utils/getSchemaMeta.js +1 -1
- package/bin/utils/logging.js +3 -0
- package/package.json +12 -12
- package/server/server.js +17 -6
package/README.md
CHANGED
|
@@ -212,7 +212,7 @@ Run for 1 service from the service folder:
|
|
|
212
212
|
| `--target` | Where to publish the `dist` directory assets.<br/>`dev` \| `production` (`string`) |
|
|
213
213
|
| `--dry-run` | Dry run, dont actually upload anything |
|
|
214
214
|
|
|
215
|
-
Send all files and directories created in the `dist` directory to either development or production versions of the Asset Store API. Files uploaded to the Asset Store API are available via a CloudFront-based CDN
|
|
215
|
+
Send all files and directories created in the `dist` directory to either development or production versions of the Asset Store API. Files uploaded to the Asset Store API are available via a CloudFront-based CDN
|
|
216
216
|
|
|
217
217
|
**Outline of implementation**
|
|
218
218
|
|
package/bin/cli.js
CHANGED
|
@@ -47,6 +47,7 @@ const run = () => {
|
|
|
47
47
|
'Download known configs from the Configuration API for environment "dev" or "production"',
|
|
48
48
|
)
|
|
49
49
|
.option('--query [configName]', 'Describe known keys for a config, omit to list all known configs')
|
|
50
|
+
.option('--skip-key-delete', 'Skip deleting keys not present in local config files on publish')
|
|
50
51
|
.action((...args) => configsCommand(...args));
|
|
51
52
|
|
|
52
53
|
cli
|
package/bin/commands/configs.js
CHANGED
|
@@ -5,7 +5,6 @@ import chalk from 'chalk';
|
|
|
5
5
|
import open from 'open';
|
|
6
6
|
import chokidar from 'chokidar4';
|
|
7
7
|
import { resolveConfig, findFertConfigDir } from '../utils/index.js';
|
|
8
|
-
import { log } from '../utils/logging.js';
|
|
9
8
|
import { validateLocalConfigs } from '../utils/configs.js';
|
|
10
9
|
import { devServer } from '../../server/server.js';
|
|
11
10
|
import { buildTokens, buildExternalAssets } from './build.js';
|
|
@@ -62,9 +61,20 @@ export async function createDevServer(options = {}) {
|
|
|
62
61
|
});
|
|
63
62
|
|
|
64
63
|
// start server
|
|
65
|
-
const server = await devServer({ start: true, fertConfig });
|
|
66
64
|
|
|
67
|
-
|
|
65
|
+
/**
|
|
66
|
+
* having a port number to start with helps keep the ports changing too much in development
|
|
67
|
+
*/
|
|
68
|
+
const STARTING_PORT_FOR_SERVICE_FOR_CONVENIENCE = {
|
|
69
|
+
'jobseekers-frontend': 4001,
|
|
70
|
+
'recruiterservices-frontend': 4021,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const server = await devServer({
|
|
74
|
+
start: true,
|
|
75
|
+
fertConfig,
|
|
76
|
+
port: STARTING_PORT_FOR_SERVICE_FOR_CONVENIENCE[fertConfig.serviceName],
|
|
77
|
+
});
|
|
68
78
|
|
|
69
79
|
if (options.open) {
|
|
70
80
|
await open(server.info.uri);
|
package/bin/utils/configs.js
CHANGED
|
@@ -53,7 +53,7 @@ export async function validateLocalConfigs({ workingDir, clientPropertyId, throw
|
|
|
53
53
|
// validate all keys individually against the schema keys to ensure we're not trying to set any read-only keys
|
|
54
54
|
const config = localConfigs[configName].data;
|
|
55
55
|
for (const key in config) {
|
|
56
|
-
const keySchema = schema.extract(key);
|
|
56
|
+
const keySchema = schema.extract([key]);
|
|
57
57
|
if (api._isSchemaReadOnly(keySchema)) {
|
|
58
58
|
throw new Error(`You're trying to set a read-only key on a config schema: ${configName}/${key}`);
|
|
59
59
|
}
|
|
@@ -124,10 +124,16 @@ export async function loadLocalConfigs(workingDir) {
|
|
|
124
124
|
* @param {string} options.workingDir - required, Working dir for configs - should usually be 'root' where fert.config.js is
|
|
125
125
|
* @param {string} options.clientPropertyId - required, clientPropertyId
|
|
126
126
|
* @param {string} options.environment - default=production, clientPropertyId
|
|
127
|
+
* @param {boolean} [options.skipKeyDelete] - Whether to skip deleting keys not present in local files during publish
|
|
127
128
|
*
|
|
128
129
|
* @returns {Promise<boolean>} - Returns a promise that resolves to true if the update is successful.
|
|
129
130
|
*/
|
|
130
|
-
export async function updateProjectConfigs({
|
|
131
|
+
export async function updateProjectConfigs({
|
|
132
|
+
clientPropertyId,
|
|
133
|
+
workingDir,
|
|
134
|
+
environment = 'production',
|
|
135
|
+
skipKeyDelete = false,
|
|
136
|
+
} = {}) {
|
|
131
137
|
Hoek.assert(clientPropertyId, 'clientPropertyId is required');
|
|
132
138
|
Hoek.assert(workingDir, 'workingDir is required');
|
|
133
139
|
|
|
@@ -149,7 +155,12 @@ export async function updateProjectConfigs({ clientPropertyId, workingDir, envir
|
|
|
149
155
|
const { toRemove, toSet } = collateConfigs(api, localConfigs);
|
|
150
156
|
|
|
151
157
|
// Will throw on first failure
|
|
152
|
-
|
|
158
|
+
if (skipKeyDelete) {
|
|
159
|
+
log.warn('Skipping deleting config keys - can no longer ensure config parity!');
|
|
160
|
+
await setConfigs(api, toSet); // only set
|
|
161
|
+
} else {
|
|
162
|
+
await Promise.all([setConfigs(api, toSet), removeConfigs(api, toRemove)]);
|
|
163
|
+
}
|
|
153
164
|
|
|
154
165
|
const { host } = new URL(api.options.apiUrl);
|
|
155
166
|
log.info(``);
|
|
@@ -182,7 +193,7 @@ export function collateConfigs(api, localConfigs) {
|
|
|
182
193
|
// remove any keys that are read-only from the unset keys collection
|
|
183
194
|
// we don't want to be deleting those!
|
|
184
195
|
for (const key in unsetKeysWithDefaults) {
|
|
185
|
-
if (api._isSchemaReadOnly(schema.extract(key))) {
|
|
196
|
+
if (api._isSchemaReadOnly(schema.extract([key]))) {
|
|
186
197
|
delete unsetKeysWithDefaults[key];
|
|
187
198
|
}
|
|
188
199
|
}
|
package/bin/utils/logging.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@madgex/fert",
|
|
3
|
-
"version": "6.0
|
|
3
|
+
"version": "6.2.0",
|
|
4
4
|
"description": "Tool to help build the V6 branding",
|
|
5
5
|
"bin": {
|
|
6
6
|
"fert": "./bin/cli.js"
|
|
@@ -24,15 +24,15 @@
|
|
|
24
24
|
"author": "Madgex",
|
|
25
25
|
"license": "UNLICENSED",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@aws-sdk/client-cloudfront": "^3.
|
|
28
|
-
"@aws-sdk/client-ssm": "^3.
|
|
27
|
+
"@aws-sdk/client-cloudfront": "^3.812.0",
|
|
28
|
+
"@aws-sdk/client-ssm": "^3.812.0",
|
|
29
29
|
"@hapi/hapi": "^21.4.0",
|
|
30
30
|
"@hapi/hoek": "^11.0.7",
|
|
31
31
|
"@hapi/inert": "^7.1.0",
|
|
32
32
|
"@hapi/vision": "^7.0.3",
|
|
33
33
|
"@hapipal/toys": "^4.0.0",
|
|
34
|
-
"@madgex/design-system": "^10.0.
|
|
35
|
-
"@madgex/config-api-sdk": "^1.
|
|
34
|
+
"@madgex/design-system": "^10.0.5",
|
|
35
|
+
"@madgex/config-api-sdk": "^1.9.1",
|
|
36
36
|
"@private/header-footer-podlet-server": "github:wiley/madgex-header-footer-podlet",
|
|
37
37
|
"axios": "^1.9.0",
|
|
38
38
|
"cac": "^6.7.14",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"debug": "^4.4.0",
|
|
42
42
|
"dedent": "^1.5.3",
|
|
43
43
|
"find-up-simple": "^1.0.1",
|
|
44
|
-
"flat-cache": "^6.1.
|
|
44
|
+
"flat-cache": "^6.1.9",
|
|
45
45
|
"form-data": "^4.0.2",
|
|
46
46
|
"joi": "^17.13.3",
|
|
47
47
|
"lodash": "^4.17.21",
|
|
@@ -54,19 +54,19 @@
|
|
|
54
54
|
"simple-git": "^3.27.0",
|
|
55
55
|
"simple-update-notifier": "^2.0.0",
|
|
56
56
|
"uuid-validate": "^0.0.3",
|
|
57
|
-
"vite": "^6.3.
|
|
57
|
+
"vite": "^6.3.5",
|
|
58
58
|
"vite-plugin-static-copy": "^2.3.1"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@commitlint/cli": "^19.8.
|
|
62
|
-
"@commitlint/config-conventional": "^19.8.
|
|
61
|
+
"@commitlint/cli": "^19.8.1",
|
|
62
|
+
"@commitlint/config-conventional": "^19.8.1",
|
|
63
63
|
"@madgex/eslint-config-madgex": "^2.3.0",
|
|
64
64
|
"@madgex/prettier-config-madgex": "^2.0.0",
|
|
65
|
-
"eslint": "^9.
|
|
65
|
+
"eslint": "^9.27.0",
|
|
66
66
|
"husky": "^9.1.7",
|
|
67
|
-
"lint-staged": "^
|
|
67
|
+
"lint-staged": "^16.0.0",
|
|
68
68
|
"prettier": "^3.5.3",
|
|
69
|
-
"semantic-release": "^24.2.
|
|
69
|
+
"semantic-release": "^24.2.4"
|
|
70
70
|
},
|
|
71
71
|
"lint-staged": {
|
|
72
72
|
"*.{js,json}": [
|
package/server/server.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
+
import chalk from 'chalk';
|
|
2
3
|
import Hapi from '@hapi/hapi';
|
|
3
4
|
import Toys from '@hapipal/toys';
|
|
4
5
|
import Vision from '@hapi/vision';
|
|
@@ -14,9 +15,9 @@ import routesPublic from './routes/public.js';
|
|
|
14
15
|
import routesViews from './routes/views.js';
|
|
15
16
|
import extensionErrorLogging from './extensions/error-logging.js';
|
|
16
17
|
|
|
17
|
-
export async function devServer({ start, fertConfig = {} } = {}) {
|
|
18
|
+
export async function devServer({ start, fertConfig = {}, port } = {}) {
|
|
18
19
|
const server = Hapi.server({
|
|
19
|
-
port: 0, // 0 === random unused port
|
|
20
|
+
port: port || 0, // 0 === random unused port
|
|
20
21
|
host: fertConfig.cli?.host ?? 'localhost',
|
|
21
22
|
});
|
|
22
23
|
|
|
@@ -91,10 +92,20 @@ export async function devServer({ start, fertConfig = {} } = {}) {
|
|
|
91
92
|
server.ext(extensionErrorLogging);
|
|
92
93
|
|
|
93
94
|
if (start) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
try {
|
|
96
|
+
await server.start();
|
|
97
|
+
log.info(`\nDev server ${fertConfig.serviceName}: ${chalk.cyan.bold(server.info.uri)}`);
|
|
98
|
+
} catch (err) {
|
|
99
|
+
if (err.message.includes('EADDRINUSE')) {
|
|
100
|
+
// stop server, we are throwing it away and starting a new one just to increment port!
|
|
101
|
+
await server.stop();
|
|
102
|
+
log.info(`Port ${server.settings.port} is in use, trying another one...`);
|
|
103
|
+
// returning devServer, it will be awaited and its result returned to the original call in dev-server.js
|
|
104
|
+
return devServer({ start, fertConfig, port: port + 1 });
|
|
105
|
+
} else {
|
|
106
|
+
throw err;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
98
109
|
return server;
|
|
99
110
|
}
|
|
100
111
|
|