@dxos/config 0.8.4-main.bc674ce → 0.8.4-main.bcb3aa67d6

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.
Files changed (40) hide show
  1. package/dist/lib/browser/{chunk-WETPAQBA.mjs → chunk-54W4ZP5U.mjs} +3 -4
  2. package/dist/lib/browser/chunk-54W4ZP5U.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +7 -7
  4. package/dist/lib/browser/index.mjs.map +3 -3
  5. package/dist/lib/browser/loaders/browser.mjs +1 -1
  6. package/dist/lib/browser/loaders/browser.mjs.map +1 -1
  7. package/dist/lib/browser/loaders/index.mjs +1 -1
  8. package/dist/lib/browser/meta.json +1 -1
  9. package/dist/lib/browser/plugin/index.mjs +1 -1
  10. package/dist/lib/browser/savers/browser.mjs +1 -1
  11. package/dist/lib/browser/savers/browser.mjs.map +1 -1
  12. package/dist/lib/node-esm/{chunk-FVCGIRXP.mjs → chunk-YHGABJ7Y.mjs} +3 -4
  13. package/dist/lib/node-esm/chunk-YHGABJ7Y.mjs.map +7 -0
  14. package/dist/lib/node-esm/index.mjs +7 -7
  15. package/dist/lib/node-esm/index.mjs.map +3 -3
  16. package/dist/lib/node-esm/loaders/browser.mjs +1 -1
  17. package/dist/lib/node-esm/loaders/browser.mjs.map +1 -1
  18. package/dist/lib/node-esm/loaders/index.mjs +1 -1
  19. package/dist/lib/node-esm/meta.json +1 -1
  20. package/dist/lib/node-esm/plugin/index.mjs +1 -1
  21. package/dist/lib/node-esm/savers/browser.mjs +1 -1
  22. package/dist/lib/node-esm/savers/browser.mjs.map +1 -1
  23. package/dist/plugin/node-esm/{chunk-QQKWALKX.mjs → chunk-4OOW7ZFE.mjs} +3 -4
  24. package/dist/plugin/node-esm/chunk-4OOW7ZFE.mjs.map +7 -0
  25. package/dist/plugin/node-esm/esbuild-plugin.mjs +1 -1
  26. package/dist/plugin/node-esm/meta.json +1 -1
  27. package/dist/plugin/node-esm/rollup-plugin.mjs +1 -1
  28. package/dist/plugin/node-esm/vite-plugin.mjs +1 -1
  29. package/dist/types/src/config-service.d.ts.map +1 -1
  30. package/dist/types/src/config.d.ts.map +1 -1
  31. package/dist/types/tsconfig.tsbuildinfo +1 -1
  32. package/package.json +12 -13
  33. package/src/config-service.ts +5 -6
  34. package/src/config.ts +1 -2
  35. package/src/loaders/browser.ts +1 -1
  36. package/src/savers/browser.ts +1 -1
  37. package/src/testing/build.js +2 -1
  38. package/dist/lib/browser/chunk-WETPAQBA.mjs.map +0 -7
  39. package/dist/lib/node-esm/chunk-FVCGIRXP.mjs.map +0 -7
  40. package/dist/plugin/node-esm/chunk-QQKWALKX.mjs.map +0 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/config",
3
- "version": "0.8.4-main.bc674ce",
3
+ "version": "0.8.4-main.bcb3aa67d6",
4
4
  "description": "Config utilities",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -90,26 +90,25 @@
90
90
  "src"
91
91
  ],
