scratch-storage 5.0.11 → 6.0.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.
Files changed (37) hide show
  1. package/.github/workflows/ci-cd.yml +10 -3
  2. package/dist/node/chunks/fetch-worker.7afe4ade866d6f6a3cb3.js +383 -0
  3. package/dist/node/chunks/fetch-worker.7afe4ade866d6f6a3cb3.js.map +1 -0
  4. package/dist/node/scratch-storage.js +316 -821
  5. package/dist/node/scratch-storage.js.map +1 -1
  6. package/dist/types/HostQueues.d.ts +20 -0
  7. package/dist/types/ScratchStorage.d.ts +2 -15
  8. package/dist/types/scratchFetch.d.ts +37 -15
  9. package/dist/web/chunks/fetch-worker.9fbe108071a9c5d6e70b.js +2 -0
  10. package/dist/web/chunks/{fetch-worker.4277f33a97fe995aa7dd.js.map → fetch-worker.9fbe108071a9c5d6e70b.js.map} +1 -1
  11. package/dist/web/chunks/fetch-worker.efebf27d479ab0f0d98c.js +394 -0
  12. package/dist/web/chunks/fetch-worker.efebf27d479ab0f0d98c.js.map +1 -0
  13. package/dist/web/scratch-storage.js +316 -821
  14. package/dist/web/scratch-storage.js.map +1 -1
  15. package/dist/web/scratch-storage.min.js +1 -1
  16. package/package.json +7 -5
  17. package/src/FetchTool.ts +3 -2
  18. package/src/FetchWorkerTool.worker.ts +94 -0
  19. package/src/HostQueues.ts +33 -0
  20. package/src/ScratchStorage.ts +1 -1
  21. package/src/{scratchFetch.js → scratchFetch.ts} +53 -34
  22. package/src/types.d.ts +4 -3
  23. package/test/build/api.test.js +60 -0
  24. package/test/build/scratchFetch.test.js +40 -0
  25. package/test/fixtures/known-assets.js +30 -2
  26. package/test/{__mocks__/cross-fetch.js → fixtures/mockFetch.js} +18 -17
  27. package/test/integration/download-known-assets.test.js +6 -3
  28. package/test/unit/fetch-tool.test.js +8 -7
  29. package/test/unit/metadata.test.js +9 -8
  30. package/tsconfig.json +0 -1
  31. package/tsconfig.test.json +1 -0
  32. package/dist/node/chunks/fetch-worker.56da39b0f4bad6747138.js +0 -809
  33. package/dist/node/chunks/fetch-worker.56da39b0f4bad6747138.js.map +0 -1
  34. package/dist/web/chunks/fetch-worker.4277f33a97fe995aa7dd.js +0 -2
  35. package/dist/web/chunks/fetch-worker.c813c32be403f91001ba.js +0 -820
  36. package/dist/web/chunks/fetch-worker.c813c32be403f91001ba.js.map +0 -1
  37. package/src/FetchWorkerTool.worker.js +0 -67
@@ -1,29 +1,44 @@
1
- const crossFetch = require('cross-fetch');
1
+ import {type QueueOptions} from '@scratch/task-herder';
2
+ import {hostQueueManager} from './HostQueues';
3
+
4
+ export const Headers = globalThis.Headers;
2
5
 
3
6
  /**
4
- * Metadata header names
5
- * @enum {string} The enum value is the name of the associated header.
6
- * @readonly
7
+ * Metadata header names.
8
+ * The enum value is the name of the associated header.
7
9
  */
