@vltpkg/dep-id 0.0.0-3 → 0.0.0-31

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
@@ -2,11 +2,10 @@
2
2
 
3
3
  # @vltpkg/dep-id
4
4
 
5
- A library for serializing dependencies into terse string identifiers, and turning those serialized identifiers back into `Spec` objects.
5
+ A library for serializing dependencies into terse string identifiers,
6
+ and turning those serialized identifiers back into `Spec` objects.
6
7
 
7
- **[Usage](#usage)**
8
- ·
9
- **[Note](#note)**
8
+ **[Usage](#usage)** · **[Note](#note)**
10
9
 
11
10
  ## Usage
12
11
 
@@ -50,12 +49,12 @@ const spec = hydrate('git;github:a/b;branch', 'x') // x@github:a/b#branch
50
49
 
51
50
  ### Note
52
51
 
53
- multiple different spec/manifest combinations _can_ result
54
- in the same identifier. For example, the specifiers
55
- `x@npm:y@latest` and `asdf@npm:y@1.x` might both ultimately
56
- resolve to the same package, so they only need to appear in the
57
- store once.
52
+ multiple different spec/manifest combinations _can_ result in the same
53
+ identifier. For example, the specifiers `x@npm:y@latest` and
54
+ `asdf@npm:y@1.x` might both ultimately resolve to the same package, so
55
+ they only need to appear in the store once.
58
56
 
59
57
  ## BROWSER API
60
58
 
61
- An isomorphic API `@vltpkg/dep-id/browser` is provided for use in the browser.
59
+ An isomorphic API `@vltpkg/dep-id/browser` is provided for use in the
60
+ browser.
@@ -1,5 +1,6 @@
1
1
  import { Spec } from '@vltpkg/spec/browser';
2
2
  import type { SpecOptions } from '@vltpkg/spec/browser';
3
+ import type { Manifest } from '@vltpkg/types';
3
4
  export declare const delimiter: Delimiter;
4
5
  export type Delimiter = '·';
5
6
  /**
@@ -52,6 +53,11 @@ export declare const joinDepIDTuple: (list: DepIDTuple) => DepID;
52
53
  * turn a {@link DepID} into a {@link DepIDTuple}
53
54
  */
54
55
  export declare const splitDepID: (id: string) => DepIDTuple;
56
+ /**
57
+ * Retrieves the base {@link DepID} for a given depID,
58
+ * ignoring any extra information that may be present.
59
+ */
60
+ export declare const baseDepID: (id: string) => DepID;
55
61
  /**
56
62
  * Turn a {@link DepID} into a {@link Spec} object
57
63
  */
@@ -60,4 +66,28 @@ export declare const hydrate: (id: DepID, name?: string, options?: SpecOptions)
60
66
  * Turn a {@link DepIDTuple} into a {@link Spec} object
61
67
  */
62
68
  export declare const hydrateTuple: (tuple: DepIDTuple, name?: string, options?: SpecOptions) => Spec;
69
+ /**
70
+ * Get the {@link DepIDTuple} for a given {@link Spec} and {@link Manifest}.
71
+ * The Manifest is used to get the name and version, if possible. If not found
72
+ * in the manifest, registry ID types will use the name or bareSpec from the
73
+ * specifier, so at least there's something to use later.
74
+ */
75
+ export declare const getTuple: (spec: Spec, mani: Pick<Manifest, "name" | "version">, extra?: string) => DepIDTuple;
76
+ /**
77
+ * Checks for a potentially manifest-confused package name.
78
+ * Returns `true` if the package name is confused, `false` otherwise.
79
+ */
80
+ export declare const isPackageNameConfused: (spec?: Spec, name?: string) => boolean;
81
+ /**
82
+ * Get the {@link DepID} for a given {@link Spec} and {@link Manifest}. The
83
+ * Manifest is used to get the name and version, if possible. If not found in
84
+ * the manifest, registry ID types will use the name or bareSpec from the
85
+ * specifier, so at least there's something to use later.
86
+ */
87
+ export declare const getId: (spec: Spec, mani: Pick<Manifest, "name" | "version">, extra?: string) => DepID;
88
+ /**
89
+ * Reset internal caches. This should be used when options change since
90
+ * they're not take into account in the memoization keys.
91
+ */
92
+ export declare const resetCaches: () => void;
63
93
  //# sourceMappingURL=browser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/browser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAEvD,eAAO,MAAM,SAAS,EAAE,SAAe,CAAA;AACvC,MAAM,MAAM,SAAS,GAAG,GAAG,CAAA;AAE3B;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,MAAM,KAAK,GACb,GAAG,EAAE,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,GAC9E,GAAG,EAAE,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,GACzD,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,GAC9E,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,EAAE,CAAA;AAE7D;;GAEG;AACH,MAAM,MAAM,UAAU,GAClB;IACE,IAAI,EAAE,KAAK;IACX,SAAS,EAAE,MAAM;IACjB,WAAW,EAAE,MAAM;IACnB,KAAK,CAAC,EAAE,MAAM;CACf,GACD;IACE,IAAI,EAAE,UAAU;IAChB,QAAQ,EAAE,MAAM;IAChB,YAAY,EAAE,MAAM;IACpB,KAAK,CAAC,EAAE,MAAM;CACf,GACD,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,GAC5C,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,GAC7C,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,CAAA;AAY1D,eAAO,MAAM,OAAO,QAAS,OAAO,KAAG,GAAG,IAAI,KACI,CAAA;AAElD,eAAO,MAAM,OAAO,QAAS,MAAM,KAAG,KAOrC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,SAAU,UAAU,KAAG,KAWjD,CAAA;AASD;;GAEG;AACH,eAAO,MAAM,UAAU,OAAQ,MAAM,KAAG,UAiCvC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,OAAO,OACd,KAAK,SACF,MAAM,YACJ,WAAW,KACnB,IAAmD,CAAA;AAEtD;;GAEG;AACH,eAAO,MAAM,YAAY,UAChB,UAAU,SACV,MAAM,YACJ,WAAW,SAmFrB,CAAA"}
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/browser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAE7C,eAAO,MAAM,SAAS,EAAE,SAAe,CAAA;AACvC,MAAM,MAAM,SAAS,GAAG,GAAG,CAAA;AAE3B;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,MAAM,KAAK,GACb,GAAG,EAAE,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,GAC9E,GAAG,EAAE,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,GACzD,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,GAC9E,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,EAAE,CAAA;AAE7D;;GAEG;AACH,MAAM,MAAM,UAAU,GAClB;IACE,IAAI,EAAE,KAAK;IACX,SAAS,EAAE,MAAM;IACjB,WAAW,EAAE,MAAM;IACnB,KAAK,CAAC,EAAE,MAAM;CACf,GACD;IACE,IAAI,EAAE,UAAU;IAChB,QAAQ,EAAE,MAAM;IAChB,YAAY,EAAE,MAAM;IACpB,KAAK,CAAC,EAAE,MAAM;CACf,GACD,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,GAC5C,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,GAC7C,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,CAAA;AAY1D,eAAO,MAAM,OAAO,QAAS,OAAO,KAAG,GAAG,IAAI,KACI,CAAA;AAElD,eAAO,MAAM,OAAO,QAAS,MAAM,KAAG,KAOrC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,SAAU,UAAU,KAAG,KAWjD,CAAA;AAmBD;;GAEG;AACH,eAAO,MAAM,UAAU,OAAQ,MAAM,KAAG,UAuCvC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,SAAS,OAAQ,MAAM,KAAG,KAStC,CAAA;AAGD;;GAEG;AACH,eAAO,MAAM,OAAO,OACd,KAAK,SACF,MAAM,YACJ,WAAW,KACnB,IASF,CAAA;AAGD;;GAEG;AACH,eAAO,MAAM,YAAY,UAChB,UAAU,SACV,MAAM,YACJ,WAAW,SAqGrB,CAAA;AAaD;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,SACb,IAAI,QACJ,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC,UAChC,MAAM,KACb,UAgFF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,UAAW,IAAI,SAAS,MAAM,YAI5C,CAAA;AAEpB;;;;;GAKG;AACH,eAAO,MAAM,KAAK,SACV,IAAI,QACJ,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC,UAChC,MAAM,KACb,KAAoD,CAAA;AAEvD;;;GAGG;AACH,eAAO,MAAM,WAAW,YAKvB,CAAA"}
@@ -29,14 +29,25 @@ export const joinDepIDTuple = (list) => {
29
29
  }
30
30
  };
31
31
  // allow @, but otherwise, escape everything urls do
32
- const encode = (s) => encodeURIComponent(s)
33
- .replaceAll('%40', '@')
34
- .replaceAll('%2f', '§')
35
- .replaceAll('%2F', '§');
32
+ const encode = (s) => s ?
33
+ encodeURIComponent(s)
34
+ .replaceAll('%40', '@')
35
+ .replaceAll('%2f', '§')
36
+ .replaceAll('%2F', '§')
37
+ : s;
38
+ const decode = (s) => s ?
39
+ decodeURIComponent(s.replaceAll('@', '%40').replaceAll('§', '%2F'))
40
+ : s;
41
+ const seenSplitDepIDs = new Map();
36
42
  /**
37
43
  * turn a {@link DepID} into a {@link DepIDTuple}
38
44
  */
39
45
  export const splitDepID = (id) => {
46
+ // memoized entries return early
47
+ const seen = seenSplitDepIDs.get(id);
48
+ if (seen)
49
+ return seen;
50
+ let res;
40
51
  const [type, first = '', second, extra] = id
41
52
  .replaceAll('§', '/')
42
53
  .split(delimiter, 4);
@@ -47,22 +58,19 @@ export const splitDepID = (id) => {
47
58
  if (second === undefined) {
48
59
  throw error(`invalid ${type} id`, { found: id });
49
60
  }
50
- const t = [
61
+ res = [
51
62
  type || 'registry',
52
63
  f,
53
64
  decodeURIComponent(second),
65
+ decode(extra),
54
66
  ];
55
- if (extra)
56
- t.push(decodeURIComponent(extra));
57
- return t;
67
+ break;
58
68
  }
59
69
  case 'file':
60
70
  case 'remote':
61
71
  case 'workspace': {
62
- const t = [type, f];
63
- if (second)
64
- t.push(decodeURIComponent(second));
65
- return t;
72
+ res = [type, f, decode(second)];
73
+ break;
66
74
  }
67
75
  default: {
68
76
  throw error('invalid DepID type', {
@@ -71,23 +79,57 @@ export const splitDepID = (id) => {
71
79
  });
72
80
  }
73
81
  }
82
+ seenSplitDepIDs.set(id, res);
83
+ return res;
74
84
  };
85
+ /**
86
+ * Retrieves the base {@link DepID} for a given depID,
87
+ * ignoring any extra information that may be present.
88
+ */
89
+ export const baseDepID = (id) => {
90
+ const [type, first, second] = splitDepID(id);
91
+ switch (type) {
92
+ case 'git':
93
+ case 'registry':
94
+ return joinDepIDTuple([type, first, second]);
95
+ default:
96
+ return joinDepIDTuple([type, first]);
97
+ }
98
+ };
99
+ const seenHydrated = new Map();
75
100
  /**
76
101
  * Turn a {@link DepID} into a {@link Spec} object
77
102
  */
78
- export const hydrate = (id, name, options = {}) => hydrateTuple(splitDepID(id), name, options);
103
+ export const hydrate = (id, name, options = {}) => {
104
+ // memozied entries return early
105
+ const cacheKey = (name ?? '') + id;
106
+ const seen = seenHydrated.get(cacheKey);
107
+ if (seen)
108
+ return seen;
109
+ const res = hydrateTuple(splitDepID(id), name, options);
110
+ seenHydrated.set(cacheKey, res);
111
+ return res;
112
+ };
113
+ const seenHydratedTuples = new Map();
79
114
  /**
80
115
  * Turn a {@link DepIDTuple} into a {@link Spec} object
81
116
  */
82
117
  export const hydrateTuple = (tuple, name, options = {}) => {
83
118
  const [type, first, second] = tuple;
119
+ // memoized entries return early
120
+ const cacheKey = (name ?? '') + type + first + (second ?? '');
121
+ const seen = seenHydratedTuples.get(cacheKey);
122
+ if (seen)
123
+ return seen;
124
+ let res;
84
125
  switch (type) {
85
126
  case 'remote': {
86
127
  if (!first)
87
128
  throw error('no remoteURL found on remote id', {
88
129
  found: tuple,
89
130
  });
90
- return Spec.parse(name ?? '(unknown)', first);
131
+ res = Spec.parse(name ?? '(unknown)', first, options);
132
+ break;
91
133
  }
92
134
  case 'file': {
93
135
  if (!first) {
@@ -95,7 +137,8 @@ export const hydrateTuple = (tuple, name, options = {}) => {
95
137
  found: tuple,
96
138
  });
97
139
  }
98
- return Spec.parse(name ?? '(unknown)', `file:${first}`, options);
140
+ res = Spec.parse(name ?? '(unknown)', `file:${first}`, options);
141
+ break;
99
142
  }
100
143
  case 'registry': {
101
144
  if (typeof first !== 'string') {
@@ -110,13 +153,14 @@ export const hydrateTuple = (tuple, name, options = {}) => {
110
153
  }
111
154
  if (!first) {
112
155
  // just a normal name@version on the default registry
113
- const s = Spec.parse(second);
156
+ const s = Spec.parseArgs(second, options);
114
157
  if (name && s.name !== name) {
115
- return Spec.parse(`${name}@npm:${second}`);
158
+ res = Spec.parse(name, `npm:${second}`, options);
116
159
  }
117
160
  else {
118
- return s;
161
+ res = s;
119
162
  }
163
+ break;
120
164
  }
121
165
  if (!/^https?:\/\//.test(first)) {
122
166
  const reg = options.registries?.[first];
@@ -126,12 +170,15 @@ export const hydrateTuple = (tuple, name, options = {}) => {
126
170
  found: tuple,
127
171
  });
128
172
  }
129
- return Spec.parse(name ?? '(unknown)', `${first}:${second}`, options);
173
+ res = Spec.parse(name ?? '(unknown)', `${first}:${second}`, options);
174
+ break;
130
175
  }
131
176
  const s = Spec.parse(name ?? '(unknown)', `registry:${first}#${second}`, options);
132
- return name && s.final.name !== name ?
133
- Spec.parse(s.final.name + '@' + s.bareSpec)
134
- : s;
177
+ res =
178
+ name && s.final.name !== name ?
179
+ Spec.parse(s.final.name, s.bareSpec, options)
180
+ : s;
181
+ break;
135
182
  }
136
183
  case 'git': {
137
184
  if (!first) {
@@ -139,16 +186,132 @@ export const hydrateTuple = (tuple, name, options = {}) => {
139
186
  found: tuple,
140
187
  });
141
188
  }
142
- return Spec.parse(name ?? '(unknown)', first + '#' + second, options);
189
+ res = Spec.parse(name ?? '(unknown)', first + '#' + second, options);
190
+ break;
143
191
  }
144
192
  case 'workspace': {
145
193
  if (!first) {
146
194
  throw error('no name/path on workspace id', { found: tuple });
147
195
  }
148
- return name && name !== first ?
149
- Spec.parse(name, `workspace:${first}@*`, options)
150
- : Spec.parse(first, `workspace:*`, options);
196
+ res =
197
+ name && name !== first ?
198
+ Spec.parse(name, `workspace:${first}@*`, options)
199
+ : Spec.parse(first, `workspace:*`, options);
200
+ break;
201
+ }
202
+ }
203
+ seenHydratedTuples.set(cacheKey, res);
204
+ return res;
205
+ };
206
+ // Strip out the default registry, there's no need to store that
207
+ const omitDefReg = (s) => (!s ||
208
+ s === 'https://registry.npmjs.org' ||
209
+ s === 'https://registry.npmjs.org/') ?
210
+ ''
211
+ : s;
212
+ const seenTuples = new Map();
213
+ /**
214
+ * Get the {@link DepIDTuple} for a given {@link Spec} and {@link Manifest}.
215
+ * The Manifest is used to get the name and version, if possible. If not found
216
+ * in the manifest, registry ID types will use the name or bareSpec from the
217
+ * specifier, so at least there's something to use later.
218
+ */
219
+ export const getTuple = (spec, mani, extra) => {
220
+ // memoized entries return early
221
+ const cacheKey = String(spec) +
222
+ (mani.name ?? '') +
223
+ (mani.version ?? '') +
224
+ (extra ?? '');
225
+ const seen = seenTuples.get(cacheKey);
226
+ if (seen)
227
+ return seen;
228
+ let res;
229
+ const f = spec.final;
230
+ switch (f.type) {
231
+ case 'registry': {
232
+ // try to shorten to a known name if we can.
233
+ const reg = omitDefReg(f.registry);
234
+ if (!f.namedRegistry && reg) {
235
+ for (const [alias, host] of Object.entries(spec.options.registries)) {
236
+ if (reg === host) {
237
+ f.namedRegistry = alias;
238
+ break;
239
+ }
240
+ }
241
+ }
242
+ const version = mani.version ?
243
+ mani.version.startsWith('v') ?
244
+ mani.version.slice(1)
245
+ : mani.version
246
+ : f.bareSpec;
247
+ res = [
248
+ f.type,
249
+ f.namedRegistry ?? reg,
250
+ `${isPackageNameConfused(spec, mani.name) ? spec.name : (mani.name ?? f.name)}@${version}`,
251
+ extra,
252
+ ];
253
+ break;
254
+ }
255
+ case 'git': {
256
+ const { namedGitHost, namedGitHostPath, gitRemote, gitSelector = '', } = f;
257
+ if (!gitRemote)
258
+ throw error('no host on git specifier', { spec });
259
+ if (namedGitHost) {
260
+ if (!namedGitHostPath) {
261
+ throw error('named git host without path portion', {
262
+ spec,
263
+ });
264
+ }
265
+ res = [
266
+ f.type,
267
+ `${namedGitHost}:${namedGitHostPath}`,
268
+ gitSelector,
269
+ extra,
270
+ ];
271
+ break;
272
+ }
273
+ else {
274
+ res = [f.type, gitRemote, gitSelector, extra];
275
+ }
276
+ break;
277
+ }
278
+ case 'remote': {
279
+ const { remoteURL } = f;
280
+ if (!remoteURL)
281
+ throw error('no URL on remote specifier', { spec });
282
+ res = [f.type, remoteURL, extra];
283
+ break;
151
284
  }
285
+ case 'file':
286
+ case 'workspace':
287
+ throw error('Path-based dep ids are not supported', { spec });
152
288
  }
289
+ seenTuples.set(cacheKey, res);
290
+ return res;
291
+ };
292
+ /**
293
+ * Checks for a potentially manifest-confused package name.
294
+ * Returns `true` if the package name is confused, `false` otherwise.
295
+ */
296
+ export const isPackageNameConfused = (spec, name) => !!spec?.name && // a nameless spec can't be checked
297
+ !spec.subspec && // it's not an aliased package or using a custom protocol
298
+ spec.type === 'registry' && // the defined spec is of type registry
299
+ spec.name !== name; // its name is not the same as the defined spec name
300
+ /**
301
+ * Get the {@link DepID} for a given {@link Spec} and {@link Manifest}. The
302
+ * Manifest is used to get the name and version, if possible. If not found in
303
+ * the manifest, registry ID types will use the name or bareSpec from the
304
+ * specifier, so at least there's something to use later.
305
+ */
306
+ export const getId = (spec, mani, extra) => joinDepIDTuple(getTuple(spec, mani, extra));
307
+ /**
308
+ * Reset internal caches. This should be used when options change since
309
+ * they're not take into account in the memoization keys.
310
+ */
311
+ export const resetCaches = () => {
312
+ seenHydrated.clear();
313
+ seenHydratedTuples.clear();
314
+ seenSplitDepIDs.clear();
315
+ seenTuples.clear();
153
316
  };
