@ms-cloudpack/path-string-parsing 1.2.6 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,5 @@
1
1
  # @ms-cloudpack/path-string-parsing
2
2
 
3
3
  Common path-related string parsing utilities for Cloudpack.
4
+
5
+ Some of the utilities from this package are used in the overlay UX in the browser, so it can't reference any Node libraries.
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Adds hash after name and version in a URL.
3
+ * If hash already exists, replaces it.
4
+ *
5
+ * @param params - Parameters for adding hash to URL
6
+ * @param params.url - URL to add hash to
7
+ * @param params.packageName - Package name
8
+ * @param params.version - Package version
9
+ * @param params.hash - Hash to add
10
+ * @returns URL with hash added or replaced
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * addHashUrl({
15
+ * url: 'http://localhost:3000/react@17.5.0/v0/bundled/index.js',
16
+ * packageName: 'react',
17
+ * version: '17.5.0',
18
+ * hash: 'abc123'
19
+ * });
20
+ * // Returns: 'http://localhost:3000/react@17.5.0/h-abc123/v0/bundled/index.js'
21
+ * ```
22
+ */
23
+ export declare function addHashUrl(params: {
24
+ /** URL to add hash to */
25
+ url: string;
26
+ /** Package name */
27
+ packageName: string;
28
+ /** Package version */
29
+ version: string;
30
+ /** Hash to add */
31
+ hash: string;
32
+ }): string;
33
+ //# sourceMappingURL=addHashUrl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addHashUrl.d.ts","sourceRoot":"","sources":["../src/addHashUrl.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE;IACjC,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,MAAM,CAUT"}
@@ -0,0 +1,35 @@
1
+ import { removeHashFromUrl } from './removeHashFromUrl.js';
2
+ /**
3
+ * Adds hash after name and version in a URL.
4
+ * If hash already exists, replaces it.
5
+ *
6
+ * @param params - Parameters for adding hash to URL
7
+ * @param params.url - URL to add hash to
8
+ * @param params.packageName - Package name
9
+ * @param params.version - Package version
10
+ * @param params.hash - Hash to add
11
+ * @returns URL with hash added or replaced
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * addHashUrl({
16
+ * url: 'http://localhost:3000/react@17.5.0/v0/bundled/index.js',
17
+ * packageName: 'react',
18
+ * version: '17.5.0',
19
+ * hash: 'abc123'
20
+ * });
21
+ * // Returns: 'http://localhost:3000/react@17.5.0/h-abc123/v0/bundled/index.js'
22
+ * ```
23
+ */
24
+ export function addHashUrl(params) {
25
+ const { url, packageName, version, hash } = params;
26
+ const packageId = `${packageName}@${version}`;
27
+ const packageUrlIndex = url.indexOf(packageId);
28
+ if (packageUrlIndex !== -1) {
29
+ const hashIndex = packageUrlIndex + packageId.length;
30
+ const urlWithoutHash = removeHashFromUrl(url);
31
+ return urlWithoutHash.slice(0, hashIndex) + `/h-${hash}` + urlWithoutHash.slice(hashIndex);
32
+ }
33
+ return url;
34
+ }
35
+ //# sourceMappingURL=addHashUrl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addHashUrl.js","sourceRoot":"","sources":["../src/addHashUrl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,UAAU,CAAC,MAS1B;IACC,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;IACnD,MAAM,SAAS,GAAG,GAAG,WAAW,IAAI,OAAO,EAAE,CAAC;IAC9C,MAAM,eAAe,GAAG,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/C,IAAI,eAAe,KAAK,CAAC,CAAC,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,eAAe,GAAG,SAAS,CAAC,MAAM,CAAC;QACrD,MAAM,cAAc,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAC9C,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,MAAM,IAAI,EAAE,GAAG,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC7F,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["import { removeHashFromUrl } from './removeHashFromUrl.js';\n\n/**\n * Adds hash after name and version in a URL.\n * If hash already exists, replaces it.\n *\n * @param params - Parameters for adding hash to URL\n * @param params.url - URL to add hash to\n * @param params.packageName - Package name\n * @param params.version - Package version\n * @param params.hash - Hash to add\n * @returns URL with hash added or replaced\n *\n * @example\n * ```ts\n * addHashUrl({\n * url: 'http://localhost:3000/react@17.5.0/v0/bundled/index.js',\n * packageName: 'react',\n * version: '17.5.0',\n * hash: 'abc123'\n * });\n * // Returns: 'http://localhost:3000/react@17.5.0/h-abc123/v0/bundled/index.js'\n * ```\n */\nexport function addHashUrl(params: {\n /** URL to add hash to */\n url: string;\n /** Package name */\n packageName: string;\n /** Package version */\n version: string;\n /** Hash to add */\n hash: string;\n}): string {\n const { url, packageName, version, hash } = params;\n const packageId = `${packageName}@${version}`;\n const packageUrlIndex = url.indexOf(packageId);\n if (packageUrlIndex !== -1) {\n const hashIndex = packageUrlIndex + packageId.length;\n const urlWithoutHash = removeHashFromUrl(url);\n return urlWithoutHash.slice(0, hashIndex) + `/h-${hash}` + urlWithoutHash.slice(hashIndex);\n }\n return url;\n}\n"]}
package/lib/index.d.ts CHANGED
@@ -4,4 +4,6 @@ export { slash } from './slash.js';
4
4
  export { parseImportString, type ImportStringResult } from './parseImportString.js';
