@wocker/testing 1.0.1 → 1.0.2

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/lib/index.d.ts +2 -0
  2. package/lib/index.js +2 -0
  3. package/lib/makes/Test.d.ts +3 -2
  4. package/lib/makes/Test.js +3 -14
  5. package/lib/makes/TestingModuleBuilder.d.ts +14 -0
  6. package/lib/makes/TestingModuleBuilder.js +56 -0
  7. package/lib/modem/index.d.ts +3 -0
  8. package/lib/modem/index.js +19 -0
  9. package/lib/modem/makes/DockerStorage.d.ts +268 -0
  10. package/lib/modem/makes/DockerStorage.js +528 -0
  11. package/lib/modem/makes/Fixtures.d.ts +18 -0
  12. package/lib/modem/makes/Fixtures.js +109 -0
  13. package/lib/modem/makes/FixturesGen.d.ts +5 -0
  14. package/lib/modem/makes/FixturesGen.js +18 -0
  15. package/lib/modem/makes/ModemMock.d.ts +16 -0
  16. package/lib/modem/makes/ModemMock.js +46 -0
  17. package/lib/modem/makes/ModemRecorder.d.ts +14 -0
  18. package/lib/modem/makes/ModemRecorder.js +60 -0
  19. package/lib/modem/router/Request.d.ts +9 -0
  20. package/lib/modem/router/Request.js +13 -0
  21. package/lib/modem/router/Response.d.ts +7 -0
  22. package/lib/modem/router/Response.js +17 -0
  23. package/lib/modem/router/Router.d.ts +20 -0
  24. package/lib/modem/router/Router.js +104 -0
  25. package/lib/modem/router/index.d.ts +3 -0
  26. package/lib/modem/router/index.js +19 -0
  27. package/lib/modem/types/Container.d.ts +10 -0
  28. package/lib/modem/types/Container.js +2 -0
  29. package/lib/modem/types/HttpMethod.d.ts +1 -0
  30. package/lib/modem/types/HttpMethod.js +2 -0
  31. package/lib/modem/types/Image.d.ts +8 -0
  32. package/lib/modem/types/Image.js +2 -0
  33. package/lib/services/MockProcessService.d.ts +7 -0
  34. package/lib/services/MockProcessService.js +42 -0
  35. package/lib/services/index.d.ts +1 -0
  36. package/lib/services/index.js +17 -0
  37. package/package.json +10 -4