154
317
  //# sourceMappingURL=browser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/browser.ts"],"names":[],"mappings":"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","sourcesContent":["import { error } from '@vltpkg/error-cause'\nimport { Spec } from '@vltpkg/spec/browser'\nimport type { SpecOptions } from '@vltpkg/spec/browser'\n\nexport const delimiter: Delimiter = '·'\nexport type Delimiter = '·'\n\n/**\n * Dependency IDs are a URI-encoded set of strings, separated\n * by the {@link Delimiter} character (`'·'`).\n *\n * The first entry is always the specifier type. The rest depend on the\n * type. `git`, `registry`, and `workspace` entries have 3 fields, the rest\n * have 2.\n *\n * - `registry`: `'registry·<registry>·name@specifier'`\n * The `<registry>` portion can be a known named registry name, or a\n * url to a registry. If empty, it is the default registry. Examples:\n * - `··some-package@2.0.1`\n * - `·npm·whatever@1.2.3`\n * - `·http%3A%2F%2Fvlt.sh%2F·x@1.2.3`\n * - `git`: `'git·<git remote>·<git selector>'`. For example:\n * - `git·github:user/project·branchname`\n * - `git·git%2Bssh%3A%2F%2Fuser%40host%3Aproject.git·semver:1.x`\n * - `workspace`: `'workspace·<path>'`. For example:\n * - `workspace·src/mything`\n * - `remote`: `'remote·<url>'`\n * - `file`: `'file·<path>'`\n *\n * Lastly, the final portion can contain arbitrary string data, and is\n * used to store peer dep resolutions to maintain the peerDep contract.\n */\nexport type DepID =\n | `${'' | 'git'}${Delimiter}${string}${Delimiter}${string}${Delimiter}${string}`\n | `${'' | 'git'}${Delimiter}${string}${Delimiter}${string}`\n | `${'file' | 'remote' | 'workspace'}${Delimiter}${string}${Delimiter}${string}`\n | `${'file' | 'remote' | 'workspace'}${Delimiter}${string}`\n\n/**\n * A {@link DepID}, split apart and URI-decoded\n */\nexport type DepIDTuple =\n | [\n type: 'git',\n gitRemote: string,\n gitSelector: string,\n extra?: string,\n ]\n | [\n type: 'registry',\n registry: string,\n registrySpec: string,\n extra?: string,\n ]\n | [type: 'file', path: string, extra?: string]\n | [type: 'remote', url: string, extra?: string]\n | [type: 'workspace', workspace: string, extra?: string]\n\nconst depIDRegExp = new RegExp(\n `^((git)?${delimiter}[^${delimiter}]*${delimiter}[^${delimiter}]*(${\n delimiter\n }[^${delimiter}]*)?$` +\n `|` +\n `^(file|remote|workspace)${delimiter}[^${\n delimiter\n }]*)(${delimiter}[^${delimiter}]*)?$`,\n)\n\nexport const isDepID = (str: unknown): str is DepID =>\n typeof str === 'string' && depIDRegExp.test(str)\n\nexport const asDepID = (str: string): DepID => {\n if (!isDepID(str)) {\n throw error('Expected dep id', {\n found: str,\n })\n }\n return str\n}\n\n/**\n * turn a {@link DepIDTuple} into a {@link DepID}\n */\nexport const joinDepIDTuple = (list: DepIDTuple): DepID => {\n const [type, first, second, extra] = list\n const f = encode(first)\n switch (type) {\n case 'registry':\n return `${delimiter}${f}${delimiter}${encode(second)}${extra ? `${delimiter}${encode(extra)}` : ''}`\n case 'git':\n return `${type}${delimiter}${f}${delimiter}${encode(second)}${extra ? `${delimiter}${encode(extra)}` : ''}`\n default:\n return `${type}${delimiter}${f}${second ? `${delimiter}${encode(second)}` : ''}`\n }\n}\n\n// allow @, but otherwise, escape everything urls do\nconst encode = (s: string): string =>\n encodeURIComponent(s)\n .replaceAll('%40', '@')\n .replaceAll('%2f', '§')\n .replaceAll('%2F', '§')\n\n/**\n * turn a {@link DepID} into a {@link DepIDTuple}\n */\nexport const splitDepID = (id: string): DepIDTuple => {\n const [type, first = '', second, extra] = id\n .replaceAll('§', '/')\n .split(delimiter, 4)\n const f = decodeURIComponent(first)\n switch (type) {\n case 'git':\n case '': {\n if (second === undefined) {\n throw error(`invalid ${type} id`, { found: id })\n }\n const t: DepIDTuple = [\n type || 'registry',\n f,\n decodeURIComponent(second),\n ]\n if (extra) t.push(decodeURIComponent(extra))\n return t\n }\n case 'file':\n case 'remote':\n case 'workspace': {\n const t: DepIDTuple = [type, f]\n if (second) t.push(decodeURIComponent(second))\n return t\n }\n default: {\n throw error('invalid DepID type', {\n found: type,\n validOptions: ['git', 'file', 'workspace', 'remote', ''],\n })\n }\n }\n}\n\n/**\n * Turn a {@link DepID} into a {@link Spec} object\n */\nexport const hydrate = (\n id: DepID,\n name?: string,\n options: SpecOptions = {},\n): Spec => hydrateTuple(splitDepID(id), name, options)\n\n/**\n * Turn a {@link DepIDTuple} into a {@link Spec} object\n */\nexport const hydrateTuple = (\n tuple: DepIDTuple,\n name?: string,\n options: SpecOptions = {},\n) => {\n const [type, first, second] = tuple\n switch (type) {\n case 'remote': {\n if (!first)\n throw error('no remoteURL found on remote id', {\n found: tuple,\n })\n return Spec.parse(name ?? '(unknown)', first)\n }\n case 'file': {\n if (!first) {\n throw error('no file path found on remote id', {\n found: tuple,\n })\n }\n return Spec.parse(name ?? '(unknown)', `file:${first}`, options)\n }\n case 'registry': {\n if (typeof first !== 'string') {\n throw error('no registry url or name in registry ID', {\n found: tuple,\n })\n }\n if (!second) {\n throw error('no name/specifier in registry ID', {\n found: tuple,\n })\n }\n if (!first) {\n // just a normal name@version on the default registry\n const s = Spec.parse(second)\n if (name && s.name !== name) {\n return Spec.parse(`${name}@npm:${second}`)\n } else {\n return s\n }\n }\n if (!/^https?:\\/\\//.test(first)) {\n const reg = options.registries?.[first]\n if (first !== 'npm' && !reg) {\n throw error('named registry not found in options', {\n name: first,\n found: tuple,\n })\n }\n return Spec.parse(\n name ?? '(unknown)',\n `${first}:${second}`,\n options,\n )\n }\n const s = Spec.parse(\n name ?? '(unknown)',\n `registry:${first}#${second}`,\n options,\n )\n return name && s.final.name !== name ?\n Spec.parse(s.final.name + '@' + s.bareSpec)\n : s\n }\n case 'git': {\n if (!first) {\n throw error('no git remote in git ID', {\n found: tuple,\n })\n }\n return Spec.parse(\n name ?? '(unknown)',\n first + '#' + second,\n options,\n )\n }\n case 'workspace': {\n if (!first) {\n throw error('no name/path on workspace id', { found: tuple })\n }\n return name && name !== first ?\n Spec.parse(name, `workspace:${first}@*`, options)\n : Spec.parse(first, `workspace:*`, options)\n }\n }\n}\n"]}
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAI3C,MAAM,CAAC,MAAM,SAAS,GAAc,GAAG,CAAA;AAsDvC,MAAM,WAAW,GAAG,IAAI,MAAM,CAC5B,WAAW,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,SAAS,MAC5D,SACF,KAAK,SAAS,OAAO;IACnB,GAAG;IACH,2BAA2B,SAAS,KAClC,SACF,OAAO,SAAS,KAAK,SAAS,OAAO,CACxC,CAAA;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAY,EAAgB,EAAE,CACpD,OAAO,GAAG,KAAK,QAAQ,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAElD,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAW,EAAS,EAAE;IAC5C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAClB,MAAM,KAAK,CAAC,iBAAiB,EAAE;YAC7B,KAAK,EAAE,GAAG;SACX,CAAC,CAAA;IACJ,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAgB,EAAS,EAAE;IACxD,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG,IAAI,CAAA;IACzC,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IACvB,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,UAAU;YACb,OAAO,GAAG,SAAS,GAAG,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;QACtG,KAAK,KAAK;YACR,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;QAC7G;YACE,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;IACpF,CAAC;AACH,CAAC,CAAA;AAED,oDAAoD;AACpD,MAAM,MAAM,GAAG,CAAC,CAAU,EAAE,EAAE,CAC5B,CAAC,CAAC,CAAC;IACD,kBAAkB,CAAC,CAAC,CAAC;SAClB,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC;SACtB,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC;SACtB,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC;IAC3B,CAAC,CAAC,CAAC,CAAA;AAEL,MAAM,MAAM,GAAG,CAAC,CAAU,EAAE,EAAE,CAC5B,CAAC,CAAC,CAAC;IACD,kBAAkB,CAChB,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAChD;IACH,CAAC,CAAC,CAAC,CAAA;AAEL,MAAM,eAAe,GAAG,IAAI,GAAG,EAAsB,CAAA;AACrD;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,EAAU,EAAc,EAAE;IACnD,gCAAgC;IAChC,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACpC,IAAI,IAAI;QAAE,OAAO,IAAI,CAAA;IAErB,IAAI,GAAe,CAAA;IACnB,MAAM,CAAC,IAAI,EAAE,KAAK,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG,EAAE;SACzC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC;SACpB,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAA;IACtB,MAAM,CAAC,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAA;IACnC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,KAAK,CAAC;QACX,KAAK,EAAE,CAAC,CAAC,CAAC;YACR,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM,KAAK,CAAC,WAAW,IAAI,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAA;YAClD,CAAC;YACD,GAAG,GAAG;gBACJ,IAAI,IAAI,UAAU;gBAClB,CAAC;gBACD,kBAAkB,CAAC,MAAM,CAAC;gBAC1B,MAAM,CAAC,KAAK,CAAC;aACd,CAAA;YACD,MAAK;QACP,CAAC;QACD,KAAK,MAAM,CAAC;QACZ,KAAK,QAAQ,CAAC;QACd,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;YAC/B,MAAK;QACP,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,KAAK,CAAC,oBAAoB,EAAE;gBAChC,KAAK,EAAE,IAAI;gBACX,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,CAAC;aACzD,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IACD,eAAe,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;IAC5B,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,EAAU,EAAS,EAAE;IAC7C,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,UAAU,CAAC,EAAE,CAAC,CAAA;IAC5C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,KAAK,CAAC;QACX,KAAK,UAAU;YACb,OAAO,cAAc,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAA;QAC9C;YACE,OAAO,cAAc,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAA;IACxC,CAAC;AACH,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,IAAI,GAAG,EAAgB,CAAA;AAC5C;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,EAAS,EACT,IAAa,EACb,UAAuB,EAAE,EACnB,EAAE;IACR,gCAAgC;IAChC,MAAM,QAAQ,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,GAAG,EAAE,CAAA;IAClC,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACvC,IAAI,IAAI;QAAE,OAAO,IAAI,CAAA;IAErB,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IACvD,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;IAC/B,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA;AAED,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAgB,CAAA;AAClD;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,KAAiB,EACjB,IAAa,EACb,UAAuB,EAAE,EACzB,EAAE;IACF,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,KAAK,CAAA;IAEnC,gCAAgC;IAChC,MAAM,QAAQ,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,GAAG,IAAI,GAAG,KAAK,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAA;IAC7D,MAAM,IAAI,GAAG,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC7C,IAAI,IAAI;QAAE,OAAO,IAAI,CAAA;IAErB,IAAI,GAAS,CAAA;IACb,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,IAAI,CAAC,KAAK;gBACR,MAAM,KAAK,CAAC,iCAAiC,EAAE;oBAC7C,KAAK,EAAE,KAAK;iBACb,CAAC,CAAA;YACJ,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;YACrD,MAAK;QACP,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,KAAK,CAAC,iCAAiC,EAAE;oBAC7C,KAAK,EAAE,KAAK;iBACb,CAAC,CAAA;YACJ,CAAC;YACD,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,WAAW,EAAE,QAAQ,KAAK,EAAE,EAAE,OAAO,CAAC,CAAA;YAC/D,MAAK;QACP,CAAC;QACD,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9B,MAAM,KAAK,CAAC,wCAAwC,EAAE;oBACpD,KAAK,EAAE,KAAK;iBACb,CAAC,CAAA;YACJ,CAAC;YACD,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,KAAK,CAAC,kCAAkC,EAAE;oBAC9C,KAAK,EAAE,KAAK;iBACb,CAAC,CAAA;YACJ,CAAC;YACD,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,qDAAqD;gBACrD,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;gBACzC,IAAI,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;oBAC5B,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,MAAM,EAAE,EAAE,OAAO,CAAC,CAAA;gBAClD,CAAC;qBAAM,CAAC;oBACN,GAAG,GAAG,CAAC,CAAA;gBACT,CAAC;gBACD,MAAK;YACP,CAAC;YACD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAChC,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAA;gBACvC,IAAI,KAAK,KAAK,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC;oBAC5B,MAAM,KAAK,CAAC,qCAAqC,EAAE;wBACjD,IAAI,EAAE,KAAK;wBACX,KAAK,EAAE,KAAK;qBACb,CAAC,CAAA;gBACJ,CAAC;gBACD,GAAG,GAAG,IAAI,CAAC,KAAK,CACd,IAAI,IAAI,WAAW,EACnB,GAAG,KAAK,IAAI,MAAM,EAAE,EACpB,OAAO,CACR,CAAA;gBACD,MAAK;YACP,CAAC;YACD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAClB,IAAI,IAAI,WAAW,EACnB,YAAY,KAAK,IAAI,MAAM,EAAE,EAC7B,OAAO,CACR,CAAA;YACD,GAAG;gBACD,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;oBAC7B,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC;oBAC/C,CAAC,CAAC,CAAC,CAAA;YACL,MAAK;QACP,CAAC;QACD,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,KAAK,CAAC,yBAAyB,EAAE;oBACrC,KAAK,EAAE,KAAK;iBACb,CAAC,CAAA;YACJ,CAAC;YACD,GAAG,GAAG,IAAI,CAAC,KAAK,CACd,IAAI,IAAI,WAAW,EACnB,KAAK,GAAG,GAAG,GAAG,MAAM,EACpB,OAAO,CACR,CAAA;YACD,MAAK;QACP,CAAC;QACD,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,KAAK,CAAC,8BAA8B,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAA;YAC/D,CAAC;YACD,GAAG;gBACD,IAAI,IAAI,IAAI,KAAK,KAAK,CAAC,CAAC;oBACtB,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,EAAE,OAAO,CAAC;oBACnD,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,CAAC,CAAA;YAC7C,MAAK;QACP,CAAC;IACH,CAAC;IACD,kBAAkB,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;IACrC,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA;AAED,gEAAgE;AAChE,MAAM,UAAU,GAAG,CAAC,CAAU,EAAU,EAAE,CACxC,CACE,CAAC,CAAC;IACF,CAAC,KAAK,4BAA4B;IAClC,CAAC,KAAK,6BAA6B,CACpC,CAAC,CAAC;IACD,EAAE;IACJ,CAAC,CAAC,CAAC,CAAA;AAEL,MAAM,UAAU,GAAG,IAAI,GAAG,EAAsB,CAAA;AAChD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,IAAU,EACV,IAAwC,EACxC,KAAc,EACF,EAAE;IACd,gCAAgC;IAChC,MAAM,QAAQ,GACZ,MAAM,CAAC,IAAI,CAAC;QACZ,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;QACjB,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;QACpB,CAAC,KAAK,IAAI,EAAE,CAAC,CAAA;IACf,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACrC,IAAI,IAAI;QAAE,OAAO,IAAI,CAAA;IAErB,IAAI,GAAe,CAAA;IACnB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAA;IACpB,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,4CAA4C;YAC5C,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;YAClC,IAAI,CAAC,CAAC,CAAC,aAAa,IAAI,GAAG,EAAE,CAAC;gBAC5B,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CACxC,IAAI,CAAC,OAAO,CAAC,UAAU,CACxB,EAAE,CAAC;oBACF,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;wBACjB,CAAC,CAAC,aAAa,GAAG,KAAK,CAAA;wBACvB,MAAK;oBACP,CAAC;gBACH,CAAC;YACH,CAAC;YACD,MAAM,OAAO,GACX,IAAI,CAAC,OAAO,CAAC,CAAC;gBACZ,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;oBAC5B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;oBACvB,CAAC,CAAC,IAAI,CAAC,OAAO;gBAChB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;YACd,GAAG,GAAG;gBACJ,CAAC,CAAC,IAAI;gBACN,CAAC,CAAC,aAAa,IAAI,GAAG;gBACtB,GAAG,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,OAAO,EAAE;gBAC1F,KAAK;aACN,CAAA;YACD,MAAK;QACP,CAAC;QACD,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,MAAM,EACJ,YAAY,EACZ,gBAAgB,EAChB,SAAS,EACT,WAAW,GAAG,EAAE,GACjB,GAAG,CAAC,CAAA;YACL,IAAI,CAAC,SAAS;gBACZ,MAAM,KAAK,CAAC,0BAA0B,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;YACnD,IAAI,YAAY,EAAE,CAAC;gBACjB,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACtB,MAAM,KAAK,CAAC,qCAAqC,EAAE;wBACjD,IAAI;qBACL,CAAC,CAAA;gBACJ,CAAC;gBACD,GAAG,GAAG;oBACJ,CAAC,CAAC,IAAI;oBACN,GAAG,YAAY,IAAI,gBAAgB,EAAE;oBACrC,WAAW;oBACX,KAAK;iBACN,CAAA;gBACD,MAAK;YACP,CAAC;iBAAM,CAAC;gBACN,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,CAAA;YAC/C,CAAC;YACD,MAAK;QACP,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,CAAA;YACvB,IAAI,CAAC,SAAS;gBACZ,MAAM,KAAK,CAAC,4BAA4B,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;YACrD,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,CAAA;YAChC,MAAK;QACP,CAAC;QACD,KAAK,MAAM,CAAC;QACZ,KAAK,WAAW;YACd,MAAM,KAAK,CAAC,sCAAsC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;IACjE,CAAC;IACD,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;IAC7B,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,IAAW,EAAE,IAAa,EAAE,EAAE,CAClE,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,mCAAmC;IACnD,CAAC,IAAI,CAAC,OAAO,IAAI,yDAAyD;IAC1E,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,uCAAuC;IACnE,IAAI,CAAC,IAAI,KAAK,IAAI,CAAA,CAAC,oDAAoD;AAEzE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,CACnB,IAAU,EACV,IAAwC,EACxC,KAAc,EACP,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAA;AAEvD;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,EAAE;IAC9B,YAAY,CAAC,KAAK,EAAE,CAAA;IACpB,kBAAkB,CAAC,KAAK,EAAE,CAAA;IAC1B,eAAe,CAAC,KAAK,EAAE,CAAA;IACvB,UAAU,CAAC,KAAK,EAAE,CAAA;AACpB,CAAC,CAAA","sourcesContent":["import { error } from '@vltpkg/error-cause'\nimport { Spec } from '@vltpkg/spec/browser'\nimport type { SpecOptions } from '@vltpkg/spec/browser'\nimport type { Manifest } from '@vltpkg/types'\n\nexport const delimiter: Delimiter = '·'\nexport type Delimiter = '·'\n\n/**\n * Dependency IDs are a URI-encoded set of strings, separated\n * by the {@link Delimiter} character (`'·'`).\n *\n * The first entry is always the specifier type. The rest depend on the\n * type. `git`, `registry`, and `workspace` entries have 3 fields, the rest\n * have 2.\n *\n * - `registry`: `'registry·<registry>·name@specifier'`\n * The `<registry>` portion can be a known named registry name, or a\n * url to a registry. If empty, it is the default registry. Examples:\n * - `··some-package@2.0.1`\n * - `·npm·whatever@1.2.3`\n * - `·http%3A%2F%2Fvlt.sh%2F·x@1.2.3`\n * - `git`: `'git·<git remote>·<git selector>'`. For example:\n * - `git·github:user/project·branchname`\n * - `git·git%2Bssh%3A%2F%2Fuser%40host%3Aproject.git·semver:1.x`\n * - `workspace`: `'workspace·<path>'`. For example:\n * - `workspace·src/mything`\n * - `remote`: `'remote·<url>'`\n * - `file`: `'file·<path>'`\n *\n * Lastly, the final portion can contain arbitrary string data, and is\n * used to store peer dep resolutions to maintain the peerDep contract.\n */\nexport type DepID =\n | `${'' | 'git'}${Delimiter}${string}${Delimiter}${string}${Delimiter}${string}`\n | `${'' | 'git'}${Delimiter}${string}${Delimiter}${string}`\n | `${'file' | 'remote' | 'workspace'}${Delimiter}${string}${Delimiter}${string}`\n | `${'file' | 'remote' | 'workspace'}${Delimiter}${string}`\n\n/**\n * A {@link DepID}, split apart and URI-decoded\n */\nexport type DepIDTuple =\n | [\n type: 'git',\n gitRemote: string,\n gitSelector: string,\n extra?: string,\n ]\n | [\n type: 'registry',\n registry: string,\n registrySpec: string,\n extra?: string,\n ]\n | [type: 'file', path: string, extra?: string]\n | [type: 'remote', url: string, extra?: string]\n | [type: 'workspace', workspace: string, extra?: string]\n\nconst depIDRegExp = new RegExp(\n `^((git)?${delimiter}[^${delimiter}]*${delimiter}[^${delimiter}]*(${\n delimiter\n }[^${delimiter}]*)?$` +\n `|` +\n `^(file|remote|workspace)${delimiter}[^${\n delimiter\n }]*)(${delimiter}[^${delimiter}]*)?$`,\n)\n\nexport const isDepID = (str: unknown): str is DepID =>\n typeof str === 'string' && depIDRegExp.test(str)\n\nexport const asDepID = (str: string): DepID => {\n if (!isDepID(str)) {\n throw error('Expected dep id', {\n found: str,\n })\n }\n return str\n}\n\n/**\n * turn a {@link DepIDTuple} into a {@link DepID}\n */\nexport const joinDepIDTuple = (list: DepIDTuple): DepID => {\n const [type, first, second, extra] = list\n const f = encode(first)\n switch (type) {\n case 'registry':\n return `${delimiter}${f}${delimiter}${encode(second)}${extra ? `${delimiter}${encode(extra)}` : ''}`\n case 'git':\n return `${type}${delimiter}${f}${delimiter}${encode(second)}${extra ? `${delimiter}${encode(extra)}` : ''}`\n default:\n return `${type}${delimiter}${f}${second ? `${delimiter}${encode(second)}` : ''}`\n }\n}\n\n// allow @, but otherwise, escape everything urls do\nconst encode = (s?: string) =>\n s ?\n encodeURIComponent(s)\n .replaceAll('%40', '@')\n .replaceAll('%2f', '§')\n .replaceAll('%2F', '§')\n : s\n\nconst decode = (s?: string) =>\n s ?\n decodeURIComponent(\n s.replaceAll('@', '%40').replaceAll('§', '%2F'),\n )\n : s\n\nconst seenSplitDepIDs = new Map<string, DepIDTuple>()\n/**\n * turn a {@link DepID} into a {@link DepIDTuple}\n */\nexport const splitDepID = (id: string): DepIDTuple => {\n // memoized entries return early\n const seen = seenSplitDepIDs.get(id)\n if (seen) return seen\n\n let res: DepIDTuple\n const [type, first = '', second, extra] = id\n .replaceAll('§', '/')\n .split(delimiter, 4)\n const f = decodeURIComponent(first)\n switch (type) {\n case 'git':\n case '': {\n if (second === undefined) {\n throw error(`invalid ${type} id`, { found: id })\n }\n res = [\n type || 'registry',\n f,\n decodeURIComponent(second),\n decode(extra),\n ]\n break\n }\n case 'file':\n case 'remote':\n case 'workspace': {\n res = [type, f, decode(second)]\n break\n }\n default: {\n throw error('invalid DepID type', {\n found: type,\n validOptions: ['git', 'file', 'workspace', 'remote', ''],\n })\n }\n }\n seenSplitDepIDs.set(id, res)\n return res\n}\n\n/**\n * Retrieves the base {@link DepID} for a given depID,\n * ignoring any extra information that may be present.\n */\nexport const baseDepID = (id: string): DepID => {\n const [type, first, second] = splitDepID(id)\n switch (type) {\n case 'git':\n case 'registry':\n return joinDepIDTuple([type, first, second])\n default:\n return joinDepIDTuple([type, first])\n }\n}\n\nconst seenHydrated = new Map<string, Spec>()\n/**\n * Turn a {@link DepID} into a {@link Spec} object\n */\nexport const hydrate = (\n id: DepID,\n name?: string,\n options: SpecOptions = {},\n): Spec => {\n // memozied entries return early\n const cacheKey = (name ?? '') + id\n const seen = seenHydrated.get(cacheKey)\n if (seen) return seen\n\n const res = hydrateTuple(splitDepID(id), name, options)\n seenHydrated.set(cacheKey, res)\n return res\n}\n\nconst seenHydratedTuples = new Map<string, Spec>()\n/**\n * Turn a {@link DepIDTuple} into a {@link Spec} object\n */\nexport const hydrateTuple = (\n tuple: DepIDTuple,\n name?: string,\n options: SpecOptions = {},\n) => {\n const [type, first, second] = tuple\n\n // memoized entries return early\n const cacheKey = (name ?? '') + type + first + (second ?? '')\n const seen = seenHydratedTuples.get(cacheKey)\n if (seen) return seen\n\n let res: Spec\n switch (type) {\n case 'remote': {\n if (!first)\n throw error('no remoteURL found on remote id', {\n found: tuple,\n })\n res = Spec.parse(name ?? '(unknown)', first, options)\n break\n }\n case 'file': {\n if (!first) {\n throw error('no file path found on remote id', {\n found: tuple,\n })\n }\n res = Spec.parse(name ?? '(unknown)', `file:${first}`, options)\n break\n }\n case 'registry': {\n if (typeof first !== 'string') {\n throw error('no registry url or name in registry ID', {\n found: tuple,\n })\n }\n if (!second) {\n throw error('no name/specifier in registry ID', {\n found: tuple,\n })\n }\n if (!first) {\n // just a normal name@version on the default registry\n const s = Spec.parseArgs(second, options)\n if (name && s.name !== name) {\n res = Spec.parse(name, `npm:${second}`, options)\n } else {\n res = s\n }\n break\n }\n if (!/^https?:\\/\\//.test(first)) {\n const reg = options.registries?.[first]\n if (first !== 'npm' && !reg) {\n throw error('named registry not found in options', {\n name: first,\n found: tuple,\n })\n }\n res = Spec.parse(\n name ?? '(unknown)',\n `${first}:${second}`,\n options,\n )\n break\n }\n const s = Spec.parse(\n name ?? '(unknown)',\n `registry:${first}#${second}`,\n options,\n )\n res =\n name && s.final.name !== name ?\n Spec.parse(s.final.name, s.bareSpec, options)\n : s\n break\n }\n case 'git': {\n if (!first) {\n throw error('no git remote in git ID', {\n found: tuple,\n })\n }\n res = Spec.parse(\n name ?? '(unknown)',\n first + '#' + second,\n options,\n )\n break\n }\n case 'workspace': {\n if (!first) {\n throw error('no name/path on workspace id', { found: tuple })\n }\n res =\n name && name !== first ?\n Spec.parse(name, `workspace:${first}@*`, options)\n : Spec.parse(first, `workspace:*`, options)\n break\n }\n }\n seenHydratedTuples.set(cacheKey, res)\n return res\n}\n\n// Strip out the default registry, there's no need to store that\nconst omitDefReg = (s?: string): string =>\n (\n !s ||\n s === 'https://registry.npmjs.org' ||\n s === 'https://registry.npmjs.org/'\n ) ?\n ''\n : s\n\nconst seenTuples = new Map<string, DepIDTuple>()\n/**\n * Get the {@link DepIDTuple} for a given {@link Spec} and {@link Manifest}.\n * The Manifest is used to get the name and version, if possible. If not found\n * in the manifest, registry ID types will use the name or bareSpec from the\n * specifier, so at least there's something to use later.\n */\nexport const getTuple = (\n spec: Spec,\n mani: Pick<Manifest, 'name' | 'version'>,\n extra?: string,\n): DepIDTuple => {\n // memoized entries return early\n const cacheKey =\n String(spec) +\n (mani.name ?? '') +\n (mani.version ?? '') +\n (extra ?? '')\n const seen = seenTuples.get(cacheKey)\n if (seen) return seen\n\n let res: DepIDTuple\n const f = spec.final\n switch (f.type) {\n case 'registry': {\n // try to shorten to a known name if we can.\n const reg = omitDefReg(f.registry)\n if (!f.namedRegistry && reg) {\n for (const [alias, host] of Object.entries(\n spec.options.registries,\n )) {\n if (reg === host) {\n f.namedRegistry = alias\n break\n }\n }\n }\n const version =\n mani.version ?\n mani.version.startsWith('v') ?\n mani.version.slice(1)\n : mani.version\n : f.bareSpec\n res = [\n f.type,\n f.namedRegistry ?? reg,\n `${isPackageNameConfused(spec, mani.name) ? spec.name : (mani.name ?? f.name)}@${version}`,\n extra,\n ]\n break\n }\n case 'git': {\n const {\n namedGitHost,\n namedGitHostPath,\n gitRemote,\n gitSelector = '',\n } = f\n if (!gitRemote)\n throw error('no host on git specifier', { spec })\n if (namedGitHost) {\n if (!namedGitHostPath) {\n throw error('named git host without path portion', {\n spec,\n })\n }\n res = [\n f.type,\n `${namedGitHost}:${namedGitHostPath}`,\n gitSelector,\n extra,\n ]\n break\n } else {\n res = [f.type, gitRemote, gitSelector, extra]\n }\n break\n }\n case 'remote': {\n const { remoteURL } = f\n if (!remoteURL)\n throw error('no URL on remote specifier', { spec })\n res = [f.type, remoteURL, extra]\n break\n }\n case 'file':\n case 'workspace':\n throw error('Path-based dep ids are not supported', { spec })\n }\n seenTuples.set(cacheKey, res)\n return res\n}\n\n/**\n * Checks for a potentially manifest-confused package name.\n * Returns `true` if the package name is confused, `false` otherwise.\n */\nexport const isPackageNameConfused = (spec?: Spec, name?: string) =>\n !!spec?.name && // a nameless spec can't be checked\n !spec.subspec && // it's not an aliased package or using a custom protocol\n spec.type === 'registry' && // the defined spec is of type registry\n spec.name !== name // its name is not the same as the defined spec name\n\n/**\n * Get the {@link DepID} for a given {@link Spec} and {@link Manifest}. The\n * Manifest is used to get the name and version, if possible. If not found in\n * the manifest, registry ID types will use the name or bareSpec from the\n * specifier, so at least there's something to use later.\n */\nexport const getId = (\n spec: Spec,\n mani: Pick<Manifest, 'name' | 'version'>,\n extra?: string,\n): DepID => joinDepIDTuple(getTuple(spec, mani, extra))\n\n/**\n * Reset internal caches. This should be used when options change since\n * they're not take into account in the memoization keys.\n */\nexport const resetCaches = () => {\n seenHydrated.clear()\n seenHydratedTuples.clear()\n seenSplitDepIDs.clear()\n seenTuples.clear()\n}\n"]}
@@ -1,78 +1,20 @@
1
1
  import { Spec } from '@vltpkg/spec';
