apify-test-tools 0.9.1-beta.3 → 0.9.1-beta.5

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 (70) hide show
  1. package/.prettierignore +3 -0
  2. package/.vscode/settings.json +2 -1
  3. package/CHANGELOG.md +4 -0
  4. package/bin/main.ts +2 -1
  5. package/bin/types.ts +0 -11
  6. package/bin/utils/config/load-config.ts +251 -0
  7. package/bin/utils/json-file.ts +55 -0
  8. package/bin/utils.ts +0 -138
  9. package/dist/bin/main.d.ts.map +1 -1
  10. package/dist/bin/main.js +2 -1
  11. package/dist/bin/main.js.map +1 -1
  12. package/dist/bin/types.d.ts +0 -9
  13. package/dist/bin/types.d.ts.map +1 -1
  14. package/dist/bin/utils/config/load-config.d.ts +44 -0
  15. package/dist/bin/utils/config/load-config.d.ts.map +1 -0
  16. package/dist/bin/utils/config/load-config.js +177 -0
  17. package/dist/bin/utils/config/load-config.js.map +1 -0
  18. package/dist/bin/utils/json-file.d.ts +20 -0
  19. package/dist/bin/utils/json-file.d.ts.map +1 -0
  20. package/dist/bin/utils/json-file.js +42 -0
  21. package/dist/bin/utils/json-file.js.map +1 -0
  22. package/dist/bin/utils.d.ts +0 -6
  23. package/dist/bin/utils.d.ts.map +1 -1
  24. package/dist/bin/utils.js +0 -98
  25. package/dist/bin/utils.js.map +1 -1
  26. package/dist/lib/consts.d.ts +1 -0
  27. package/dist/lib/consts.d.ts.map +1 -1
  28. package/dist/lib/consts.js +3 -0
  29. package/dist/lib/consts.js.map +1 -1
  30. package/dist/lib/lib.d.ts +4 -0
  31. package/dist/lib/lib.d.ts.map +1 -1
  32. package/dist/lib/lib.js +12 -16
  33. package/dist/lib/lib.js.map +1 -1
  34. package/dist/lib/types.d.ts +11 -3
  35. package/dist/lib/types.d.ts.map +1 -1
  36. package/dist/test/unit/bin/utils/actor-config.test.d.ts +2 -0
  37. package/dist/test/unit/bin/utils/actor-config.test.d.ts.map +1 -0
  38. package/dist/test/unit/bin/{utils.test.js → utils/actor-config.test.js} +126 -51
  39. package/dist/test/unit/bin/utils/actor-config.test.js.map +1 -0
  40. package/dist/test/unit/bin/utils/files.test.d.ts +2 -0
  41. package/dist/test/unit/bin/utils/files.test.d.ts.map +1 -0
  42. package/dist/test/unit/bin/utils/files.test.js +117 -0
  43. package/dist/test/unit/bin/utils/files.test.js.map +1 -0
  44. package/dist/test/unit/lib.test.d.ts +2 -0
  45. package/dist/test/unit/lib.test.d.ts.map +1 -0
  46. package/dist/test/unit/lib.test.js +37 -0
  47. package/dist/test/unit/lib.test.js.map +1 -0
  48. package/dist/tsconfig.tsbuildinfo +1 -1
  49. package/lib/consts.ts +4 -0
  50. package/lib/lib.ts +20 -18
  51. package/lib/types.ts +11 -3
  52. package/package.json +3 -2
  53. package/test/fixtures/bin/utils/files/array.json +1 -0
  54. package/test/fixtures/bin/utils/files/comments.jsonc +4 -0
  55. package/test/fixtures/bin/utils/files/directory.json/.gitkeep +0 -0
  56. package/test/fixtures/bin/utils/files/empty-object.json +1 -0
  57. package/test/fixtures/bin/utils/files/empty.json +0 -0
  58. package/test/fixtures/bin/utils/files/malformed.json +1 -0
  59. package/test/fixtures/bin/utils/files/nested.json +6 -0
  60. package/test/fixtures/bin/utils/files/no-json-extension.actorrc +1 -0
  61. package/test/fixtures/bin/utils/files/null.json +1 -0
  62. package/test/fixtures/bin/utils/files/number.json +1 -0
  63. package/test/fixtures/bin/utils/files/unreadable.json +1 -0
  64. package/test/tsconfig.json +4 -2
  65. package/test/unit/bin/{utils.test.ts → utils/actor-config.test.ts} +152 -52
  66. package/test/unit/bin/utils/files.test.ts +158 -0
  67. package/test/unit/lib.test.ts +53 -0
  68. package/dist/test/unit/bin/utils.test.d.ts +0 -2
  69. package/dist/test/unit/bin/utils.test.d.ts.map +0 -1
  70. package/dist/test/unit/bin/utils.test.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAErD,MAAM,MAAM,UAAU,GAAG;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI;IACxB,KAAK,EAAE,IAAI,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;IAC5B,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI;IACrB,KAAK,EAAE,CAAC,EAAE,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,YAAY,GAClB;IACI,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,SAAS,CAAC;CACnB,GACD;IACI,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACf,CAAC;AAER,MAAM,MAAM,cAAc,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,YAAY,GAAG,cAAc,CAAC;AAE9D,MAAM,MAAM,+BAA+B,GAAG;IAC1C,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,cAAc,EAAE,QAAQ,GAAG,IAAI,CAAC;IAChC,eAAe,EAAE,QAAQ,GAAG,IAAI,CAAC;IACjC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,mBAAmB,CAAC,QAAQ,SAAS,MAAM,IAAI,OAAO,CAAC,+BAA+B,CAAC,GAAG;IAClG,gBAAgB,EAAE,QAAQ,CAAC;IAC3B;;;;;;;;;;;;;OAaG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;CACnD,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,uBAAuB,EAAE,MAAM,CAAC;IAChC,yBAAyB,EAAE,MAAM,CAAC;IAClC,wBAAwB,EAAE,MAAM,CAAC;IACjC,wBAAwB,EAAE,MAAM,CAAC;IACjC,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,gCAAgC,EAAE,MAAM,CAAC;IACzC,kCAAkC,EAAE,MAAM,CAAC;IAC3C,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,yBAAyB,EAAE,MAAM,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,SAAS,GACf,WAAW,GACX,OAAO,GACP,SAAS,GACT,QAAQ,GACR,UAAU,GACV,SAAS,GACT,YAAY,GACZ,WAAW,CAAC;AAElB,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,OAAO;IACtC,SAAS,EAAE,MAAM,CAAC,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC,CAAC;IACzB,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,CAAC;IACrD;;;;;;;;;;OAUG;IACH,YAAY,EAAE,CAAC,QAAQ,SAAS,MAAM,EAAE,OAAO,EAAE,mBAAmB,CAAC,QAAQ,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9F,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,CAAC,CAAC;IACnC,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,SAAS,CAAC;CACvD;AAED,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,SAAS,CAAC,GAAG;IACpE;;;;;OAKG;IAEH,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;CACzC,CAAC;AAEF,OAAO,QAAQ,QAAQ,CAAC;IAEpB,UAAU,SAAS,CAAC,CAAC,GAAG,GAAG,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC;KAAG;IAExD,UAAU,QAAQ,CAAC,CAAC,GAAG,GAAG,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC;KAAG;IAEvD,UAAU,4BAA6B,SAAQ,aAAa;KAAG;CAClE"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../lib/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=actor-config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actor-config.test.d.ts","sourceRoot":"","sources":["../../../../../test/unit/bin/utils/actor-config.test.ts"],"names":[],"mappings":""}