@@ -0,0 +1,528 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DockerStorage = void 0;
4
+ const http_1 = require("http");
5
+ const stream_1 = require("stream");
6
+ const cli_1 = require("@kearisp/cli");
7
+ const router_1 = require("../router");
8
+ class DockerStorage {
9
+ constructor() {
10
+ this.containers = [];
11
+ this.images = [];
12
+ this.fixtures = [];
13
+ this.router = new router_1.Router();
14
+ this.router.post(["/session", "/:version/session"], (_req, res) => {
15
+ const duplex = new stream_1.Duplex();
16
+ res.send(duplex);
17
+ });
18
+ this.router.get(["/containers/json", "/:version/containers/json"], (req, res) => {
19
+ res.status(200).send(this.listContainers(req.body));
20
+ });
21
+ this.router.post(["/containers/create", "/:version/containers/create"], (req, res) => {
22
+ const id = this.createContainer(req.body);
23
+ res.status(201).send({
24
+ Id: id
25
+ });
26
+ });
27
+ this.router.get(["/containers/:id/json", "/:version/containers/:id/json"], (req, res) => {
28
+ const inspect = this.containerInspect(req.params.id);
29
+ if (!inspect) {
30
+ throw new Error("Not found");
31
+ }
32
+ res.status(200).send(inspect);
33
+ });
34
+ this.router.post(["/containers/:id/start", "/:version/containers/:id/start"], (req, res) => {
35
+ this.run(req.params.id);
36
+ res.send(Buffer.from([]));
37
+ });
38
+ this.router.get(["/images/json", "/:version/images/json"], (req, res) => {
39
+ res.status(200).send(this.imageList(req.body));
40
+ });
41
+ this.router.get(["/images/:tag/json", "/:version/images/:tag/json"], (req, res) => {
42
+ const inspect = this.imageInspect(req.params.tag);
43
+ if (!inspect) {
44
+ throw new Error("Image not found");
45
+ }
46
+ res.status(200).send(inspect);
47
+ });
48
+ this.router.delete(["/images/:tag", "/:version/images/:tag"], (req, res) => {
49
+ res.status(200).send(this.imageDelete(req.params.tag));
50
+ });
51
+ this.router.post(["/images/create", "/:version/images/create"], (req, res) => {
52
+ const { params: { version = "v1" }, body: { fromImage, tag } } = req;
53
+ const stream = this.imagePull(version, fromImage, tag);
54
+ if (stream) {
55
+ res.status(200).send(stream);
56
+ }
57
+ else {
58
+ throw new Error(`Not image "${fromImage}:${tag}" found`);
59
+ }
60
+ });
61
+ this.router.post(["/build", "/:version/build"], (req, res) => {
62
+ const { params: { version = "v1" }, body } = req;
63
+ res.status(200).send(this.build(version, body));
64
+ });
65
+ }
66
+ listContainers(body) {
67
+ const { all, filters: { name } = {} } = body;
68
+ return this.containers.filter((container) => {
69
+ if (all) {
70
+ return true;
71
+ }
72
+ if (name && container.Name === `/${name}`) {
73
+ }
74
+ return container.State.Running;
75
+ }).map((container) => {
76
+ return {
77
+ Id: container.Id,
78
+ Names: [container.Name],
79
+ Image: container.Image,
80
+ ImageID: "",
81
+ Created: container.Created,
82
+ State: container.State.Status,
83
+ Status: "Up 1 seconds",
84
+ Ports: []
85
+ };
86
+ });
87
+ }
88
+ createContainer(info) {
89
+ const container = {
90
+ Id: this.generateId(),
91
+ Name: `/${info.name}`,
92
+ Image: info.Image,
93
+ State: {
94
+ Running: false,
95
+ Dead: false,
96
+ Status: "created",
97
+ Error: ""
98
+ },
99
+ Created: new Date().getTime() / 1000,
100
+ };
101
+ this.containers.push(container);
102
+ return container.Id;
103
+ }
104
+ run(id) {
105
+ const container = this.containers.find((container) => container.Id === id);
106
+ if (!container) {
107
+ throw new Error(`No such container: ${id}`);
108
+ }
109
+ container.State.Running = true;
110
+ container.State.Status = "running";
111
+ }
112
+ containerInspect(id) {
113
+ const container = this.containers.find((container) => container.Id === id);
114
+ if (!container) {
115
+ throw new Error(`No such container: ${id}`);
116
+ }
117
+ return {
118
+ Id: container.Id,
119
+ Name: container.Name,
120
+ Created: "2025-05-13T19:52:40.68081109Z",
121
+ Path: "/usr/local/bin/docker-entrypoint.sh",
122
+ Args: ["/usr/local/bin/bun"],
123
+ State: {
124
+ Status: container.State.Status,
125
+ Running: container.State.Running,
126
+ Paused: false,
127
+ Restarting: false,
128
+ OOMKilled: false,
129
+ Dead: false,
130
+ Pid: 0,
131
+ ExitCode: 0,
132
+ Error: "",
133
+ StartedAt: "0001-01-01T00:00:00Z",
134
+ FinishedAt: "0001-01-01T00:00:00Z"
135
+ },
136
+ Image: "sha256:3476c857e7c05a7950b3a8a684ffbc82f5cbeffe1b523ea1a92bdefc4539dc57",
137
+ ResolvConfPath: "",
138
+ HostnamePath: "",
139
+ HostsPath: "",
140
+ LogPath: "",
141
+ RestartCount: 0,
142
+ Driver: "overlayfs",
143
+ Platform: "linux",
144
+ MountLabel: "",
145
+ ProcessLabel: "",
146
+ AppArmorProfile: "",
147
+ ExecIDs: null,
148
+ HostConfig: {
149
+ Binds: null,
150
+ ContainerIDFile: "",
151
+ LogConfig: {
152
+ Type: "json-file",
153
+ Config: {}
154
+ },
155
+ NetworkMode: "bridge",
156
+ PortBindings: {},
157
+ RestartPolicy: {
158
+ Name: "no",
159
+ MaximumRetryCount: 0
160
+ },
161
+ AutoRemove: false,
162
+ VolumeDriver: "",
163
+ VolumesFrom: null,
164
+ ConsoleSize: [0, 0],
165
+ CapAdd: null,
166
+ CapDrop: null,
167
+ CgroupnsMode: "host",
168
+ Dns: null,
169
+ DnsOptions: null,
170
+ DnsSearch: null,
171
+ ExtraHosts: null,
172
+ GroupAdd: null,
173
+ IpcMode: "private",
174
+ Cgroup: "",
175
+ Links: null,
176
+ OomScoreAdj: 0,
177
+ PidMode: "",
178
+ Privileged: false,
179
+ PublishAllPorts: false,
180
+ ReadonlyRootfs: false,
181
+ SecurityOpt: null,
182
+ UTSMode: "",
183
+ UsernsMode: "",
184
+ ShmSize: 67108864,
185
+ Runtime: "runc",
186
+ Isolation: "",
187
+ CpuShares: 0,
188
+ Memory: 0,
189
+ NanoCpus: 0,
190
+ CgroupParent: "",
191
+ BlkioWeight: 0,
192
+ BlkioWeightDevice: null,
193
+ BlkioDeviceReadBps: null,
194
+ BlkioDeviceWriteBps: null,
195
+ BlkioDeviceReadIOps: null,
196
+ BlkioDeviceWriteIOps: null,
197
+ CpuPeriod: 0,
198
+ CpuQuota: 0,
199
+ CpuRealtimePeriod: 0,
200
+ CpuRealtimeRuntime: 0,
201
+ CpusetCpus: "",
202
+ CpusetMems: "",
203
+ Devices: null,
204
+ DeviceCgroupRules: null,
205
+ DeviceRequests: null,
206
+ MemoryReservation: 0,
207
+ MemorySwap: 0,
208
+ MemorySwappiness: null,
209
+ OomKillDisable: false,
210
+ PidsLimit: null,
211
+ Ulimits: null,
212
+ CpuCount: 0,
213
+ CpuPercent: 0,
214
+ IOMaximumIOps: 0,
215
+ IOMaximumBandwidth: 0,
216
+ MaskedPaths: [
217
+ "/proc/asound", "/proc/acpi", "/proc/kcore", "/proc/keys", "/proc/latency_stats",
218
+ "/proc/timer_list", "/proc/timer_stats", "/proc/sched_debug", "/proc/scsi",
219
+ "/sys/firmware", "/sys/devices/virtual/powercap"
220
+ ],
221
+ ReadonlyPaths: [
222
+ "/proc/bus", "/proc/fs", "/proc/irq", "/proc/sys", "/proc/sysrq-trigger"
223
+ ]
224
+ },
225
+ GraphDriver: {
226
+ Data: null,
227
+ Name: "overlayfs"
228
+ },
229
+ Mounts: [],
230
+ Config: {
231
+ Hostname: "36a07d831a95",
232
+ Domainname: "",
233
+ User: "",
234
+ AttachStdin: false,
235
+ AttachStdout: false,
236
+ AttachStderr: false,
237
+ Tty: false,
238
+ OpenStdin: false,
239
+ StdinOnce: false,
240
+ Env: [
241
+ "PATH=/usr/local/sbin:/usr/local/b in:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/bun-node-fallback-bin",
242
+ "BUN_RUNTIME_TRANSPILER_CACHE_PATH=0",
243
+ "BUN_INSTALL_BIN=/usr/local/bin"
244
+ ],
245
+ Cmd: [
246
+ "/usr/local/bin/bun"
247
+ ],
248
+ Image: "oven/bun:alpine",
249
+ Volumes: null,
250
+ WorkingDir: "/home/bun/app",
251
+ Entrypoint: [
252
+ "/usr/local/bin/docker-entrypoint.sh"
253
+ ],
254
+ OnBuild: null,
255
+ Labels: {
256
+ "desktop.docker.io/wsl-distro": "Ubuntu",
257
+ "org.opencontainers.image.created": "2025-05-10T14:05:09.084Z",
258
+ "org.opencontainers.image.description": "Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one",
259
+ "org.opencontainers.image.licenses": "NOASSERTION",
260
+ "org.opencontainers.image.revision": "64ed68c9e0faa7f5224876be8681d2bdc311454b",
261
+ "org.opencontainers.image.source": "https://github.com/oven-sh/bun",
262
+ "org.opencontainers.image.title": "bun",
263
+ "org.opencontainers.image.url": "https://github.com/oven-sh/bun",
264
+ "org.opencontainers.image.version": "1.2.13-alpine"
265
+ }
266
+ },
267
+ NetworkSettings: {
268
+ Bridge: "",
269
+ SandboxID: "",
270
+ SandboxKey: "",
271
+ Ports: {},
272
+ HairpinMode: false,
273
+ LinkLocalIPv6Address: "",
274
+ LinkLocalIPv6PrefixLen: 0,
275
+ SecondaryIPAddresses: null,
276
+ SecondaryIPv6Addresses: null,
277
+ EndpointID: "",
278
+ Gateway: "",
279
+ GlobalIPv6Address: "",
280
+ GlobalIPv6PrefixLen: 0,
281
+ IPAddress: "",
282
+ IPPrefixLen: 0,
283
+ IPv6Gateway: "",
284
+ MacAddress: "",
285
+ Networks: {
286
+ bridge: {
287
+ IPAMConfig: null,
288
+ Links: null,
289
+ Aliases: null,
290
+ MacAddress: "",
291
+ DriverOpts: null,
292
+ GwPriority: 0,
293
+ NetworkID: "",
294
+ EndpointID: "",
295
+ Gateway: "",
296
+ IPAddress: "",
297
+ IPPrefixLen: 0,
298
+ IPv6Gateway: "",
299
+ GlobalIPv6Address: "",
300
+ GlobalIPv6PrefixLen: 0,
301
+ DNSNames: null
302
+ }
303
+ }
304
+ },
305
+ ImageManifestDescriptor: {
306
+ mediaType: "application/vnd.oci.image.manifest.v1+json",
307
+ digest: "sha256:2cdc992a4322a4f82e07435700d22687a5f2101cbbbe2e4f9956eb490b07675b",
308
+ size: 1430,
309
+ platform: {
310
+ architecture: "amd64",
311
+ os: "linux"
312
+ }
313
+ }
314
+ };
315
+ }
316
+ imageList(body) {
317
+ if (Object.keys(body).length > 0) {
318
+ cli_1.Logger.warn("imageList(", body, ")");
319
+ return [];
320
+ }
321
+ const images = [];
322
+ for (const image of this.images) {
323
+ images.push({
324
+ Containers: -1,
325
+ Created: 1747579856,
326
+ Id: image.Id,
327
+ Labels: image.Labels,
328
+ ParentId: image.ParentId,
329
+ Descriptor: {
330
+ mediaType: "application/vnd.oci.image.manifest.v1+json",
331
+ digest: "sha256:72e58c97811826c57ab14f700f6a7cbb5147e4c8a60e84c53e5c07981bd62498",
332
+ size: 6461
333
+ },
334
+ RepoDigests: [
335
+ "project-lidermarket@sha256:72e58c97811826c57ab14f700f6a7cbb5147e4c8a60e84c53e5c07981bd62498"
336
+ ],
337
+ RepoTags: image.RepoTags,
338
+ SharedSize: -1,
339
+ Size: 746947017
340
+ });
341
+ }
342
+ return images;
343
+ }
344
+ imageInspect(tag) {
345
+ const image = this.images.find((image) => {
346
+ return image.RepoTags.includes(tag);
347
+ });
348
+ if (!image) {
349
+ return null;
350
+ }
351
+ return {
352
+ Id: image.Id,
353
+ RepoTags: image.RepoTags,
354
+ RepoDigests: [
355
+ "oven/bun@sha256:3476c857e7c05a7950b3a8a684ffbc82f5cbeffe1b523ea1a92bdefc4539dc57"
356
+ ],
357
+ Parent: "",
358
+ Comment: "buildkit.dockerfile.v0",
359
+ Created: "2025-05-10T14:05:18.376365783Z",
360
+ DockerVersion: "",
361
+ Author: "",
362
+ Config: {
363
+ Hostname: "",
364
+ Domainname: "",
365
+ User: "",
366
+ AttachStdin: false,
367
+ AttachStdout: false,
368
+ AttachStderr: false,
369
+ Tty: false,
370
+ OpenStdin: false,
371
+ StdinOnce: false,
372
+ Env: [
373
+ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/bun-node-fallback-bin",
374
+ "BUN_RUNTIME_TRANSPILER_CACHE_PATH=0",
375
+ "BUN_INSTALL_BIN=/usr/local/bin"
376
+ ],
377
+ Cmd: [
378
+ "/usr/local/bin/bun"
379
+ ],
380
+ ArgsEscaped: true,
381
+ Image: "",
382
+ Volumes: null,
383
+ WorkingDir: "/home/bun/app",
384
+ Entrypoint: [
385
+ "/usr/local/bin/docker-entrypoint.sh"
386
+ ],
387
+ OnBuild: null,
388
+ Labels: {
389
+ "org.opencontainers.image.created": "2025-05-10T14:05:09.084Z",
390
+ "org.opencontainers.image.description": "Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all inone",
391
+ "org.opencontainers.image.licenses": "NOASSERTION",
392
+ "org.opencontainers.image.revision": "64ed68c9e0faa7f5224876be8681d2bdc311454b",
393
+ "org.opencontainers.image.source": "https://github.com/oven-sh/bun",
394
+ "org.opencontainers.image.title": "bun",
395
+ "org.opencontainers.image.url": "https://github.com/oven-sh/bun",
396
+ "org.opencontainers.image.version": "1.2.13-alpine"
397
+ }
398
+ },
399
+ Architecture: "amd64",
400
+ Os: "linux",
401
+ Size: 43424417,
402
+ GraphDriver: {
403
+ Data: null,
404
+ Name: "overlayfs"
405
+ },
406
+ RootFS: {
407
+ Type: "layers",
408
+ Layers: [
409
+ "sha256:994456c4fd7b2b87346a81961efb4ce945a39592d32e0762b38768bca7c7d085",
410
+ "sha256:ef70d6692b1e80a64fc0b2e711743f8c48f3e6ee466627c41e8b20860e7f2585",
411
+ "sha256:d58e9e6425c6cae4632955cdfd38a4999dd9388c6634d715313daaac9597f75a",
412
+ "sha256:ad245466e7de8bcb67fcaeebd8b389a7d16d2b0c6f8f324991bf9cc4df245f2f",
413
+ "sha256:e372adeb3e6e54f548965d7606f46b59ebbbfff41adcbc82887fcc57f6f309af",
414
+ "sha256:93b857d12c79ea9799ac3c88b898ab836916901d160964b6e0088809af60cfe1"
415
+ ]
416
+ },
417
+ Metadata: {
418
+ LastTagTime: "2025-05-10T20:18:24.410728378Z"
419
+ },
420
+ Descriptor: {
421
+ mediaType: "application/vnd.oci.image.index.v1+json",
422
+ digest: "sha256:3476c857e7c05a7950b3a8a684ffbc82f5cbeffe1b523ea1a92bdefc4539dc57",
423
+ size: 1609
424
+ }
425
+ };
426
+ }
427
+ imagePull(version, imageName, tag) {
428
+ const fixture = (() => {
429
+ for (const fixture of this.fixtures) {
430
+ if (fixture.hasPull(version, imageName, tag)) {
431
+ return fixture;
432
+ }
433
+ }
434
+ return null;
435
+ })();
436
+ if (!fixture) {
437
+ return null;
438
+ }
439
+ const stream = fixture.pull(version, imageName, tag);
440
+ stream.on("end", () => {
441
+ const image = fixture.imageInspect(version, imageName, tag);
442
+ if (!image) {
443
+ return null;
444
+ }
445
+ this.images.push(image);
446
+ });
447
+ return stream;
448
+ }
449
+ imageDelete(imageTag) {
450
+ this.images = this.images
451
+ .filter((image) => {
452
+ return !(image.RepoTags.length === 1 && image.RepoTags.includes(imageTag));
453
+ })
454
+ .map((image) => {
455
+ if (image.RepoTags.includes(imageTag)) {
456
+ image.RepoTags = image.RepoTags.filter((tag) => {
457
+ return tag !== imageTag;
458
+ });
459
+ }
460
+ return image;
461
+ });
462
+ return null;
463
+ }
464
+ build(version, body) {
465
+ const { t: tag, version: builderVersion = "1" } = body;
466
+ const [imageName, imageTag = "latest"] = tag.split(":");
467
+ const fixture = this.fixtures.find((fixture) => {
468
+ return fixture.hasBuild(version, builderVersion, imageName, imageTag);
469
+ });
470
+ if (!fixture) {
471
+ throw new Error("Not found");
472
+ }
473
+ const stream = fixture.build(version, builderVersion, imageName, imageTag);
474
+ cli_1.Logger.info("1 >", version, builderVersion, imageName, imageTag);
475
+ stream.on("end", () => {
476
+ let image = this.images.find((image) => {
477
+ return image.RepoTags.includes(`${imageName}:${imageTag}`);
478
+ });
479
+ if (!image) {
480
+ image = fixture.imageInspect(version, imageName, imageTag);
481
+ this.images.push(image);
482
+ }
483
+ });
484
+ stream.on("error", (err) => {
485
+ cli_1.Logger.error(err.message);
486
+ });
487
+ return stream;
488
+ }
489
+ generateId(short = false) {
490
+ const chars = '0123456789abcdef';
491
+ const length = short ? 12 : 64;
492
+ let result = '';
493
+ for (let i = 0; i < length; i++) {
494
+ const randomIndex = Math.floor(Math.random() * chars.length);
495
+ result += chars[randomIndex];
496
+ }
497
+ return result;
498
+ }
499
+ chunkedResponse(chunks) {
500
+ const socket = {
501
+ end: () => { }
502
+ };
503
+ const response = new http_1.IncomingMessage(socket);
504
+ response.statusCode = 200;
505
+ response.statusMessage = "OK";
506
+ response.headers = {
507
+ "content-type": "application/json"
508
+ };
509
+ for (const chunk of chunks) {
510
+ response.push(Buffer.from(chunk));
511
+ }
512
+ response.push(null);
513
+ response.emit("readable");
514
+ return response;
515
+ }
516
+ registerFixtures(fixtures) {
517
+ this.fixtures.push(fixtures);
518
+ }
519
+ reset() {
520
+ this.containers = [];
521
+ this.images = [];
522
+ this.fixtures = [];
523
+ }
524
+ async exec(method, path, body, options) {
525
+ return this.router.exec(method, path, body, options);
526
+ }
527
+ }
528
+ exports.DockerStorage = DockerStorage;
@@ -0,0 +1,18 @@
1
+ import { FileSystem } from "@wocker/core";
2
+ import { Readable } from "stream";
3
+ export declare class Fixtures {
4
+ protected readonly fs: FileSystem;
5
+ protected constructor(fs: FileSystem);
6
+ imageInspect(version: string, image: string, tag: string): any;
7
+ saveImage(version: string, image: string, tag: string, data: any): void;
8
+ hasPull(version: string, image: string, tag: string): boolean;
9
+ pull(version: string, image: string, tag: string): Readable;
10
+ hasBuild(version: string, builderVersion: string, image: string, tag: string): boolean;
11
+ build(version: string, builderVersion: string, image: string, tag: string): Readable;
12
+ recordPullStream(version: string, image: string, tag: string, stream: NodeJS.ReadableStream): Promise<void>;
13
+ recordBuildStream(version: string, builderVersion: string, image: string, tag: string, stream: NodeJS.ReadableStream): Promise<void>;
14
+ recordJSON(data: any): void;
15
+ recordStream(stream: NodeJS.ReadableStream, target: NodeJS.WritableStream): Promise<void>;
16
+ static fromFS(fs: FileSystem): Fixtures;
17
+ static fromPath(path: string): Fixtures;
18
+ }
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Fixtures = void 0;
4
+ const core_1 = require("@wocker/core");
5
+ class Fixtures {
6
+ constructor(fs) {
7
+ this.fs = fs;
8
+ }
9
+ imageInspect(version, image, tag) {
10
+ const path = `records/${version}/image/${image}/${tag}.json`;
11
+ if (!this.fs.exists(path)) {
12
+ return null;
13
+ }
14
+ return this.fs.readJSON(path);
15
+ }
16
+ saveImage(version, image, tag, data) {
17
+ const dir = `records/${version}/image/${image}`;
18
+ if (!this.fs.exists(dir)) {
19
+ this.fs.mkdir(dir, {
20
+ recursive: true
21
+ });
22
+ }
23
+ this.fs.writeJSON(`${dir}/${tag}.json`, data);
24
+ }
25
+ hasPull(version, image, tag) {
26
+ return this.fs.exists(`records/${version}/pull/${image}/${tag}.jsonl`);
27
+ }
28
+ pull(version, image, tag) {
29
+ return this.fs.createReadlineStream(`records/${version}/pull/${image}/${tag}.jsonl`);
30
+ }
31
+ hasBuild(version, builderVersion, image, tag) {
32
+ return this.fs.exists(`records/${version}/build-${builderVersion}/${image}/${tag}.jsonl`);
33
+ }
34
+ build(version, builderVersion, image, tag) {
35
+ return this.fs.createReadlineStream(`records/${version}/build-${builderVersion}/${image}/${tag}.jsonl`);
36
+ }
37
+ async recordPullStream(version, image, tag, stream) {
38
+ const dir = `records/${version}/pull/${image}`;
39
+ if (!this.fs.exists(dir)) {
40
+ this.fs.mkdir(dir, {
41
+ recursive: true
42
+ });
43
+ }
44
+ const target = this.fs.createWriteStream(`${dir}/${tag}.jsonl`);
45
+ await this.recordStream(stream, target);
46
+ }
47
+ async recordBuildStream(version, builderVersion, image, tag, stream) {
48
+ const dir = `records/${version}/build-${builderVersion}/${image}`;
49
+ if (!this.fs.exists(dir)) {
50
+ this.fs.mkdir(dir, {
51
+ recursive: true
52
+ });
53
+ }
54
+ const target = this.fs.createWriteStream(`${dir}/${tag}.jsonl`, {
55
+ encoding: "utf8"
56
+ });
57
+ await this.recordStream(stream, target);
58
+ }
59
+ recordJSON(data) {
60
+ const dir = "records";
61
+ if (!this.fs.exists(dir)) {
62
+ this.fs.mkdir(dir, {
63
+ recursive: true
64
+ });
65
+ }
66
+ this.fs.writeJSON(`${dir}/file.json`, data);
67
+ }
68
+ async recordStream(stream, target) {
69
+ await new Promise((resolve, reject) => {
70
+ const cleanup = () => {
71
+ };
72
+ const resolveCleanup = () => {
73
+ cleanup();
74
+ resolve();
75
+ };
76
+ const rejectCleanup = (err) => {
77
+ cleanup();
78
+ reject(err);
79
+ };
80
+ const handleData = (chunk) => {
81
+ const canContinue = target.write(chunk.toString().replace(/\r\n/g, "\n"));
82
+ if (!canContinue) {
83
+ stream.pause();
84
+ target.once("drain", () => stream.resume());
85
+ }
86
+ };
87
+ const handleEnd = () => {
88
+ target.once("finish", resolveCleanup);
89
+ target.once("error", rejectCleanup);
90
+ target.end();
91
+ };
92
+ const handleError = (err) => {
93
+ target.once("finish", () => rejectCleanup(err));
94
+ target.once("error", rejectCleanup);
95
+ target.end();
96
+ };
97
+ stream.on("data", handleData);
98
+ stream.on("end", handleEnd);
99
+ stream.on("error", handleError);
100
+ });
101
+ }
102
+ static fromFS(fs) {
103
+ return new this(fs);
104
+ }
105
+ static fromPath(path) {
106
+ return this.fromFS(new core_1.FileSystem(path));
107
+ }
108
+ }
109
+ exports.Fixtures = Fixtures;
@@ -0,0 +1,5 @@
1
+ import { Readable } from "stream";
2
+ import { Fixtures } from "./Fixtures";
3
+ export declare class FixturesGen extends Fixtures {
4
+ build(version: string, builderVersion: string, image: string, tag: string): Readable;
5
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FixturesGen = void 0;
4
+ const stream_1 = require("stream");
5
+ const Fixtures_1 = require("./Fixtures");
6
+ class FixturesGen extends Fixtures_1.Fixtures {
7
+ build(version, builderVersion, image, tag) {
8
+ const stream = new stream_1.Readable({
9
+ objectMode: true
10
+ });
11
+ stream.push(`{"stream":"Successfully built 8fadf8b40731\\n"}`);
12
+ stream.push(`{"stream":"Successfully tagged ${tag}\\n"}`);
13
+ stream.push(null);
14
+ stream.emit("readable");
15
+ return stream;
16
+ }
17
+ }
18
+ exports.FixturesGen = FixturesGen;