2
2
  import type { SpecOptions } from '@vltpkg/spec';
3
- import type { Manifest } from '@vltpkg/types';
4
- export declare const delimiter: Delimiter;
5
- export type Delimiter = '·';
3
+ import type { DepID, DepIDTuple } from './browser.ts';
4
+ export * from './browser.ts';
6
5
  /**
7
- * Dependency IDs are a URI-encoded set of strings, separated
8
- * by the {@link Delimiter} character (`'·'`).
9
- *
10
- * The first entry is always the specifier type. The rest depend on the
11
- * type. `git`, `registry`, and `workspace` entries have 3 fields, the rest
12
- * have 2.
13
- *
14
- * - `registry`: `'registry·<registry>·name@specifier'`
15
- * The `<registry>` portion can be a known named registry name, or a
16
- * url to a registry. If empty, it is the default registry. Examples:
17
- * - `··some-package@2.0.1`
18
- * - `·npm·whatever@1.2.3`
19
- * - `·http%3A%2F%2Fvlt.sh%2F·x@1.2.3`
20
- * - `git`: `'git·<git remote>·<git selector>'`. For example:
21
- * - `git·github:user/project·branchname`
22
- * - `git·git%2Bssh%3A%2F%2Fuser%40host%3Aproject.git·semver:1.x`
23
- * - `workspace`: `'workspace·<path>'`. For example:
24
- * - `workspace·src/mything`
25
- * - `remote`: `'remote·<url>'`
26
- * - `file`: `'file·<path>'`
27
- *
28
- * Lastly, the final portion can contain arbitrary string data, and is
29
- * used to store peer dep resolutions to maintain the peerDep contract.
30
- */
31
- export type DepID = `${'' | 'git'}${Delimiter}${string}${Delimiter}${string}${Delimiter}${string}` | `${'' | 'git'}${Delimiter}${string}${Delimiter}${string}` | `${'file' | 'remote' | 'workspace'}${Delimiter}${string}${Delimiter}${string}` | `${'file' | 'remote' | 'workspace'}${Delimiter}${string}`;
32
- /**
33
- * A {@link DepID}, split apart and URI-decoded
34
- */
35
- export type DepIDTuple = [
36
- type: 'git',
37
- gitRemote: string,
38
- gitSelector: string,
39
- extra?: string
40
- ] | [
41
- type: 'registry',
42
- registry: string,
43
- registrySpec: string,
44
- extra?: string
45
- ] | [type: 'file', path: string, extra?: string] | [type: 'remote', url: string, extra?: string] | [type: 'workspace', workspace: string, extra?: string];
46
- export declare const isDepID: (str: unknown) => str is DepID;
47
- export declare const asDepID: (str: string) => DepID;
48
- /**
49
- * turn a {@link DepIDTuple} into a {@link DepID}
50
- */
51
- export declare const joinDepIDTuple: (list: DepIDTuple) => DepID;
52
- /**
53
- * turn a {@link DepID} into a {@link DepIDTuple}
54
- */
55
- export declare const splitDepID: (id: string) => DepIDTuple;
56
- /**
57
- * Turn a {@link DepID} into a {@link Spec} object
6
+ * Turn a {@link DepID} into a {@link Spec} object using
7
+ * the Node.js-specific `Spec.parse` method.
58
8
  */