92
92
  "dependencies": {
93
- "@effect/platform": "0.93.6",
94
- "boolean": "^3.0.1",
95
- "effect": "3.19.11",
93
+ "@effect/platform": "0.94.4",
94
+ "effect": "3.20.0",
96
95
  "localforage": "^1.10.0",
97
96
  "lodash.defaultsdeep": "^4.6.1",
98
97
  "lodash.ismatch": "^4.4.0",
99
98
  "pkg-up": "^3.1.0",
100
- "yaml": "^2.7.0",
101
- "@dxos/client-protocol": "0.8.4-main.bc674ce",
102
- "@dxos/invariant": "0.8.4-main.bc674ce",
103
- "@dxos/protocols": "0.8.4-main.bc674ce",
104
- "@dxos/tracing": "0.8.4-main.bc674ce",
105
- "@dxos/util": "0.8.4-main.bc674ce",
106
- "@dxos/node-std": "0.8.4-main.bc674ce",
107
- "@dxos/log": "0.8.4-main.bc674ce"
99
+ "yaml": "^2.8.2",
100
+ "@dxos/client-protocol": "0.8.4-main.bcb3aa67d6",
101
+ "@dxos/log": "0.8.4-main.bcb3aa67d6",
102
+ "@dxos/node-std": "0.8.4-main.bcb3aa67d6",
103
+ "@dxos/invariant": "0.8.4-main.bcb3aa67d6",
104
+ "@dxos/protocols": "0.8.4-main.bcb3aa67d6",
105
+ "@dxos/tracing": "0.8.4-main.bcb3aa67d6",
106
+ "@dxos/util": "0.8.4-main.bcb3aa67d6"
108
107
  },
109
108
  "devDependencies": {
110
109
  "@types/lodash.defaultsdeep": "^4.6.6",
111
110
  "@types/lodash.ismatch": "^4.4.9",
112
- "webpack": "^5.88.2"
111
+ "webpack": "^5.104.1"
113
112
  },