8
- const RequestMetadata = {
10
+ export enum RequestMetadata {
9
11
  /** The ID of the project associated with this request */
10
- ProjectId: 'X-Project-ID',
12
+ ProjectId = 'X-Project-ID',
11
13
  /** The ID of the project run associated with this request */
12
- RunId: 'X-Run-ID'
14
+ RunId = 'X-Run-ID'
15
+ }
16
+
17
+ export type ScratchFetchOptions = {
18
+ /**
19
+ * The name of the queue to use for this request.
20
+ * If absent, the hostname of the requested URL will be used as the queue name.
21
+ * This is a Scratch-specific extension to the standard RequestInit type.
22
+ */
23
+ queueName?: string;
24
+
25
+ /**
26
+ * The options to use when creating the queue for this request.
27
+ * Ignored if a queue with the specified name already exists.
28
+ */
29
+ queueOptions?: QueueOptions;
13
30
  };
14
31
 
15
32
  /**
16
- * Metadata headers for requests
17
- * @type {Headers}
33
+ * Metadata headers for requests.
18
34
  */
19
- const metadata = new crossFetch.Headers();
35
+ const metadata = new Headers();
20
36
 
21
37
  /**
22
38
  * Check if there is any metadata to apply.
23
39
  * @returns {boolean} true if `metadata` has contents, or false if it is empty.
24
40
  */
25
- const hasMetadata = () => {
26
- /* global self */
41
+ export const hasMetadata = (): boolean => {
27
42
  const searchParams = (
28
43
  typeof self !== 'undefined' &&
29
44
  self &&
@@ -51,16 +66,16 @@ const hasMetadata = () => {
51
66
  * @param {RequestInit} [options] The initial request options. May be null or undefined.
52
67
  * @returns {RequestInit|undefined} the provided options parameter without modification, or a new options object.
53
68
  */
54
- const applyMetadata = options => {
69
+ export const applyMetadata = (options?: globalThis.RequestInit): globalThis.RequestInit | undefined => {
55
70
  if (hasMetadata()) {
56
71
  const augmentedOptions = Object.assign({}, options);
57
- augmentedOptions.headers = new crossFetch.Headers(metadata);
72
+ augmentedOptions.headers = new Headers(metadata);
58
73
  if (options && options.headers) {
59
74
  // the Fetch spec says options.headers could be:
60
75
  // "A Headers object, an object literal, or an array of two-item arrays to set request's headers."
61
76
  // turn it into a Headers object to be sure of how to interact with it
62
- const overrideHeaders = options.headers instanceof crossFetch.Headers ?
63
- options.headers : new crossFetch.Headers(options.headers);
77
+ const overrideHeaders = options.headers instanceof Headers ?
78
+ options.headers : new Headers(options.headers);
64
79
  for (const [name, value] of overrideHeaders.entries()) {
65
80
  augmentedOptions.headers.set(name, value);
66
81
  }
@@ -74,13 +89,27 @@ const applyMetadata = options => {
74
89
  * Make a network request.
75
90
  * This is a wrapper for the global fetch method, adding some Scratch-specific functionality.
76
91
  * @param {RequestInfo|URL} resource The resource to fetch.
77
- * @param {RequestInit} options Optional object containing custom settings for this request.
92
+ * @param {RequestInit} [requestOptions] Optional object containing custom settings for this request.
93
+ * @param {ScratchFetchOptions} [scratchOptions] Optional Scratch-specific settings for this request.
78
94
  * @see {@link https://developer.mozilla.org/docs/Web/API/fetch} for more about the fetch API.
79
95
  * @returns {Promise<Response>} A promise for the response to the request.
80
96
  */
81
- const scratchFetch = (resource, options) => {
82
- const augmentedOptions = applyMetadata(options);
83
- return crossFetch(resource, augmentedOptions);
97
+ export const scratchFetch = (
98
+ resource: RequestInfo | URL,
99
+ requestOptions?: globalThis.RequestInit,
100
+ scratchOptions?: ScratchFetchOptions
101
+ ): Promise<Response> => {
102
+ requestOptions = applyMetadata(requestOptions);
103
+
104
+ let queueName = scratchOptions?.queueName;
105
+ if (!queueName) {
106
+ // Normalize resource to a Request object. The `fetch` call will do this anyway, so it's not much extra work,
107
+ // but it guarantees availability of the URL for queue naming.
108
+ resource = new Request(resource, requestOptions);
109
+ queueName = new URL(resource.url).hostname;
110
+ }
111
+ const queue = hostQueueManager.getOrCreate(queueName, scratchOptions?.queueOptions);
112
+ return queue.do(() => fetch(resource, requestOptions));
84
113
  };
85
114
 
86
115
  /**
@@ -90,7 +119,7 @@ const scratchFetch = (resource, options) => {
90
119
  * @param {RequestMetadata} name The name of the metadata item to set.
91
120
  * @param {any} value The value to set (will be converted to a string).
92
121
  */
93
- const setMetadata = (name, value) => {
122
+ export const setMetadata = (name: RequestMetadata, value: any): void => {
94
123
  metadata.set(name, value);
95
124
  };
96
125
 
@@ -98,7 +127,7 @@ const setMetadata = (name, value) => {
98
127
  * Remove a named request metadata item.
99
128
  * @param {RequestMetadata} name The name of the metadata item to remove.
100
129
  */
101
- const unsetMetadata = name => {
130
+ export const unsetMetadata = (name: RequestMetadata): void => {
102
131
  metadata.delete(name);
103
132
  };
104
133
 
@@ -106,16 +135,6 @@ const unsetMetadata = name => {
106
135
  * Retrieve a named request metadata item.
107
136
  * Only for use in tests. At the time of writing, used in scratch-vm tests.
108
137
  * @param {RequestMetadata} name The name of the metadata item to retrieve.
109
- * @returns {any} value The value of the metadata item, or `undefined` if it was not found.
138
+ * @returns {string|null} The value of the metadata item, or `null` if it was not found.
110
139
  */
111
- const getMetadata = name => metadata.get(name);
112
-
113
- module.exports = {
114
- Headers: crossFetch.Headers,
115
- RequestMetadata,
116
- applyMetadata,
117
- scratchFetch,
118
- setMetadata,
119
- unsetMetadata,
120
- getMetadata
121
- };
140
+ export const getMetadata = (name: RequestMetadata): string | null => metadata.get(name);
package/src/types.d.ts CHANGED
@@ -1,3 +1,4 @@
1
- declare module '*.png?arrayBuffer';
2
- declare module '*.wav?arrayBuffer';
3
- declare module '*.svg?arrayBuffer';
1
+ declare module '*?arrayBuffer' {
2
+ const value: ArrayBuffer;
3
+ export default value;
4
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @file Tests the build output to verify the general parts of the public API.
3
+ */
4
+
5
+ const ScratchStorageModule = require('../../dist/node/scratch-storage.js');
6
+
7
+ /** @type {ScratchStorageModule.ScratchStorage} */
8
+ let storage;
9
+
10
+ beforeEach(() => {
11
+ const {ScratchStorage} = ScratchStorageModule;
12
+ storage = new ScratchStorage();
13
+ });
14
+
15
+ test('constructor', () => {
16
+ const {ScratchStorage} = ScratchStorageModule;
17
+ expect(storage).toBeInstanceOf(ScratchStorage);
18
+ });
19
+
20
+ test('DataFormat', () => {
21
+ const {DataFormat} = ScratchStorageModule;
22
+ expect(DataFormat).toBeDefined();
23
+ expect(DataFormat.JPG).toBe('jpg');
24
+ expect(DataFormat.JSON).toBe('json');
25
+ expect(DataFormat.MP3).toBe('mp3');
26
+ expect(DataFormat.PNG).toBe('png');
27
+ expect(DataFormat.SB2).toBe('sb2');
28
+ expect(DataFormat.SB3).toBe('sb3');
29
+ expect(DataFormat.SVG).toBe('svg');
30
+ expect(DataFormat.WAV).toBe('wav');
31
+ });
32
+
33
+ test('AssetType', () => {
34
+ const {AssetType, DataFormat} = ScratchStorageModule;
35
+ expect(AssetType).toBeDefined();
36
+ expect(AssetType.ImageBitmap.contentType).toBe('image/png');
37
+ expect(AssetType.ImageVector.contentType).toBe('image/svg+xml');
38
+ expect(AssetType.Project.runtimeFormat).toBe(DataFormat.JSON);
39
+ expect(AssetType.Sound.immutable).toBe(true);
40
+ expect(AssetType.Sprite.name).toBe('Sprite');
41
+ });
42
+
43
+ test('Asset', () => {
44
+ const {Asset, AssetType} = ScratchStorageModule;
45
+ expect(Asset).toBeDefined();
46
+ const asset = new Asset(
47
+ AssetType.ImageVector,
48
+ 'some-hash'
49
+ );
50
+ expect(asset).toBeInstanceOf(Asset);
51
+ expect(asset.dataFormat).toBe('svg');
52
+ expect(asset.assetId).toBe('some-hash');
53
+ });
54
+
55
+ test('Helper', () => {
56
+ const {Helper} = ScratchStorageModule;
57
+ expect(Helper).toBeDefined();
58
+ const helper = new Helper();
59
+ expect(helper).toBeInstanceOf(Helper);
60
+ });
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @file Tests the build output to verify the scratchFetch portion of the public API.
3
+ */
4
+
5
+ const ScratchStorageModule = require('../../dist/node/scratch-storage.js');
6
+
7
+ /** @type {ScratchStorageModule.ScratchStorage} */
8
+ let storage;
9
+
10
+ beforeEach(() => {
11
+ const {ScratchStorage} = ScratchStorageModule;
12
+ storage = new ScratchStorage();
13
+ });
14
+
15
+ test('scratchFetch accessor', () => {
16
+ expect(storage.scratchFetch).toBeDefined();
17
+ });
18
+
19
+ test('Headers', () => {
20
+ expect(storage.scratchFetch).toBeDefined();
21
+ const headers = new storage.scratchFetch.Headers();
22
+ expect(headers).toBeInstanceOf(storage.scratchFetch.Headers);
23
+ });
24
+
25
+ test('RequestMetadata enum', () => {
26
+ expect(storage.scratchFetch.RequestMetadata).toBeDefined();
27
+ expect(typeof storage.scratchFetch.RequestMetadata.ProjectId).toBe('string');
28
+ expect(typeof storage.scratchFetch.RequestMetadata.RunId).toBe('string');
29
+ });
30
+
31
+ test('scratchFetch function', () => {
32
+ expect(typeof storage.scratchFetch.scratchFetch).toBe('function');
33
+ });
34
+
35
+ test('metadata functions', () => {
36
+ expect(typeof storage.scratchFetch.applyMetadata).toBe('function');
37
+ expect(typeof storage.scratchFetch.setMetadata).toBe('function');
38
+ expect(typeof storage.scratchFetch.unsetMetadata).toBe('function');
39
+ expect(typeof storage.scratchFetch.getMetadata).toBe('function');
40
+ });
@@ -3,6 +3,16 @@ const path = require('path');
3
3
 
4
4
  const md5 = require('js-md5');
5
5
 
6
+ /**
7
+ * @typedef {object} KnownAsset
8
+ * @property {Buffer} content - The content of the asset.
9
+ * @property {string} hash - The MD5 hash of the asset content.
10
+ */
11
+
12
+ /**
13
+ * @typedef {{[id: string]: KnownAsset}} KnownAssetCollection
14
+ */
15
+
6
16
  const projects = [
7
17
  '117504922'
8
18
  ];
@@ -15,6 +25,11 @@ const assets = [
15
25
  'fe5e3566965f9de793beeffce377d054.jpg'
16
26
  ];
17
27
 
28
+ /**
29
+ * Load a file from disk, then return its content and hash.
30
+ * @param {string} filename - The file to load
31
+ * @returns {KnownAsset} The loaded asset
32
+ */
18
33
  const loadSomething = filename => {
19
34
  const fullPath = path.join(__dirname, 'assets', filename);
20
35
  const content = fs.readFileSync(fullPath);
@@ -25,6 +40,11 @@ const loadSomething = filename => {
25
40
  };
26
41
  };
27
42
 
43
+ /**
44
+ * Load a project from disk, ensure it's valid JSON, then return its content and hash.
45
+ * @param {string} id - The project ID
46
+ * @returns {KnownAsset} The loaded project asset
47
+ */
28
48
  const loadProject = id => {
29
49
  const filename = `${id}.json`;
30
50
  const result = loadSomething(filename);
@@ -35,6 +55,11 @@ const loadProject = id => {
35
55
  return result;
36
56
  };
37
57
 
58
+ /**
59
+ * Load an asset from disk, ensuring its hash matches its filename.
60
+ * @param {string} filename - The file to load
61
+ * @returns {KnownAsset} The loaded asset
62
+ */
38
63
  const loadAsset = filename => {
39
64
  const result = loadSomething(filename);
40
65
 
@@ -46,15 +71,18 @@ const loadAsset = filename => {
46
71
  return result;
47
72
  };
48
73
 
74
+ /**
75
+ * @type {KnownAssetCollection}
76
+ */
49
77
  const knownAssets = Object.assign({},
50
78
  projects.reduce((bag, id) => {
51
79
  bag[id] = loadProject(id);
52
80
  return bag;
53
- }, {}),
81
+ }, /** @type {KnownAssetCollection} */ ({})),
54
82
  assets.reduce((bag, filename) => {
55
83
  bag[filename] = loadAsset(filename);
56
84
  return bag;
57
- }, {})
85
+ }, /** @type {KnownAssetCollection} */ ({}))
58
86
  );
59
87
 
60
88
  module.exports = knownAssets;
@@ -1,8 +1,15 @@
1
+ /**
2
+ * Mock implementation of the fetch function for testing.
3
+ * Since `fetch` is a global, Jest will not automatically mock it from `__mocks__`.
4
+ *
5
+ * // In your test setup file or at the top of your test files:
6
+ * global.fetch = require('../mocks/fetch').default;
7
+ */
8
+
1
9
  const TextEncoder = require('util').TextEncoder;
2
- const crossFetch = jest.requireActual('cross-fetch');
3
10
  const knownAssets = require('../fixtures/known-assets.js');
4
11
 
5
- const Headers = crossFetch.Headers;
12
+ const Headers = global.Headers;
6
13
  const successText = 'successful response';
7
14
 
8
15
  /**
@@ -30,7 +37,7 @@ const successText = 'successful response';
30
37
  * @returns {Promise<MockFetchResponse>} A promise for a Response-like object. Does not fully implement Response.
31
38
  */
32
39
  const mockFetch = (resource, options) => {
33
- /** @type MockFetchResponse */
40
+ /** @type {MockFetchResponse} */
34
41
  const results = {
35
42
  ok: false,
36
43
  status: 0
@@ -39,14 +46,15 @@ const mockFetch = (resource, options) => {
39
46
  options.mockFetchTestData.headers = new Headers(options.headers);
40
47
  options.mockFetchTestData.headersCount = Array.from(options.mockFetchTestData.headers).length;
41
48
  }
42
-
43
- const assetInfo = knownAssets[resource];
49
+ const request = new Request(resource, options);
50
+ const path = new URL(request.url).pathname.slice(1); // remove leading '/'
51
+ const assetInfo = knownAssets[path];
44
52
  if (assetInfo) {
45
53
  results.ok = true;
46
54
  results.status = 200;
47
55
  results.arrayBuffer = () => Promise.resolve(assetInfo.content);
48
56
  } else {
49
- switch (resource) {
57
+ switch (path) {
50
58
  case '200':
51
59
  results.ok = true;
52
60
  results.status = 200;
@@ -68,14 +76,7 @@ const mockFetch = (resource, options) => {
68
76
  return Promise.resolve(results);
69
77
  };
70
78
 
71
- // Mimic the cross-fetch module, but replace its `fetch` with `mockFetch` and add a few extras
72
-
73
- module.exports = exports = mockFetch;
74
- exports.fetch = mockFetch;
75
- exports.Headers = crossFetch.Headers;
76
- exports.Request = crossFetch.Request;
77
- exports.Response = crossFetch.Response;
78
- exports.successText = successText;
79
-
80
- // Needed for TypeScript consumers without esModuleInterop.
81
- exports.default = mockFetch;
79
+ module.exports = {
80
+ fetch: mockFetch,
81
+ successText
82
+ };
@@ -1,7 +1,10 @@
1
1
  const md5 = require('js-md5');
2
2
 
3
+ const mockFetch = require('../fixtures/mockFetch.js');
3
4
  const ScratchStorage = require('../../src/index').ScratchStorage;
4
5
 
6
+ jest.spyOn(global, 'fetch').mockImplementation(mockFetch.fetch);
7
+
5
8
  test('constructor', () => {
6
9
  const storage = new ScratchStorage();
7
10
  expect(storage).toBeInstanceOf(ScratchStorage);
@@ -68,15 +71,15 @@ const getTestAssets = storage => [
68
71
  ];
69
72
 
70
73
  const addWebStores = storage => {
71
- // these `asset => ...` callbacks generate values specifically for the cross-fetch mock
74
+ // these `asset => ...` callbacks generate values specifically for the fetch mock
72
75
  // in the real world they would generate proper URIs
73
76
  storage.addWebStore(
74
77
  [storage.AssetType.Project],
75
- asset => asset.assetId,
78
+ asset => `http://example.com/${asset.assetId}`,
76
79
  null, null);
77
80
  storage.addWebStore(
78
81
  [storage.AssetType.ImageVector, storage.AssetType.ImageBitmap, storage.AssetType.Sound],
79
- asset => `${asset.assetId}.${asset.dataFormat}`,
82
+ asset => `http://example.com/${asset.assetId}.${asset.dataFormat}`,
80
83
  null, null
81
84
  );
82
85
  };
@@ -1,13 +1,14 @@
1
1
  const TextDecoder = require('util').TextDecoder;
2
2
 
3
- jest.mock('cross-fetch');
4
- const mockFetch = require('cross-fetch');
3
+ const mockFetch = require('../fixtures/mockFetch.js');
4
+ jest.spyOn(global, 'fetch').mockImplementation(mockFetch.fetch);
5
+
5
6
  const {FetchTool} = require('../../src/FetchTool');
6
7
 
7
8
  test('send success returns response.text()', async () => {
8
9
  const tool = new FetchTool();
9
10
 
10
- const result = await tool.send({url: '200'});
11
+ const result = await tool.send({url: 'http://example.com/200'});
11
12
  expect(result).toBe(mockFetch.successText);
12
13
  });
13
14
 
@@ -17,7 +18,7 @@ test('send failure returns response.status', async () => {
17
18
  const catcher = jest.fn();
18
19
 
19
20
  try {
20
- await tool.send({url: '500'});
21
+ await tool.send({url: 'http://example.com/500'});
21
22
  } catch (e) {
22
23
  catcher(e);
23
24
  }
@@ -31,14 +32,14 @@ test('get success returns Uint8Array.body(response.arrayBuffer())', async () =>
31
32
 
32
33
  const tool = new FetchTool();
33
34
 
34
- const result = await tool.get({url: '200'});
35
+ const result = await tool.get({url: 'http://example.com/200'});
35
36
  expect(decoder.decode(result)).toBe(mockFetch.successText);
36
37
  });
37
38
 
38
39
  test('get with 404 response returns null data', async () => {
39
40
  const tool = new FetchTool();
40
41
 
41
- const result = await tool.get({url: '404'});
42
+ const result = await tool.get({url: 'http://example.com/404'});
42
43
  expect(result).toBeNull();
43
44
  });
44
45
 
@@ -47,7 +48,7 @@ test('get failure returns response.status', async () => {
47
48
  const catcher = jest.fn();
48
49
 
49
50
  try {
50
- await tool.get({url: '500'});
51
+ await tool.get({url: 'http://example.com/500'});
51
52
  } catch (e) {
52
53
  catcher(e);
53
54
  }
@@ -1,4 +1,5 @@
1
- jest.mock('cross-fetch');
1
+ const mockFetch = require('../fixtures/mockFetch.js');
2
+ jest.spyOn(global, 'fetch').mockImplementation(mockFetch.fetch);
2
3
 
3
4
  beforeEach(() => {
4
5
  // reset the metadata container to ensure the tests don't interfere with each other
@@ -17,7 +18,7 @@ test('get without metadata', async () => {
17
18
  const tool = new FetchTool();
18
19
 
19
20
  const mockFetchTestData = {};
20
- const result = await tool.get({url: '200', mockFetchTestData});
21
+ const result = await tool.get({url: 'http://example.com/200', mockFetchTestData});
21
22
 
22
23
  expect(result).toBeInstanceOf(Uint8Array);
23
24
  expect(mockFetchTestData.headers).toBeTruthy();
@@ -35,7 +36,7 @@ test('get with metadata', async () => {
35
36
  setMetadata(RequestMetadata.RunId, 5678);
36
37
 
37
38
  const mockFetchTestData = {};
38
- const result = await tool.get({url: '200', mockFetchTestData});
39
+ const result = await tool.get({url: 'http://example.com/200', mockFetchTestData});
39
40
 
40
41
  expect(result).toBeInstanceOf(Uint8Array);
41
42
  expect(mockFetchTestData.headers).toBeTruthy();
@@ -49,7 +50,7 @@ test('send without metadata', async () => {
49
50
  const tool = new FetchTool();
50
51
 
51
52
  const mockFetchTestData = {};
52
- const result = await tool.send({url: '200', mockFetchTestData});
53
+ const result = await tool.send({url: 'http://example.com/200', mockFetchTestData});
53
54
 
54
55
  expect(typeof result).toBe('string');
55
56
  expect(mockFetchTestData.headers).toBeTruthy();
@@ -67,7 +68,7 @@ test('send with metadata', async () => {
67
68
  setMetadata(RequestMetadata.RunId, 8765);
68
69
 
69
70
  const mockFetchTestData = {};
70
- const result = await tool.send({url: '200', mockFetchTestData});
71
+ const result = await tool.send({url: 'http://example.com/200', mockFetchTestData});
71
72
 
72
73
  expect(typeof result).toBe('string');
73
74
  expect(mockFetchTestData.headers).toBeTruthy();
@@ -89,7 +90,7 @@ test('selectively delete metadata', async () => {
89
90
 
90
91
  const mockFetchTestData = {};
91
92
 
92
- const result1 = await tool.send({url: '200', mockFetchTestData});
93
+ const result1 = await tool.send({url: 'http://example.com/200', mockFetchTestData});
93
94
  expect(typeof result1).toBe('string');
94
95
  expect(mockFetchTestData.headers).toBeTruthy();
95
96
 
@@ -100,7 +101,7 @@ test('selectively delete metadata', async () => {
100
101
  // remove the Project ID from metadata
101
102
  unsetMetadata(RequestMetadata.ProjectId);
102
103
 
103
- const result2 = await tool.send({url: '200', mockFetchTestData});
104
+ const result2 = await tool.send({url: 'http://example.com/200', mockFetchTestData});
104
105
  expect(typeof result2).toBe('string');
105
106
  expect(mockFetchTestData.headers).toBeTruthy();
106
107
 
@@ -120,7 +121,7 @@ test('metadata has case-insensitive keys', async () => {
120
121
  const tool = new FetchTool();
121
122
 
122
123
  const mockFetchTestData = {};
123
- await tool.get({url: '200', mockFetchTestData});
124
+ await tool.get({url: 'http://example.com/200', mockFetchTestData});
124
125
 
125
126
  expect(mockFetchTestData.headers).toBeTruthy();
126
127
  expect(mockFetchTestData.headersCount).toBe(1);
package/tsconfig.json CHANGED
@@ -9,7 +9,6 @@
9
9
 
10
10
  /* Modules */
11
11
  "module": "Preserve",
12
- "types": ["./src/types.d.ts"],
13
12
 
14
13
  /* Emit */
15
14
  "declaration": true,
@@ -5,6 +5,7 @@
5
5
  /* Visit https://aka.ms/tsconfig to read more about this file */
6
6
 
7
7
  /* Modules */
8
+ "isolatedModules": true, // for ts-jest
8
9
  "module": "CommonJS",
9
10
  "types": ["jest", "./src/types.d.ts"],
10
11
  }