59
9
  export declare const hydrate: (id: DepID, name?: string, options?: SpecOptions) => Spec;
60
10
  /**
61
- * Turn a {@link DepIDTuple} into a {@link Spec} object
62
- */
63
- export declare const hydrateTuple: (tuple: DepIDTuple, name?: string, options?: SpecOptions) => import("@vltpkg/spec/browser").Spec;
64
- /**
65
- * Get the {@link DepIDTuple} for a given {@link Spec} and {@link Manifest}.
66
- * The Manifest is used to get the name and version, if possible. If not found
67
- * in the manifest, registry ID types will use the name or bareSpec from the
68
- * specifier, so at least there's something to use later.
11
+ * Turn a {@link DepIDTuple} into a {@link Spec} object using
12
+ * the Node.js-specific `Spec.parse` method.
69
13
  */
70
- export declare const getTuple: (spec: Spec, mani: Manifest) => DepIDTuple;
14
+ export declare const hydrateTuple: (tuple: DepIDTuple, name?: string, options?: SpecOptions) => Spec;
71
15
  /**
72
- * Get the {@link DepID} for a given {@link Spec} and {@link Manifest}. The
73
- * Manifest is used to get the name and version, if possible. If not found in
74
- * the manifest, registry ID types will use the name or bareSpec from the
75
- * specifier, so at least there's something to use later.
16
+ * Reset internal caches. This should be used when options change since
17
+ * they're not take into account in the memoization keys.
76
18
  */
