@ms-cloudpack/config 0.33.13 → 0.33.14

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.
@@ -1,5 +1,9 @@
1
- import type { AppConfig, PackageSettings } from '@ms-cloudpack/common-types';
1
+ import type { AppConfig, Features, PackageSettings } from '@ms-cloudpack/common-types';
2
2
  export interface ReadAppConfigOptions {
3
+ /**
4
+ * Extra feature settings. There will be a warning if any of these are invalid.
5
+ */
6
+ extraFeatures?: Features;
3
7
  /**
4
8
  * Extra package settings to add at the end of user-provided settings (so they take precedence).
5
9
  */
@@ -1 +1 @@
1
- {"version":3,"file":"readAppConfig.d.ts","sourceRoot":"","sources":["../../src/readConfig/readAppConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAU7E,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,oBAAoB,CAAC,EAAE,eAAe,EAAE,CAAC;CAC1C;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,SAAS,CAAC,CAsBvG"}
1
+ {"version":3,"file":"readAppConfig.d.ts","sourceRoot":"","sources":["../../src/readConfig/readAppConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAWvF,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,aAAa,CAAC,EAAE,QAAQ,CAAC;IAEzB;;OAEG;IACH,oBAAoB,CAAC,EAAE,eAAe,EAAE,CAAC;CAC1C;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,SAAS,CAAC,CA2BvG"}
@@ -1,3 +1,4 @@
1
+ import { allFeatures } from '@ms-cloudpack/common-types';
1
2
  import { readJson } from '@ms-cloudpack/json-utilities';
2
3
  import fs from 'fs';
3
4
  import { getConfigPath } from '../getConfigPath.js';
@@ -16,7 +17,7 @@ import { expandEnvironmentVariables } from './expandEnvironmentVariables.js';
16
17
  * checks certain specific settings.)
17
18
  */
18
19
  export async function readAppConfig(appPath, options) {
19
- const { extraPackageSettings } = options || {};
20
+ const { extraPackageSettings, extraFeatures } = options || {};
20
21
  const { appConfigPath } = getConfigPath(appPath);
21
22
  // Do a separate existence check for the top-level config, since it's fine if that doesn't exist.
22
23
  // (readAppConfigInternal throws if the file doesn't exist because it's also used for reading
@@ -33,6 +34,10 @@ export async function readAppConfig(appPath, options) {
33
34
  // Add these last so they take precedence.
34
35
  (config.packageSettings ??= []).push(...extraPackageSettings);
35
36
  }
37
+ if (extraFeatures) {
38
+ // Merge extra features
39
+ config.features = { ...config.features, ...extraFeatures };
40
+ }
36
41
  return config;
37
42
  }
38
43
  /**
@@ -67,6 +72,7 @@ async function readAppConfigInternal(configPath) {
67
72
  if (!validateConfig(appConfig)) {
68
73
  throw new Error(`Config file ${configPath} has invalid settings (see above for details)`);
69
74
  }
75
+ checkFeatures(appConfig.features, configPath);
70
76
  resolveBundlerCapabilities({ appConfig, configPath });
71
77
  processDeprecatedValues(appConfig);
72
78
  // Read and merge with any parent configs (the same processing is applied to parent configs)
@@ -96,6 +102,25 @@ function validateConfig(appConfig) {
96
102
  }
97
103
  return isValid;
98
104
  }
105
+ /**
106
+ * Warn if any feature names are invalid, and remove them.
107
+ */
108
+ function checkFeatures(features, configPath) {
109
+ if (!features) {
110
+ return;
111
+ }
112
+ const invalidFeatures = [];
113
+ for (const featureName of Object.keys(features)) {
114
+ if (!allFeatures[featureName]) {
115
+ invalidFeatures.push(featureName);
116
+ delete features[featureName];
117
+ }
118
+ }
119
+ if (invalidFeatures.length) {
120
+ console.warn(`Unknown feature(s) found in ${configPath} (most likely they were graduated or removed in Cloudpack):\n ` +
121
+ invalidFeatures.join(', '));
122
+ }
123
+ }
99
124
  /**
100
125
  * Delete deprecated values and convert them to the new format. (This mutates the `config` object.)
101
126
  */
@@ -1 +1 @@
1
- {"version":3,"file":"readAppConfig.js","sourceRoot":"","sources":["../../src/readConfig/readAppConfig.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AppConfig, PackageSettings } from '@ms-cloudpack/common-types';\nimport { readJson } from '@ms-cloudpack/json-utilities';\nimport fs from 'fs';\nimport { getConfigPath } from '../getConfigPath.js';\nimport { mergeParentConfig } from './mergeParentConfig.js';\nimport { resolveParentConfig } from './resolveParentConfig.js';\nimport { resolveModule } from '@ms-cloudpack/path-utilities';\nimport { validateMatch } from '../packageSettings/validateMatch.js';\nimport { expandEnvironmentVariables } from './expandEnvironmentVariables.js';\n\nexport interface ReadAppConfigOptions {\n /**\n * Extra package settings to add at the end of user-provided settings (so they take precedence).\n */\n extraPackageSettings?: PackageSettings[];\n}\n\n/**\n * Reads the user config file and merges with any parent configs asynchronously.\n * Note this is only useful for making modifications to the user config.\n * For a full merged representation of config, use `readConfig` instead.\n *\n * Throws an error if the config file exists but is not valid JSON, there's some error reading it,\n * or any settings are invalid. (As of writing, this doesn't do full schema validation; it only\n * checks certain specific settings.)\n */\nexport async function readAppConfig(appPath: string, options?: ReadAppConfigOptions): Promise<AppConfig> {\n const { extraPackageSettings } = options || {};\n\n const { appConfigPath } = getConfigPath(appPath);\n\n // Do a separate existence check for the top-level config, since it's fine if that doesn't exist.\n // (readAppConfigInternal throws if the file doesn't exist because it's also used for reading\n // parent configs from \"extends\", which must exist if specified.)\n let config: AppConfig;\n if (!fs.existsSync(appConfigPath)) {\n config = {};\n } else {\n config = (await readAppConfigInternal(appConfigPath)) || {};\n expandEnvironmentVariables(config as Record<string, unknown>);\n }\n\n if (extraPackageSettings) {\n // Add these last so they take precedence.\n (config.packageSettings ??= []).push(...extraPackageSettings);\n }\n\n return config;\n}\n\n/**\n * Resolve import specifiers for bundler capabilities registry.\n * Throws if a specifier can't be resolved.\n */\nfunction resolveBundlerCapabilities(params: { appConfig: AppConfig; configPath: string }): void {\n const {\n appConfig: { bundlerCapabilitiesRegistry },\n configPath,\n } = params;\n if (!bundlerCapabilitiesRegistry) {\n return;\n }\n\n for (const [name, importSpecifier] of Object.entries(bundlerCapabilitiesRegistry)) {\n try {\n const moduleUrl = resolveModule({ parentPath: configPath, importSpecifier });\n bundlerCapabilitiesRegistry[name] = moduleUrl.toString();\n } catch (e) {\n throw new Error(`Error resolving bundler capability \"${importSpecifier}\":\\n${(e as Error).message || e}`);\n }\n }\n}\n/**\n * Reads the user config, with any `extends` parent configs merged in.\n * Throws an error if the config file exists but is not valid JSON, or there's some error reading it.\n */\nasync function readAppConfigInternal(configPath: string): Promise<AppConfig> {\n const appConfig = await readJson<AppConfig>(configPath, { mode: 'permissive', throwOnError: true });\n if (!appConfig) {\n // shouldn't happen, but just in case/to satisfy the types...\n throw new Error(`Could not read config file ${configPath}`);\n }\n\n if (!validateConfig(appConfig)) {\n throw new Error(`Config file ${configPath} has invalid settings (see above for details)`);\n }\n\n resolveBundlerCapabilities({ appConfig, configPath });\n\n processDeprecatedValues(appConfig);\n\n // Read and merge with any parent configs (the same processing is applied to parent configs)\n const { extends: _extends = [] } = appConfig;\n const extendsArray = Array.isArray(_extends) ? _extends : [_extends];\n const parentConfigs = await Promise.all(\n extendsArray.map((importSpecifier) => readAppConfigInternal(resolveParentConfig({ configPath, importSpecifier }))),\n );\n return mergeParentConfig({ appConfig, parentConfigs });\n}\n\n/**\n * Validate parts of the current config file (before merging with parents) and log any errors.\n * Logging here and then letting the caller throw if needed allows us to show more errors at once.\n * @returns true if valid, false if not\n */\nfunction validateConfig(appConfig: AppConfig): boolean {\n let isValid = true;\n\n // Verify that there are no matches with a negated name and a version\n for (const setting of appConfig.packageSettings || []) {\n const { match } = setting;\n const matches = Array.isArray(match) ? match : [match];\n for (const m of matches) {\n const result = validateMatch(m);\n if (!result.isValid) {\n isValid = false;\n console.error(`Invalid packageSettings match: ${result.error}`);\n }\n }\n }\n\n return isValid;\n}\n\n/**\n * Delete deprecated values and convert them to the new format. (This mutates the `config` object.)\n */\nfunction processDeprecatedValues(config: AppConfig): void {\n /* eslint-disable etc/no-deprecated */\n const { devServer, server, packageSettings = [] } = config;\n\n if (devServer) {\n if (server) {\n throw new Error('Cannot have both \"devServer\" and \"server\" in the config file. Use \"server\" only.');\n }\n\n config.server = devServer;\n delete config.devServer;\n }\n\n if (server?.routes) {\n config.routes = server.routes;\n delete server.routes;\n }\n\n for (const setting of packageSettings) {\n if (setting.bundlerType) {\n setting.bundler = setting.bundlerType;\n delete setting.bundlerType;\n }\n }\n /* eslint-enable etc/no-deprecated */\n}\n"]}
1
+ {"version":3,"file":"readAppConfig.js","sourceRoot":"","sources":["../../src/readConfig/readAppConfig.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AppConfig, Features, PackageSettings } from '@ms-cloudpack/common-types';\nimport { allFeatures } from '@ms-cloudpack/common-types';\nimport { readJson } from '@ms-cloudpack/json-utilities';\nimport fs from 'fs';\nimport { getConfigPath } from '../getConfigPath.js';\nimport { mergeParentConfig } from './mergeParentConfig.js';\nimport { resolveParentConfig } from './resolveParentConfig.js';\nimport { resolveModule } from '@ms-cloudpack/path-utilities';\nimport { validateMatch } from '../packageSettings/validateMatch.js';\nimport { expandEnvironmentVariables } from './expandEnvironmentVariables.js';\n\nexport interface ReadAppConfigOptions {\n /**\n * Extra feature settings. There will be a warning if any of these are invalid.\n */\n extraFeatures?: Features;\n\n /**\n * Extra package settings to add at the end of user-provided settings (so they take precedence).\n */\n extraPackageSettings?: PackageSettings[];\n}\n\n/**\n * Reads the user config file and merges with any parent configs asynchronously.\n * Note this is only useful for making modifications to the user config.\n * For a full merged representation of config, use `readConfig` instead.\n *\n * Throws an error if the config file exists but is not valid JSON, there's some error reading it,\n * or any settings are invalid. (As of writing, this doesn't do full schema validation; it only\n * checks certain specific settings.)\n */\nexport async function readAppConfig(appPath: string, options?: ReadAppConfigOptions): Promise<AppConfig> {\n const { extraPackageSettings, extraFeatures } = options || {};\n\n const { appConfigPath } = getConfigPath(appPath);\n\n // Do a separate existence check for the top-level config, since it's fine if that doesn't exist.\n // (readAppConfigInternal throws if the file doesn't exist because it's also used for reading\n // parent configs from \"extends\", which must exist if specified.)\n let config: AppConfig;\n if (!fs.existsSync(appConfigPath)) {\n config = {};\n } else {\n config = (await readAppConfigInternal(appConfigPath)) || {};\n expandEnvironmentVariables(config as Record<string, unknown>);\n }\n\n if (extraPackageSettings) {\n // Add these last so they take precedence.\n (config.packageSettings ??= []).push(...extraPackageSettings);\n }\n\n if (extraFeatures) {\n // Merge extra features\n config.features = { ...config.features, ...extraFeatures };\n }\n\n return config;\n}\n\n/**\n * Resolve import specifiers for bundler capabilities registry.\n * Throws if a specifier can't be resolved.\n */\nfunction resolveBundlerCapabilities(params: { appConfig: AppConfig; configPath: string }): void {\n const {\n appConfig: { bundlerCapabilitiesRegistry },\n configPath,\n } = params;\n if (!bundlerCapabilitiesRegistry) {\n return;\n }\n\n for (const [name, importSpecifier] of Object.entries(bundlerCapabilitiesRegistry)) {\n try {\n const moduleUrl = resolveModule({ parentPath: configPath, importSpecifier });\n bundlerCapabilitiesRegistry[name] = moduleUrl.toString();\n } catch (e) {\n throw new Error(`Error resolving bundler capability \"${importSpecifier}\":\\n${(e as Error).message || e}`);\n }\n }\n}\n/**\n * Reads the user config, with any `extends` parent configs merged in.\n * Throws an error if the config file exists but is not valid JSON, or there's some error reading it.\n */\nasync function readAppConfigInternal(configPath: string): Promise<AppConfig> {\n const appConfig = await readJson<AppConfig>(configPath, { mode: 'permissive', throwOnError: true });\n if (!appConfig) {\n // shouldn't happen, but just in case/to satisfy the types...\n throw new Error(`Could not read config file ${configPath}`);\n }\n\n if (!validateConfig(appConfig)) {\n throw new Error(`Config file ${configPath} has invalid settings (see above for details)`);\n }\n\n checkFeatures(appConfig.features, configPath);\n\n resolveBundlerCapabilities({ appConfig, configPath });\n\n processDeprecatedValues(appConfig);\n\n // Read and merge with any parent configs (the same processing is applied to parent configs)\n const { extends: _extends = [] } = appConfig;\n const extendsArray = Array.isArray(_extends) ? _extends : [_extends];\n const parentConfigs = await Promise.all(\n extendsArray.map((importSpecifier) => readAppConfigInternal(resolveParentConfig({ configPath, importSpecifier }))),\n );\n return mergeParentConfig({ appConfig, parentConfigs });\n}\n\n/**\n * Validate parts of the current config file (before merging with parents) and log any errors.\n * Logging here and then letting the caller throw if needed allows us to show more errors at once.\n * @returns true if valid, false if not\n */\nfunction validateConfig(appConfig: AppConfig): boolean {\n let isValid = true;\n\n // Verify that there are no matches with a negated name and a version\n for (const setting of appConfig.packageSettings || []) {\n const { match } = setting;\n const matches = Array.isArray(match) ? match : [match];\n for (const m of matches) {\n const result = validateMatch(m);\n if (!result.isValid) {\n isValid = false;\n console.error(`Invalid packageSettings match: ${result.error}`);\n }\n }\n }\n\n return isValid;\n}\n\n/**\n * Warn if any feature names are invalid, and remove them.\n */\nfunction checkFeatures(features: Record<string, boolean> | undefined, configPath: string): void {\n if (!features) {\n return;\n }\n\n const invalidFeatures: string[] = [];\n for (const featureName of Object.keys(features)) {\n if (!allFeatures[featureName as keyof Features]) {\n invalidFeatures.push(featureName);\n delete features[featureName];\n }\n }\n\n if (invalidFeatures.length) {\n console.warn(\n `Unknown feature(s) found in ${configPath} (most likely they were graduated or removed in Cloudpack):\\n ` +\n invalidFeatures.join(', '),\n );\n }\n}\n\n/**\n * Delete deprecated values and convert them to the new format. (This mutates the `config` object.)\n */\nfunction processDeprecatedValues(config: AppConfig): void {\n /* eslint-disable etc/no-deprecated */\n const { devServer, server, packageSettings = [] } = config;\n\n if (devServer) {\n if (server) {\n throw new Error('Cannot have both \"devServer\" and \"server\" in the config file. Use \"server\" only.');\n }\n\n config.server = devServer;\n delete config.devServer;\n }\n\n if (server?.routes) {\n config.routes = server.routes;\n delete server.routes;\n }\n\n for (const setting of packageSettings) {\n if (setting.bundlerType) {\n setting.bundler = setting.bundlerType;\n delete setting.bundlerType;\n }\n }\n /* eslint-enable etc/no-deprecated */\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"readConfig.d.ts","sourceRoot":"","sources":["../../src/readConfig/readConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,eAAe,EAOhB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAiB,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAc9E,MAAM,MAAM,iBAAiB,GAAG,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC;AAEhH;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC,CAqBvG"}
1
+ {"version":3,"file":"readConfig.d.ts","sourceRoot":"","sources":["../../src/readConfig/readConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,eAAe,EAOhB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAiB,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAc9E,MAAM,MAAM,iBAAiB,GAAG,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC;AAEhH;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC,CAyBvG"}
@@ -4,7 +4,7 @@ import { readGeneratedConfig } from './readGeneratedConfig.js';
4
4
  import { intermediateToSourcePath, sourceToIntermediatePath } from '@ms-cloudpack/path-utilities';
5
5
  import { flattenExportsMap } from '@ms-cloudpack/package-utilities';
6
6
  import path from 'path';
7
- import { readJsonSync } from '@ms-cloudpack/json-utilities';
7
+ import { cloneJson, readJsonSync } from '@ms-cloudpack/json-utilities';
8
8
  import { normalizeRelativePath } from '@ms-cloudpack/path-string-parsing';
9
9
  /**
10
10
  * Read the app config and generated config if they exist.
@@ -20,10 +20,13 @@ export async function readConfig(appPath, options) {
20
20
  ...appConfig,
21
21
  appPath,
22
22
  mode,
23
- logBundleInfo,
24
23
  generated: generatedConfig,
25
- generatedSnapshot: structuredClone(generatedConfig),
24
+ generatedSnapshot: cloneJson(generatedConfig),
26
25
  };
26
+ if (logBundleInfo) {
27
+ // Only set this if true, mainly to avoid interfering with tests.
28
+ config.logBundleInfo = true;
29
+ }
27
30
  // Expands all routes which refer to source files into fully transformed route objects.
28
31
  if (routes?.length) {
29
32
  config.routes = expandRoutes(routes, appPath);
@@ -1 +1 @@
1
- {"version":3,"file":"readConfig.js","sourceRoot":"","sources":["../../src/readConfig/readConfig.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n BootstrapRoute,\n CloudpackConfig,\n ExpandedSourcePath,\n PackageJson,\n RenderedRoute,\n Route,\n ShorthandRenderedRoute,\n ShorthandRoute,\n} from '@ms-cloudpack/common-types';\nimport { isShorthandBootstrapRoute, isShorthandRenderedRoute } from '@ms-cloudpack/common-types';\nimport { readAppConfig, type ReadAppConfigOptions } from './readAppConfig.js';\nimport { readGeneratedConfig } from './readGeneratedConfig.js';\nimport { intermediateToSourcePath, sourceToIntermediatePath } from '@ms-cloudpack/path-utilities';\nimport { flattenExportsMap } from '@ms-cloudpack/package-utilities';\nimport path from 'path';\nimport { readJsonSync } from '@ms-cloudpack/json-utilities';\nimport { normalizeRelativePath } from '@ms-cloudpack/path-string-parsing';\n\n/**\n * package.json with only the keys used in this file, since we're missing some logic from\n * PackageDefinitions which is assumed in the full type.\n */\ntype PartialPackageJson = Pick<PackageJson, 'exports' | 'module' | 'main'>;\n\nexport type ReadConfigOptions = ReadAppConfigOptions & Partial<Pick<CloudpackConfig, 'mode' | 'logBundleInfo'>>;\n\n/**\n * Read the app config and generated config if they exist.\n *\n * Throws if there's an error reading a file or certain settings are invalid. (As of writing,\n * this doesn't do full schema validation; it only validates certain specific settings.)\n */\nexport async function readConfig(appPath: string, options?: ReadConfigOptions): Promise<CloudpackConfig> {\n const { mode = 'library', logBundleInfo, extraPackageSettings } = options || {};\n\n const { routes, ...appConfig } = await readAppConfig(appPath, { extraPackageSettings });\n const generatedConfig = await readGeneratedConfig(appPath);\n\n const config: CloudpackConfig = {\n ...appConfig,\n appPath,\n mode,\n logBundleInfo,\n generated: generatedConfig,\n generatedSnapshot: structuredClone(generatedConfig),\n };\n\n // Expands all routes which refer to source files into fully transformed route objects.\n if (routes?.length) {\n config.routes = expandRoutes(routes, appPath);\n }\n\n return config;\n}\n\n/**\n * Ensure all source entries in routes are expanded to fully qualified entry paths.\n */\nfunction expandRoutes(routes: ShorthandRoute[], appPath: string): Route[] {\n // Cached flattened exports for appPath, used to expand entries\n const flattenedExports = getFlattenedExports(appPath);\n\n return routes.map((route) => {\n if (!isShorthandRenderedRoute(route) && !isShorthandBootstrapRoute(route)) {\n // Skip extra processing for other route types.\n return route;\n }\n\n // eslint-disable-next-line etc/no-deprecated\n const { entry, exportEntry, ...rest } = route;\n const renderedRoute: RenderedRoute | BootstrapRoute = rest;\n\n if (entry?.length) {\n // Expand the entry to full info about the file path.\n renderedRoute.entry = expandEntry({ entry, appPath, flattenedExports });\n }\n\n if (exportEntry) {\n // Handle backwards compatibility with moving from exportEntry to entry.\n const filePath = flattenedExports[exportEntry];\n if (!filePath) {\n throw new Error(\n `A route referenced exportEntry \"${exportEntry}\" but this couldn't be resolved from the package.json.`,\n );\n }\n\n const expanded = expandRouteEntry({ importPath: exportEntry, filePath, appPath });\n console.warn(\n 'The route property \"exportEntry\" is deprecated. Update your route as follows:',\n JSON.stringify({ ...renderedRoute, entry: expanded.sourcePath }, null, 2),\n );\n (renderedRoute.entry ??= []).push(expanded);\n }\n\n return renderedRoute;\n });\n}\n\nfunction expandEntry(params: {\n entry: ShorthandRenderedRoute['entry'];\n appPath: string;\n flattenedExports: Record<string, string | undefined>;\n}): ExpandedSourcePath[] {\n const { entry, appPath, flattenedExports } = params;\n const entryArray = Array.isArray(entry) ? entry : entry !== undefined ? [entry] : [];\n\n return entryArray.map((entryPath) =>\n expandRouteEntry({\n // Usually entryPath will be a source path, but also handle if it's an exports map key.\n importPath: flattenedExports[entryPath] ? entryPath : undefined,\n filePath: flattenedExports[entryPath] || entryPath,\n appPath,\n }),\n );\n}\n\n/**\n * Get flattened exports from package.json at `appPath`.\n * If there's no export for `.`, it will be filled in from `module || main`.\n */\nfunction getFlattenedExports(appPath: string): Record<string, string | undefined> {\n // We can't use PackageDefinitions.get here because we're reading the config, and definitions\n // cache requires config resulting in a cycle.\n const definition = readJsonSync<PartialPackageJson>(path.join(appPath, 'package.json')) || {};\n const flatExports: Record<string, string | undefined> = flattenExportsMap(definition.exports || {});\n flatExports['.'] ??= definition.module || definition.main;\n return flatExports;\n}\n\n/** Expands shorthand route entries into fully qualified ones. */\nfunction expandRouteEntry(options: { importPath?: string; filePath: string; appPath: string }): ExpandedSourcePath {\n const { filePath, appPath, importPath } = options;\n const sourcePath = intermediateToSourcePath(filePath, appPath);\n\n if (!sourcePath) {\n throw new Error(`Could not resolve source path for entry: ${filePath}`);\n }\n\n return {\n // Used to derive bundle entry path\n sourcePath,\n // Import map key\n importPath: importPath ? normalizeRelativePath(importPath) : sourceToIntermediatePath(sourcePath),\n };\n}\n"]}
1
+ {"version":3,"file":"readConfig.js","sourceRoot":"","sources":["../../src/readConfig/readConfig.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n BootstrapRoute,\n CloudpackConfig,\n ExpandedSourcePath,\n PackageJson,\n RenderedRoute,\n Route,\n ShorthandRenderedRoute,\n ShorthandRoute,\n} from '@ms-cloudpack/common-types';\nimport { isShorthandBootstrapRoute, isShorthandRenderedRoute } from '@ms-cloudpack/common-types';\nimport { readAppConfig, type ReadAppConfigOptions } from './readAppConfig.js';\nimport { readGeneratedConfig } from './readGeneratedConfig.js';\nimport { intermediateToSourcePath, sourceToIntermediatePath } from '@ms-cloudpack/path-utilities';\nimport { flattenExportsMap } from '@ms-cloudpack/package-utilities';\nimport path from 'path';\nimport { cloneJson, readJsonSync } from '@ms-cloudpack/json-utilities';\nimport { normalizeRelativePath } from '@ms-cloudpack/path-string-parsing';\n\n/**\n * package.json with only the keys used in this file, since we're missing some logic from\n * PackageDefinitions which is assumed in the full type.\n */\ntype PartialPackageJson = Pick<PackageJson, 'exports' | 'module' | 'main'>;\n\nexport type ReadConfigOptions = ReadAppConfigOptions & Partial<Pick<CloudpackConfig, 'mode' | 'logBundleInfo'>>;\n\n/**\n * Read the app config and generated config if they exist.\n *\n * Throws if there's an error reading a file or certain settings are invalid. (As of writing,\n * this doesn't do full schema validation; it only validates certain specific settings.)\n */\nexport async function readConfig(appPath: string, options?: ReadConfigOptions): Promise<CloudpackConfig> {\n const { mode = 'library', logBundleInfo, extraPackageSettings } = options || {};\n\n const { routes, ...appConfig } = await readAppConfig(appPath, { extraPackageSettings });\n const generatedConfig = await readGeneratedConfig(appPath);\n\n const config: CloudpackConfig = {\n ...appConfig,\n appPath,\n mode,\n generated: generatedConfig,\n generatedSnapshot: cloneJson(generatedConfig),\n };\n\n if (logBundleInfo) {\n // Only set this if true, mainly to avoid interfering with tests.\n config.logBundleInfo = true;\n }\n\n // Expands all routes which refer to source files into fully transformed route objects.\n if (routes?.length) {\n config.routes = expandRoutes(routes, appPath);\n }\n\n return config;\n}\n\n/**\n * Ensure all source entries in routes are expanded to fully qualified entry paths.\n */\nfunction expandRoutes(routes: ShorthandRoute[], appPath: string): Route[] {\n // Cached flattened exports for appPath, used to expand entries\n const flattenedExports = getFlattenedExports(appPath);\n\n return routes.map((route) => {\n if (!isShorthandRenderedRoute(route) && !isShorthandBootstrapRoute(route)) {\n // Skip extra processing for other route types.\n return route;\n }\n\n // eslint-disable-next-line etc/no-deprecated\n const { entry, exportEntry, ...rest } = route;\n const renderedRoute: RenderedRoute | BootstrapRoute = rest;\n\n if (entry?.length) {\n // Expand the entry to full info about the file path.\n renderedRoute.entry = expandEntry({ entry, appPath, flattenedExports });\n }\n\n if (exportEntry) {\n // Handle backwards compatibility with moving from exportEntry to entry.\n const filePath = flattenedExports[exportEntry];\n if (!filePath) {\n throw new Error(\n `A route referenced exportEntry \"${exportEntry}\" but this couldn't be resolved from the package.json.`,\n );\n }\n\n const expanded = expandRouteEntry({ importPath: exportEntry, filePath, appPath });\n console.warn(\n 'The route property \"exportEntry\" is deprecated. Update your route as follows:',\n JSON.stringify({ ...renderedRoute, entry: expanded.sourcePath }, null, 2),\n );\n (renderedRoute.entry ??= []).push(expanded);\n }\n\n return renderedRoute;\n });\n}\n\nfunction expandEntry(params: {\n entry: ShorthandRenderedRoute['entry'];\n appPath: string;\n flattenedExports: Record<string, string | undefined>;\n}): ExpandedSourcePath[] {\n const { entry, appPath, flattenedExports } = params;\n const entryArray = Array.isArray(entry) ? entry : entry !== undefined ? [entry] : [];\n\n return entryArray.map((entryPath) =>\n expandRouteEntry({\n // Usually entryPath will be a source path, but also handle if it's an exports map key.\n importPath: flattenedExports[entryPath] ? entryPath : undefined,\n filePath: flattenedExports[entryPath] || entryPath,\n appPath,\n }),\n );\n}\n\n/**\n * Get flattened exports from package.json at `appPath`.\n * If there's no export for `.`, it will be filled in from `module || main`.\n */\nfunction getFlattenedExports(appPath: string): Record<string, string | undefined> {\n // We can't use PackageDefinitions.get here because we're reading the config, and definitions\n // cache requires config resulting in a cycle.\n const definition = readJsonSync<PartialPackageJson>(path.join(appPath, 'package.json')) || {};\n const flatExports: Record<string, string | undefined> = flattenExportsMap(definition.exports || {});\n flatExports['.'] ??= definition.module || definition.main;\n return flatExports;\n}\n\n/** Expands shorthand route entries into fully qualified ones. */\nfunction expandRouteEntry(options: { importPath?: string; filePath: string; appPath: string }): ExpandedSourcePath {\n const { filePath, appPath, importPath } = options;\n const sourcePath = intermediateToSourcePath(filePath, appPath);\n\n if (!sourcePath) {\n throw new Error(`Could not resolve source path for entry: ${filePath}`);\n }\n\n return {\n // Used to derive bundle entry path\n sourcePath,\n // Import map key\n importPath: importPath ? normalizeRelativePath(importPath) : sourceToIntermediatePath(sourcePath),\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ms-cloudpack/config",
3
- "version": "0.33.13",
3
+ "version": "0.33.14",
4
4
  "description": "Configuration handling for cloudpack.",
5
5
  "license": "MIT",
6
6
  "type": "module",