114
113
  "publishConfig": {
115
114
  "access": "public"
@@ -11,8 +11,7 @@ import * as Layer from 'effect/Layer';
11
11
  import * as Option from 'effect/Option';
12
12
  import * as Yaml from 'yaml';
13
13
 
14
- import { DX_CONFIG, DX_DATA } from '@dxos/client-protocol';
15
- import { getProfilePath } from '@dxos/client-protocol';
14
+ import { DX_CONFIG, DX_DATA, getProfileConfigPath, getProfilePath } from '@dxos/client-protocol';
16
15
  import { invariant } from '@dxos/invariant';
17
16
 
18
17
  import { Config } from './config';
@@ -69,7 +68,7 @@ export class ConfigService extends Context.Tag('ConfigService')<ConfigService, C
69
68
  static fromConfig = (config: Config) => Layer.succeed(ConfigService, config);
70
69
 
71
70
  static load = (args: { config: Option.Option<string>; profile: string }) => {
72
- const defaultConfigPath = `${getProfilePath(DX_CONFIG, args.profile)}.yml`;
71
+ const defaultConfigPath = getProfileConfigPath(DX_CONFIG, args.profile);
73
72
  return Effect.gen(function* () {
74
73
  const fs = yield* FileSystem.FileSystem;
75
74
  const configPath = Option.getOrElse(args.config, () => defaultConfigPath);
@@ -82,9 +81,9 @@ export class ConfigService extends Context.Tag('ConfigService')<ConfigService, C
82
81
  Effect.gen(function* () {
83
82
  const configValues = defaultConfig.values;
84
83
  const fs = yield* FileSystem.FileSystem;
85
- yield* fs.makeDirectory(dirname(defaultConfigPath), { recursive: true });
86
- yield* fs.writeFileString(defaultConfigPath, Yaml.stringify(configValues));
87
-
84
+ const pathToCreate = Option.getOrElse(args.config, () => defaultConfigPath);
85
+ yield* fs.makeDirectory(dirname(pathToCreate), { recursive: true });
86
+ yield* fs.writeFileString(pathToCreate, Yaml.stringify(configValues));
88
87
  return ConfigService.of(new Config(configValues));
89
88
  }),
90
89
  ),
package/src/config.ts CHANGED
@@ -2,7 +2,6 @@
2
2
  // Copyright 2021 DXOS.org
3
3
  //
4
4
 
5
- import { boolean } from 'boolean';
6
5
  import defaultsDeep from 'lodash.defaultsdeep';
7
6
  import isMatch from 'lodash.ismatch';
8
7
 
@@ -39,7 +38,7 @@ export const mapFromKeyValues = (spec: MappingSpec, values: Record<string, any>)
39
38
  if (type) {
40
39
  switch (type) {
41
40
  case 'boolean': {
42
- value = boolean(value);
41
+ value = String(value).toLowerCase() === 'true' || value === '1';
43
42
  break;
44
43
  }
45
44
 
@@ -51,7 +51,7 @@ export const Defaults = (_basePath?: string): Partial<ConfigProto> => {
51
51
  */
52
52
  export const Storage = async (): Promise<Partial<ConfigProto>> => {
53
53
  try {
54
- const config = await localforage.getItem<Partial<ConfigProto>>('dxos.org/settings/config');
54
+ const config = await localforage.getItem<Partial<ConfigProto>>('org.dxos.settings.config');
55
55
  if (config) {
56
56
  return config;
57
57
  }
@@ -19,7 +19,7 @@ export const SaveConfig = async (config: ConfigProto): Promise<void> => {
19
19
  PERFORMING_CONFIG_SAVE = true;
20
20
 
21
21
  try {
22
- await localforage.setItem('dxos.org/settings/config', config);
22
+ await localforage.setItem('org.dxos.settings.config', config);
23
23
  } catch (err) {
24
24
  log.warn('Failed to save config', { err });
25
25
  } finally {
@@ -5,9 +5,10 @@
5
5
  // This script is used to test whether the esbuild config plugin is properly injecting config constants.
6
6
  // TODO(wittjosiah): Automate this test.
7
7
 
8
- const { build } = require('esbuild');
9
8
  const { join } = require('node:path');
10
9
 
10
+ const { build } = require('esbuild');
11
+
11
12
  // eslint-disable-next-line
12
13
  // @ts-ignore
13
14
  const { ConfigPlugin } = require('../../dist/plugin/node/esbuild-plugin.cjs');
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/config.ts"],
4
- "sourcesContent": ["//\n// Copyright 2021 DXOS.org\n//\n\nimport { boolean } from 'boolean';\nimport defaultsDeep from 'lodash.defaultsdeep';\nimport isMatch from 'lodash.ismatch';\n\nimport { InvalidConfigError } from '@dxos/protocols';\nimport { schema } from '@dxos/protocols/proto';\nimport { type Config as ConfigProto } from '@dxos/protocols/proto/dxos/config';\nimport { trace } from '@dxos/tracing';\nimport { getDeep, setDeep } from '@dxos/util';\n\nimport { type ConfigKey, type DeepIndex, type ParseKey } from './types';\n\ntype MappingSpec = Record<string, { path: string; type?: string }>;\nconst configRootType = schema.getCodecForType('dxos.config.Config');\n\n/**\n * Maps the given objects onto a flattened set of (key x values).\n * Expects parsed yaml content of the form:\n *\n * ```\n * ENV_VAR:\n * path: config.selector.path\n * ```\n *\n * @param {object} spec\n * @param {object} values\n * @return {object}\n */\nexport const mapFromKeyValues = (spec: MappingSpec, values: Record<string, any>) => {\n const config = {};\n\n for (const [key, { path, type }] of Object.entries(spec)) {\n let value = values[key];\n if (value !== undefined) {\n if (type) {\n switch (type) {\n case 'boolean': {\n value = boolean(value);\n break;\n }\n\n case 'number': {\n value = Number(value);\n break;\n }\n\n case 'string': {\n break;\n }\n\n case 'json': {\n value = value ? JSON.parse(value) : null;\n break;\n }\n\n default: {\n throw new Error(`Invalid type: ${type}`);\n }\n }\n }\n\n setDeep(config, path.split('.'), value);\n }\n }\n\n return config;\n};\n\n/**\n * Maps the given flattend set of (key x values) onto a JSON object.\n * @param {object} spec\n * @param {object} values\n */\nexport const mapToKeyValues = (spec: MappingSpec, values: any) => {\n const config: Record<string, any> = {};\n\n for (const [key, { path, type }] of Object.entries(spec)) {\n const value = getDeep(values, path.split('.'));\n if (value !== undefined) {\n switch (type) {\n case 'json':\n config[key] = JSON.stringify(value);\n break;\n default:\n config[key] = value;\n }\n }\n }\n\n return config;\n};\n\n/**\n * Validate config object.\n */\nexport const validateConfig = (config: ConfigProto): ConfigProto => {\n if (!('version' in config)) {\n throw new InvalidConfigError({ message: 'Version not specified' });\n }\n\n if (config?.version !== 1) {\n throw new InvalidConfigError({ message: `Invalid config version: ${config.version}` });\n }\n\n const error = configRootType.protoType.verify(config);\n if (error) {\n throw new InvalidConfigError({ message: String(error) });\n }\n\n return config;\n};\n\nexport const ConfigResource = Symbol.for('dxos.resource.Config');\n\n/**\n * Global configuration object.\n * NOTE: Config objects are immutable.\n */\n@trace.resource({ annotation: ConfigResource })\nexport class Config {\n private readonly _config: any;\n\n /**\n * Creates an immutable instance.\n * @constructor\n */\n constructor(config: ConfigProto = {}, ...objects: ConfigProto[]) {\n this._config = validateConfig(defaultsDeep(config, ...objects, { version: 1 }));\n }\n\n /**\n * Returns an immutable config JSON object.\n */\n get values(): ConfigProto {\n return this._config;\n }\n\n /**\n * Returns the given config property.\n *\n * @param key A key in the config object. Can be a nested property with keys separated by dots: 'services.signal.server'.\n * @param defaultValue Default value to return if option is not present in the config.\n * @returns The config value or undefined if the option is not present.\n */\n get<K extends ConfigKey>(\n key: K,\n defaultValue?: DeepIndex<ConfigProto, ParseKey<K>>,\n ): DeepIndex<ConfigProto, ParseKey<K>> | undefined {\n return getDeep(this._config, key.split('.')) ?? defaultValue;\n }\n\n /**\n * Get unique key.\n */\n find<T = any>(path: string, test: object): T | undefined {\n const values = getDeep(this._config, path.split('.'));\n if (!Array.isArray(values)) {\n return;\n }\n\n return values.find((value) => isMatch(value, test));\n }\n\n /**\n * Returns the given config property or throw if it doesn't exist.\n *\n * @param key A key in the config object. Can be a nested property with keys separated by dots: 'services.signal.server'.\n */\n getOrThrow<K extends ConfigKey>(key: K): Exclude<DeepIndex<ConfigProto, ParseKey<K>>, undefined> {\n const value: DeepIndex<ConfigProto, ParseKey<K>> | undefined = getDeep(this._config, key.split('.'));\n if (!value) {\n throw new Error(`Config option not present: ${key}`);\n }\n return value;\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["boolean", "defaultsDeep", "isMatch", "InvalidConfigError", "schema", "trace", "getDeep", "setDeep", "configRootType", "schema", "getCodecForType", "mapFromKeyValues", "spec", "values", "config", "key", "path", "type", "Object", "entries", "value", "undefined", "boolean", "Number", "JSON", "parse", "Error", "setDeep", "split", "mapToKeyValues", "getDeep", "stringify", "validateConfig", "InvalidConfigError", "message", "version", "error", "protoType", "verify", "String", "ConfigResource", "Symbol", "for", "Config", "_config", "objects", "defaultsDeep", "get", "defaultValue", "find", "test", "Array", "isArray", "isMatch", "getOrThrow", "resource", "annotation"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/config.ts"],
4
- "sourcesContent": ["//\n// Copyright 2021 DXOS.org\n//\n\nimport { boolean } from 'boolean';\nimport defaultsDeep from 'lodash.defaultsdeep';\nimport isMatch from 'lodash.ismatch';\n\nimport { InvalidConfigError } from '@dxos/protocols';\nimport { schema } from '@dxos/protocols/proto';\nimport { type Config as ConfigProto } from '@dxos/protocols/proto/dxos/config';\nimport { trace } from '@dxos/tracing';\nimport { getDeep, setDeep } from '@dxos/util';\n\nimport { type ConfigKey, type DeepIndex, type ParseKey } from './types';\n\ntype MappingSpec = Record<string, { path: string; type?: string }>;\nconst configRootType = schema.getCodecForType('dxos.config.Config');\n\n/**\n * Maps the given objects onto a flattened set of (key x values).\n * Expects parsed yaml content of the form:\n *\n * ```\n * ENV_VAR:\n * path: config.selector.path\n * ```\n *\n * @param {object} spec\n * @param {object} values\n * @return {object}\n */\nexport const mapFromKeyValues = (spec: MappingSpec, values: Record<string, any>) => {\n const config = {};\n\n for (const [key, { path, type }] of Object.entries(spec)) {\n let value = values[key];\n if (value !== undefined) {\n if (type) {\n switch (type) {\n case 'boolean': {\n value = boolean(value);\n break;\n }\n\n case 'number': {\n value = Number(value);\n break;\n }\n\n case 'string': {\n break;\n }\n\n case 'json': {\n value = value ? JSON.parse(value) : null;\n break;\n }\n\n default: {\n throw new Error(`Invalid type: ${type}`);\n }\n }\n }\n\n setDeep(config, path.split('.'), value);\n }\n }\n\n return config;\n};\n\n/**\n * Maps the given flattend set of (key x values) onto a JSON object.\n * @param {object} spec\n * @param {object} values\n */\nexport const mapToKeyValues = (spec: MappingSpec, values: any) => {\n const config: Record<string, any> = {};\n\n for (const [key, { path, type }] of Object.entries(spec)) {\n const value = getDeep(values, path.split('.'));\n if (value !== undefined) {\n switch (type) {\n case 'json':\n config[key] = JSON.stringify(value);\n break;\n default:\n config[key] = value;\n }\n }\n }\n\n return config;\n};\n\n/**\n * Validate config object.\n */\nexport const validateConfig = (config: ConfigProto): ConfigProto => {\n if (!('version' in config)) {\n throw new InvalidConfigError({ message: 'Version not specified' });\n }\n\n if (config?.version !== 1) {\n throw new InvalidConfigError({ message: `Invalid config version: ${config.version}` });\n }\n\n const error = configRootType.protoType.verify(config);\n if (error) {\n throw new InvalidConfigError({ message: String(error) });\n }\n\n return config;\n};\n\nexport const ConfigResource = Symbol.for('dxos.resource.Config');\n\n/**\n * Global configuration object.\n * NOTE: Config objects are immutable.\n */\n@trace.resource({ annotation: ConfigResource })\nexport class Config {\n private readonly _config: any;\n\n /**\n * Creates an immutable instance.\n * @constructor\n */\n constructor(config: ConfigProto = {}, ...objects: ConfigProto[]) {\n this._config = validateConfig(defaultsDeep(config, ...objects, { version: 1 }));\n }\n\n /**\n * Returns an immutable config JSON object.\n */\n get values(): ConfigProto {\n return this._config;\n }\n\n /**\n * Returns the given config property.\n *\n * @param key A key in the config object. Can be a nested property with keys separated by dots: 'services.signal.server'.\n * @param defaultValue Default value to return if option is not present in the config.\n * @returns The config value or undefined if the option is not present.\n */\n get<K extends ConfigKey>(\n key: K,\n defaultValue?: DeepIndex<ConfigProto, ParseKey<K>>,\n ): DeepIndex<ConfigProto, ParseKey<K>> | undefined {\n return getDeep(this._config, key.split('.')) ?? defaultValue;\n }\n\n /**\n * Get unique key.\n */\n find<T = any>(path: string, test: object): T | undefined {\n const values = getDeep(this._config, path.split('.'));\n if (!Array.isArray(values)) {\n return;\n }\n\n return values.find((value) => isMatch(value, test));\n }\n\n /**\n * Returns the given config property or throw if it doesn't exist.\n *\n * @param key A key in the config object. Can be a nested property with keys separated by dots: 'services.signal.server'.\n */\n getOrThrow<K extends ConfigKey>(key: K): Exclude<DeepIndex<ConfigProto, ParseKey<K>>, undefined> {\n const value: DeepIndex<ConfigProto, ParseKey<K>> | undefined = getDeep(this._config, key.split('.'));\n if (!value) {\n throw new Error(`Config option not present: ${key}`);\n }\n return value;\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["boolean", "defaultsDeep", "isMatch", "InvalidConfigError", "schema", "trace", "getDeep", "setDeep", "configRootType", "schema", "getCodecForType", "mapFromKeyValues", "spec", "values", "config", "key", "path", "type", "Object", "entries", "value", "undefined", "boolean", "Number", "JSON", "parse", "Error", "setDeep", "split", "mapToKeyValues", "getDeep", "stringify", "validateConfig", "InvalidConfigError", "message", "version", "error", "protoType", "verify", "String", "ConfigResource", "Symbol", "for", "Config", "_config", "objects", "defaultsDeep", "get", "defaultValue", "find", "test", "Array", "isArray", "isMatch", "getOrThrow", "resource", "annotation"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/plugin/definitions.ts", "../../../src/config.ts"],
4
- "sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport { execSync } from 'node:child_process';\nimport { readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport pkgUp from 'pkg-up';\nimport { parse } from 'yaml';\n\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { setDeep } from '@dxos/util';\n\nimport { mapFromKeyValues } from '../config';\n\nimport { type ConfigPluginOpts } from './types';\n\nconst CWD = process.cwd();\n\nexport const definitions = ({\n configPath,\n envPath,\n devPath,\n mode = process.env.NODE_ENV,\n publicUrl = '',\n env,\n}: ConfigPluginOpts) => {\n const KEYS_TO_FILE = {\n __CONFIG_DEFAULTS__: configPath?.length ? configPath : resolve(CWD, 'dx.yml'),\n __CONFIG_ENVS__: envPath?.length ? envPath : resolve(CWD, 'dx-env.yml'),\n } as { [key: string]: string };\n if (mode !== 'production') {\n KEYS_TO_FILE.__CONFIG_LOCAL__ = devPath ?? resolve(CWD, 'dx-local.yml');\n }\n\n return Object.entries(KEYS_TO_FILE).reduce(\n (prev, [key, value]) => {\n invariant(key);\n let content = {};\n try {\n content = parse(readFileSync(value, 'utf-8')) as any;\n\n // Map environment variables to config values.\n if (key === '__CONFIG_ENVS__') {\n content = mapFromKeyValues(content, process.env);\n }\n\n if (key === '__CONFIG_DEFAULTS__') {\n // Load app environment variables into default config.\n Object.entries(process.env).forEach(([key, value]) => {\n if (key.startsWith('DX_') || env?.includes(key)) {\n setDeep(content, ['runtime', 'app', 'env', key], value);\n }\n });\n\n // Set build info automatically if available.\n try {\n const timestamp = new Date().toISOString();\n const commitHash =\n process.env.DX_COMMIT_HASH ??\n execSync('git rev-parse --short HEAD', { encoding: 'utf-8' }).replace('\\n', '');\n const packagePath = pkgUp.sync();\n const packageJson = packagePath && JSON.parse(readFileSync(packagePath, 'utf-8'));\n setDeep(content, ['runtime', 'app', 'build', 'timestamp'], timestamp);\n setDeep(content, ['runtime', 'app', 'build', 'commitHash'], commitHash);\n setDeep(content, ['runtime', 'app', 'build', 'version'], packageJson?.version);\n } catch {}\n }\n } catch (err: any) {\n if (err.message.includes('YAMLException')) {\n log.error(`Failed to parse file ${value}:`, err);\n } else {\n log(`Failed to load file ${value}:`, err);\n }\n\n if (key === '__CONFIG_DEFAULTS__') {\n // Default config is required.\n throw new Error(`Failed to load default config file from ${value}`);\n }\n }\n\n return {\n ...prev,\n [key]: content,\n };\n },\n {\n __CONFIG_DEFAULTS__: {},\n __CONFIG_ENVS__: {},\n __CONFIG_LOCAL__: {},\n __DXOS_CONFIG__: { dynamic: mode === 'production', publicUrl },\n },\n );\n};\n", "//\n// Copyright 2021 DXOS.org\n//\n\nimport { boolean } from 'boolean';\nimport defaultsDeep from 'lodash.defaultsdeep';\nimport isMatch from 'lodash.ismatch';\n\nimport { InvalidConfigError } from '@dxos/protocols';\nimport { schema } from '@dxos/protocols/proto';\nimport { type Config as ConfigProto } from '@dxos/protocols/proto/dxos/config';\nimport { trace } from '@dxos/tracing';\nimport { getDeep, setDeep } from '@dxos/util';\n\nimport { type ConfigKey, type DeepIndex, type ParseKey } from './types';\n\ntype MappingSpec = Record<string, { path: string; type?: string }>;\nconst configRootType = schema.getCodecForType('dxos.config.Config');\n\n/**\n * Maps the given objects onto a flattened set of (key x values).\n * Expects parsed yaml content of the form:\n *\n * ```\n * ENV_VAR:\n * path: config.selector.path\n * ```\n *\n * @param {object} spec\n * @param {object} values\n * @return {object}\n */\nexport const mapFromKeyValues = (spec: MappingSpec, values: Record<string, any>) => {\n const config = {};\n\n for (const [key, { path, type }] of Object.entries(spec)) {\n let value = values[key];\n if (value !== undefined) {\n if (type) {\n switch (type) {\n case 'boolean': {\n value = boolean(value);\n break;\n }\n\n case 'number': {\n value = Number(value);\n break;\n }\n\n case 'string': {\n break;\n }\n\n case 'json': {\n value = value ? JSON.parse(value) : null;\n break;\n }\n\n default: {\n throw new Error(`Invalid type: ${type}`);\n }\n }\n }\n\n setDeep(config, path.split('.'), value);\n }\n }\n\n return config;\n};\n\n/**\n * Maps the given flattend set of (key x values) onto a JSON object.\n * @param {object} spec\n * @param {object} values\n */\nexport const mapToKeyValues = (spec: MappingSpec, values: any) => {\n const config: Record<string, any> = {};\n\n for (const [key, { path, type }] of Object.entries(spec)) {\n const value = getDeep(values, path.split('.'));\n if (value !== undefined) {\n switch (type) {\n case 'json':\n config[key] = JSON.stringify(value);\n break;\n default:\n config[key] = value;\n }\n }\n }\n\n return config;\n};\n\n/**\n * Validate config object.\n */\nexport const validateConfig = (config: ConfigProto): ConfigProto => {\n if (!('version' in config)) {\n throw new InvalidConfigError({ message: 'Version not specified' });\n }\n\n if (config?.version !== 1) {\n throw new InvalidConfigError({ message: `Invalid config version: ${config.version}` });\n }\n\n const error = configRootType.protoType.verify(config);\n if (error) {\n throw new InvalidConfigError({ message: String(error) });\n }\n\n return config;\n};\n\nexport const ConfigResource = Symbol.for('dxos.resource.Config');\n\n/**\n * Global configuration object.\n * NOTE: Config objects are immutable.\n */\n@trace.resource({ annotation: ConfigResource })\nexport class Config {\n private readonly _config: any;\n\n /**\n * Creates an immutable instance.\n * @constructor\n */\n constructor(config: ConfigProto = {}, ...objects: ConfigProto[]) {\n this._config = validateConfig(defaultsDeep(config, ...objects, { version: 1 }));\n }\n\n /**\n * Returns an immutable config JSON object.\n */\n get values(): ConfigProto {\n return this._config;\n }\n\n /**\n * Returns the given config property.\n *\n * @param key A key in the config object. Can be a nested property with keys separated by dots: 'services.signal.server'.\n * @param defaultValue Default value to return if option is not present in the config.\n * @returns The config value or undefined if the option is not present.\n */\n get<K extends ConfigKey>(\n key: K,\n defaultValue?: DeepIndex<ConfigProto, ParseKey<K>>,\n ): DeepIndex<ConfigProto, ParseKey<K>> | undefined {\n return getDeep(this._config, key.split('.')) ?? defaultValue;\n }\n\n /**\n * Get unique key.\n */\n find<T = any>(path: string, test: object): T | undefined {\n const values = getDeep(this._config, path.split('.'));\n if (!Array.isArray(values)) {\n return;\n }\n\n return values.find((value) => isMatch(value, test));\n }\n\n /**\n * Returns the given config property or throw if it doesn't exist.\n *\n * @param key A key in the config object. Can be a nested property with keys separated by dots: 'services.signal.server'.\n */\n getOrThrow<K extends ConfigKey>(key: K): Exclude<DeepIndex<ConfigProto, ParseKey<K>>, undefined> {\n const value: DeepIndex<ConfigProto, ParseKey<K>> | undefined = getDeep(this._config, key.split('.'));\n if (!value) {\n throw new Error(`Config option not present: ${key}`);\n }\n return value;\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["execSync", "readFileSync", "resolve", "pkgUp", "parse", "invariant", "log", "setDeep", "boolean", "defaultsDeep", "isMatch", "InvalidConfigError", "schema", "trace", "getDeep", "setDeep", "configRootType", "schema", "getCodecForType", "mapFromKeyValues", "spec", "values", "config", "key", "path", "type", "Object", "entries", "value", "undefined", "boolean", "Number", "JSON", "parse", "Error", "setDeep", "split", "validateConfig", "config", "InvalidConfigError", "message", "version", "error", "configRootType", "protoType", "verify", "String", "ConfigResource", "Symbol", "for", "Config", "_config", "objects", "defaultsDeep", "values", "get", "key", "defaultValue", "getDeep", "split", "find", "path", "test", "Array", "isArray", "value", "isMatch", "getOrThrow", "Error", "resource", "annotation", "CWD", "process", "cwd", "definitions", "configPath", "envPath", "devPath", "mode", "env", "NODE_ENV", "publicUrl", "KEYS_TO_FILE", "__CONFIG_DEFAULTS__", "length", "resolve", "__CONFIG_ENVS__", "__CONFIG_LOCAL__", "Object", "entries", "reduce", "prev", "key", "value", "invariant", "content", "parse", "readFileSync", "mapFromKeyValues", "forEach", "startsWith", "includes", "setDeep", "timestamp", "Date", "toISOString", "commitHash", "DX_COMMIT_HASH", "execSync", "encoding", "replace", "packagePath", "pkgUp", "sync", "packageJson", "JSON", "version", "err", "message", "log", "error", "Error", "__DXOS_CONFIG__", "dynamic"]
7
- }