77
- export declare const getId: (spec: Spec, mani: Manifest) => DepID;
19
+ export declare const resetCaches: () => void;
78
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AACnC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAE7C,eAAO,MAAM,SAAS,EAAE,SAAe,CAAA;AACvC,MAAM,MAAM,SAAS,GAAG,GAAG,CAAA;AAE3B;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,MAAM,KAAK,GACb,GAAG,EAAE,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,GAC9E,GAAG,EAAE,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,GACzD,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,GAC9E,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,EAAE,CAAA;AAE7D;;GAEG;AACH,MAAM,MAAM,UAAU,GAClB;IACE,IAAI,EAAE,KAAK;IACX,SAAS,EAAE,MAAM;IACjB,WAAW,EAAE,MAAM;IACnB,KAAK,CAAC,EAAE,MAAM;CACf,GACD;IACE,IAAI,EAAE,UAAU;IAChB,QAAQ,EAAE,MAAM;IAChB,YAAY,EAAE,MAAM;IACpB,KAAK,CAAC,EAAE,MAAM;CACf,GACD,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,GAC5C,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,GAC7C,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,CAAA;AAY1D,eAAO,MAAM,OAAO,QAAS,OAAO,KAAG,GAAG,IAAI,KACI,CAAA;AAElD,eAAO,MAAM,OAAO,QAAS,MAAM,KAAG,KAOrC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,SAAU,UAAU,KAAG,KAWjD,CAAA;AASD;;GAEG;AACH,eAAO,MAAM,UAAU,OAAQ,MAAM,KAAG,UAiCvC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,OAAO,OACd,KAAK,SACF,MAAM,YACJ,WAAW,KACnB,IAAmD,CAAA;AAEtD;;GAEG;AACH,eAAO,MAAM,YAAY,UAChB,UAAU,SACV,MAAM,YACJ,WAAW,wCAmFrB,CAAA;AAYD;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,SAAU,IAAI,QAAQ,QAAQ,KAAG,UAwDrD,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,KAAK,SAAU,IAAI,QAAQ,QAAQ,KAAG,KACb,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAKnC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAQrD,cAAc,cAAc,CAAA;AAG5B;;;GAGG;AAEH,eAAO,MAAM,OAAO,OACd,KAAK,SACF,MAAM,YACJ,WAAW,KACnB,IAQF,CAAA;AAGD;;;GAGG;AAEH,eAAO,MAAM,YAAY,UAChB,UAAU,SACV,MAAM,YACJ,WAAW,KACnB,IAoGF,CAAA;AAED;;;GAGG;AAEH,eAAO,MAAM,WAAW,YAIvB,CAAA"}
package/dist/esm/index.js CHANGED
@@ -1,93 +1,51 @@
1
1
  import { error } from '@vltpkg/error-cause';