5
5
  export { parseNamedImports } from './parseNamedImports.js';
6
6
  export { makeUrl } from './makeUrl.js';
7
+ export { addHashUrl } from './addHashUrl.js';
8
+ export { removeHashFromUrl } from './removeHashFromUrl.js';
7
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC"}
package/lib/index.js CHANGED
@@ -4,4 +4,6 @@ export { slash } from './slash.js';
4
4
  export { parseImportString } from './parseImportString.js';
5
5
  export { parseNamedImports } from './parseNamedImports.js';
6
6
  export { makeUrl } from './makeUrl.js';
7
+ export { addHashUrl } from './addHashUrl.js';
8
+ export { removeHashFromUrl } from './removeHashFromUrl.js';
7
9
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAA2B,MAAM,wBAAwB,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC","sourcesContent":["export { safeRelativePath } from './safeRelativePath.js';\nexport { normalizeRelativePath } from './normalizeRelativePath.js';\nexport { slash } from './slash.js';\nexport { parseImportString, type ImportStringResult } from './parseImportString.js';\nexport { parseNamedImports } from './parseNamedImports.js';\nexport { makeUrl } from './makeUrl.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAA2B,MAAM,wBAAwB,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC","sourcesContent":["export { safeRelativePath } from './safeRelativePath.js';\nexport { normalizeRelativePath } from './normalizeRelativePath.js';\nexport { slash } from './slash.js';\nexport { parseImportString, type ImportStringResult } from './parseImportString.js';\nexport { parseNamedImports } from './parseNamedImports.js';\nexport { makeUrl } from './makeUrl.js';\nexport { addHashUrl } from './addHashUrl.js';\nexport { removeHashFromUrl } from './removeHashFromUrl.js';\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"makeUrl.d.ts","sourceRoot":"","sources":["../src/makeUrl.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,GAAG,OAOzD"}
1
+ {"version":3,"file":"makeUrl.d.ts","sourceRoot":"","sources":["../src/makeUrl.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,GAAG,CAO/D"}
@@ -1 +1 @@
1
- {"version":3,"file":"makeUrl.js","sourceRoot":"","sources":["../src/makeUrl.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa,EAAE,IAAmB;IACxD,IAAI,CAAC;QACH,mFAAmF;QACnF,OAAO,IAAI,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,aAAa,IAAI,IAAI,EAAE,GAAG,CAAC,CAAC;IACpE,CAAC;AACH,CAAC","sourcesContent":["/**\n * Attempt to create a URL object from a string, and throw an informative error if it fails.\n * (The URL constructor throws a very generic error.)\n */\nexport function makeUrl(input: string, base?: string | URL) {\n try {\n // eslint-disable-next-line no-restricted-syntax -- this is the function definition\n return new URL(input, base);\n } catch {\n throw new Error(`Invalid URL: \"${input}\", base: \"${base || ''}\"`);\n }\n}\n"]}
1
+ {"version":3,"file":"makeUrl.js","sourceRoot":"","sources":["../src/makeUrl.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa,EAAE,IAAmB;IACxD,IAAI,CAAC;QACH,mFAAmF;QACnF,OAAO,IAAI,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,aAAa,IAAI,IAAI,EAAE,GAAG,CAAC,CAAC;IACpE,CAAC;AACH,CAAC","sourcesContent":["/**\n * Attempt to create a URL object from a string, and throw an informative error if it fails.\n * (The URL constructor throws a very generic error.)\n */\nexport function makeUrl(input: string, base?: string | URL): URL {\n try {\n // eslint-disable-next-line no-restricted-syntax -- this is the function definition\n return new URL(input, base);\n } catch {\n throw new Error(`Invalid URL: \"${input}\", base: \"${base || ''}\"`);\n }\n}\n"]}
@@ -1,8 +1,15 @@
1
1
  /**
2
2
  * Parses a JS import/export statement (from a path) into its component parts.
3
- * Does NOT handle typescript (import/export type) or exports without paths.
3
+ * Does NOT handle typescript (`import/export type`), imports not from paths, exports without paths,
4
+ * or anything that's not a syntactically valid import/export statement.
5
+ *
6
+ * The statement is expected to be copied verbatim from a source file, so there's a slight chance it
7
+ * could contain comments embedded in the middle. This will try to remove the comments, but
8
+ * accuracy is not guaranteed (especially for contrived scenarios like imports inside comments).
9
+ *
4
10
  * @param importLine - The import string to parse.
5
- * @returns A string array with the named imports, default and/or '*'.
11
+ * @returns A string array with the named imports, `'default'` and/or `'*'`.
12
+ * This will return the original names, not the imported names.
6
13
  */
7
14
  export declare function parseNamedImports(importLine: string): string[];
8
15
  //# sourceMappingURL=parseNamedImports.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parseNamedImports.d.ts","sourceRoot":"","sources":["../src/parseNamedImports.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAkC9D"}
1
+ {"version":3,"file":"parseNamedImports.d.ts","sourceRoot":"","sources":["../src/parseNamedImports.ts"],"names":[],"mappings":"AAYA;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CA8C9D"}
@@ -1,35 +1,63 @@
1
+ const namedImportRegex =
2
+ // 1: maybe name for default (imports only): import foo from "package"
3
+ // 2: maybe * part: import * as myModule from "package"
4
+ // note that these can be combined: import foo, * as myModule from "package"
5
+ // 3: maybe names: import { foo, bar } from "package"
6
+ // (can be combined with 1 but not 2)
7
+ // Matches of \s in the middle of the string are non-greedy to reduce potential backtracking.
8
+ // The { names } match is very crude (all possible characters in any order) to improve performance,
9
+ // since we know the input is syntactically valid and we'll actually match the names later.
10
+ // ( 1 ) ( 2 ) ( 3 ) from path
11
+ /^\s*[ie][mx]port\s*?([\w$]+)?\s*?,?\s*?(\*(?:\s*?as\s+?[\w$]+)?)?\s*?(?:\{([\w$\s,]*)\})?\s*from\s*["']/;
1
12
  /**
2
13
  * Parses a JS import/export statement (from a path) into its component parts.
3
- * Does NOT handle typescript (import/export type) or exports without paths.
14
+ * Does NOT handle typescript (`import/export type`), imports not from paths, exports without paths,
15
+ * or anything that's not a syntactically valid import/export statement.
16
+ *
17
+ * The statement is expected to be copied verbatim from a source file, so there's a slight chance it
18
+ * could contain comments embedded in the middle. This will try to remove the comments, but
19
+ * accuracy is not guaranteed (especially for contrived scenarios like imports inside comments).
20
+ *
4
21
  * @param importLine - The import string to parse.
5
- * @returns A string array with the named imports, default and/or '*'.
22
+ * @returns A string array with the named imports, `'default'` and/or `'*'`.
23
+ * This will return the original names, not the imported names.
6
24
  */
7
25
  export function parseNamedImports(importLine) {
8
- // Regex from: https://github.com/antonkc/MOR/blob/main/matchJsImports.md
9
- // With some edits to catch export * from "package" and removing lots of unneeded groups.
10
- // (This won't handle comments; if that's ever needed, we should use acorn for full parsing.)
11
- const matches = importLine.match(
12
- // 1 default 2 * 3 names 4 path
13
- /^\s*(?:import|export)\s*(?=[\s*{])\s*((?:[$\w]+(?:\s+as\s+[$\w]+)?(?=\s*,\s*[{*]|\s+from))?)[\s,]*((?:\*\s*as\s+[$\w]+)?|\*)[\s,]*(?:\{\s*((?:[$\w]+(?:\s+as\s+[$\w]+)?\s*,?\s*)*)\})?\s*from\s*["']([^"']*)/);
14
- // If no matches return empty array
26
+ let matches = importLine.match(namedImportRegex);
15
27
  if (!matches) {
16
- return [];
28
+ if (/^import\s*?["'][^"']*["']/.test(importLine)) {
29
+ // This is a side effect import, so return empty array.
30
+ return [];
31
+ }
32
+ // Maybe there are some embedded comments? Try removing them.
33
+ importLine = importLine
34
+ // Start by finding and removing the path to reduce chance of accidents.
35
+ .replace(/\bfrom\s*(["'])[^"']*["'].*/, 'from "removed"')
36
+ // Remove single-line and multi-line comments. This could behave badly in contrived
37
+ // nesting scenarios, but should be reliable for more common cases.
38
+ .replaceAll(/\/\/.*/g, '')
39
+ .replaceAll(/\/\*[\s\S]*?\*\//g, '');
40
+ // Try again
41
+ matches = importLine.match(namedImportRegex);
42
+ if (!matches) {
43
+ return [];
44
+ }
17
45
  }
18
46
  const names = [];
19
- // Default export
20
47
  if (matches[1]) {
48
+ // Default export
21
49
  names.push('default');
22
50
  }
23
- // Imported or exported names
24
51
  if (matches[3]) {
25
- // Clean out the braces, whitespace, and get alias
52
+ // Imported or exported names
53
+ // Clean out the whitespace, and get the original names not the aliases
26
54
  const namedImports = matches[3].matchAll(/([\w$]+)(?:\s+as\s+[\w$]+,?)?/g);
27
55
  for (const namedImport of namedImports) {
28
56
  names.push(namedImport[1]);
29
57
  }
30
58
  }
31
- // If there is a namespace export, push it to the names array
32
59
  if (matches[2]) {
60
+ // All names
33
61
  names.push('*');
34
62
  }
35
63
  return names;
@@ -1 +1 @@
1
- {"version":3,"file":"parseNamedImports.js","sourceRoot":"","sources":["../src/parseNamedImports.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAAkB;IAClD,yEAAyE;IACzE,yFAAyF;IACzF,6FAA6F;IAC7F,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK;IAC9B,2MAA2M;IAC3M,8MAA8M,CAC/M,CAAC;IACF,mCAAmC;IACnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,iBAAiB;IACjB,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACxB,CAAC;IAED,6BAA6B;IAC7B,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACf,kDAAkD;QAClD,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,gCAAgC,CAAC,CAAC;QAC3E,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,6DAA6D;IAC7D,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["/**\n * Parses a JS import/export statement (from a path) into its component parts.\n * Does NOT handle typescript (import/export type) or exports without paths.\n * @param importLine - The import string to parse.\n * @returns A string array with the named imports, default and/or '*'.\n */\nexport function parseNamedImports(importLine: string): string[] {\n // Regex from: https://github.com/antonkc/MOR/blob/main/matchJsImports.md\n // With some edits to catch export * from \"package\" and removing lots of unneeded groups.\n // (This won't handle comments; if that's ever needed, we should use acorn for full parsing.)\n const matches = importLine.match(\n // 1 default 2 * 3 names 4 path\n /^\\s*(?:import|export)\\s*(?=[\\s*{])\\s*((?:[$\\w]+(?:\\s+as\\s+[$\\w]+)?(?=\\s*,\\s*[{*]|\\s+from))?)[\\s,]*((?:\\*\\s*as\\s+[$\\w]+)?|\\*)[\\s,]*(?:\\{\\s*((?:[$\\w]+(?:\\s+as\\s+[$\\w]+)?\\s*,?\\s*)*)\\})?\\s*from\\s*[\"']([^\"']*)/,\n );\n // If no matches return empty array\n if (!matches) {\n return [];\n }\n\n const names: string[] = [];\n // Default export\n if (matches[1]) {\n names.push('default');\n }\n\n // Imported or exported names\n if (matches[3]) {\n // Clean out the braces, whitespace, and get alias\n const namedImports = matches[3].matchAll(/([\\w$]+)(?:\\s+as\\s+[\\w$]+,?)?/g);\n for (const namedImport of namedImports) {\n names.push(namedImport[1]);\n }\n }\n\n // If there is a namespace export, push it to the names array\n if (matches[2]) {\n names.push('*');\n }\n\n return names;\n}\n"]}
1
+ {"version":3,"file":"parseNamedImports.js","sourceRoot":"","sources":["../src/parseNamedImports.ts"],"names":[],"mappings":"AAAA,MAAM,gBAAgB;AACpB,uEAAuE;AACvE,iFAAiF;AACjF,sFAAsF;AACtF,gFAAgF;AAChF,wCAAwC;AACxC,6FAA6F;AAC7F,mGAAmG;AACnG,2FAA2F;AAC3F,wGAAwG;AACxG,yGAAyG,CAAC;AAE5G;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAAkB;IAClD,IAAI,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAEjD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,IAAI,2BAA2B,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YACjD,uDAAuD;YACvD,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,6DAA6D;QAC7D,UAAU,GAAG,UAAU;YACrB,wEAAwE;aACvE,OAAO,CAAC,6BAA6B,EAAE,gBAAgB,CAAC;YACzD,mFAAmF;YACnF,mEAAmE;aAClE,UAAU,CAAC,SAAS,EAAE,EAAE,CAAC;aACzB,UAAU,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;QAEvC,YAAY;QACZ,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACf,iBAAiB;QACjB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACxB,CAAC;IAED,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACf,6BAA6B;QAC7B,uEAAuE;QACvE,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,gCAAgC,CAAC,CAAC;QAC3E,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACf,YAAY;QACZ,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["const namedImportRegex =\n // 1: maybe name for default (imports only): import foo from \"package\"\n // 2: maybe * part: import * as myModule from \"package\"\n // note that these can be combined: import foo, * as myModule from \"package\"\n // 3: maybe names: import { foo, bar } from \"package\"\n // (can be combined with 1 but not 2)\n // Matches of \\s in the middle of the string are non-greedy to reduce potential backtracking.\n // The { names } match is very crude (all possible characters in any order) to improve performance,\n // since we know the input is syntactically valid and we'll actually match the names later.\n // ( 1 ) ( 2 ) ( 3 ) from path\n /^\\s*[ie][mx]port\\s*?([\\w$]+)?\\s*?,?\\s*?(\\*(?:\\s*?as\\s+?[\\w$]+)?)?\\s*?(?:\\{([\\w$\\s,]*)\\})?\\s*from\\s*[\"']/;\n\n/**\n * Parses a JS import/export statement (from a path) into its component parts.\n * Does NOT handle typescript (`import/export type`), imports not from paths, exports without paths,\n * or anything that's not a syntactically valid import/export statement.\n *\n * The statement is expected to be copied verbatim from a source file, so there's a slight chance it\n * could contain comments embedded in the middle. This will try to remove the comments, but\n * accuracy is not guaranteed (especially for contrived scenarios like imports inside comments).\n *\n * @param importLine - The import string to parse.\n * @returns A string array with the named imports, `'default'` and/or `'*'`.\n * This will return the original names, not the imported names.\n */\nexport function parseNamedImports(importLine: string): string[] {\n let matches = importLine.match(namedImportRegex);\n\n if (!matches) {\n if (/^import\\s*?[\"'][^\"']*[\"']/.test(importLine)) {\n // This is a side effect import, so return empty array.\n return [];\n }\n\n // Maybe there are some embedded comments? Try removing them.\n importLine = importLine\n // Start by finding and removing the path to reduce chance of accidents.\n .replace(/\\bfrom\\s*([\"'])[^\"']*[\"'].*/, 'from \"removed\"')\n // Remove single-line and multi-line comments. This could behave badly in contrived\n // nesting scenarios, but should be reliable for more common cases.\n .replaceAll(/\\/\\/.*/g, '')\n .replaceAll(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n\n // Try again\n matches = importLine.match(namedImportRegex);\n if (!matches) {\n return [];\n }\n }\n\n const names: string[] = [];\n if (matches[1]) {\n // Default export\n names.push('default');\n }\n\n if (matches[3]) {\n // Imported or exported names\n // Clean out the whitespace, and get the original names not the aliases\n const namedImports = matches[3].matchAll(/([\\w$]+)(?:\\s+as\\s+[\\w$]+,?)?/g);\n for (const namedImport of namedImports) {\n names.push(namedImport[1]);\n }\n }\n\n if (matches[2]) {\n // All names\n names.push('*');\n }\n\n return names;\n}\n"]}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Removes hash segment from URL for comparison purposes.
3
+ *
4
+ * This function normalizes URLs by removing the hash segment (e.g., `/h-abc123/`)
5
+ * that appears after the package name and version. This is useful for comparing
6
+ * URLs that point to the same resource but with different hash values.
7
+ *
8
+ * The hash segment is used for cache-busting and content versioning. By removing it,
9
+ * we can check if two URLs refer to the same logical resource regardless of their
10
+ * specific hash values.
11
+ *
12
+ * @param url - URL to remove hash from
13
+ * @returns URL with hash segment removed, or original URL if no hash segment is found
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * // Remove hash from a URL
18
+ * removeHashFromUrl('http://localhost:3000/react@17.5.0/h-abc123/v0/bundled/index.js');
19
+ * // Returns: 'http://localhost:3000/react@17.5.0/v0/bundled/index.js'
20
+ *
21
+ * // URL without hash is returned unchanged
22
+ * removeHashFromUrl('http://localhost:3000/react@17.5.0/v0/bundled/index.js');
23
+ * // Returns: 'http://localhost:3000/react@17.5.0/v0/bundled/index.js'
24
+ *
25
+ * // Compare URLs with different hashes
26
+ * const url1 = 'http://localhost:3000/pkg@1.0.0/h-old/bundled/index.js';
27
+ * const url2 = 'http://localhost:3000/pkg@1.0.0/h-new/bundled/index.js';
28
+ * removeHashFromUrl(url1) === removeHashFromUrl(url2); // true
29
+ * ```
30
+ */
31
+ export declare function removeHashFromUrl(url: string): string;
32
+ //# sourceMappingURL=removeHashFromUrl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"removeHashFromUrl.d.ts","sourceRoot":"","sources":["../src/removeHashFromUrl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAerD"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Removes hash segment from URL for comparison purposes.
3
+ *
4
+ * This function normalizes URLs by removing the hash segment (e.g., `/h-abc123/`)
5
+ * that appears after the package name and version. This is useful for comparing
6
+ * URLs that point to the same resource but with different hash values.
7
+ *
8
+ * The hash segment is used for cache-busting and content versioning. By removing it,
9
+ * we can check if two URLs refer to the same logical resource regardless of their
10
+ * specific hash values.
11
+ *
12
+ * @param url - URL to remove hash from
13
+ * @returns URL with hash segment removed, or original URL if no hash segment is found
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * // Remove hash from a URL
18
+ * removeHashFromUrl('http://localhost:3000/react@17.5.0/h-abc123/v0/bundled/index.js');
19
+ * // Returns: 'http://localhost:3000/react@17.5.0/v0/bundled/index.js'
20
+ *
21
+ * // URL without hash is returned unchanged
22
+ * removeHashFromUrl('http://localhost:3000/react@17.5.0/v0/bundled/index.js');
23
+ * // Returns: 'http://localhost:3000/react@17.5.0/v0/bundled/index.js'
24
+ *
25
+ * // Compare URLs with different hashes
26
+ * const url1 = 'http://localhost:3000/pkg@1.0.0/h-old/bundled/index.js';
27
+ * const url2 = 'http://localhost:3000/pkg@1.0.0/h-new/bundled/index.js';
28
+ * removeHashFromUrl(url1) === removeHashFromUrl(url2); // true
29
+ * ```
30
+ */
31
+ export function removeHashFromUrl(url) {
32
+ // Find the start of the hash segment (e.g., '/h-abc123/')
33
+ const hashStart = url.indexOf('/h-');
34
+ if (hashStart === -1) {
35
+ return url;
36
+ }
37
+ // Find the end of the hash segment (the next '/' after '/h-')
38
+ const hashEnd = url.indexOf('/', hashStart + 1);
39
+ if (hashEnd === -1) {
40
+ return url;
41
+ }
42
+ // Remove the hash segment by concatenating everything before and after it
43
+ return url.slice(0, hashStart) + url.slice(hashEnd);
44
+ }
45
+ //# sourceMappingURL=removeHashFromUrl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"removeHashFromUrl.js","sourceRoot":"","sources":["../src/removeHashFromUrl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,0DAA0D;IAC1D,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACrC,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;QACrB,OAAO,GAAG,CAAC;IACb,CAAC;IAED,8DAA8D;IAC9D,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC;IAChD,IAAI,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC;QACnB,OAAO,GAAG,CAAC;IACb,CAAC;IAED,0EAA0E;IAC1E,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AACtD,CAAC","sourcesContent":["/**\n * Removes hash segment from URL for comparison purposes.\n *\n * This function normalizes URLs by removing the hash segment (e.g., `/h-abc123/`)\n * that appears after the package name and version. This is useful for comparing\n * URLs that point to the same resource but with different hash values.\n *\n * The hash segment is used for cache-busting and content versioning. By removing it,\n * we can check if two URLs refer to the same logical resource regardless of their\n * specific hash values.\n *\n * @param url - URL to remove hash from\n * @returns URL with hash segment removed, or original URL if no hash segment is found\n *\n * @example\n * ```ts\n * // Remove hash from a URL\n * removeHashFromUrl('http://localhost:3000/react@17.5.0/h-abc123/v0/bundled/index.js');\n * // Returns: 'http://localhost:3000/react@17.5.0/v0/bundled/index.js'\n *\n * // URL without hash is returned unchanged\n * removeHashFromUrl('http://localhost:3000/react@17.5.0/v0/bundled/index.js');\n * // Returns: 'http://localhost:3000/react@17.5.0/v0/bundled/index.js'\n *\n * // Compare URLs with different hashes\n * const url1 = 'http://localhost:3000/pkg@1.0.0/h-old/bundled/index.js';\n * const url2 = 'http://localhost:3000/pkg@1.0.0/h-new/bundled/index.js';\n * removeHashFromUrl(url1) === removeHashFromUrl(url2); // true\n * ```\n */\nexport function removeHashFromUrl(url: string): string {\n // Find the start of the hash segment (e.g., '/h-abc123/')\n const hashStart = url.indexOf('/h-');\n if (hashStart === -1) {\n return url;\n }\n\n // Find the end of the hash segment (the next '/' after '/h-')\n const hashEnd = url.indexOf('/', hashStart + 1);\n if (hashEnd === -1) {\n return url;\n }\n\n // Remove the hash segment by concatenating everything before and after it\n return url.slice(0, hashStart) + url.slice(hashEnd);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ms-cloudpack/path-string-parsing",
3
- "version": "1.2.6",
3
+ "version": "1.3.0",
4
4
  "description": "Common path-related string parsing utilities for Cloudpack",
5
5
  "license": "MIT",
6
6
  "type": "module",