@lowdefy/node-utils 0.0.0-experimental-20260928062533 → 0.0.0-experimental-20260928120643
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.
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/ import { type } from '@lowdefy/helpers';
|
|
16
|
+
import { ConfigError } from '@lowdefy/errors';
|
|
17
|
+
import collectEnvironmentGuards from './collectEnvironmentGuards.js';
|
|
18
|
+
// Checks the current environment's guards against this process's environment variables. The build
|
|
19
|
+
// runs it before anything deploys, and the production server again at startup: an image built once
|
|
20
|
+
// can be started with different variables. Values are never echoed: a failure names the variable,
|
|
21
|
+
// not what it holds.
|
|
22
|
+
function checkEnvironmentGuards({ name, guards, configKey }) {
|
|
23
|
+
const failures = collectEnvironmentGuards({
|
|
24
|
+
guards
|
|
25
|
+
}).filter(({ variable, pattern })=>{
|
|
26
|
+
const value = process.env[variable];
|
|
27
|
+
return !type.isString(value) || !new RegExp(pattern).test(value);
|
|
28
|
+
});
|
|
29
|
+
if (failures.length === 0) return;
|
|
30
|
+
throw new ConfigError(`Environment "${name}" guards failed: ${failures.map(({ label, variable })=>type.isString(process.env[variable]) ? `${label} does not match its guard` : `${label} is not set (${variable})`).join('; ')}. Update the guard in config.environments.${name}.guards together with the value, or fix the value.`, {
|
|
31
|
+
configKey
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
export default checkEnvironmentGuards;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/ // Guards pin an environment's secrets and environment variables to a pattern kept in code: the
|
|
16
|
+
// value must match the regular expression, so changing a guarded value (the prod database URI,
|
|
17
|
+
// say) takes a change to the deployment's variables AND a reviewed change to the app config — a
|
|
18
|
+
// second factor for deploy-time configuration. Checked at build, before anything deploys.
|
|
19
|
+
//
|
|
20
|
+
// guards:
|
|
21
|
+
// secrets: { MONGODB_URI: 'acme-prod\.a1b2c\.mongodb\.net' } # LOWDEFY_SECRET_<NAME>
|
|
22
|
+
// env: { BETTER_AUTH_URL: '^https://app\.acme\.com$' }
|
|
23
|
+
//
|
|
24
|
+
// Values are never echoed: a failure names the variable, not what it holds.
|
|
25
|
+
function collectEnvironmentGuards({ guards }) {
|
|
26
|
+
const checks = [];
|
|
27
|
+
Object.entries(guards?.secrets ?? {}).forEach(([name, pattern])=>{
|
|
28
|
+
if (name.startsWith('~')) return;
|
|
29
|
+
checks.push({
|
|
30
|
+
label: `secret "${name}"`,
|
|
31
|
+
variable: `LOWDEFY_SECRET_${name}`,
|
|
32
|
+
pattern
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
Object.entries(guards?.env ?? {}).forEach(([name, pattern])=>{
|
|
36
|
+
if (name.startsWith('~')) return;
|
|
37
|
+
checks.push({
|
|
38
|
+
label: `environment variable "${name}"`,
|
|
39
|
+
variable: name,
|
|
40
|
+
pattern
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
return checks;
|
|
44
|
+
}
|
|
45
|
+
export default collectEnvironmentGuards;
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
13
|
See the License for the specific language governing permissions and
|
|
14
14
|
limitations under the License.
|
|
15
|
-
*/ import
|
|
15
|
+
*/ import checkEnvironmentGuards from './checkEnvironmentGuards.js';
|
|
16
|
+
import cleanDirectory from './cleanDirectory.js';
|
|
17
|
+
import collectEnvironmentGuards from './collectEnvironmentGuards.js';
|
|
16
18
|
import copyFileOrDirectory from './copyFileOrDirectory.js';
|
|
17
19
|
import createClientAddressResolver from './createClientAddressResolver.js';
|
|
18
20
|
import createSecretScrubber from './createSecretScrubber.js';
|
|
@@ -30,4 +32,4 @@ import spawnProcess from './spawnProcess.js';
|
|
|
30
32
|
import readFile from './readFile.js';
|
|
31
33
|
import writeFile from './writeFile.js';
|
|
32
34
|
import writeFileIfChanged from './writeFileIfChanged.js';
|
|
33
|
-
export { cleanDirectory, copyFileOrDirectory, createClientAddressResolver, createSecretScrubber, findAvailablePort, getDevInstancePath, getFileExtension, getFileSubExtension, getProcessStartTime, getSecretsFromEnv, installIfPackageJsonChanged, isPidAlive, isPortAvailable, parseIpRange, readDevInstance, spawnProcess, readFile, writeFile, writeFileIfChanged };
|
|
35
|
+
export { checkEnvironmentGuards, cleanDirectory, collectEnvironmentGuards, copyFileOrDirectory, createClientAddressResolver, createSecretScrubber, findAvailablePort, getDevInstancePath, getFileExtension, getFileSubExtension, getProcessStartTime, getSecretsFromEnv, installIfPackageJsonChanged, isPidAlive, isPortAvailable, parseIpRange, readDevInstance, spawnProcess, readFile, writeFile, writeFileIfChanged };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lowdefy/node-utils",
|
|
3
|
-
"version": "0.0.0-experimental-
|
|
3
|
+
"version": "0.0.0-experimental-20260928120643",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "",
|
|
6
6
|
"homepage": "https://lowdefy.com",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"dist/*"
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@lowdefy/errors": "0.0.0-experimental-
|
|
38
|
-
"@lowdefy/helpers": "0.0.0-experimental-
|
|
37
|
+
"@lowdefy/errors": "0.0.0-experimental-20260928120643",
|
|
38
|
+
"@lowdefy/helpers": "0.0.0-experimental-20260928120643",
|
|
39
39
|
"fs-extra": "11.3.4"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|