2
2
  import { Spec } from '@vltpkg/spec';
3
- export const delimiter = '·';
4
- const depIDRegExp = new RegExp(`^((git)?${delimiter}[^${delimiter}]*${delimiter}[^${delimiter}]*(${delimiter}[^${delimiter}]*)?$` +
5
- `|` +
6
- `^(file|remote|workspace)${delimiter}[^${delimiter}]*)(${delimiter}[^${delimiter}]*)?$`);
7
- export const isDepID = (str) => typeof str === 'string' && depIDRegExp.test(str);
8
- export const asDepID = (str) => {
9
- if (!isDepID(str)) {
10
- throw error('Expected dep id', {
11
- found: str,
12
- });
13
- }
14
- return str;
15
- };
16
- /**
17
- * turn a {@link DepIDTuple} into a {@link DepID}
18
- */
19
- export const joinDepIDTuple = (list) => {
20
- const [type, first, second, extra] = list;
21
- const f = encode(first);
22
- switch (type) {
23
- case 'registry':
24
- return `${delimiter}${f}${delimiter}${encode(second)}${extra ? `${delimiter}${encode(extra)}` : ''}`;
25
- case 'git':
26
- return `${type}${delimiter}${f}${delimiter}${encode(second)}${extra ? `${delimiter}${encode(extra)}` : ''}`;
27
- default:
28
- return `${type}${delimiter}${f}${second ? `${delimiter}${encode(second)}` : ''}`;
29
- }
30
- };
31
- // allow @, but otherwise, escape everything urls do
32
- const encode = (s) => encodeURIComponent(s)
33
- .replaceAll('%40', '@')
34
- .replaceAll('%2f', '§')
35
- .replaceAll('%2F', '§');
3
+ import { resetCaches as browserResetCaches, splitDepID, } from "./browser.js";
4
+ // Here we re-export the browser-specific parts of the implementation
5
+ // we disable the eslint rules for import/export since we are intentionally
6
+ // re-exporting the `hydrate` and `hydrateTuple` functions to make sure they
7
+ // use the Node.js-specific `Spec.parse` method that relies on internal node
8
+ // modules like `util` and `path` that are not isomorphic.
9
+ // eslint-disable-next-line import/export
10
+ export * from "./browser.js";
11
+ const seenHydrated = new Map();
36
12
  /**
37
- * turn a {@link DepID} into a {@link DepIDTuple}
13
+ * Turn a {@link DepID} into a {@link Spec} object using
14
+ * the Node.js-specific `Spec.parse` method.
38
15
  */
39
- export const splitDepID = (id) => {
40
- const [type, first = '', second, extra] = id
41
- .replaceAll('§', '/')
42
- .split(delimiter, 4);
43
- const f = decodeURIComponent(first);
44
- switch (type) {
45
- case 'git':
46
- case '': {
47
- if (second === undefined) {
48
- throw error(`invalid ${type} id`, { found: id });
49
- }
50
- const t = [
51
- type || 'registry',
52
- f,
53
- decodeURIComponent(second),
54
- ];
55
- if (extra)
56
- t.push(decodeURIComponent(extra));
57
- return t;
58
- }
59
- case 'file':
60
- case 'remote':
61
- case 'workspace': {
62
- const t = [type, f];
63
- if (second)
64
- t.push(decodeURIComponent(second));
65
- return t;
66
- }
67
- default: {
68
- throw error('invalid DepID type', {
69
- found: type,
70
- validOptions: ['git', 'file', 'workspace', 'remote', ''],
71
- });
72
- }
73
- }
16
+ // eslint-disable-next-line import/export
17
+ export const hydrate = (id, name, options = {}) => {
18
+ // memoized entries return early
19
+ const cacheKey = (name ?? '') + id;
20
+ const seen = seenHydrated.get(cacheKey);
21
+ if (seen)
22
+ return seen;
23
+ const res = hydrateTuple(splitDepID(id), name, options);
24
+ seenHydrated.set(cacheKey, res);
25
+ return res;
74
26
  };
27
+ const seenHydratedTuples = new Map();
75
28
  /**
76
- * Turn a {@link DepID} into a {@link Spec} object
77
- */
78
- export const hydrate = (id, name, options = {}) => hydrateTuple(splitDepID(id), name, options);
79
- /**
80
- * Turn a {@link DepIDTuple} into a {@link Spec} object
29
+ * Turn a {@link DepIDTuple} into a {@link Spec} object using
30
+ * the Node.js-specific `Spec.parse` method.
81
31
  */
32
+ // eslint-disable-next-line import/export
82
33
  export const hydrateTuple = (tuple, name, options = {}) => {
83
34
  const [type, first, second] = tuple;
35
+ // memoized entries return early
36
+ const cacheKey = (name ?? '') + type + first + (second ?? '');
37
+ const seen = seenHydratedTuples.get(cacheKey);
38
+ if (seen)
39
+ return seen;
40
+ let res;
84
41
  switch (type) {
85
42
  case 'remote': {
86
43
  if (!first)
87
44
  throw error('no remoteURL found on remote id', {
88
45
  found: tuple,
89
46
  });
90
- return Spec.parse(name ?? '(unknown)', first);
47
+ res = Spec.parse(name ?? '(unknown)', first);
48
+ break;
91
49
  }
92
50
  case 'file': {
93
51
  if (!first) {
@@ -95,7 +53,8 @@ export const hydrateTuple = (tuple, name, options = {}) => {
95
53
  found: tuple,
96
54
  });
97
55
  }
98
- return Spec.parse(name ?? '(unknown)', `file:${first}`, options);
56
+ res = Spec.parse(name ?? '(unknown)', `file:${first}`, options);
57
+ break;
99
58
  }
100
59
  case 'registry': {
101
60
  if (typeof first !== 'string') {
@@ -112,11 +71,12 @@ export const hydrateTuple = (tuple, name, options = {}) => {
112
71
  // just a normal name@version on the default registry
113
72
  const s = Spec.parse(second);
114
73
  if (name && s.name !== name) {
115
- return Spec.parse(`${name}@npm:${second}`);
74
+ res = Spec.parse(`${name}@npm:${second}`);
116
75
  }
117
76
  else {
118
- return s;
77
+ res = s;
119
78
  }
79
+ break;
120
80
  }
121
81
  if (!/^https?:\/\//.test(first)) {
122
82
  const reg = options.registries?.[first];
@@ -126,12 +86,15 @@ export const hydrateTuple = (tuple, name, options = {}) => {
126
86
  found: tuple,
127
87
  });
128
88
  }
129
- return Spec.parse(name ?? '(unknown)', `${first}:${second}`, options);
89
+ res = Spec.parse(name ?? '(unknown)', `${first}:${second}`, options);
90
+ break;
130
91
  }
131
92
  const s = Spec.parse(name ?? '(unknown)', `registry:${first}#${second}`, options);
132
- return name && s.final.name !== name ?
133
- Spec.parse(s.final.name + '@' + s.bareSpec)
134
- : s;
93
+ res =
94
+ name && s.final.name !== name ?
95
+ Spec.parse(s.final.name + '@' + s.bareSpec)
96
+ : s;
97
+ break;
135
98
  }
136
99
  case 'git': {
137
100
  if (!first) {
@@ -139,86 +102,31 @@ export const hydrateTuple = (tuple, name, options = {}) => {
139
102
  found: tuple,
140
103
  });
141
104
  }
142
- return Spec.parse(name ?? '(unknown)', first + '#' + second, options);
105
+ res = Spec.parse(name ?? '(unknown)', first + '#' + second, options);
106
+ break;
143
107
  }