@@ -1,28 +1,76 @@
1
- import { afterEach, describe, expect, it, vi } from 'vitest';
2
- import { CONFIG_FILE_NAME, readConfigFile } from '../../../bin/utils.js';
3
- const { fsMock } = vi.hoisted(() => ({
4
- fsMock: {
5
- readFile: vi.fn(),
6
- },
7
- }));
8
- vi.mock('node:fs/promises', () => ({ default: fsMock }));
9
- afterEach(() => vi.restoreAllMocks());
1
+ import fs from 'node:fs/promises';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
5
+ import { CONFIG_FILE_NAME, loadActorConfig, parseConfigFile, readConfigFile, resolveRawConfig, } from '../../../../bin/utils/config/load-config.js';
6
+ // `readConfigFile` resolves every path against the process's working directory, so these tests give it
7
+ // a real one: a throwaway repo in a temp dir. Reading actual files rather than a mocked
8
+ // `node:fs/promises` is what makes the path handling (the ".actor/" hop, a dockerContextDir escaping
9
+ // the repo root) worth asserting on — against a mock those assertions only describe the mock.
10
+ let repoDir;
11
+ let originalCwd;
12
+ beforeEach(async () => {
13
+ originalCwd = process.cwd();
14
+ // `realpath` because macOS hands out a symlinked temp dir, while `process.cwd()` reports the target.
15
+ repoDir = await fs.realpath(await fs.mkdtemp(path.join(os.tmpdir(), 'apify-test-tools-config-')));
16
+ process.chdir(repoDir);
17
+ });
18
+ afterEach(async () => {
19
+ process.chdir(originalCwd);
20
+ await fs.rm(repoDir, { recursive: true, force: true });
21
+ });
10
22
  const emptyActorSelection = { actors: [], ignore: [] };
11
23
  const validConfig = (actors) => JSON.stringify({ actors });
12
24
  const actorJson = (fields = {}) => JSON.stringify(fields);
