@ms-cloudpack/api-server 0.30.4 → 0.30.6

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,13 +1,15 @@
1
1
  /**
2
2
  * BundleInfo is a map of entry file paths to produce/consume information.
3
3
  * e.g.:
4
+ * ```json
4
5
  * {
5
6
  * ".": {
6
7
  * "bundlePath": "./index.js",
7
- * "produces": ['bar'],
8
+ * "produces": ["bar"],
8
9
  * "consumes": [{ "packageName": "foo", "importPath": "foo", "names": [ "foo" ] }],
9
10
  * },
10
11
  * }
12
+ * ```
11
13
  */
12
14
  export type BundleInfo = {
13
15
  entry: {
@@ -1 +1 @@
1
- {"version":3,"file":"BundleInfo.d.ts","sourceRoot":"","sources":["../../src/types/BundleInfo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE;QACL,CAAC,QAAQ,EAAE,MAAM,GAAG;YAClB,UAAU,EAAE,MAAM,CAAC;YACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;YACnB,QAAQ,EAAE;gBACR,WAAW,EAAE,MAAM,CAAC;gBACpB,UAAU,EAAE,MAAM,CAAC;gBACnB,KAAK,EAAE,MAAM,EAAE,CAAC;aACjB,EAAE,CAAC;SACL,CAAC;KACH,CAAC;CACH,CAAC"}
1
+ {"version":3,"file":"BundleInfo.d.ts","sourceRoot":"","sources":["../../src/types/BundleInfo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE;QACL,CAAC,QAAQ,EAAE,MAAM,GAAG;YAClB,UAAU,EAAE,MAAM,CAAC;YACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;YACnB,QAAQ,EAAE;gBACR,WAAW,EAAE,MAAM,CAAC;gBACpB,UAAU,EAAE,MAAM,CAAC;gBACnB,KAAK,EAAE,MAAM,EAAE,CAAC;aACjB,EAAE,CAAC;SACL,CAAC;KACH,CAAC;CACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"BundleInfo.js","sourceRoot":"","sources":["../../src/types/BundleInfo.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * BundleInfo is a map of entry file paths to produce/consume information.\n * e.g.:\n * {\n * \".\": {\n * \"bundlePath\": \"./index.js\",\n * \"produces\": ['bar'],\n * \"consumes\": [{ \"packageName\": \"foo\", \"importPath\": \"foo\", \"names\": [ \"foo\" ] }],\n * },\n * }\n */\nexport type BundleInfo = {\n entry: {\n [filePath: string]: {\n bundlePath: string;\n produces: string[];\n consumes: {\n packageName: string;\n importPath: string;\n names: string[];\n }[];\n };\n };\n};\n"]}
1
+ {"version":3,"file":"BundleInfo.js","sourceRoot":"","sources":["../../src/types/BundleInfo.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * BundleInfo is a map of entry file paths to produce/consume information.\n * e.g.:\n * ```json\n * {\n * \".\": {\n * \"bundlePath\": \"./index.js\",\n * \"produces\": [\"bar\"],\n * \"consumes\": [{ \"packageName\": \"foo\", \"importPath\": \"foo\", \"names\": [ \"foo\" ] }],\n * },\n * }\n * ```\n */\nexport type BundleInfo = {\n entry: {\n [filePath: string]: {\n bundlePath: string;\n produces: string[];\n consumes: {\n packageName: string;\n importPath: string;\n names: string[];\n }[];\n };\n };\n};\n"]}
@@ -1,9 +1,8 @@
1
- import type { BundleInfo } from '../types/BundleInfo.js';
2
- import type { PackageJsonExports } from '@ms-cloudpack/config-types';
3
1
  import type { BundleOutputFile } from '@ms-cloudpack/bundler-types';
2
+ import type { PackageJsonExports } from '@ms-cloudpack/config-types';
3
+ import type { BundleInfo } from '../types/BundleInfo.js';
4
4
  /**
5
- * Returns a mapping from dependency name to list of paths
6
- * that are produced and consumed in the searched files.
5
+ * Returns a mapping from entry file path to list of paths that are produced and consumed in the searched files.
7
6
  */
8
7
  export declare function getBundleInfo(params: {
9
8
  outputPath: string;
@@ -1 +1 @@
1
- {"version":3,"file":"getBundleInfo.d.ts","sourceRoot":"","sources":["../../src/utilities/getBundleInfo.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAEpE;;;GAGG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;CACrB,GAAG,OAAO,CAAC,UAAU,CAAC,CA+OtB"}
1
+ {"version":3,"file":"getBundleInfo.d.ts","sourceRoot":"","sources":["../../src/utilities/getBundleInfo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAIrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD;;GAEG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;CACrB,GAAG,OAAO,CAAC,UAAU,CAAC,CAmItB"}
@@ -1,11 +1,9 @@
1
- import { parse } from 'es-module-lexer';
2
- import fsPromises from 'fs/promises';
1
+ import { flattenExportsMap, getResolvedFilePath } from '@ms-cloudpack/package-utilities';
2
+ import { safeRelativePath } from '@ms-cloudpack/path-string-parsing';
3
3
  import path from 'path';
4
- import { parseImportString, parseNamedImports, safeRelativePath, } from '@ms-cloudpack/path-string-parsing';
5
- import { flattenExportsMap } from '@ms-cloudpack/package-utilities';
4
+ import { getImportsAndExports } from './getImportsAndExports.js';
6
5
  /**
7
- * Returns a mapping from dependency name to list of paths
8
- * that are produced and consumed in the searched files.
6
+ * Returns a mapping from entry file path to list of paths that are produced and consumed in the searched files.
9
7
  */
10
8
  export async function getBundleInfo(params) {
11
9
  const { outputPath, outputFiles, exportsMap, isExternal } = params;
@@ -16,18 +14,18 @@ export async function getBundleInfo(params) {
16
14
  if (!outputFiles.length) {
17
15
  return bundleInfo;
18
16
  }
19
- const safeOutputFiles = {};
17
+ /** Mapping from output file (safe/normalized relative path) to possible entry path and exports. */
18
+ const outputFileInfo = {};
20
19
  outputFiles.forEach((file) => {
21
- // Make path safe
20
+ // Normalize the path to start with ./ (or . for an empty path)
22
21
  const safePath = safeRelativePath(file.outputPath);
23
22
  // Store safe path to possible entry path and exports.
24
- safeOutputFiles[safePath] = {
23
+ outputFileInfo[safePath] = {
25
24
  entry: safePath,
26
25
  produces: new Set(file.exports),
27
26
  };
28
27
  });
29
- // raw output file, safe output file, exports entry
30
- // Get both the unbundled entries from the exports map
28
+ // Get both the unbundled and bundled entries from the exports map
31
29
  const unbundledExportsMap = flattenExportsMap(exportsMap, {
32
30
  conditions: ['browser-esm'],
33
31
  requiredConditions: ['browser-esm'],
@@ -39,38 +37,24 @@ export async function getBundleInfo(params) {
39
37
  if (typeof entryPath !== 'string' || typeof bundledFilePath !== 'string') {
40
38
  continue;
41
39
  }
42
- const unbundledFilePath = isExternal ? unbundledExportsMap[entryPath] : undefined;
43
- // TODO: This logic is the same from createImportMap.ts file.
44
- // It should be moved into a shared function with tests.
45
- // It is used here to use the same entry paths as the import map.
46
- let resolvedFilePath = unbundledFilePath || bundledFilePath;
47
- const ext = path.extname(resolvedFilePath);
48
- // For bundled files:
49
- if (!unbundledFilePath) {
50
- // Ignore .d.ts entries
51
- if (resolvedFilePath.endsWith('.d.ts')) {
52
- continue;
53
- }
54
- // We always expect responses to come back as javascript (.js extensions.)
55
- if (ext !== '.js') {
56
- resolvedFilePath = path.join(path.dirname(resolvedFilePath), path.basename(resolvedFilePath, ext) + (ext === '.mjs' ? '.js' : ext + '.js'));
57
- }
58
- resolvedFilePath = resolvedFilePath.replace(/\+/g, '_');
40
+ const resolvedFilePath = getResolvedFilePath({ entryPath, isExternal, unbundledExportsMap, bundledFilePath });
41
+ if (resolvedFilePath === undefined) {
42
+ continue; // entry is ignored
59
43
  }
60
44
  const safePath = safeRelativePath(resolvedFilePath);
61
- if (safeOutputFiles[safePath]) {
45
+ if (outputFileInfo[safePath]) {
62
46
  if (repeatedExports[safePath]) {
63
47
  repeatedExports[safePath].push(entryPath);
64
48
  }
65
49
  else {
66
50
  // Change best guess entry path to exports map entry.
67
- safeOutputFiles[safePath].entry = entryPath;
51
+ outputFileInfo[safePath].entry = entryPath;
68
52
  repeatedExports[safePath] = [entryPath];
69
53
  }
70
54
  }
71
55
  }
72
56
  const localPathToSafe = {};
73
- Object.keys(safeOutputFiles).forEach((safePath) => {
57
+ Object.keys(outputFileInfo).forEach((safePath) => {
74
58
  localPathToSafe[path.resolve(outputPath, safePath)] = safePath;
75
59
  });
76
60
  const filePaths = Object.keys(localPathToSafe);
@@ -84,92 +68,18 @@ export async function getBundleInfo(params) {
84
68
  }
85
69
  const safePath = localPathToSafe[filePath];
86
70
  if (safePath === undefined) {
87
- throw new Error(`Failed to find safe path for ${filePath}`);
88
- }
89
- let entry;
90
- let produces;
91
- if (!safeOutputFiles[safePath]) {
92
- entry = safePath;
93
- produces = new Set();
94
- }
95
- else {
96
- const result = safeOutputFiles[safePath];
97
- entry = result.entry;
98
- produces = result.produces;
99
- }
100
- let source;
101
- try {
102
- source = await fsPromises.readFile(filePath, 'utf-8');
103
- }
104
- catch (err) {
105
- // This could happen if a package is missing a file.
106
- console.warn(`Failed to read import ${safePath}:`, err);
107
- continue;
71
+ throw new Error(`Found file that was not expected to be processed: ${filePath}`);
108
72
  }
109
- let rawImports;
110
- let rawExports;
111
- try {
112
- // es-module-lexer/parse may return Promise in some conditions
113
- // although it is not declared in the type definition
114
- // https://github.com/guybedford/es-module-lexer/issues/155
115
- [rawImports, rawExports] = await parse(source);
116
- }
117
- catch (err) {
118
- // This could happen if the source file isn't valid JS
119
- // (unlikely after adding the check above to only attempt parsing JS/TS files)
120
- console.warn(`Failed to parse ${filePath}:`, err, '\nSource is:\n', source);
73
+ const parseResult = await getImportsAndExports(filePath);
74
+ if (!parseResult) {
121
75
  continue;
122
76
  }
123
- // TODO: Remove when https://github.com/guybedford/es-module-lexer/issues/76 is fixed
124
- // es-module-lexer doesn't handle export * from statements correctly as it parses them as
125
- // imports but not as exports. We need to handle them separately.
126
- let exportStarImport = false;
127
- const imports = Array.from(new Set(rawImports))
128
- .map((i) => {
129
- // The es-module-lexer returns entries where the "n" property equals the import source.
130
- // This includes the package name and path. For example, in this case:
131
- //
132
- // import { Button } from '@fluentui/react/lib/Button';
133
- //
134
- // The "n" property would be "@fluentui/react/lib/Button".
135
- // The "s" and "e" properties represent the start/end character positions of
136
- // the import source. The "ss" and "se" properties represent the start/end
137
- // character positions of the import specifier starting with "import". This
138
- // is useful for parsing the import specifier into its component parts.
139
- //
140
- // Currently when the import source is a backtick string, the "n" property
141
- // is undefined. This is a bug in es-module-lexer. We may need to handle this
142
- // at the javascript layer and expand it into multiple potential imports.
143
- if (!i.n) {
144
- console.debug(`Found an import that didn't parse correctly:\nFilename:\n${filePath}\n\nImport:\n${source.slice(i.s, i.e)}`);
145
- return undefined;
146
- }
147
- // Handling export * from import statements
148
- if (source.slice(i.ss, i.se).includes('export * from')) {
149
- exportStarImport = true;
150
- }
151
- // Parse the import string into its component parts.
152
- const namedImports = {
153
- ...parseImportString(i.n),
154
- names: new Set(parseNamedImports(source.slice(i.ss, i.se))),
155
- };
156
- return namedImports;
157
- })
158
- .filter(Boolean);
159
- // Processing exports is cheap as we already have to parse the source.
160
- // Helps find exports uncaught by output files.
161
- rawExports.forEach((i) => {
162
- if (!i.n) {
163
- console.debug(`Found an export that didn't parse correctly:\nFilename:\n${filePath}\nExport:\n${source.slice(i.s, i.e)}`);
164
- return undefined;
165
- }
166
- // Exports don't need to be parsed as it is
167
- // already in the format we need.
168
- produces.add(i.n);
169
- });
170
- if (exportStarImport) {
171
- produces.add('*');
172
- }
77
+ const { exportNames, imports } = parseResult;
78
+ const { entry, produces } = outputFileInfo[safePath] || {
79
+ entry: safePath,
80
+ produces: new Set(),
81
+ };
82
+ exportNames.forEach((name) => produces.add(name));
173
83
  bundleInfo.entry[entry] ??= {
174
84
  bundlePath: safePath,
175
85
  produces: Array.from(produces),
@@ -1 +1 @@
1
- {"version":3,"file":"getBundleInfo.js","sourceRoot":"","sources":["../../src/utilities/getBundleInfo.ts"],"names":[],"mappings":"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","sourcesContent":["import { parse } from 'es-module-lexer';\nimport fsPromises from 'fs/promises';\nimport path from 'path';\nimport {\n parseImportString,\n parseNamedImports,\n type ImportStringResult,\n safeRelativePath,\n} from '@ms-cloudpack/path-string-parsing';\nimport { flattenExportsMap } from '@ms-cloudpack/package-utilities';\nimport type { BundleInfo } from '../types/BundleInfo.js';\nimport type { PackageJsonExports } from '@ms-cloudpack/config-types';\nimport type { BundleOutputFile } from '@ms-cloudpack/bundler-types';\n\n/**\n * Returns a mapping from dependency name to list of paths\n * that are produced and consumed in the searched files.\n */\nexport async function getBundleInfo(params: {\n outputPath: string;\n outputFiles: BundleOutputFile[];\n exportsMap: PackageJsonExports;\n isExternal: boolean;\n}): Promise<BundleInfo> {\n const { outputPath, outputFiles, exportsMap, isExternal } = params;\n const bundleInfo: BundleInfo = {\n entry: {},\n };\n\n // If there are no output files, return the empty bundle info.\n if (!outputFiles.length) {\n return bundleInfo;\n }\n\n const safeOutputFiles: Record<string, { entry: string; produces: Set<string> }> = {};\n outputFiles.forEach((file) => {\n // Make path safe\n const safePath = safeRelativePath(file.outputPath);\n // Store safe path to possible entry path and exports.\n safeOutputFiles[safePath] = {\n entry: safePath,\n produces: new Set<string>(file.exports),\n };\n });\n\n // raw output file, safe output file, exports entry\n\n // Get both the unbundled entries from the exports map\n const unbundledExportsMap = flattenExportsMap(exportsMap, {\n conditions: ['browser-esm'],\n requiredConditions: ['browser-esm'],\n });\n const bundledExportsMap = flattenExportsMap(exportsMap);\n const repeatedExports: Record<string, string[]> = {};\n\n // Verify the bundled entries, but prefer unbundled if the entry exists.\n for (const [entryPath, bundledFilePath] of Object.entries(bundledExportsMap)) {\n if (typeof entryPath !== 'string' || typeof bundledFilePath !== 'string') {\n continue;\n }\n const unbundledFilePath = isExternal ? unbundledExportsMap[entryPath] : undefined;\n\n // TODO: This logic is the same from createImportMap.ts file.\n // It should be moved into a shared function with tests.\n // It is used here to use the same entry paths as the import map.\n let resolvedFilePath = unbundledFilePath || bundledFilePath;\n const ext = path.extname(resolvedFilePath);\n\n // For bundled files:\n if (!unbundledFilePath) {\n // Ignore .d.ts entries\n if (resolvedFilePath.endsWith('.d.ts')) {\n continue;\n }\n\n // We always expect responses to come back as javascript (.js extensions.)\n if (ext !== '.js') {\n resolvedFilePath = path.join(\n path.dirname(resolvedFilePath),\n path.basename(resolvedFilePath, ext) + (ext === '.mjs' ? '.js' : ext + '.js'),\n );\n }\n\n resolvedFilePath = resolvedFilePath.replace(/\\+/g, '_');\n }\n\n const safePath = safeRelativePath(resolvedFilePath);\n\n if (safeOutputFiles[safePath]) {\n if (repeatedExports[safePath]) {\n repeatedExports[safePath].push(entryPath);\n } else {\n // Change best guess entry path to exports map entry.\n safeOutputFiles[safePath].entry = entryPath;\n repeatedExports[safePath] = [entryPath];\n }\n }\n }\n\n const localPathToSafe: Record<string, string> = {};\n Object.keys(safeOutputFiles).forEach((safePath) => {\n localPathToSafe[path.resolve(outputPath, safePath)] = safePath;\n });\n\n const filePaths = Object.keys(localPathToSafe);\n const visitedPaths = new Set(filePaths);\n const pathsToParse: string[] = [...filePaths];\n\n while (pathsToParse.length) {\n const filePath = pathsToParse.shift();\n // Ignore any non-JS/TS files such as SVGs and sourcemaps\n if (!filePath || path.extname(filePath) !== '.js') {\n continue;\n }\n\n const safePath = localPathToSafe[filePath];\n\n if (safePath === undefined) {\n throw new Error(`Failed to find safe path for ${filePath}`);\n }\n\n let entry: string;\n let produces: Set<string>;\n if (!safeOutputFiles[safePath]) {\n entry = safePath;\n produces = new Set();\n } else {\n const result = safeOutputFiles[safePath];\n entry = result.entry;\n produces = result.produces;\n }\n\n let source: string;\n try {\n source = await fsPromises.readFile(filePath, 'utf-8');\n } catch (err) {\n // This could happen if a package is missing a file.\n console.warn(`Failed to read import ${safePath}:`, err);\n continue;\n }\n let rawImports: ReturnType<typeof parse>[0];\n let rawExports: ReturnType<typeof parse>[1];\n try {\n // es-module-lexer/parse may return Promise in some conditions\n // although it is not declared in the type definition\n // https://github.com/guybedford/es-module-lexer/issues/155\n [rawImports, rawExports] = await (parse(source) as unknown as Promise<ReturnType<typeof parse>>);\n } catch (err) {\n // This could happen if the source file isn't valid JS\n // (unlikely after adding the check above to only attempt parsing JS/TS files)\n console.warn(`Failed to parse ${filePath}:`, err, '\\nSource is:\\n', source);\n continue;\n }\n\n // TODO: Remove when https://github.com/guybedford/es-module-lexer/issues/76 is fixed\n // es-module-lexer doesn't handle export * from statements correctly as it parses them as\n // imports but not as exports. We need to handle them separately.\n let exportStarImport = false;\n\n const imports = Array.from(new Set(rawImports))\n .map((i) => {\n // The es-module-lexer returns entries where the \"n\" property equals the import source.\n // This includes the package name and path. For example, in this case:\n //\n // import { Button } from '@fluentui/react/lib/Button';\n //\n // The \"n\" property would be \"@fluentui/react/lib/Button\".\n // The \"s\" and \"e\" properties represent the start/end character positions of\n // the import source. The \"ss\" and \"se\" properties represent the start/end\n // character positions of the import specifier starting with \"import\". This\n // is useful for parsing the import specifier into its component parts.\n //\n // Currently when the import source is a backtick string, the \"n\" property\n // is undefined. This is a bug in es-module-lexer. We may need to handle this\n // at the javascript layer and expand it into multiple potential imports.\n if (!i.n) {\n console.debug(\n `Found an import that didn't parse correctly:\\nFilename:\\n${filePath}\\n\\nImport:\\n${source.slice(\n i.s,\n i.e,\n )}`,\n );\n return undefined;\n }\n\n // Handling export * from import statements\n if (source.slice(i.ss, i.se).includes('export * from')) {\n exportStarImport = true;\n }\n\n // Parse the import string into its component parts.\n const namedImports = {\n ...parseImportString(i.n),\n names: new Set<string>(parseNamedImports(source.slice(i.ss, i.se))),\n };\n\n return namedImports;\n })\n .filter(Boolean) as ImportStringResult[] & { names: Set<string> }[];\n\n // Processing exports is cheap as we already have to parse the source.\n // Helps find exports uncaught by output files.\n rawExports.forEach((i) => {\n if (!i.n) {\n console.debug(\n `Found an export that didn't parse correctly:\\nFilename:\\n${filePath}\\nExport:\\n${source.slice(i.s, i.e)}`,\n );\n return undefined;\n }\n\n // Exports don't need to be parsed as it is\n // already in the format we need.\n produces.add(i.n);\n });\n\n if (exportStarImport) {\n produces.add('*');\n }\n\n bundleInfo.entry[entry] ??= {\n bundlePath: safePath,\n produces: Array.from(produces),\n consumes: [],\n };\n\n for (const { packageName, importPath, names } of imports) {\n if (packageName?.startsWith('.')) {\n const localPath = path.resolve(path.dirname(filePath), packageName, importPath || '');\n\n if (!visitedPaths.has(localPath)) {\n visitedPaths.add(localPath);\n pathsToParse.push(localPath);\n localPathToSafe[localPath] = importPath;\n }\n } else if (packageName && !packageName.startsWith('node:')) {\n // Find if the import is already in the consumes list.\n const entryIndex = bundleInfo.entry[entry].consumes.findIndex(\n (c) => c.packageName === packageName && c.importPath === importPath,\n );\n if (entryIndex < 0) {\n // If not, add it.\n bundleInfo.entry[entry].consumes.push({ packageName, importPath: importPath || '.', names: [...names] });\n } else {\n // If so, add the names to the existing entry.\n // This is necessary because the same import may be used in multiple places.\n bundleInfo.entry[entry].consumes[entryIndex].names = Array.from(\n new Set([...names, ...bundleInfo.entry[entry].consumes[entryIndex].names]),\n );\n }\n }\n }\n if (repeatedExports[safePath]?.length > 1) {\n // Multiple entries for the same path.\n for (const repeatedEntry of repeatedExports[safePath]) {\n if (repeatedEntry !== entry) {\n bundleInfo.entry[repeatedEntry] = bundleInfo.entry[entry];\n }\n }\n }\n }\n\n return bundleInfo;\n}\n"]}
1
+ {"version":3,"file":"getBundleInfo.js","sourceRoot":"","sources":["../../src/utilities/getBundleInfo.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BundleOutputFile } from '@ms-cloudpack/bundler-types';\nimport type { PackageJsonExports } from '@ms-cloudpack/config-types';\nimport { flattenExportsMap, getResolvedFilePath } from '@ms-cloudpack/package-utilities';\nimport { safeRelativePath } from '@ms-cloudpack/path-string-parsing';\nimport path from 'path';\nimport type { BundleInfo } from '../types/BundleInfo.js';\nimport { getImportsAndExports } from './getImportsAndExports.js';\n/**\n * Returns a mapping from entry file path to list of paths that are produced and consumed in the searched files.\n */\nexport async function getBundleInfo(params: {\n outputPath: string;\n outputFiles: BundleOutputFile[];\n exportsMap: PackageJsonExports;\n isExternal: boolean;\n}): Promise<BundleInfo> {\n const { outputPath, outputFiles, exportsMap, isExternal } = params;\n const bundleInfo: BundleInfo = {\n entry: {},\n };\n\n // If there are no output files, return the empty bundle info.\n if (!outputFiles.length) {\n return bundleInfo;\n }\n\n /** Mapping from output file (safe/normalized relative path) to possible entry path and exports. */\n const outputFileInfo: Record<string, { entry: string; produces: Set<string> }> = {};\n outputFiles.forEach((file) => {\n // Normalize the path to start with ./ (or . for an empty path)\n const safePath = safeRelativePath(file.outputPath);\n // Store safe path to possible entry path and exports.\n outputFileInfo[safePath] = {\n entry: safePath,\n produces: new Set<string>(file.exports),\n };\n });\n\n // Get both the unbundled and bundled entries from the exports map\n const unbundledExportsMap = flattenExportsMap(exportsMap, {\n conditions: ['browser-esm'],\n requiredConditions: ['browser-esm'],\n });\n const bundledExportsMap = flattenExportsMap(exportsMap);\n const repeatedExports: Record<string, string[]> = {};\n\n // Verify the bundled entries, but prefer unbundled if the entry exists.\n for (const [entryPath, bundledFilePath] of Object.entries(bundledExportsMap)) {\n if (typeof entryPath !== 'string' || typeof bundledFilePath !== 'string') {\n continue;\n }\n\n const resolvedFilePath = getResolvedFilePath({ entryPath, isExternal, unbundledExportsMap, bundledFilePath });\n if (resolvedFilePath === undefined) {\n continue; // entry is ignored\n }\n\n const safePath = safeRelativePath(resolvedFilePath);\n\n if (outputFileInfo[safePath]) {\n if (repeatedExports[safePath]) {\n repeatedExports[safePath].push(entryPath);\n } else {\n // Change best guess entry path to exports map entry.\n outputFileInfo[safePath].entry = entryPath;\n repeatedExports[safePath] = [entryPath];\n }\n }\n }\n\n const localPathToSafe: Record<string, string> = {};\n Object.keys(outputFileInfo).forEach((safePath) => {\n localPathToSafe[path.resolve(outputPath, safePath)] = safePath;\n });\n\n const filePaths = Object.keys(localPathToSafe);\n const visitedPaths = new Set(filePaths);\n const pathsToParse = [...filePaths];\n\n while (pathsToParse.length) {\n const filePath = pathsToParse.shift();\n // Ignore any non-JS/TS files such as SVGs and sourcemaps\n if (!filePath || path.extname(filePath) !== '.js') {\n continue;\n }\n\n const safePath = localPathToSafe[filePath];\n if (safePath === undefined) {\n throw new Error(`Found file that was not expected to be processed: ${filePath}`);\n }\n\n const parseResult = await getImportsAndExports(filePath);\n if (!parseResult) {\n continue;\n }\n const { exportNames, imports } = parseResult;\n\n const { entry, produces } = outputFileInfo[safePath] || {\n entry: safePath,\n produces: new Set<string>(),\n };\n exportNames.forEach((name) => produces.add(name));\n\n bundleInfo.entry[entry] ??= {\n bundlePath: safePath,\n produces: Array.from(produces),\n consumes: [],\n };\n\n for (const { packageName, importPath, names } of imports) {\n if (packageName?.startsWith('.')) {\n const localPath = path.resolve(path.dirname(filePath), packageName, importPath || '');\n\n if (!visitedPaths.has(localPath)) {\n visitedPaths.add(localPath);\n pathsToParse.push(localPath);\n localPathToSafe[localPath] = importPath;\n }\n } else if (packageName && !packageName.startsWith('node:')) {\n // Find if the import is already in the consumes list.\n const entryIndex = bundleInfo.entry[entry].consumes.findIndex(\n (c) => c.packageName === packageName && c.importPath === importPath,\n );\n if (entryIndex < 0) {\n // If not, add it.\n bundleInfo.entry[entry].consumes.push({ packageName, importPath: importPath || '.', names: [...names] });\n } else {\n // If so, add the names to the existing entry.\n // This is necessary because the same import may be used in multiple places.\n bundleInfo.entry[entry].consumes[entryIndex].names = Array.from(\n new Set([...names, ...bundleInfo.entry[entry].consumes[entryIndex].names]),\n );\n }\n }\n }\n if (repeatedExports[safePath]?.length > 1) {\n // Multiple entries for the same path.\n for (const repeatedEntry of repeatedExports[safePath]) {\n if (repeatedEntry !== entry) {\n bundleInfo.entry[repeatedEntry] = bundleInfo.entry[entry];\n }\n }\n }\n }\n\n return bundleInfo;\n}\n"]}
@@ -22,7 +22,7 @@ export async function getBundleLocation(options, context) {
22
22
  shouldRecalculate,
23
23
  });
24
24
  // Derive where the output should be.
25
- const folderName = `${filenamify(name)}-${version}-${hashResult}`;
25
+ const folderName = `${filenamify(name, { replacement: '^' })}-${version}-${hashResult}`;
26
26
  const outputPath = path.join(getCachePath(), folderName);
27
27
  return {
28
28
  path: outputPath,
@@ -1 +1 @@
1
- {"version":3,"file":"getBundleLocation.js","sourceRoot":"","sources":["../../src/utilities/getBundleLocation.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIjD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAA6D,EAC7D,OAA4E;IAE5E,MAAM,EAAE,WAAW,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC;IACnD,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;IAC5C,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAEnD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,4DAA4D,WAAW,GAAG,CAAC,CAAC;IAC9F,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,sDAAsD,WAAW,GAAG,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;IAErC,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC;QACzC,WAAW;QACX;;;WAGG;QACH,sBAAsB,EAAE,KAAK;QAC7B,iBAAiB;KAClB,CAAC,CAAC;IACH,qCAAqC;IACrC,MAAM,UAAU,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,OAAO,IAAI,UAAU,EAAE,CAAC;IAClE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,UAAU,CAAC,CAAC;IAEzD,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,UAAU;KACX,CAAC;AACJ,CAAC","sourcesContent":["import filenamify from 'filenamify';\nimport path from 'path';\nimport { getCachePath } from './getCachePath.js';\nimport type { PackageDefinitionsCache } from '@ms-cloudpack/bundler-types';\nimport type { PackageHashes } from '@ms-cloudpack/package-hashes';\n\nexport async function getBundleLocation(\n options: { packagePath: string; shouldRecalculate?: boolean },\n context: { packages: PackageDefinitionsCache; packageHashes: PackageHashes },\n) {\n const { packagePath, shouldRecalculate } = options;\n const { packages, packageHashes } = context;\n const definition = await packages.get(packagePath);\n\n if (!definition) {\n throw new Error(`Package definition (package.json) missing or invalid at \"${packagePath}\"`);\n }\n\n if (!definition.name) {\n throw new Error(`Package definition (package.json) missing name at \"${packagePath}\"`);\n }\n\n const { name, version } = definition;\n\n const hashResult = await packageHashes.get({\n packagePath,\n /**\n * We don't use source hashing for location,\n * because we do not want to create a new folder for each change in a package.\n */\n isSourceHashingEnabled: false,\n shouldRecalculate,\n });\n // Derive where the output should be.\n const folderName = `${filenamify(name)}-${version}-${hashResult}`;\n const outputPath = path.join(getCachePath(), folderName);\n\n return {\n path: outputPath,\n folderName,\n };\n}\n"]}
1
+ {"version":3,"file":"getBundleLocation.js","sourceRoot":"","sources":["../../src/utilities/getBundleLocation.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIjD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAA6D,EAC7D,OAA4E;IAE5E,MAAM,EAAE,WAAW,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC;IACnD,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;IAC5C,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAEnD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,4DAA4D,WAAW,GAAG,CAAC,CAAC;IAC9F,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,sDAAsD,WAAW,GAAG,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;IAErC,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC;QACzC,WAAW;QACX;;;WAGG;QACH,sBAAsB,EAAE,KAAK;QAC7B,iBAAiB;KAClB,CAAC,CAAC;IACH,qCAAqC;IACrC,MAAM,UAAU,GAAG,GAAG,UAAU,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI,OAAO,IAAI,UAAU,EAAE,CAAC;IACxF,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,UAAU,CAAC,CAAC;IAEzD,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,UAAU;KACX,CAAC;AACJ,CAAC","sourcesContent":["import filenamify from 'filenamify';\nimport path from 'path';\nimport { getCachePath } from './getCachePath.js';\nimport type { PackageDefinitionsCache } from '@ms-cloudpack/bundler-types';\nimport type { PackageHashes } from '@ms-cloudpack/package-hashes';\n\nexport async function getBundleLocation(\n options: { packagePath: string; shouldRecalculate?: boolean },\n context: { packages: PackageDefinitionsCache; packageHashes: PackageHashes },\n) {\n const { packagePath, shouldRecalculate } = options;\n const { packages, packageHashes } = context;\n const definition = await packages.get(packagePath);\n\n if (!definition) {\n throw new Error(`Package definition (package.json) missing or invalid at \"${packagePath}\"`);\n }\n\n if (!definition.name) {\n throw new Error(`Package definition (package.json) missing name at \"${packagePath}\"`);\n }\n\n const { name, version } = definition;\n\n const hashResult = await packageHashes.get({\n packagePath,\n /**\n * We don't use source hashing for location,\n * because we do not want to create a new folder for each change in a package.\n */\n isSourceHashingEnabled: false,\n shouldRecalculate,\n });\n // Derive where the output should be.\n const folderName = `${filenamify(name, { replacement: '^' })}-${version}-${hashResult}`;\n const outputPath = path.join(getCachePath(), folderName);\n\n return {\n path: outputPath,\n folderName,\n };\n}\n"]}
@@ -0,0 +1,12 @@
1
+ import { type ImportStringResult } from '@ms-cloudpack/path-string-parsing';
2
+ /**
3
+ * Get info about imports and exports from a file.
4
+ * Returns undefined if the file doesn't exist or can't be parsed.
5
+ */
6
+ export declare function getImportsAndExports(filePath: string): Promise<{
7
+ exportNames: Set<string>;
8
+ imports: Array<ImportStringResult & {
9
+ names: Set<string>;
10
+ }>;
11
+ } | undefined>;
12
+ //# sourceMappingURL=getImportsAndExports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getImportsAndExports.d.ts","sourceRoot":"","sources":["../../src/utilities/getImportsAndExports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwC,KAAK,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAIlH;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CACjE;IACE,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,OAAO,EAAE,KAAK,CAAC,kBAAkB,GAAG;QAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;KAAE,CAAC,CAAC;CAC7D,GACD,SAAS,CACZ,CAkGA"}
@@ -0,0 +1,96 @@
1
+ import { parseImportString, parseNamedImports } from '@ms-cloudpack/path-string-parsing';
2
+ import { parse } from 'es-module-lexer';
3
+ import fsPromises from 'fs/promises';
4
+ /**
5
+ * Get info about imports and exports from a file.
6
+ * Returns undefined if the file doesn't exist or can't be parsed.
7
+ */
8
+ export async function getImportsAndExports(filePath) {
9
+ let source;
10
+ try {
11
+ source = await fsPromises.readFile(filePath, 'utf-8');
12
+ }
13
+ catch (err) {
14
+ // This could happen if a package is missing a file.
15
+ console.warn(`Failed to read ${filePath}:`, err);
16
+ return;
17
+ }
18
+ let rawImports;
19
+ let rawExports;
20
+ try {
21
+ // es-module-lexer/parse may return Promise in some conditions
22
+ // https://github.com/guybedford/es-module-lexer/issues/155
23
+ // eslint-disable-next-line @typescript-eslint/await-thenable
24
+ [rawImports, rawExports] = await parse(source);
25
+ }
26
+ catch (err) {
27
+ // This could happen if the source file isn't valid JS
28
+ console.warn(`Failed to parse ${filePath}: ${err}\nSource is:\n${source}`);
29
+ return;
30
+ }
31
+ // es-module-lexer doesn't handle export * from statements correctly as it parses them as
32
+ // imports but not as exports. We need to handle them separately.
33
+ // TODO: Remove when https://github.com/guybedford/es-module-lexer/issues/76 is fixed
34
+ let exportStarImport = false;
35
+ const imports = [];
36
+ for (const imprt of new Set(rawImports)) {
37
+ // es-module-lexer returns entries where the "n" property equals the import source.
38
+ // This includes the package name and path. For example, in this case:
39
+ // import { Button } from '@fluentui/react/lib/Button';
40
+ // imprt.n is "@fluentui/react/lib/Button"
41
+ let importPath = imprt.n;
42
+ // ss and se point to the entire import string's start/end
43
+ const importCode = source.slice(imprt.ss, imprt.se);
44
+ // s and e point to the specificer's start/end, including quotes -- e.g. "@fluentui/react/lib/Button"
45
+ const importSpecifier = source.slice(imprt.s, imprt.e);
46
+ if (!importPath) {
47
+ if (imprt.d === -2) {
48
+ continue; // -2 means import.meta, which we don't care about
49
+ }
50
+ // Currently when the import source is a backtick string, the path ("n" property) is undefined.
51
+ // This is a limitation in es-module-lexer.
52
+ if (/^`[^$`]+`$/.test(importSpecifier)) {
53
+ // If it's a static string which happened to use backticks for some reason, we can parse that.
54
+ importPath = importSpecifier.slice(1, -1);
55
+ }
56
+ else {
57
+ // For more complex cases, it's possible that we could handle this in the future at the
58
+ // javascript layer and expand it into multiple potential imports.
59
+ console.debug(`Found an import that didn't have a static path:\nFilename:${filePath}\nImport:\n ${importCode}`);
60
+ continue;
61
+ }
62
+ }
63
+ // Handling export * from import statements
64
+ if (importCode.includes('export * from')) {
65
+ exportStarImport = true;
66
+ }
67
+ // Parse the import string into its component parts.
68
+ const importedNames = parseNamedImports(importCode);
69
+ if (imprt.d >= 0 && !importedNames.length) {
70
+ // This is a dynamic import. In this case we don't know which names are used, so assume all of them.
71
+ importedNames.push('*');
72
+ }
73
+ imports.push({
74
+ ...parseImportString(importPath),
75
+ names: new Set(importedNames),
76
+ });
77
+ }
78
+ // Processing exports is cheap as we already have to parse the source.
79
+ // Helps find exports uncaught by output files.
80
+ const exportNames = new Set();
81
+ for (const exprt of rawExports) {
82
+ if (exprt.n) {
83
+ // Exports don't need to be parsed as it is
84
+ // already in the format we need.
85
+ exportNames.add(exprt.n);
86
+ }
87
+ else {
88
+ console.debug(`Found an export that didn't parse correctly:\nFilename: ${filePath}\nExport:\n ${source.slice(exprt.s, exprt.e)}`);
89
+ }
90
+ }
91
+ if (exportStarImport) {
92
+ exportNames.add('*');
93
+ }
94
+ return { exportNames, imports };
95
+ }
96
+ //# sourceMappingURL=getImportsAndExports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getImportsAndExports.js","sourceRoot":"","sources":["../../src/utilities/getImportsAndExports.ts"],"names":[],"mappings":"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","sourcesContent":["import { parseImportString, parseNamedImports, type ImportStringResult } from '@ms-cloudpack/path-string-parsing';\nimport { parse, type ImportSpecifier, type ExportSpecifier } from 'es-module-lexer';\nimport fsPromises from 'fs/promises';\n\n/**\n * Get info about imports and exports from a file.\n * Returns undefined if the file doesn't exist or can't be parsed.\n */\nexport async function getImportsAndExports(filePath: string): Promise<\n | {\n exportNames: Set<string>;\n imports: Array<ImportStringResult & { names: Set<string> }>;\n }\n | undefined\n> {\n let source: string;\n try {\n source = await fsPromises.readFile(filePath, 'utf-8');\n } catch (err) {\n // This could happen if a package is missing a file.\n console.warn(`Failed to read ${filePath}:`, err);\n return;\n }\n\n let rawImports: readonly ImportSpecifier[];\n let rawExports: readonly ExportSpecifier[];\n try {\n // es-module-lexer/parse may return Promise in some conditions\n // https://github.com/guybedford/es-module-lexer/issues/155\n // eslint-disable-next-line @typescript-eslint/await-thenable\n [rawImports, rawExports] = await parse(source);\n } catch (err) {\n // This could happen if the source file isn't valid JS\n console.warn(`Failed to parse ${filePath}: ${err}\\nSource is:\\n${source}`);\n return;\n }\n\n // es-module-lexer doesn't handle export * from statements correctly as it parses them as\n // imports but not as exports. We need to handle them separately.\n // TODO: Remove when https://github.com/guybedford/es-module-lexer/issues/76 is fixed\n let exportStarImport = false;\n\n const imports: Array<ImportStringResult & { names: Set<string> }> = [];\n for (const imprt of new Set(rawImports)) {\n // es-module-lexer returns entries where the \"n\" property equals the import source.\n // This includes the package name and path. For example, in this case:\n // import { Button } from '@fluentui/react/lib/Button';\n // imprt.n is \"@fluentui/react/lib/Button\"\n let importPath = imprt.n;\n // ss and se point to the entire import string's start/end\n const importCode = source.slice(imprt.ss, imprt.se);\n // s and e point to the specificer's start/end, including quotes -- e.g. \"@fluentui/react/lib/Button\"\n const importSpecifier = source.slice(imprt.s, imprt.e);\n\n if (!importPath) {\n if (imprt.d === -2) {\n continue; // -2 means import.meta, which we don't care about\n }\n\n // Currently when the import source is a backtick string, the path (\"n\" property) is undefined.\n // This is a limitation in es-module-lexer.\n if (/^`[^$`]+`$/.test(importSpecifier)) {\n // If it's a static string which happened to use backticks for some reason, we can parse that.\n importPath = importSpecifier.slice(1, -1);\n } else {\n // For more complex cases, it's possible that we could handle this in the future at the\n // javascript layer and expand it into multiple potential imports.\n console.debug(\n `Found an import that didn't have a static path:\\nFilename:${filePath}\\nImport:\\n ${importCode}`,\n );\n continue;\n }\n }\n\n // Handling export * from import statements\n if (importCode.includes('export * from')) {\n exportStarImport = true;\n }\n\n // Parse the import string into its component parts.\n const importedNames = parseNamedImports(importCode);\n if (imprt.d >= 0 && !importedNames.length) {\n // This is a dynamic import. In this case we don't know which names are used, so assume all of them.\n importedNames.push('*');\n }\n\n imports.push({\n ...parseImportString(importPath),\n names: new Set<string>(importedNames),\n });\n }\n\n // Processing exports is cheap as we already have to parse the source.\n // Helps find exports uncaught by output files.\n const exportNames = new Set<string>();\n for (const exprt of rawExports) {\n if (exprt.n) {\n // Exports don't need to be parsed as it is\n // already in the format we need.\n exportNames.add(exprt.n);\n } else {\n console.debug(\n `Found an export that didn't parse correctly:\\nFilename: ${filePath}\\nExport:\\n ${source.slice(exprt.s, exprt.e)}`,\n );\n }\n }\n\n if (exportStarImport) {\n exportNames.add('*');\n }\n\n return { exportNames, imports };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"resolveDependenciesTask.d.ts","sourceRoot":"","sources":["../../src/utilities/resolveDependenciesTask.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAmB,MAAM,iCAAiC,CAAC;AAE/F,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAElG;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE;IACP,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;CAC5B,EACD,OAAO,EAAE;IAAE,QAAQ,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,uBAAuB,CAAA;CAAE,uBAsCvE"}
1
+ {"version":3,"file":"resolveDependenciesTask.d.ts","sourceRoot":"","sources":["../../src/utilities/resolveDependenciesTask.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAmB,MAAM,iCAAiC,CAAC;AAE/F,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAElG;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE;IACP,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;CAC5B,EACD,OAAO,EAAE;IAAE,QAAQ,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,uBAAuB,CAAA;CAAE,uBA4CvE"}
@@ -9,7 +9,8 @@ export async function resolveDependenciesTask(options, context) {
9
9
  const { reporter, packages } = context;
10
10
  let resolveMap;
11
11
  // Grab the installed dependency locations.
12
- await reporter.runTask('Resolving dependencies', async () => {
12
+ const task = reporter.addTask('Resolving dependencies');
13
+ try {
13
14
  resolveMap = await createResolveMap({
14
15
  appPath,
15
16
  additionalPaths,
@@ -20,14 +21,17 @@ export async function resolveDependenciesTask(options, context) {
20
21
  const { allPackages, duplicatedPackages } = getPackagesFromResolveMap(resolveMap);
21
22
  const message = `Found ${cyan(allPackages.size)} total packages, ${duplicatedPackages.size ? `${yellow(duplicatedPackages.size)} with multiple versions.` : `no duplicates.`}`;
22
23
  const extended = bulletedList(Array.from(duplicatedPackages.entries()).map(([name, versions]) => `${bold(name)}: ${Array.from(versions).join(', ')}`));
23
- return {
24
- message,
25
- extended,
26
- forceShow: true,
27
- };
28
- });
29
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- will be defined after the task runs
30
- return resolveMap;
24
+ task.complete({ message, extended, forceShow: true });
25
+ return resolveMap;
26
+ }
27
+ catch (err) {
28
+ task.complete({ status: 'fail', message: 'Failed to resolve dependencies', forceShow: true });
29
+ // Suppress the stack trace for this error because it's not useful to the user.
30
+ if (err instanceof Error) {
31
+ err.stack = undefined;
32
+ }
33
+ throw err;
34
+ }
31
35
  }
32
36
  /**
33
37
  * Given a resolveMap, returns a map of all packages and a map of packages with multiple versions.
@@ -1 +1 @@
1
- {"version":3,"file":"resolveDependenciesTask.js","sourceRoot":"","sources":["../../src/utilities/resolveDependenciesTask.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PackageDefinitionsCache } from '@ms-cloudpack/bundler-types';\nimport type { LinkedPath, ResolveMap, ResolveMapEntry } from '@ms-cloudpack/package-utilities';\nimport { createResolveMap } from '@ms-cloudpack/package-utilities';\nimport { bold, bulletedList, cyan, yellow, type TaskReporter } from '@ms-cloudpack/task-reporter';\n\n/**\n * Resolves the locations of dependencies and returns the resolve map, logging results\n * to the task reporter.\n */\nexport async function resolveDependenciesTask(\n options: {\n appPath: string;\n additionalPaths?: string[];\n linkedPaths?: LinkedPath[];\n },\n context: { reporter: TaskReporter; packages: PackageDefinitionsCache },\n) {\n const { appPath, additionalPaths, linkedPaths } = options;\n const { reporter, packages } = context;\n let resolveMap: ResolveMap | undefined;\n\n // Grab the installed dependency locations.\n await reporter.runTask('Resolving dependencies', async () => {\n resolveMap = await createResolveMap(\n {\n appPath,\n additionalPaths,\n linkedPaths,\n },\n {\n packages,\n },\n );\n\n const { allPackages, duplicatedPackages } = getPackagesFromResolveMap(resolveMap);\n const message = `Found ${cyan(allPackages.size)} total packages, ${\n duplicatedPackages.size ? `${yellow(duplicatedPackages.size)} with multiple versions.` : `no duplicates.`\n }`;\n const extended = bulletedList(\n Array.from(duplicatedPackages.entries()).map(\n ([name, versions]) => `${bold(name)}: ${Array.from(versions).join(', ')}`,\n ),\n );\n\n return {\n message,\n extended,\n forceShow: true,\n };\n });\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- will be defined after the task runs\n return resolveMap!;\n}\n\n/**\n * Given a resolveMap, returns a map of all packages and a map of packages with multiple versions.\n * This is used to log the results of the resolve task.\n */\nfunction getPackagesFromResolveMap(resolveMap: ResolveMap) {\n const allPackages = new Map<string, ResolveMapEntry>();\n const duplicatedPackages = new Map<string, Set<string>>();\n\n function addEntry(entry: ResolveMapEntry) {\n const existingEntry = allPackages.get(entry.name);\n if (existingEntry) {\n let dupeSet = duplicatedPackages.get(entry.name);\n if (!dupeSet) {\n dupeSet = new Set([existingEntry.version]);\n duplicatedPackages.set(entry.name, dupeSet);\n }\n dupeSet.add(entry.version);\n } else {\n allPackages.set(entry.name, entry);\n }\n }\n\n for (const currentEntry of Object.values(resolveMap)) {\n addEntry(currentEntry);\n\n if (currentEntry.scopedVersions) {\n for (const scopedEntry of Object.values(currentEntry.scopedVersions)) {\n addEntry(scopedEntry);\n }\n }\n }\n\n return {\n allPackages,\n duplicatedPackages,\n };\n}\n"]}
1
+ {"version":3,"file":"resolveDependenciesTask.js","sourceRoot":"","sources":["../../src/utilities/resolveDependenciesTask.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAqB,MAAM,6BAA6B,CAAC;AAElG;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,OAIC,EACD,OAAsE;IAEtE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAC1D,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IACvC,IAAI,UAAkC,CAAC;IAEvC,2CAA2C;IAC3C,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAExD,IAAI,CAAC;QACH,UAAU,GAAG,MAAM,gBAAgB,CACjC;YACE,OAAO;YACP,eAAe;YACf,WAAW;SACZ,EACD;YACE,QAAQ;SACT,CACF,CAAC;QAEF,MAAM,EAAE,WAAW,EAAE,kBAAkB,EAAE,GAAG,yBAAyB,CAAC,UAAU,CAAC,CAAC;QAClF,MAAM,OAAO,GAAG,SAAS,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,oBAC7C,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC,gBAC3F,EAAE,CAAC;QACH,MAAM,QAAQ,GAAG,YAAY,CAC3B,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAC1C,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC1E,CACF,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEtD,OAAO,UAAU,CAAC;IACpB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,gCAAgC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE9F,+EAA+E;QAC/E,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;YACzB,GAAG,CAAC,KAAK,GAAG,SAAS,CAAC;QACxB,CAAC;QAED,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,yBAAyB,CAAC,UAAsB;IACvD,MAAM,WAAW,GAAG,IAAI,GAAG,EAA2B,CAAC;IACvD,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAuB,CAAC;IAE1D,SAAS,QAAQ,CAAC,KAAsB;QACtC,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,aAAa,EAAE,CAAC;YAClB,IAAI,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACjD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;gBAC3C,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAC9C,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,KAAK,MAAM,YAAY,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;QACrD,QAAQ,CAAC,YAAY,CAAC,CAAC;QAEvB,IAAI,YAAY,CAAC,cAAc,EAAE,CAAC;YAChC,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;gBACrE,QAAQ,CAAC,WAAW,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,WAAW;QACX,kBAAkB;KACnB,CAAC;AACJ,CAAC","sourcesContent":["import type { PackageDefinitionsCache } from '@ms-cloudpack/bundler-types';\nimport type { LinkedPath, ResolveMap, ResolveMapEntry } from '@ms-cloudpack/package-utilities';\nimport { createResolveMap } from '@ms-cloudpack/package-utilities';\nimport { bold, bulletedList, cyan, yellow, type TaskReporter } from '@ms-cloudpack/task-reporter';\n\n/**\n * Resolves the locations of dependencies and returns the resolve map, logging results\n * to the task reporter.\n */\nexport async function resolveDependenciesTask(\n options: {\n appPath: string;\n additionalPaths?: string[];\n linkedPaths?: LinkedPath[];\n },\n context: { reporter: TaskReporter; packages: PackageDefinitionsCache },\n) {\n const { appPath, additionalPaths, linkedPaths } = options;\n const { reporter, packages } = context;\n let resolveMap: ResolveMap | undefined;\n\n // Grab the installed dependency locations.\n const task = reporter.addTask('Resolving dependencies');\n\n try {\n resolveMap = await createResolveMap(\n {\n appPath,\n additionalPaths,\n linkedPaths,\n },\n {\n packages,\n },\n );\n\n const { allPackages, duplicatedPackages } = getPackagesFromResolveMap(resolveMap);\n const message = `Found ${cyan(allPackages.size)} total packages, ${\n duplicatedPackages.size ? `${yellow(duplicatedPackages.size)} with multiple versions.` : `no duplicates.`\n }`;\n const extended = bulletedList(\n Array.from(duplicatedPackages.entries()).map(\n ([name, versions]) => `${bold(name)}: ${Array.from(versions).join(', ')}`,\n ),\n );\n\n task.complete({ message, extended, forceShow: true });\n\n return resolveMap;\n } catch (err) {\n task.complete({ status: 'fail', message: 'Failed to resolve dependencies', forceShow: true });\n\n // Suppress the stack trace for this error because it's not useful to the user.\n if (err instanceof Error) {\n err.stack = undefined;\n }\n\n throw err;\n }\n}\n\n/**\n * Given a resolveMap, returns a map of all packages and a map of packages with multiple versions.\n * This is used to log the results of the resolve task.\n */\nfunction getPackagesFromResolveMap(resolveMap: ResolveMap) {\n const allPackages = new Map<string, ResolveMapEntry>();\n const duplicatedPackages = new Map<string, Set<string>>();\n\n function addEntry(entry: ResolveMapEntry) {\n const existingEntry = allPackages.get(entry.name);\n if (existingEntry) {\n let dupeSet = duplicatedPackages.get(entry.name);\n if (!dupeSet) {\n dupeSet = new Set([existingEntry.version]);\n duplicatedPackages.set(entry.name, dupeSet);\n }\n dupeSet.add(entry.version);\n } else {\n allPackages.set(entry.name, entry);\n }\n }\n\n for (const currentEntry of Object.values(resolveMap)) {\n addEntry(currentEntry);\n\n if (currentEntry.scopedVersions) {\n for (const scopedEntry of Object.values(currentEntry.scopedVersions)) {\n addEntry(scopedEntry);\n }\n }\n }\n\n return {\n allPackages,\n duplicatedPackages,\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ms-cloudpack/api-server",
3
- "version": "0.30.4",
3
+ "version": "0.30.6",
4
4
  "description": "An implementation of the API server that does interacts with a task scheduler.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -28,16 +28,16 @@
28
28
  "@lage-run/scheduler": "^1.1.9",
29
29
  "@lage-run/target-graph": "^0.8.9",
30
30
  "@lage-run/hasher": "^1.0.5",
31
- "@ms-cloudpack/bundler": "^0.17.29",
31
+ "@ms-cloudpack/bundler": "^0.17.31",
32
32
  "@ms-cloudpack/bundler-types": "^0.24.1",
33
- "@ms-cloudpack/config": "^0.17.23",
33
+ "@ms-cloudpack/config": "^0.17.26",
34
34
  "@ms-cloudpack/config-types": "^0.4.3",
35
35
  "@ms-cloudpack/create-express-app": "^1.4.0",
36
36
  "@ms-cloudpack/data-bus": "^0.4.2",
37
37
  "@ms-cloudpack/file-watcher": "^0.1.2",
38
38
  "@ms-cloudpack/json-utilities": "^0.1.3",
39
- "@ms-cloudpack/package-hashes": "^0.3.20",
40
- "@ms-cloudpack/package-utilities": "^5.8.3",
39
+ "@ms-cloudpack/package-hashes": "^0.3.23",
40
+ "@ms-cloudpack/package-utilities": "^5.10.1",
41
41
  "@ms-cloudpack/path-string-parsing": "^1.1.3",
42
42
  "@ms-cloudpack/path-utilities": "^2.5.0",
43
43
  "@ms-cloudpack/task-reporter": "^0.11.1",