144
108
  case 'workspace': {
145
109
  if (!first) {
146
110
  throw error('no name/path on workspace id', { found: tuple });
147
111
  }
148
- return name && name !== first ?
149
- Spec.parse(name, `workspace:${first}@*`, options)
150
- : Spec.parse(first, `workspace:*`, options);
112
+ res =
113
+ name && name !== first ?
114
+ Spec.parse(name, `workspace:${first}@*`, options)
115
+ : Spec.parse(first, `workspace:*`, options);
116
+ break;
151
117
  }
152
118
  }
119
+ seenHydratedTuples.set(cacheKey, res);
120
+ return res;
153
121
  };
154
- // Strip out the default registry, there's no need to store that
155
- const omitDefReg = (s) => (!s ||
156
- s === 'https://registry.npmjs.org' ||
157
- s === 'https://registry.npmjs.org/') ?
158
- ''
159
- : s;
160
122
  /**
161
- * Get the {@link DepIDTuple} for a given {@link Spec} and {@link Manifest}.
162
- * The Manifest is used to get the name and version, if possible. If not found
163
- * in the manifest, registry ID types will use the name or bareSpec from the
164
- * specifier, so at least there's something to use later.
123
+ * Reset internal caches. This should be used when options change since
124
+ * they're not take into account in the memoization keys.
165
125
  */
