@scaleway/configuration-loader 2.2.0 → 2.3.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/.turbo/turbo-build.log +14 -10
- package/CHANGELOG.md +6 -0
- package/dist/config-loader.d.ts +29 -0
- package/dist/config-loader.js +49 -5
- package/dist/env.js +3 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -2
- package/dist/path-resolver.js +6 -4
- package/dist/types.js +0 -0
- package/dist/yml-loader.d.ts +30 -1
- package/dist/yml-loader.js +44 -5
- package/package.json +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
|
|
2
|
-
> @scaleway/configuration-loader@2.
|
|
2
|
+
> @scaleway/configuration-loader@2.2.0 build /home/runner/work/scaleway-sdk-js/scaleway-sdk-js/packages/configuration-loader
|
|
3
3
|
> vite build --config ../../vite.config.ts && pnpm run type:generate
|
|
4
4
|
|
|
5
|
-
[36mvite v8.0.
|
|
6
|
-
[2K
|
|
5
|
+
[36mvite v8.0.1 [32mbuilding ssr environment for production...[36m[39m
|
|
6
|
+
[2K
|
|
7
7
|
rendering chunks...
|
|
8
8
|
computing gzip size...
|
|
9
|
-
dist/
|
|
10
|
-
dist/
|
|
11
|
-
dist/env.js
|
|
12
|
-
dist/
|
|
13
|
-
dist/
|
|
9
|
+
dist/types.js 0.00 kB │ gzip: 0.02 kB
|
|
10
|
+
dist/index.js 0.51 kB │ gzip: 0.16 kB
|
|
11
|
+
dist/env.js 0.94 kB │ gzip: 0.41 kB
|
|
12
|
+
dist/path-resolver.js 0.96 kB │ gzip: 0.41 kB
|
|
13
|
+
dist/__tests__/path-resolver.test.js 1.50 kB │ gzip: 0.57 kB
|
|
14
|
+
dist/__tests__/yml-loader.test.js 2.63 kB │ gzip: 0.81 kB
|
|
15
|
+
dist/yml-loader.js 2.78 kB │ gzip: 1.09 kB
|
|
16
|
+
dist/__tests__/config-loader.test.js 3.08 kB │ gzip: 1.04 kB
|
|
17
|
+
dist/config-loader.js 4.34 kB │ gzip: 0.95 kB
|
|
14
18
|
|
|
15
|
-
[32m✓ built in
|
|
19
|
+
[32m✓ built in 32ms[39m
|
|
16
20
|
|
|
17
|
-
> @scaleway/configuration-loader@2.
|
|
21
|
+
> @scaleway/configuration-loader@2.2.0 type:generate /home/runner/work/scaleway-sdk-js/scaleway-sdk-js/packages/configuration-loader
|
|
18
22
|
> tsc --declaration -p tsconfig.build.json
|
|
19
23
|
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# 2.3.0 (2026-04-02)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- **configuration-loader:** add async config loading and file permission check ([#2860](https://github.com/scaleway/scaleway-sdk-js/issues/2860)) ([1377d94](https://github.com/scaleway/scaleway-sdk-js/commit/1377d94a2a01c6a717781513affd634c7fc61b98))
|
|
11
|
+
|
|
6
12
|
# 2.2.0 (2026-03-05)
|
|
7
13
|
|
|
8
14
|
### Features
|
package/dist/config-loader.d.ts
CHANGED
|
@@ -32,3 +32,32 @@ export declare const loadAllProfilesFromConfigurationFile: (params?: Readonly<Al
|
|
|
32
32
|
* @public
|
|
33
33
|
*/
|
|
34
34
|
export declare const loadProfileFromConfigurationFile: (params?: Readonly<ProfileFromFileParams>) => Profile;
|
|
35
|
+
/**
|
|
36
|
+
* Loads all profiles from configuration file (asynchronous).
|
|
37
|
+
*
|
|
38
|
+
* Non-blocking alternative to {@link loadAllProfilesFromConfigurationFile}.
|
|
39
|
+
*
|
|
40
|
+
* @param params - The parameters to load the profile
|
|
41
|
+
* @returns The profiles filled with values found in the configuration profile
|
|
42
|
+
*
|
|
43
|
+
* @throws Error
|
|
44
|
+
* Thrown if the configuration file couldn't be found.
|
|
45
|
+
*
|
|
46
|
+
* @public
|
|
47
|
+
*/
|
|
48
|
+
export declare const loadAllProfilesFromConfigurationFileAsync: (params?: Readonly<AllProfilesFromFileParams>) => Promise<Record<string, Profile>>;
|
|
49
|
+
/**
|
|
50
|
+
* Loads profile from configuration file (asynchronous).
|
|
51
|
+
*
|
|
52
|
+
* Non-blocking alternative to {@link loadProfileFromConfigurationFile}.
|
|
53
|
+
*
|
|
54
|
+
* @param params - The parameters to load the profile
|
|
55
|
+
* @returns The profile filled with values found in the configuration profile
|
|
56
|
+
*
|
|
57
|
+
* @throws Error
|
|
58
|
+
* Thrown if the configuration file couldn't be found,
|
|
59
|
+
* or if the specified profile can't be found.
|
|
60
|
+
*
|
|
61
|
+
* @public
|
|
62
|
+
*/
|
|
63
|
+
export declare const loadProfileFromConfigurationFileAsync: (params?: Readonly<ProfileFromFileParams>) => Promise<Profile>;
|
package/dist/config-loader.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { EnvironmentKey } from "./env.js";
|
|
2
2
|
import { resolveConfigurationFilePath } from "./path-resolver.js";
|
|
3
|
-
import { loadConfigurationFromFile } from "./yml-loader.js";
|
|
3
|
+
import { loadConfigurationFromFile, loadConfigurationFromFileAsync } from "./yml-loader.js";
|
|
4
4
|
import { env } from "node:process";
|
|
5
|
+
//#region src/config-loader.ts
|
|
5
6
|
var convertFileConfigToSDK = (obj) => ({
|
|
6
7
|
accessKey: obj.access_key,
|
|
7
8
|
apiURL: obj.api_url,
|
|
@@ -18,7 +19,7 @@ var convertFileConfigToSDK = (obj) => ({
|
|
|
18
19
|
*
|
|
19
20
|
* @public
|
|
20
21
|
*/
|
|
21
|
-
|
|
22
|
+
var loadProfileFromEnvironmentValues = () => ({
|
|
22
23
|
accessKey: env[EnvironmentKey.ScwAccessKey],
|
|
23
24
|
apiURL: env[EnvironmentKey.ScwAPIURL],
|
|
24
25
|
defaultOrganizationId: env[EnvironmentKey.ScwDefaultOrganizationId],
|
|
@@ -38,7 +39,7 @@ const loadProfileFromEnvironmentValues = () => ({
|
|
|
38
39
|
*
|
|
39
40
|
* @public
|
|
40
41
|
*/
|
|
41
|
-
|
|
42
|
+
var loadAllProfilesFromConfigurationFile = (params) => {
|
|
42
43
|
const filePath = params?.filepath ?? resolveConfigurationFilePath();
|
|
43
44
|
if (typeof filePath !== "string" || filePath.length === 0) throw new Error("Could not find the path to the configuration file.");
|
|
44
45
|
const configs = loadConfigurationFromFile(filePath);
|
|
@@ -58,11 +59,54 @@ const loadAllProfilesFromConfigurationFile = (params) => {
|
|
|
58
59
|
*
|
|
59
60
|
* @public
|
|
60
61
|
*/
|
|
61
|
-
|
|
62
|
+
var loadProfileFromConfigurationFile = (params) => {
|
|
62
63
|
const configs = loadAllProfilesFromConfigurationFile(params);
|
|
63
64
|
const profileName = params?.profileName ?? "default";
|
|
64
65
|
const profileMap = configs[profileName];
|
|
65
66
|
if (typeof profileMap !== "object") throw new Error(`Could not find the desired profile '${profileName}' in the configuration file.`);
|
|
66
67
|
return profileMap;
|
|
67
68
|
};
|
|
68
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Loads all profiles from configuration file (asynchronous).
|
|
71
|
+
*
|
|
72
|
+
* Non-blocking alternative to {@link loadAllProfilesFromConfigurationFile}.
|
|
73
|
+
*
|
|
74
|
+
* @param params - The parameters to load the profile
|
|
75
|
+
* @returns The profiles filled with values found in the configuration profile
|
|
76
|
+
*
|
|
77
|
+
* @throws Error
|
|
78
|
+
* Thrown if the configuration file couldn't be found.
|
|
79
|
+
*
|
|
80
|
+
* @public
|
|
81
|
+
*/
|
|
82
|
+
var loadAllProfilesFromConfigurationFileAsync = async (params) => {
|
|
83
|
+
const filePath = params?.filepath ?? resolveConfigurationFilePath();
|
|
84
|
+
if (typeof filePath !== "string" || filePath.length === 0) throw new Error("Could not find the path to the configuration file.");
|
|
85
|
+
const configs = await loadConfigurationFromFileAsync(filePath);
|
|
86
|
+
const result = {};
|
|
87
|
+
for (const pKey of Object.keys(configs)) result[pKey] = convertFileConfigToSDK(configs[pKey]);
|
|
88
|
+
return result;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Loads profile from configuration file (asynchronous).
|
|
92
|
+
*
|
|
93
|
+
* Non-blocking alternative to {@link loadProfileFromConfigurationFile}.
|
|
94
|
+
*
|
|
95
|
+
* @param params - The parameters to load the profile
|
|
96
|
+
* @returns The profile filled with values found in the configuration profile
|
|
97
|
+
*
|
|
98
|
+
* @throws Error
|
|
99
|
+
* Thrown if the configuration file couldn't be found,
|
|
100
|
+
* or if the specified profile can't be found.
|
|
101
|
+
*
|
|
102
|
+
* @public
|
|
103
|
+
*/
|
|
104
|
+
var loadProfileFromConfigurationFileAsync = async (params) => {
|
|
105
|
+
const configs = await loadAllProfilesFromConfigurationFileAsync(params);
|
|
106
|
+
const profileName = params?.profileName ?? "default";
|
|
107
|
+
const profileMap = configs[profileName];
|
|
108
|
+
if (typeof profileMap !== "object") throw new Error(`Could not find the desired profile '${profileName}' in the configuration file.`);
|
|
109
|
+
return profileMap;
|
|
110
|
+
};
|
|
111
|
+
//#endregion
|
|
112
|
+
export { loadAllProfilesFromConfigurationFile, loadAllProfilesFromConfigurationFileAsync, loadProfileFromConfigurationFile, loadProfileFromConfigurationFileAsync, loadProfileFromEnvironmentValues };
|
package/dist/env.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
//#region src/env.ts
|
|
1
2
|
/**
|
|
2
3
|
* Environment Key.
|
|
3
4
|
*/
|
|
4
|
-
|
|
5
|
+
var EnvironmentKey = /* @__PURE__ */ function(EnvironmentKey) {
|
|
5
6
|
/** Path to the Scaleway configuration file */
|
|
6
7
|
EnvironmentKey["ScwConfigPath"] = "SCW_CONFIG_PATH";
|
|
7
8
|
/** Scaleway access key */
|
|
@@ -23,4 +24,5 @@ let EnvironmentKey = /* @__PURE__ */ function(EnvironmentKey) {
|
|
|
23
24
|
EnvironmentKey["ScwDefaultZone"] = "SCW_DEFAULT_ZONE";
|
|
24
25
|
return EnvironmentKey;
|
|
25
26
|
}({});
|
|
27
|
+
//#endregion
|
|
26
28
|
export { EnvironmentKey };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export { loadAllProfilesFromConfigurationFile, loadProfileFromConfigurationFile, loadProfileFromEnvironmentValues, } from './config-loader.js';
|
|
1
|
+
export { loadAllProfilesFromConfigurationFile, loadAllProfilesFromConfigurationFileAsync, loadProfileFromConfigurationFile, loadProfileFromConfigurationFileAsync, loadProfileFromEnvironmentValues, } from './config-loader.js';
|
|
2
2
|
export type { AllProfilesFromFileParams, Profile, ProfileFromFileParams, } from './types.js';
|
|
3
|
+
export { hasSecureFilePermissions } from './yml-loader.js';
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { hasSecureFilePermissions } from "./yml-loader.js";
|
|
2
|
+
import { loadAllProfilesFromConfigurationFile, loadAllProfilesFromConfigurationFileAsync, loadProfileFromConfigurationFile, loadProfileFromConfigurationFileAsync, loadProfileFromEnvironmentValues } from "./config-loader.js";
|
|
3
|
+
export { hasSecureFilePermissions, loadAllProfilesFromConfigurationFile, loadAllProfilesFromConfigurationFileAsync, loadProfileFromConfigurationFile, loadProfileFromConfigurationFileAsync, loadProfileFromEnvironmentValues };
|
package/dist/path-resolver.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { EnvironmentKey } from "./env.js";
|
|
2
|
-
import { env } from "node:process";
|
|
3
2
|
import { homedir } from "node:os";
|
|
4
3
|
import * as path from "node:path";
|
|
4
|
+
import { env } from "node:process";
|
|
5
|
+
//#region src/path-resolver.ts
|
|
5
6
|
/**
|
|
6
7
|
* Gets the Scaleway directory.
|
|
7
8
|
*
|
|
@@ -9,7 +10,7 @@ import * as path from "node:path";
|
|
|
9
10
|
*
|
|
10
11
|
* @internal
|
|
11
12
|
*/
|
|
12
|
-
|
|
13
|
+
var getScwConfigurationDirectory = () => {
|
|
13
14
|
const xdgConfigPath = env.XDG_CONFIG_HOME;
|
|
14
15
|
if (typeof xdgConfigPath === "string" && xdgConfigPath.length > 0) return path.join(xdgConfigPath, "scw");
|
|
15
16
|
return path.join(homedir(), ".config", "scw");
|
|
@@ -21,9 +22,10 @@ const getScwConfigurationDirectory = () => {
|
|
|
21
22
|
*
|
|
22
23
|
* @internal
|
|
23
24
|
*/
|
|
24
|
-
|
|
25
|
+
var resolveConfigurationFilePath = () => {
|
|
25
26
|
const envFilePath = env[EnvironmentKey.ScwConfigPath];
|
|
26
27
|
if (typeof envFilePath === "string" && envFilePath.length > 0) return envFilePath;
|
|
27
28
|
return path.join(getScwConfigurationDirectory(), "config.yaml");
|
|
28
29
|
};
|
|
29
|
-
|
|
30
|
+
//#endregion
|
|
31
|
+
export { getScwConfigurationDirectory, resolveConfigurationFilePath };
|
package/dist/types.js
ADDED
|
File without changes
|
package/dist/yml-loader.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ import type { ConfigurationType } from './types.js';
|
|
|
9
9
|
*/
|
|
10
10
|
export declare const convertYamlToConfiguration: (input: string | null) => ConfigurationType;
|
|
11
11
|
/**
|
|
12
|
-
* Loads configuration from a file.
|
|
12
|
+
* Loads configuration from a file (synchronous).
|
|
13
13
|
*
|
|
14
14
|
* @param filePath - Path to the configuration file
|
|
15
15
|
* @returns The configuration
|
|
@@ -20,3 +20,32 @@ export declare const convertYamlToConfiguration: (input: string | null) => Confi
|
|
|
20
20
|
* @internal
|
|
21
21
|
*/
|
|
22
22
|
export declare const loadConfigurationFromFile: (filePath: string) => ConfigurationType;
|
|
23
|
+
/**
|
|
24
|
+
* Loads configuration from a file (asynchronous).
|
|
25
|
+
*
|
|
26
|
+
* Non-blocking alternative to {@link loadConfigurationFromFile} that avoids
|
|
27
|
+
* stalling the event loop on slow filesystems or large config files.
|
|
28
|
+
*
|
|
29
|
+
* @param filePath - Path to the configuration file
|
|
30
|
+
* @returns The configuration
|
|
31
|
+
*
|
|
32
|
+
* @throws Error
|
|
33
|
+
* Thrown if the file doesn't exist.
|
|
34
|
+
*
|
|
35
|
+
* @public
|
|
36
|
+
*/
|
|
37
|
+
export declare const loadConfigurationFromFileAsync: (filePath: string) => Promise<ConfigurationType>;
|
|
38
|
+
/**
|
|
39
|
+
* Checks whether a configuration file has secure permissions.
|
|
40
|
+
*
|
|
41
|
+
* The Scaleway config file contains secret keys that grant full API access.
|
|
42
|
+
* On POSIX systems this function verifies the file is not readable by group
|
|
43
|
+
* or others (mode 0o600 or stricter). Returns `true` on Windows where POSIX
|
|
44
|
+
* permission bits are not meaningful.
|
|
45
|
+
*
|
|
46
|
+
* @param filePath - Path to the configuration file
|
|
47
|
+
* @returns `true` if the file has secure permissions (or on Windows)
|
|
48
|
+
*
|
|
49
|
+
* @public
|
|
50
|
+
*/
|
|
51
|
+
export declare const hasSecureFilePermissions: (filePath: string) => Promise<boolean>;
|
package/dist/yml-loader.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import { readFileSync } from "node:fs";
|
|
1
|
+
import { readFile, readFileSync, stat } from "node:fs";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
//#region src/yml-loader.ts
|
|
4
|
+
var readFileAsync = promisify(readFile);
|
|
5
|
+
var statAsync = promisify(stat);
|
|
2
6
|
var STRIP_COMMENT_REGEX = /(^|\s)[;#]/;
|
|
3
7
|
var DETECT_SECTION_REGEX = /^\s*([\s\S]+?):\s*$/;
|
|
4
8
|
var DETECT_ITEM_REGEX = /^\s*(.+?)\s*:\s*(.+?)\s*$/;
|
|
@@ -10,7 +14,7 @@ var DETECT_ITEM_REGEX = /^\s*(.+?)\s*:\s*(.+?)\s*$/;
|
|
|
10
14
|
*
|
|
11
15
|
* @internal
|
|
12
16
|
*/
|
|
13
|
-
|
|
17
|
+
var convertYamlToConfiguration = (input) => {
|
|
14
18
|
let foundProfilesKey = false;
|
|
15
19
|
let currentSection = "default";
|
|
16
20
|
const map = {};
|
|
@@ -33,7 +37,7 @@ const convertYamlToConfiguration = (input) => {
|
|
|
33
37
|
return map;
|
|
34
38
|
};
|
|
35
39
|
/**
|
|
36
|
-
* Loads configuration from a file.
|
|
40
|
+
* Loads configuration from a file (synchronous).
|
|
37
41
|
*
|
|
38
42
|
* @param filePath - Path to the configuration file
|
|
39
43
|
* @returns The configuration
|
|
@@ -43,7 +47,42 @@ const convertYamlToConfiguration = (input) => {
|
|
|
43
47
|
*
|
|
44
48
|
* @internal
|
|
45
49
|
*/
|
|
46
|
-
|
|
50
|
+
var loadConfigurationFromFile = (filePath) => {
|
|
47
51
|
return convertYamlToConfiguration(readFileSync(filePath, "utf-8"));
|
|
48
52
|
};
|
|
49
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Loads configuration from a file (asynchronous).
|
|
55
|
+
*
|
|
56
|
+
* Non-blocking alternative to {@link loadConfigurationFromFile} that avoids
|
|
57
|
+
* stalling the event loop on slow filesystems or large config files.
|
|
58
|
+
*
|
|
59
|
+
* @param filePath - Path to the configuration file
|
|
60
|
+
* @returns The configuration
|
|
61
|
+
*
|
|
62
|
+
* @throws Error
|
|
63
|
+
* Thrown if the file doesn't exist.
|
|
64
|
+
*
|
|
65
|
+
* @public
|
|
66
|
+
*/
|
|
67
|
+
var loadConfigurationFromFileAsync = async (filePath) => {
|
|
68
|
+
return convertYamlToConfiguration(await readFileAsync(filePath, "utf-8"));
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Checks whether a configuration file has secure permissions.
|
|
72
|
+
*
|
|
73
|
+
* The Scaleway config file contains secret keys that grant full API access.
|
|
74
|
+
* On POSIX systems this function verifies the file is not readable by group
|
|
75
|
+
* or others (mode 0o600 or stricter). Returns `true` on Windows where POSIX
|
|
76
|
+
* permission bits are not meaningful.
|
|
77
|
+
*
|
|
78
|
+
* @param filePath - Path to the configuration file
|
|
79
|
+
* @returns `true` if the file has secure permissions (or on Windows)
|
|
80
|
+
*
|
|
81
|
+
* @public
|
|
82
|
+
*/
|
|
83
|
+
var hasSecureFilePermissions = async (filePath) => {
|
|
84
|
+
if (process.platform === "win32") return true;
|
|
85
|
+
return ((await statAsync(filePath)).mode & 63) === 0;
|
|
86
|
+
};
|
|
87
|
+
//#endregion
|
|
88
|
+
export { convertYamlToConfiguration, hasSecureFilePermissions, loadConfigurationFromFile, loadConfigurationFromFileAsync };
|