13
- const expectFileRead = (filePath) => {
14
- expect(fsMock.readFile).toHaveBeenCalledWith(filePath, expect.anything());
15
- };
16
- const mockFiles = (files) => {
17
- fsMock.readFile.mockImplementation(async (filePath) => {
18
- if (filePath in files)
19
- return Promise.resolve(files[filePath]);
20
- return Promise.reject(new Error(`ENOENT: ${filePath}`));
21
- });
22
- };
25
+ const writeFiles = async (files) => Promise.all(Object.entries(files).map(async ([filePath, contents]) => {
26
+ const absPath = path.join(repoDir, filePath);
27
+ await fs.mkdir(path.dirname(absPath), { recursive: true });
28
+ await fs.writeFile(absPath, contents);
29
+ }));
30
+ // Stages 2-4 are callable on their own, which is the point: a differently shaped config file only
31
+ // has to reach `resolveRawConfig`'s output to work with everything downstream.
32
+ describe('the parse/resolve/load seam', () => {
33
+ it('parseConfigFile validates the file shape without touching the filesystem', () => {
34
+ const entry = { folder: 'actors/shopify', actorFullName: 'myteam/shopify', tokenEnvVar: 'APIFY_TOKEN' };
35
+ expect(parseConfigFile({ actors: [entry] })).toEqual({ actors: [entry] });
36
+ expect(() => parseConfigFile({ actors: [{ ...entry, folder: 123 }] })).toThrow(/Invalid "folder"/);
37
+ });
38
+ it('resolveRawConfig is where the repo root becomes "" and trailing slashes go', () => {
39
+ const result = resolveRawConfig({
40
+ actors: [
41
+ { folder: '.', actorFullName: 'myteam/root', tokenEnvVar: 'APIFY_TOKEN' },
42
+ {
43
+ folder: 'actors/shopify/',
44
+ actorFullName: 'myteam/shopify',
45
+ tokenEnvVar: 'APIFY_TOKEN',
46
+ overrideActorContext: ['packages/'],
47
+ },
48
+ ],
49
+ });
50
+ expect(result).toEqual([
51
+ { folder: '', actorFullName: 'myteam/root', tokenEnvVar: 'APIFY_TOKEN', overrideActorContext: undefined },
52
+ {
53
+ folder: 'actors/shopify',
54
+ actorFullName: 'myteam/shopify',
55
+ tokenEnvVar: 'APIFY_TOKEN',
56
+ overrideActorContext: ['packages'],
57
+ },
58
+ ]);
59
+ });
60
+ it('loadActorConfig resolves data coming from actor.json', async () => {
61
+ await writeFiles({ 'actors/shopify/.actor/actor.json': actorJson({ dockerContextDir: '..' }) });
62
+ expect(loadActorConfig({ folder: 'actors/shopify', actorFullName: 'myteam/shopify', tokenEnvVar: 'APIFY_TOKEN' })).toEqual({
63
+ actorFullName: 'myteam/shopify',
64
+ folder: 'actors/shopify',
65
+ tokenEnvVar: 'APIFY_TOKEN',
66
+ dockerContextDir: 'actors/shopify',
67
+ contextPaths: ['actors/shopify'],
68
+ });
69
+ });
70
+ });
23
71
  describe('readConfigFile', () => {
24
72
  it('returns correct ActorConfig[] for a valid config', async () => {
25
- mockFiles({
73
+ await writeFiles({
26
74
  [CONFIG_FILE_NAME]: validConfig([
27
75
  {
28
76
  folder: 'actors/shopify',
@@ -33,7 +81,6 @@ describe('readConfigFile', () => {
33
81
  'actors/shopify/.actor/actor.json': actorJson({ dockerContextDir: '../../..' }),
34
82
  });
35
83
  const result = await readConfigFile(emptyActorSelection);
36
- expectFileRead('actors/shopify/.actor/actor.json');
37
84
  expect(result).toEqual([
38
85
  {
39
86
  actorFullName: 'myteam/shopify-scraper',
@@ -45,7 +92,7 @@ describe('readConfigFile', () => {
45
92
  ]);
46
93
  });
47
94
  it('normalizes folder "." to ""', async () => {
48
- mockFiles({
95
+ await writeFiles({
49
96
  [CONFIG_FILE_NAME]: validConfig([
50
97
  { folder: '.', actorFullName: 'apify/my-actor', tokenEnvVar: 'APIFY_TOKEN_APIFY' },
51
98
  ]),
@@ -53,10 +100,9 @@ describe('readConfigFile', () => {
53
100
  });
54
101
  const result = await readConfigFile(emptyActorSelection);
55
102
  expect(result[0].folder).toBe('');
56
- expectFileRead('.actor/actor.json');
57
103
  });
58
104
  it('defaults dockerContextDir to actor folder when absent from actor.json', async () => {
59
- mockFiles({
105
+ await writeFiles({
60
106
  [CONFIG_FILE_NAME]: validConfig([
61
107
  { folder: 'actors/web-scraper', actorFullName: 'apify/web-scraper', tokenEnvVar: 'APIFY_TOKEN_APIFY' },
62
108
  ]),
@@ -67,7 +113,7 @@ describe('readConfigFile', () => {
67
113
  expect(result[0].contextPaths).toEqual(['actors/web-scraper']);
68
114
  });
69
115
  it('resolves dockerContextDir relative to .actor/ folder', async () => {
70
- mockFiles({
116
+ await writeFiles({
71
117
  [CONFIG_FILE_NAME]: validConfig([
72
118
  { folder: 'actors/shopify', actorFullName: 'myteam/shopify', tokenEnvVar: 'APIFY_TOKEN' },
73
119
  ]),
@@ -76,8 +122,17 @@ describe('readConfigFile', () => {
76
122
  const result = await readConfigFile(emptyActorSelection);
77
123
  expect(result[0].dockerContextDir).toBe('');
78
124
  });
125
+ it('throws when dockerContextDir resolves outside the repository root', async () => {
126
+ await writeFiles({
127
+ [CONFIG_FILE_NAME]: validConfig([
128
+ { folder: 'actors/shopify', actorFullName: 'myteam/shopify', tokenEnvVar: 'APIFY_TOKEN' },
129
+ ]),
130
+ 'actors/shopify/.actor/actor.json': actorJson({ dockerContextDir: '../../../..' }),
131
+ });
132
+ await expect(readConfigFile(emptyActorSelection)).rejects.toThrow(/resolves outside the repository root/);
133
+ });
79
134
  it('resolves contextPaths from overrideActorContext', async () => {
80
- mockFiles({
135
+ await writeFiles({
81
136
  [CONFIG_FILE_NAME]: validConfig([
82
137
  {
83
138
  folder: 'actors/shopify',
@@ -92,7 +147,7 @@ describe('readConfigFile', () => {
92
147
  expect(result[0].contextPaths).toEqual(['actors/shopify', 'packages']);
93
148
  });
94
149
  it('handles multiple actors', async () => {
95
- mockFiles({
150
+ await writeFiles({
96
151
  [CONFIG_FILE_NAME]: validConfig([
97
152
  { folder: 'actors/web-scraper', actorFullName: 'apify/web-scraper', tokenEnvVar: 'APIFY_TOKEN_APIFY' },
98
153
  {
@@ -110,19 +165,22 @@ describe('readConfigFile', () => {
110
165
  expect(result[1].actorFullName).toBe('other-team/email-sender');
111
166
  });
112
167
  it('throws when config file is missing', async () => {
113
- fsMock.readFile.mockRejectedValue(new Error('ENOENT'));
114
168
  await expect(readConfigFile(emptyActorSelection)).rejects.toThrow('not found');
115
169
  });
116
170
  it('throws when config file contains invalid JSON', async () => {
117
- fsMock.readFile.mockResolvedValue('{bad json');
171
+ await writeFiles({ [CONFIG_FILE_NAME]: '{bad json' });
118
172
  await expect(readConfigFile(emptyActorSelection)).rejects.toThrow('invalid JSON');
119
173
  });
120
174
  it('throws when actors array is missing', async () => {
121
- fsMock.readFile.mockResolvedValue(JSON.stringify({ notActors: [] }));
175
+ await writeFiles({ [CONFIG_FILE_NAME]: JSON.stringify({ notActors: [] }) });
176
+ await expect(readConfigFile(emptyActorSelection)).rejects.toThrow('"actors" array');
177
+ });
178
+ it('throws when the config file is not a JSON object', async () => {
179
+ await writeFiles({ [CONFIG_FILE_NAME]: JSON.stringify([{ folder: 'actors/shopify' }]) });
122
180
  await expect(readConfigFile(emptyActorSelection)).rejects.toThrow('"actors" array');
123
181
  });
124
182
  it('throws on duplicate folders', async () => {
125
- mockFiles({
183
+ await writeFiles({
126
184
  [CONFIG_FILE_NAME]: validConfig([
127
185
  { folder: 'actors/shopify', actorFullName: 'apify/shopify', tokenEnvVar: 'APIFY_TOKEN_APIFY' },
128
186
  { folder: 'actors/shopify', actorFullName: 'other/shopify', tokenEnvVar: 'APIFY_TOKEN_OTHER' },
@@ -132,7 +190,7 @@ describe('readConfigFile', () => {
132
190
  await expect(readConfigFile(emptyActorSelection)).rejects.toThrow('Duplicate folder');
133
191
  });
134
192
  it('throws on duplicate folders after normalization ("." and "")', async () => {
135
- mockFiles({
193
+ await writeFiles({
136
194
  [CONFIG_FILE_NAME]: validConfig([
137
195
  { folder: '.', actorFullName: 'apify/actor-a', tokenEnvVar: 'APIFY_TOKEN_APIFY' },
138
196
  { folder: '', actorFullName: 'other/actor-b', tokenEnvVar: 'APIFY_TOKEN_OTHER' },
@@ -142,7 +200,7 @@ describe('readConfigFile', () => {
142
200
  await expect(readConfigFile(emptyActorSelection)).rejects.toThrow('Duplicate folder');
143
201
  });
144
202
  it('throws when actor.json is missing', async () => {
145
- mockFiles({
203
+ await writeFiles({
146
204
  [CONFIG_FILE_NAME]: validConfig([
147
205
  { folder: 'actors/shopify', actorFullName: 'apify/shopify', tokenEnvVar: 'APIFY_TOKEN_APIFY' },
148
206
  ]),
@@ -150,13 +208,13 @@ describe('readConfigFile', () => {
150
208
  await expect(readConfigFile(emptyActorSelection)).rejects.toThrow('Cannot read');
151
209
  });
152
210
  it('throws when folder is missing', async () => {
153
- mockFiles({
211
+ await writeFiles({
154
212
  [CONFIG_FILE_NAME]: validConfig([{ actorFullName: 'apify/shopify', tokenEnvVar: 'APIFY_TOKEN_APIFY' }]),
155
213
  });
156
214
  await expect(readConfigFile(emptyActorSelection)).rejects.toThrow(/Invalid "folder"/);
157
215
  });
158
216
  it('throws when folder is not a string', async () => {
159
- mockFiles({
217
+ await writeFiles({
160
218
  [CONFIG_FILE_NAME]: validConfig([
161
219
  { folder: 123, actorFullName: 'apify/shopify', tokenEnvVar: 'APIFY_TOKEN_APIFY' },
162
220
  ]),
@@ -164,14 +222,14 @@ describe('readConfigFile', () => {
164
222
  await expect(readConfigFile(emptyActorSelection)).rejects.toThrow(/Invalid "folder"/);
165
223
  });
166
224
  it('throws when actorFullName is missing', async () => {
167
- mockFiles({
225
+ await writeFiles({
168
226
  [CONFIG_FILE_NAME]: validConfig([{ folder: 'actors/shopify', tokenEnvVar: 'APIFY_TOKEN_APIFY' }]),
169
227
  'actors/shopify/.actor/actor.json': actorJson({}),
170
228
  });
171
229
  await expect(readConfigFile(emptyActorSelection)).rejects.toThrow('Invalid "actorFullName"');
172
230
  });
173
231
  it('throws when actorFullName has no slash', async () => {
174
- mockFiles({
232
+ await writeFiles({
175
233
  [CONFIG_FILE_NAME]: validConfig([
176
234
  { folder: 'actors/shopify', actorFullName: 'shopify-scraper', tokenEnvVar: 'APIFY_TOKEN_APIFY' },
177
235
  ]),
@@ -180,7 +238,7 @@ describe('readConfigFile', () => {
180
238
  await expect(readConfigFile(emptyActorSelection)).rejects.toThrow('Invalid "actorFullName"');
181
239
  });
182
240
  it('throws when actorFullName has empty parts', async () => {
183
- mockFiles({
241
+ await writeFiles({
184
242
  [CONFIG_FILE_NAME]: validConfig([
185
243
  { folder: 'actors/shopify', actorFullName: '/shopify', tokenEnvVar: 'APIFY_TOKEN_APIFY' },
186
244
  ]),
@@ -188,8 +246,25 @@ describe('readConfigFile', () => {
188
246
  });
189
247
  await expect(readConfigFile(emptyActorSelection)).rejects.toThrow('Invalid "actorFullName"');
190
248
  });
249
+ it('throws when tokenEnvVar is missing', async () => {
250
+ await writeFiles({
251
+ [CONFIG_FILE_NAME]: validConfig([{ folder: 'actors/shopify', actorFullName: 'apify/shopify' }]),
252
+ 'actors/shopify/.actor/actor.json': actorJson({}),
253
+ });
254
+ await expect(readConfigFile(emptyActorSelection)).rejects.toThrow('Invalid "tokenEnvVar"');
255
+ });
256
+ it('reports every invalid field at once instead of only the first', async () => {
257
+ await writeFiles({
258
+ [CONFIG_FILE_NAME]: validConfig([{ folder: 123, actorFullName: 'shopify', overrideActorContext: 'nope' }]),
259
+ });
260
+ const promise = readConfigFile(emptyActorSelection);
261
+ await expect(promise).rejects.toThrow(/Invalid "folder"/);
262
+ await expect(promise).rejects.toThrow(/Invalid "actorFullName"/);
263
+ await expect(promise).rejects.toThrow(/Invalid "tokenEnvVar"/);
264
+ await expect(promise).rejects.toThrow(/Invalid "overrideActorContext"/);
265
+ });
191
266
  it('throws when overrideActorContext is not an array', async () => {
192
- mockFiles({
267
+ await writeFiles({
193
268
  [CONFIG_FILE_NAME]: validConfig([
194
269
  {
195
270
  folder: 'actors/shopify',
@@ -203,7 +278,7 @@ describe('readConfigFile', () => {
203
278
  await expect(readConfigFile(emptyActorSelection)).rejects.toThrow('Invalid "overrideActorContext"');
204
279
  });
205
280
  it('throws when overrideActorContext contains non-strings', async () => {
206
- mockFiles({
281
+ await writeFiles({
207
282
  [CONFIG_FILE_NAME]: validConfig([
208
283
  {
209
284
  folder: 'actors/shopify',
@@ -217,7 +292,7 @@ describe('readConfigFile', () => {
217
292
  await expect(readConfigFile(emptyActorSelection)).rejects.toThrow('Invalid "overrideActorContext"');
218
293
  });
219
294
  it('throws when overrideActorContext entries overlap (one is a prefix of another)', async () => {
220
- mockFiles({
295
+ await writeFiles({
221
296
  [CONFIG_FILE_NAME]: validConfig([
222
297
  {
223
298
  folder: 'actors/shopify',
@@ -231,7 +306,7 @@ describe('readConfigFile', () => {
231
306
  await expect(readConfigFile(emptyActorSelection)).rejects.toThrow(/overlap/);
232
307
  });
233
308
  it('throws when overrideActorContext contains the repo root alongside another entry', async () => {
234
- mockFiles({
309
+ await writeFiles({
235
310
  [CONFIG_FILE_NAME]: validConfig([
236
311
  {
237
312
  folder: 'actors/shopify',
@@ -245,7 +320,7 @@ describe('readConfigFile', () => {
245
320
  await expect(readConfigFile(emptyActorSelection)).rejects.toThrow(/overlap/);
246
321
  });
247
322
  it('adds the actor own folder automatically when overrideActorContext does not cover it', async () => {
248
- mockFiles({
323
+ await writeFiles({
249
324
  [CONFIG_FILE_NAME]: validConfig([
250
325
  {
251
326
  folder: 'actors/shopify',
@@ -260,7 +335,7 @@ describe('readConfigFile', () => {
260
335
  expect(result[0].contextPaths).toEqual(['code', 'shared', 'actors/shopify']);
261
336
  });
262
337
  it('strips trailing slashes from folder and overrideActorContext entries', async () => {
263
- mockFiles({
338
+ await writeFiles({
264
339
  [CONFIG_FILE_NAME]: validConfig([
265
340
  {
266
341
  folder: 'actors/shopify/',
@@ -276,7 +351,7 @@ describe('readConfigFile', () => {
276
351
  expect(result[0].contextPaths).toEqual(['actors/shopify', 'packages']);
277
352
  });
278
353
  it('allows overrideActorContext with disjoint sibling paths that all reach the actor folder via one entry', async () => {
279
- mockFiles({
354
+ await writeFiles({
280
355
  [CONFIG_FILE_NAME]: validConfig([
281
356
  {
282
357
  folder: 'actors/shopify',
@@ -291,7 +366,7 @@ describe('readConfigFile', () => {
291
366
  expect(result[0].contextPaths).toEqual(['actors/shopify', 'code', 'shared']);
292
367
  });
293
368
  describe('actor selection', () => {
294
- const twoActors = () => mockFiles({
369
+ const twoActors = async () => writeFiles({
295
370
  [CONFIG_FILE_NAME]: validConfig([
296
371
  { folder: 'actors/a', actorFullName: 'team/a', tokenEnvVar: 'TOKEN' },
297
372
  { folder: 'actors/b', actorFullName: 'team/b', tokenEnvVar: 'TOKEN' },
@@ -301,21 +376,21 @@ describe('readConfigFile', () => {
301
376
  });
302
377
  const fullNames = (result) => result.map((c) => c.actorFullName);
303
378
  it('returns all actors when the selection is empty', async () => {
304
- twoActors();
379
+ await twoActors();
305
380
  expect(fullNames(await readConfigFile(emptyActorSelection))).toEqual(['team/a', 'team/b']);
306
381
  });
307
382
  it('keeps only the selected actors', async () => {
308
- twoActors();
383
+ await twoActors();
309
384
  expect(fullNames(await readConfigFile({ actors: ['team/a'], ignore: [] }))).toEqual(['team/a']);
310
385
  });
311
386
  it('drops ignored actors', async () => {
312
- twoActors();
387
+ await twoActors();
313
388
  expect(fullNames(await readConfigFile({ actors: [], ignore: ['team/a'] }))).toEqual(['team/b']);
314
389
  });
315
390
  it('throws on an unknown actor name', async () => {
316
- twoActors();
391
+ await twoActors();
317
392
  await expect(readConfigFile({ actors: ['team/nope'], ignore: [] })).rejects.toThrow('do not exist: team/nope');
318
393
  });
319
394
  });
320
395
  });
321
- //# sourceMappingURL=utils.test.js.map
396
+ //# sourceMappingURL=actor-config.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actor-config.test.js","sourceRoot":"","sources":["../../../../../test/unit/bin/utils/actor-config.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=files.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.test.d.ts","sourceRoot":"","sources":["../../../../../test/unit/bin/utils/files.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,117 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { afterEach, describe, expect, it } from 'vitest';
5
+ import { safeReadJsonObjectFile } from '../../../../bin/utils/json-file.js';
6
+ // These tests read real fixture files rather than mocking `node:fs`: the whole point of
7
+ // `safeReadJsonObjectFile` is how it reacts to real stat/readFile outcomes (missing path, directory,
8
+ // symlink, unreadable file), so mocking those away would only assert the mock back to itself.
9
+ const FIXTURE_DIR = fileURLToPath(new URL('../../../fixtures/bin/utils/files/', import.meta.url));
10
+ const fixture = (name) => path.join(FIXTURE_DIR, name);
11
+ const NESTED_FIXTURE = {
12
+ storages: { datasets: { default: { title: 'Default' } } },
13
+ overrideActorContext: ['../shared', '.'],
14
+ changelog: null,
15
+ nested: [{ deep: [1, 2, { deeper: true }] }],
16
+ };
17
+ describe('safeReadJsonObjectFile', () => {
18
+ describe('valid JSON objects', () => {
19
+ it('returns the parsed contents, preserving nested objects, arrays and null values', () => {
20
+ const result = safeReadJsonObjectFile(fixture('nested.json'));
21
+ expect(result).toStrictEqual({ success: true, contents: NESTED_FIXTURE });
22
+ });
23
+ it('accepts an empty JSON object', () => {
24
+ const result = safeReadJsonObjectFile(fixture('empty-object.json'));
25
+ expect(result).toStrictEqual({ success: true, contents: {} });
26
+ });
27
+ it('reads files that are not named *.json', () => {
28
+ const result = safeReadJsonObjectFile(fixture('no-json-extension.actorrc'));
29
+ expect(result).toStrictEqual({ success: true, contents: { a: 1 } });
30
+ });
31
+ });
32
+ describe('filesystem-level handling', () => {
33
+ it('fails when the path does not exist', () => {
34
+ const filePath = fixture('does-not-exist.json');
35
+ const result = safeReadJsonObjectFile(filePath);
36
+ expect(result).toMatchObject({
37
+ success: false,
38
+ reason: 'unreadable',
39
+ });
40
+ });
41
+ // The fixture is named `directory.json` on purpose — the check is `stat().isFile()`, not the extension.
42
+ it('fails when the path is a directory', () => {
43
+ const filePath = fixture('directory.json');
44
+ const result = safeReadJsonObjectFile(filePath);
45
+ expect(result).toMatchObject({
46
+ success: false,
47
+ reason: 'not-a-file',
48
+ });
49
+ });
50
+ // Regression guard: `lstat` would report the link itself as "not a file" and reject it, even
51
+ // though `readFile` follows symlinks and would have read the target without complaint.
52
+ it('follows a symlink to its target file', () => {
53
+ const result = safeReadJsonObjectFile(fixture('symlink-to-valid.json'));
54
+ expect(result).toStrictEqual({ success: true, contents: NESTED_FIXTURE });
55
+ });
56
+ // Git only tracks the executable bit, so this is the one case whose fixture cannot carry its own
57
+ // mode — `unreadable.json` is committed readable and stripped of permissions just for this test.
58
+ describe('unreadable file', () => {
59
+ const filePath = fixture('unreadable.json');
60
+ afterEach(async () => fs.chmod(filePath, 0o644));
61
+ it.runIf(process.getuid?.() !== 0)('fails when the file exists but cannot be read', async () => {
62
+ await fs.chmod(filePath, 0o000);
63
+ const result = safeReadJsonObjectFile(filePath);
64
+ expect(result).toMatchObject({
65
+ success: false,
66
+ reason: 'unreadable',
67
+ });
68
+ });
69
+ });
70
+ });
71
+ describe('JSON that is not an object', () => {
72
+ it('rejects a JSON array', () => {
73
+ const filePath = fixture('array.json');
74
+ const result = safeReadJsonObjectFile(filePath);
75
+ expect(result).toMatchObject({
76
+ success: false,
77
+ reason: 'not-an-object',
78
+ });
79
+ });
80
+ it('rejects JSON null', () => {
81
+ const filePath = fixture('null.json');
82
+ const result = safeReadJsonObjectFile(filePath);
83
+ expect(result).toMatchObject({
84
+ success: false,
85
+ reason: 'not-an-object',
86
+ });
87
+ });
88
+ it('rejects a JSON primitive', () => {
89
+ const filePath = fixture('number.json');
90
+ const result = safeReadJsonObjectFile(filePath);
91
+ expect(result).toMatchObject({
92
+ success: false,
93
+ reason: 'not-an-object',
94
+ });
95
+ });
96
+ });
97
+ describe('unparseable files', () => {
98
+ it('fails on malformed JSON', () => {
99
+ const filePath = fixture('malformed.json');
100
+ const result = safeReadJsonObjectFile(filePath);
101
+ expect(result).toMatchObject({ success: false, reason: 'invalid-json' });
102
+ expect(result.failure.message).toContain(`Failed to parse ${filePath}`);
103
+ });
104
+ it('fails on an empty file', () => {
105
+ const filePath = fixture('empty.json');
106
+ const result = safeReadJsonObjectFile(filePath);
107
+ expect(result).toMatchObject({ success: false, reason: 'invalid-json' });
108
+ expect(result.failure.message).toContain(`Failed to parse ${filePath}`);
109
+ });
110
+ it.fails('reads jsonc', () => {
111
+ const filePath = fixture('comments.jsonc');
112
+ const result = safeReadJsonObjectFile(filePath);
113
+ expect(result).toMatchObject({ success: true, contents: { a: 3 } });
114
+ });
115
+ });
116
+ });
117
+ //# sourceMappingURL=files.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.test.js","sourceRoot":"","sources":["../../../../../test/unit/bin/utils/files.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=lib.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.test.d.ts","sourceRoot":"","sources":["../../../test/unit/lib.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,37 @@
1
+ import { ApifyClient } from 'apify-client';
2
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
3
+ import { DEFAULT_TEST_ACTOR_TIMEOUT_SECS } from '../../lib/consts.js';
4
+ import { _private } from '../../lib/lib.js';
5
+ import * as UtilsModule from '../../lib/utils.js';
6
+ const { createStartRunFn } = _private;
7
+ describe('createStartRunFn()', () => {
8
+ const actorCallMock = vi.fn(async () => Promise.resolve({ id: 'fake-run-id' }));
9
+ const testContext = { task: {}, annotate: vi.fn() };
10
+ vi.spyOn(UtilsModule, 'sleep').mockResolvedValue(undefined);
11
+ beforeEach(vi.clearAllMocks);
12
+ it('should apply default timeout to actor runs', async () => {
13
+ // Arrange
14
+ vi.spyOn(ApifyClient.prototype, 'actor').mockReturnValue({
15
+ call: actorCallMock,
16
+ get: vi.fn(async () => ({ defaultRunOptions: {} })),
17
+ });
18
+ // Act
19
+ await createStartRunFn('123', testContext)({ input: {} });
20
+ // Assert
21
+ expect(actorCallMock).toHaveBeenCalledTimes(1);
22
+ expect(actorCallMock).toHaveBeenCalledWith({}, { build: undefined, log: null, timeout: DEFAULT_TEST_ACTOR_TIMEOUT_SECS });
23
+ });
24
+ it('should respect the default actor run timeout if less', async () => {
25
+ // Arrange
26
+ vi.spyOn(ApifyClient.prototype, 'actor').mockReturnValue({
27
+ call: actorCallMock,
28
+ get: vi.fn(async () => ({ defaultRunOptions: { timeoutSecs: 60 } })),
29
+ });
30
+ // Act
31
+ await createStartRunFn('123', testContext)({ input: {} });
32
+ // Assert
33
+ expect(actorCallMock).toHaveBeenCalledTimes(1);
34
+ expect(actorCallMock).toHaveBeenCalledWith({}, { build: undefined, log: null, timeout: 60 });
35
+ });
36
+ });
37
+ //# sourceMappingURL=lib.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.test.js","sourceRoot":"","sources":["../../../test/unit/lib.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9D,OAAO,EAAE,+BAA+B,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,WAAW,MAAM,oBAAoB,CAAC;AAElD,MAAM,EAAE,gBAAgB,EAAE,GAAG,QAAQ,CAAC;AAEtC,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAChC,MAAM,aAAa,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,aAAa,EAAc,CAAC,CAAC,CAAC;IAC5F,MAAM,WAAW,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,EAAE,EAA6B,EAAiB,CAAC;IAE9F,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAE5D,UAAU,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC;IAE7B,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QACxD,UAAU;QAEV,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,eAAe,CAAC;YACrD,IAAI,EAAE,aAAoC;YAC1C,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,iBAAiB,EAAE,EAAE,EAAE,CAAU,CAAuB;SACtE,CAAC,CAAC;QAElB,MAAM;QACN,MAAM,gBAAgB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAE1D,SAAS;QACT,MAAM,CAAC,aAAa,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,aAAa,CAAC,CAAC,oBAAoB,CACtC,EAAE,EACF,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,+BAA+B,EAAE,CAC5E,CAAC;IACN,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QAClE,UAAU;QACV,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,eAAe,CAAC;YACrD,IAAI,EAAE,aAAoC;YAC1C,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,iBAAiB,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,CAAU,CAAuB;SACvF,CAAC,CAAC;QAElB,MAAM;QACN,MAAM,gBAAgB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAE1D,SAAS;QACT,MAAM,CAAC,aAAa,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,aAAa,CAAC,CAAC,oBAAoB,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;IACjG,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}