166
- export const getTuple = (spec, mani) => {
167
- const f = spec.final;
168
- switch (f.type) {
169
- case 'registry': {
170
- // try to shorten to a known name if we can.
171
- const reg = omitDefReg(f.registry);
172
- if (!f.namedRegistry && reg) {
173
- for (const [alias, host] of Object.entries(spec.options.registries)) {
174
- if (reg === host) {
175
- f.namedRegistry = alias;
176
- break;
177
- }
178
- }
179
- }
180
- return [
181
- f.type,
182
- f.namedRegistry ?? reg,
183
- `${mani.name ?? spec.name}@${mani.version ?? spec.bareSpec}`,
184
- ];
185
- }
186
- case 'git': {
187
- const { namedGitHost, namedGitHostPath, gitRemote, gitSelector = '', } = f;
188
- if (!gitRemote)
189
- throw error('no host on git specifier', { spec });
190
- if (namedGitHost) {
191
- if (!namedGitHostPath) {
192
- throw error('named git host without path portion', {
193
- spec,
194
- });
195
- }
196
- return [
197
- f.type,
198
- `${namedGitHost}:${namedGitHostPath}`,
199
- gitSelector,
200
- ];
201
- }
202
- else {
203
- return [f.type, gitRemote, gitSelector];
204
- }
205
- }
206
- case 'remote': {
207
- const { remoteURL } = f;
208
- if (!remoteURL)
209
- throw error('no URL on remote specifier', { spec });
210
- return [f.type, remoteURL];
211
- }
212
- case 'file':
213
- case 'workspace':
214
- throw error('Path-based dep ids are not supported', { spec });
215
- }
126
+ // eslint-disable-next-line import/export
127
+ export const resetCaches = () => {
128
+ seenHydrated.clear();
129
+ seenHydratedTuples.clear();
130
+ browserResetCaches();
216
131
  };
217
- /**
218
- * Get the {@link DepID} for a given {@link Spec} and {@link Manifest}. The
219
- * Manifest is used to get the name and version, if possible. If not found in
220
- * the manifest, registry ID types will use the name or bareSpec from the
221
- * specifier, so at least there's something to use later.
222
- */
223
- export const getId = (spec, mani) => joinDepIDTuple(getTuple(spec, mani));
224
132
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { error } from '@vltpkg/error-cause'\nimport { Spec } from '@vltpkg/spec'\nimport type { SpecOptions } from '@vltpkg/spec'\nimport type { Manifest } from '@vltpkg/types'\n\nexport const delimiter: Delimiter = '·'\nexport type Delimiter = '·'\n\n/**\n * Dependency IDs are a URI-encoded set of strings, separated\n * by the {@link Delimiter} character (`'·'`).\n *\n * The first entry is always the specifier type. The rest depend on the\n * type. `git`, `registry`, and `workspace` entries have 3 fields, the rest\n * have 2.\n *\n * - `registry`: `'registry·<registry>·name@specifier'`\n * The `<registry>` portion can be a known named registry name, or a\n * url to a registry. If empty, it is the default registry. Examples:\n * - `··some-package@2.0.1`\n * - `·npm·whatever@1.2.3`\n * - `·http%3A%2F%2Fvlt.sh%2F·x@1.2.3`\n * - `git`: `'git·<git remote>·<git selector>'`. For example:\n * - `git·github:user/project·branchname`\n * - `git·git%2Bssh%3A%2F%2Fuser%40host%3Aproject.git·semver:1.x`\n * - `workspace`: `'workspace·<path>'`. For example:\n * - `workspace·src/mything`\n * - `remote`: `'remote·<url>'`\n * - `file`: `'file·<path>'`\n *\n * Lastly, the final portion can contain arbitrary string data, and is\n * used to store peer dep resolutions to maintain the peerDep contract.\n */\nexport type DepID =\n | `${'' | 'git'}${Delimiter}${string}${Delimiter}${string}${Delimiter}${string}`\n | `${'' | 'git'}${Delimiter}${string}${Delimiter}${string}`\n | `${'file' | 'remote' | 'workspace'}${Delimiter}${string}${Delimiter}${string}`\n | `${'file' | 'remote' | 'workspace'}${Delimiter}${string}`\n\n/**\n * A {@link DepID}, split apart and URI-decoded\n */\nexport type DepIDTuple =\n | [\n type: 'git',\n gitRemote: string,\n gitSelector: string,\n extra?: string,\n ]\n | [\n type: 'registry',\n registry: string,\n registrySpec: string,\n extra?: string,\n ]\n | [type: 'file', path: string, extra?: string]\n | [type: 'remote', url: string, extra?: string]\n | [type: 'workspace', workspace: string, extra?: string]\n\nconst depIDRegExp = new RegExp(\n `^((git)?${delimiter}[^${delimiter}]*${delimiter}[^${delimiter}]*(${\n delimiter\n }[^${delimiter}]*)?$` +\n `|` +\n `^(file|remote|workspace)${delimiter}[^${\n delimiter\n }]*)(${delimiter}[^${delimiter}]*)?$`,\n)\n\nexport const isDepID = (str: unknown): str is DepID =>\n typeof str === 'string' && depIDRegExp.test(str)\n\nexport const asDepID = (str: string): DepID => {\n if (!isDepID(str)) {\n throw error('Expected dep id', {\n found: str,\n })\n }\n return str\n}\n\n/**\n * turn a {@link DepIDTuple} into a {@link DepID}\n */\nexport const joinDepIDTuple = (list: DepIDTuple): DepID => {\n const [type, first, second, extra] = list\n const f = encode(first)\n switch (type) {\n case 'registry':\n return `${delimiter}${f}${delimiter}${encode(second)}${extra ? `${delimiter}${encode(extra)}` : ''}`\n case 'git':\n return `${type}${delimiter}${f}${delimiter}${encode(second)}${extra ? `${delimiter}${encode(extra)}` : ''}`\n default:\n return `${type}${delimiter}${f}${second ? `${delimiter}${encode(second)}` : ''}`\n }\n}\n\n// allow @, but otherwise, escape everything urls do\nconst encode = (s: string): string =>\n encodeURIComponent(s)\n .replaceAll('%40', '@')\n .replaceAll('%2f', '§')\n .replaceAll('%2F', '§')\n\n/**\n * turn a {@link DepID} into a {@link DepIDTuple}\n */\nexport const splitDepID = (id: string): DepIDTuple => {\n const [type, first = '', second, extra] = id\n .replaceAll('§', '/')\n .split(delimiter, 4)\n const f = decodeURIComponent(first)\n switch (type) {\n case 'git':\n case '': {\n if (second === undefined) {\n throw error(`invalid ${type} id`, { found: id })\n }\n const t: DepIDTuple = [\n type || 'registry',\n f,\n decodeURIComponent(second),\n ]\n if (extra) t.push(decodeURIComponent(extra))\n return t\n }\n case 'file':\n case 'remote':\n case 'workspace': {\n const t: DepIDTuple = [type, f]\n if (second) t.push(decodeURIComponent(second))\n return t\n }\n default: {\n throw error('invalid DepID type', {\n found: type,\n validOptions: ['git', 'file', 'workspace', 'remote', ''],\n })\n }\n }\n}\n\n/**\n * Turn a {@link DepID} into a {@link Spec} object\n */\nexport const hydrate = (\n id: DepID,\n name?: string,\n options: SpecOptions = {},\n): Spec => hydrateTuple(splitDepID(id), name, options)\n\n/**\n * Turn a {@link DepIDTuple} into a {@link Spec} object\n */\nexport const hydrateTuple = (\n tuple: DepIDTuple,\n name?: string,\n options: SpecOptions = {},\n) => {\n const [type, first, second] = tuple\n switch (type) {\n case 'remote': {\n if (!first)\n throw error('no remoteURL found on remote id', {\n found: tuple,\n })\n return Spec.parse(name ?? '(unknown)', first)\n }\n case 'file': {\n if (!first) {\n throw error('no file path found on remote id', {\n found: tuple,\n })\n }\n return Spec.parse(name ?? '(unknown)', `file:${first}`, options)\n }\n case 'registry': {\n if (typeof first !== 'string') {\n throw error('no registry url or name in registry ID', {\n found: tuple,\n })\n }\n if (!second) {\n throw error('no name/specifier in registry ID', {\n found: tuple,\n })\n }\n if (!first) {\n // just a normal name@version on the default registry\n const s = Spec.parse(second)\n if (name && s.name !== name) {\n return Spec.parse(`${name}@npm:${second}`)\n } else {\n return s\n }\n }\n if (!/^https?:\\/\\//.test(first)) {\n const reg = options.registries?.[first]\n if (first !== 'npm' && !reg) {\n throw error('named registry not found in options', {\n name: first,\n found: tuple,\n })\n }\n return Spec.parse(\n name ?? '(unknown)',\n `${first}:${second}`,\n options,\n )\n }\n const s = Spec.parse(\n name ?? '(unknown)',\n `registry:${first}#${second}`,\n options,\n )\n return name && s.final.name !== name ?\n Spec.parse(s.final.name + '@' + s.bareSpec)\n : s\n }\n case 'git': {\n if (!first) {\n throw error('no git remote in git ID', {\n found: tuple,\n })\n }\n return Spec.parse(\n name ?? '(unknown)',\n first + '#' + second,\n options,\n )\n }\n case 'workspace': {\n if (!first) {\n throw error('no name/path on workspace id', { found: tuple })\n }\n return name && name !== first ?\n Spec.parse(name, `workspace:${first}@*`, options)\n : Spec.parse(first, `workspace:*`, options)\n }\n }\n}\n\n// Strip out the default registry, there's no need to store that\nconst omitDefReg = (s?: string): string =>\n (\n !s ||\n s === 'https://registry.npmjs.org' ||\n s === 'https://registry.npmjs.org/'\n ) ?\n ''\n : s\n\n/**\n * Get the {@link DepIDTuple} for a given {@link Spec} and {@link Manifest}.\n * The Manifest is used to get the name and version, if possible. If not found\n * in the manifest, registry ID types will use the name or bareSpec from the\n * specifier, so at least there's something to use later.\n */\nexport const getTuple = (spec: Spec, mani: Manifest): DepIDTuple => {\n const f = spec.final\n switch (f.type) {\n case 'registry': {\n // try to shorten to a known name if we can.\n const reg = omitDefReg(f.registry)\n if (!f.namedRegistry && reg) {\n for (const [alias, host] of Object.entries(\n spec.options.registries,\n )) {\n if (reg === host) {\n f.namedRegistry = alias\n break\n }\n }\n }\n return [\n f.type,\n f.namedRegistry ?? reg,\n `${mani.name ?? spec.name}@${mani.version ?? spec.bareSpec}`,\n ]\n }\n case 'git': {\n const {\n namedGitHost,\n namedGitHostPath,\n gitRemote,\n gitSelector = '',\n } = f\n if (!gitRemote)\n throw error('no host on git specifier', { spec })\n if (namedGitHost) {\n if (!namedGitHostPath) {\n throw error('named git host without path portion', {\n spec,\n })\n }\n return [\n f.type,\n `${namedGitHost}:${namedGitHostPath}`,\n gitSelector,\n ]\n } else {\n return [f.type, gitRemote, gitSelector]\n }\n }\n case 'remote': {\n const { remoteURL } = f\n if (!remoteURL)\n throw error('no URL on remote specifier', { spec })\n return [f.type, remoteURL]\n }\n case 'file':\n case 'workspace':\n throw error('Path-based dep ids are not supported', { spec })\n }\n}\n\n/**\n * Get the {@link DepID} for a given {@link Spec} and {@link Manifest}. The\n * Manifest is used to get the name and version, if possible. If not found in\n * the manifest, registry ID types will use the name or bareSpec from the\n * specifier, so at least there's something to use later.\n */\nexport const getId = (spec: Spec, mani: Manifest): DepID =>\n joinDepIDTuple(getTuple(spec, mani))\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { error } from '@vltpkg/error-cause'\nimport { Spec } from '@vltpkg/spec'\nimport {\n resetCaches as browserResetCaches,\n splitDepID,\n} from './browser.ts'\nimport type { SpecOptions } from '@vltpkg/spec'\nimport type { DepID, DepIDTuple } from './browser.ts'\n\n// Here we re-export the browser-specific parts of the implementation\n// we disable the eslint rules for import/export since we are intentionally\n// re-exporting the `hydrate` and `hydrateTuple` functions to make sure they\n// use the Node.js-specific `Spec.parse` method that relies on internal node\n// modules like `util` and `path` that are not isomorphic.\n// eslint-disable-next-line import/export\nexport * from './browser.ts'\n\nconst seenHydrated = new Map<string, Spec>()\n/**\n * Turn a {@link DepID} into a {@link Spec} object using\n * the Node.js-specific `Spec.parse` method.\n */\n// eslint-disable-next-line import/export\nexport const hydrate = (\n id: DepID,\n name?: string,\n options: SpecOptions = {},\n): Spec => {\n // memoized entries return early\n const cacheKey = (name ?? '') + id\n const seen = seenHydrated.get(cacheKey)\n if (seen) return seen\n const res = hydrateTuple(splitDepID(id), name, options)\n seenHydrated.set(cacheKey, res)\n return res\n}\n\nconst seenHydratedTuples = new Map<string, Spec>()\n/**\n * Turn a {@link DepIDTuple} into a {@link Spec} object using\n * the Node.js-specific `Spec.parse` method.\n */\n// eslint-disable-next-line import/export\nexport const hydrateTuple = (\n tuple: DepIDTuple,\n name?: string,\n options: SpecOptions = {},\n): Spec => {\n const [type, first, second] = tuple\n\n // memoized entries return early\n const cacheKey = (name ?? '') + type + first + (second ?? '')\n const seen = seenHydratedTuples.get(cacheKey)\n if (seen) return seen\n\n let res: Spec\n switch (type) {\n case 'remote': {\n if (!first)\n throw error('no remoteURL found on remote id', {\n found: tuple,\n })\n res = Spec.parse(name ?? '(unknown)', first)\n break\n }\n case 'file': {\n if (!first) {\n throw error('no file path found on remote id', {\n found: tuple,\n })\n }\n res = Spec.parse(name ?? '(unknown)', `file:${first}`, options)\n break\n }\n case 'registry': {\n if (typeof first !== 'string') {\n throw error('no registry url or name in registry ID', {\n found: tuple,\n })\n }\n if (!second) {\n throw error('no name/specifier in registry ID', {\n found: tuple,\n })\n }\n if (!first) {\n // just a normal name@version on the default registry\n const s = Spec.parse(second)\n if (name && s.name !== name) {\n res = Spec.parse(`${name}@npm:${second}`)\n } else {\n res = s\n }\n break\n }\n if (!/^https?:\\/\\//.test(first)) {\n const reg = options.registries?.[first]\n if (first !== 'npm' && !reg) {\n throw error('named registry not found in options', {\n name: first,\n found: tuple,\n })\n }\n res = Spec.parse(\n name ?? '(unknown)',\n `${first}:${second}`,\n options,\n )\n break\n }\n const s = Spec.parse(\n name ?? '(unknown)',\n `registry:${first}#${second}`,\n options,\n )\n res =\n name && s.final.name !== name ?\n Spec.parse(s.final.name + '@' + s.bareSpec)\n : s\n break\n }\n case 'git': {\n if (!first) {\n throw error('no git remote in git ID', {\n found: tuple,\n })\n }\n res = Spec.parse(\n name ?? '(unknown)',\n first + '#' + second,\n options,\n )\n break\n }\n case 'workspace': {\n if (!first) {\n throw error('no name/path on workspace id', { found: tuple })\n }\n res =\n name && name !== first ?\n Spec.parse(name, `workspace:${first}@*`, options)\n : Spec.parse(first, `workspace:*`, options)\n break\n }\n }\n seenHydratedTuples.set(cacheKey, res)\n return res\n}\n\n/**\n * Reset internal caches. This should be used when options change since\n * they're not take into account in the memoization keys.\n */\n// eslint-disable-next-line import/export\nexport const resetCaches = () => {\n seenHydrated.clear()\n seenHydratedTuples.clear()\n browserResetCaches()\n}\n"]}
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@vltpkg/dep-id",
3
3
  "description": "create and hydrate dependency IDs",
4
- "version": "0.0.0-3",
4
+ "version": "0.0.0-31",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/vltpkg/vltpkg.git",
8
8
  "directory": "src/dep-id"
9
9
  },
10
+ "author": "vlt technology inc. <support@vlt.sh> (http://vlt.sh)",
10
11
  "tshy": {
11
12
  "selfLink": false,
12
13
  "liveDev": true,
@@ -20,21 +21,20 @@
20
21
  }
21
22
  },
22
23
  "dependencies": {
23
- "@vltpkg/error-cause": "0.0.0-3",
24
- "@vltpkg/types": "0.0.0-3",
25
- "@vltpkg/spec": "0.0.0-3"
24
+ "@vltpkg/types": "0.0.0-31",
25
+ "@vltpkg/spec": "0.0.0-31",
26
+ "@vltpkg/error-cause": "0.0.0-31"
26
27
  },
27
28
  "devDependencies": {
28
- "@eslint/js": "^9.20.0",
29
- "@types/eslint__js": "^8.42.3",
30
- "@types/node": "^22.13.1",
31
- "eslint": "^9.20.0",
32
- "prettier": "^3.4.2",
29
+ "@eslint/js": "^9.34.0",
30
+ "@types/node": "^22.17.2",
31
+ "eslint": "^9.34.0",
32
+ "prettier": "^3.6.2",
33
33
  "tap": "^21.1.0",
34
34
  "tshy": "^3.0.2",
35
- "typedoc": "0.27.6",
35
+ "typedoc": "~0.27.9",
36
36
  "typescript": "5.7.3",
37
- "typescript-eslint": "^8.23.0"
37
+ "typescript-eslint": "^8.40.0"
38
38
  },
39
39
  "license": "BSD-2-Clause-Patent",
40
40
  "engines": {
@@ -72,6 +72,7 @@
72
72
  "snap": "tap",
73
73
  "test": "tap",
74
74
  "posttest": "tsc --noEmit",
75
+ "tshy": "tshy",
75
76
  "typecheck": "tsc --noEmit"
76
77
  }
77
78
  }