@phreshos/node 0.1.10 → 0.1.12

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/dist/main.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { gatewayAddress } from "./address.js";
2
2
  export { Client, ClientService, Endpoint, Process, Program, Server, ServerService, System, type ProgramProcessRunEvent, type ProgramProcessRunOptions } from "./system.js";
3
- export { Service, type ClientLaunch, type Launch, type ProgramDefinition, type ServerLaunch, type ServiceKey, } from "@phreshos/core";
3
+ export { Service, type ClientLaunch, type Launch, type ProgramPermission, type ProgramDefinition, type ServerLaunch, type ServiceKey, type SystemProgramStartup, type SystemStorage, } from "@phreshos/core";
4
4
  export { resolveHome } from "./home.js";
5
5
  export { Project, type Manifest, type PackedProject, type ProjectMode, type ProjectOptions, type ProjectRunOptions } from "./project.js";
@@ -1,7 +1,13 @@
1
- import type { ProgramSql, ProgramStore } from "@phreshos/core";
1
+ import type { ProgramPermission, ProgramSql, ProgramStore } from "@phreshos/core";
2
2
  type Request = (value: object) => Promise<unknown>;
3
+ type ProgramAddress = Readonly<{
4
+ identity: string;
5
+ reference: string;
6
+ }>;
3
7
  /** Program-owned key-value storage carried through the owner-local Gateway. */
4
- export declare function programStore(request: Request, program: string): ProgramStore;
8
+ export declare function programStore(request: Request, handle: ProgramAddress): ProgramStore;
5
9
  /** Program-owned SQL capability carried through the owner-local Gateway. */
6
- export declare function programSql(request: Request, program: string, database: "database" | "logs"): ProgramSql;
10
+ export declare function programSql(request: Request, handle: ProgramAddress, database: "database" | "logs"): ProgramSql;
11
+ /** Persistent Program permission decisions carried through the owner-local Gateway. */
12
+ export declare function programPermission(request: Request, handle: ProgramAddress): ProgramPermission;
7
13
  export {};
@@ -1,9 +1,9 @@
1
1
  /** Program-owned key-value storage carried through the owner-local Gateway. */
2
- export function programStore(request, program) {
2
+ export function programStore(request, handle) {
3
3
  const operate = (storeOperation, key, value, ttl) => request({
4
4
  capability: "program",
5
5
  operation: "store",
6
- program,
6
+ handle,
7
7
  storeOperation,
8
8
  key,
9
9
  value,
@@ -18,14 +18,31 @@ export function programStore(request, program) {
18
18
  };
19
19
  }
20
20
  /** Program-owned SQL capability carried through the owner-local Gateway. */
21
- export function programSql(request, program, database) {
21
+ export function programSql(request, handle, database) {
22
22
  return {
23
23
  query(statement, ...rest) {
24
24
  const [text, values] = written(statement, rest);
25
- return request({ capability: "program", operation: "query", program, database, statement: text, values });
25
+ return request({ capability: "program", operation: "query", handle, database, statement: text, values });
26
26
  }
27
27
  };
28
28
  }
29
+ /** Persistent Program permission decisions carried through the owner-local Gateway. */
30
+ export function programPermission(request, handle) {
31
+ const operate = (permissionOperation, name, value) => request({
32
+ capability: "program",
33
+ operation: "permission",
34
+ handle,
35
+ permissionOperation,
36
+ name,
37
+ value
38
+ });
39
+ return {
40
+ get: name => operate("get", name),
41
+ getAll: () => operate("getAll"),
42
+ set: (name, value) => operate("set", name, value),
43
+ delete: name => operate("delete", name)
44
+ };
45
+ }
29
46
  function written(statement, rest) {
30
47
  if (typeof statement === "string")
31
48
  return [statement, Array.isArray(rest[0]) ? rest[0] : []];
package/dist/storage.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import type { Storage } from "@phreshos/core";
1
+ import type { SystemStorage } from "@phreshos/core";
2
2
  /** Create one filesystem implementation bounded beneath a resolved absolute root. */
3
- export declare function filesystemStorage(source: string | (() => Promise<string>), label: string): Storage;
3
+ export declare function filesystemStorage(source: string | (() => Promise<string>), label: string): SystemStorage;
package/dist/storage.js CHANGED
@@ -16,7 +16,8 @@ export function filesystemStorage(source, label) {
16
16
  });
17
17
  return root;
18
18
  };
19
- const resolve = async (...parts) => contained(await resolveRoot(), parts);
19
+ const path = () => resolveRoot();
20
+ const resolve = async (...parts) => contained(await path(), parts);
20
21
  async function stream(...parts) {
21
22
  const destination = await resolve(...parts);
22
23
  const found = describe(destination);
@@ -41,6 +42,8 @@ export function filesystemStorage(source, label) {
41
42
  }
42
43
  }
43
44
  return {
45
+ path,
46
+ resolve,
44
47
  stream,
45
48
  async bytes(...parts) { return new Uint8Array(await new Response(await stream(...parts)).arrayBuffer()); },
46
49
  async text(...parts) { return new Response(await stream(...parts)).text(); },
package/dist/system.d.ts CHANGED
@@ -1,20 +1,9 @@
1
- import { Client as CoreClient, ClientService as CoreClientService, Endpoint as CoreEndpoint, Process as CoreProcess, Program as CoreProgram, Server as CoreServer, ServerService as CoreServerService, type ProgramDefinition, type ProgramCommandChunk, type ServiceKey, type System as CoreSystem, type SystemClientEntity, type SystemEndpointEntity, type SystemProcessEntity, type SystemProcess, type SystemProgram, type SystemProgramEntity, type SystemServerEntity, type SystemUploads, type Storage, type WritableAppearance } from "@phreshos/core";
2
- export type ProgramProcessRunOptions = Readonly<{
3
- signal?: AbortSignal;
4
- }>;
5
- export type ProgramProcessRunEvent = Readonly<{
6
- event: "started";
7
- process: SystemProcessEntity;
8
- }> | (Readonly<{
9
- event: "output";
10
- }> & ProgramCommandChunk) | Readonly<{
11
- event: "exited";
12
- process: SystemProcessEntity;
13
- exit: import("@phreshos/core").Exit;
14
- }>;
1
+ import { Client as CoreClient, ClientService as CoreClientService, Endpoint as CoreEndpoint, Process as CoreProcess, Program as CoreProgram, Server as CoreServer, ServerService as CoreServerService, type ProgramDefinition, type ServiceKey, type System as CoreSystem, type SystemClientEntity, type SystemEndpointEntity, type SystemProcessEntity, type SystemProcess, type SystemProcessRunEvent, type SystemProcessRunOptions, type SystemProgram, type SystemProgramEntity, type SystemServerEntity, type SystemUploads, type SystemStorage, type WritableAppearance } from "@phreshos/core";
2
+ export type ProgramProcessRunOptions = SystemProcessRunOptions;
3
+ export type ProgramProcessRunEvent = SystemProcessRunEvent;
15
4
  /** One connected owner-local implementation of the shared System contract. */
16
5
  export declare class System implements CoreSystem {
17
- readonly storage: Storage;
6
+ readonly storage: SystemStorage;
18
7
  readonly appearance: WritableAppearance;
19
8
  readonly program: SystemProgram;
20
9
  readonly process: SystemProcess;
@@ -26,28 +15,28 @@ export declare class System implements CoreSystem {
26
15
  forceCreateProgram(source: ProgramDefinition | string): Promise<SystemProgramEntity>;
27
16
  /** Close this owner connection and abort every attached operation it owns. */
28
17
  disconnect(): Promise<void>;
29
- service<EventsMap extends object = {}>(key: ServiceKey & {
18
+ service<EventsMap extends object = {}, Fallback = unknown>(key: ServiceKey & {
30
19
  endpoint: "server";
31
- }): ServerService<EventsMap>;
32
- service<EventsMap extends object = {}>(key: ServiceKey & {
20
+ }): ServerService<EventsMap, Fallback>;
21
+ service<EventsMap extends object = {}, Fallback = unknown>(key: ServiceKey & {
33
22
  endpoint: "client";
34
- }): ClientService<EventsMap>;
23
+ }): ClientService<EventsMap, Fallback>;
35
24
  }
36
25
  /** Node-SDK handle for a Service provided by a Server Endpoint. */
37
- export declare class ServerService<EventsMap extends object = {}> extends CoreServerService<EventsMap> {
26
+ export declare class ServerService<EventsMap extends object = {}, Fallback = unknown> extends CoreServerService<EventsMap, Fallback> {
38
27
  protected constructor();
39
28
  }
40
29
  /** Node-SDK handle for a Service provided by a Client Endpoint. */
41
- export declare class ClientService<EventsMap extends object = {}> extends CoreClientService<EventsMap> {
30
+ export declare class ClientService<EventsMap extends object = {}, Fallback = unknown> extends CoreClientService<EventsMap, Fallback> {
42
31
  protected constructor();
43
32
  }
44
33
  export type Program = SystemProgramEntity;
45
34
  export declare const Program: typeof CoreProgram;
46
35
  export type Process = SystemProcessEntity;
47
36
  export declare const Process: typeof CoreProcess;
48
- export type Endpoint<EventsMap extends object = {}> = SystemEndpointEntity<EventsMap>;
37
+ export type Endpoint<EventsMap extends object = {}, Fallback = unknown> = SystemEndpointEntity<EventsMap, Fallback>;
49
38
  export declare const Endpoint: typeof CoreEndpoint;
50
- export type Server<EventsMap extends object = {}> = SystemServerEntity<EventsMap>;
39
+ export type Server<EventsMap extends object = {}, Fallback = unknown> = SystemServerEntity<EventsMap, Fallback>;
51
40
  export declare const Server: typeof CoreServer;
52
- export type Client<EventsMap extends object = {}> = SystemClientEntity<EventsMap>;
41
+ export type Client<EventsMap extends object = {}, Fallback = unknown> = SystemClientEntity<EventsMap, Fallback>;
53
42
  export declare const Client: typeof CoreClient;
package/dist/system.js CHANGED
@@ -5,7 +5,7 @@ import Events from "./events.js";
5
5
  import HandleRegistry from "./handle-registry.js";
6
6
  import { resolveHome } from "./home.js";
7
7
  import { filesystemStorage } from "./storage.js";
8
- import { programSql, programStore } from "./program-resources.js";
8
+ import { programPermission, programSql, programStore } from "./program-resources.js";
9
9
  import { EndpointTrafficHandle, ServerTrafficHandle } from "./traffic.js";
10
10
  import { openConnection, request, streamProgram } from "./transport.js";
11
11
  import Uploads from "./uploads.js";
@@ -173,6 +173,7 @@ class ProgramHandle extends ProgramBase {
173
173
  store;
174
174
  logs;
175
175
  database;
176
+ permission;
176
177
  process;
177
178
  startup;
178
179
  snapshot;
@@ -180,17 +181,19 @@ class ProgramHandle extends ProgramBase {
180
181
  super();
181
182
  this.system = system;
182
183
  this.snapshot = snapshot;
183
- bindEvents(this, new Events(["forget", "uninstall"], (event, signal, timeout) => transport(system).control({
184
- capability: "program", operation: "wait", input: { program: snapshot.identity, event, timeout }
185
- }, signal).then(value => programEntityEvent(event, value))));
186
184
  this.reference = snapshot.reference;
187
185
  this.identity = snapshot.identity;
186
+ const address = this.address();
187
+ bindEvents(this, new Events(["forget", "uninstall"], (event, signal, timeout) => transport(system).api({
188
+ capability: "program", operation: "wait", handle: address, event, timeout
189
+ }, signal)));
188
190
  const request = (value) => transport(system).api(value);
189
- this.data = filesystemStorage(() => programStoragePath(system, this.identity, "data"), `Program "${this.identity}" data`);
190
- this.cache = filesystemStorage(() => programStoragePath(system, this.identity, "cache"), `Program "${this.identity}" cache`);
191
- this.store = programStore(request, this.identity);
192
- this.logs = programSql(request, this.identity, "logs");
193
- this.database = programSql(request, this.identity, "database");
191
+ this.data = filesystemStorage(() => programStoragePath(system, address, "data"), `Program "${this.identity}" data`);
192
+ this.cache = filesystemStorage(() => programStoragePath(system, address, "cache"), `Program "${this.identity}" cache`);
193
+ this.store = programStore(request, address);
194
+ this.logs = programSql(request, address, "logs");
195
+ this.database = programSql(request, address, "database");
196
+ this.permission = programPermission(request, address);
194
197
  this.process = new ProgramProcesses(system, this);
195
198
  this.startup = new ProgramStartup(system, this);
196
199
  }
@@ -221,7 +224,7 @@ class ProgramHandle extends ProgramBase {
221
224
  this.snapshot = snapshot;
222
225
  }
223
226
  async icon(size = "medium") {
224
- const value = await transport(this.system).api({ capability: "program", operation: "icon", program: this.identity, size });
227
+ const value = await transport(this.system).api({ capability: "program", operation: "icon", handle: this.address(), size });
225
228
  if (!Array.isArray(value) || value.some(byte => typeof byte !== "number"))
226
229
  throw new Error("The System returned an invalid Program icon");
227
230
  return new Blob([Uint8Array.from(value)], { type: "image/png" });
@@ -229,8 +232,8 @@ class ProgramHandle extends ProgramBase {
229
232
  async agent() {
230
233
  if (!this.hasAgent)
231
234
  return null;
232
- const value = await transport(this.system).control({ capability: "program", operation: "agent", input: { program: this.identity } });
233
- return typeof value.content === "string" ? value.content : null;
235
+ const value = await transport(this.system).api({ capability: "program", operation: "agent", handle: this.address() });
236
+ return typeof value === "string" ? value : null;
234
237
  }
235
238
  async installed() {
236
239
  for await (const event of transport(this.system).lifecycle({ word: "installed", handle: this.address() })) {
@@ -241,6 +244,13 @@ class ProgramHandle extends ProgramBase {
241
244
  }
242
245
  install() { return command(this.system, { word: "install-existing", handle: this.address() }); }
243
246
  uninstall(everything = false) { return command(this.system, { word: "uninstall-existing", handle: this.address(), everything }); }
247
+ async fork(identity) {
248
+ for await (const event of transport(this.system).lifecycle({ word: "fork", handle: this.address(), identity })) {
249
+ if (event.event === "created")
250
+ return programHandle(this.system, required(event.program));
251
+ }
252
+ throw new Error("The System did not confirm the forked Program");
253
+ }
244
254
  async forget() {
245
255
  for await (const _event of transport(this.system).lifecycle({ word: "forget", handle: this.address() })) { /* consume completion */ }
246
256
  }
@@ -282,13 +292,18 @@ class ProgramProcesses extends Events {
282
292
  system;
283
293
  program;
284
294
  constructor(system, program) {
285
- super(["create", "exit"], (event, signal, timeout) => transport(system).control({
286
- capability: "process", operation: "wait", input: { program: program.identity, event, timeout }
287
- }, signal).then(value => processEvent(system, value)));
295
+ super(["create", "exit"], (event, signal, timeout) => transport(system).api({
296
+ capability: "programProcess", operation: "wait", handle: program.address(), event, timeout
297
+ }, signal).then(value => programProcessEvent(system, event, value)));
288
298
  this.system = system;
289
299
  this.program = program;
290
300
  }
291
- async list() { return await listProcesses(this.system, this.program.identity); }
301
+ async list() {
302
+ const value = await transport(this.system).api({ capability: "programProcess", operation: "list", handle: this.program.address() });
303
+ if (!Array.isArray(value))
304
+ throw new Error("The System returned an invalid Program Process list");
305
+ return value.map(snapshot => processHandle(this.system, snapshot));
306
+ }
292
307
  async first() { return (await this.list()).sort(chronological)[0] ?? null; }
293
308
  async last() { return (await this.list()).sort(chronological).at(-1) ?? null; }
294
309
  async find(identityOrName) {
@@ -437,6 +452,11 @@ class EndpointOperations extends Events {
437
452
  }
438
453
  async start(launch = {}) { await this.operation("start", launch); }
439
454
  async stop() { await this.operation("stop"); }
455
+ async waitReady(timeout) {
456
+ await transport(this.system).control({ capability: "endpoint", operation: "waitReady", input: {
457
+ process: this.owner.identity, endpoint: this.endpoint, timeout
458
+ } });
459
+ }
440
460
  async isService() {
441
461
  return await transport(this.system).api({
442
462
  capability: "endpoint", operation: "isService", process: this.owner.identity, endpoint: this.endpoint
@@ -476,6 +496,7 @@ class ServerEndpoint extends ServerBase {
476
496
  }
477
497
  process() { return this.base.process(); }
478
498
  exists() { return this.base.exists(); }
499
+ waitReady(timeout) { return this.base.waitReady(timeout); }
479
500
  isService() { return this.base.isService(); }
480
501
  start(launch) { return this.base.start(launch); }
481
502
  stop() { return this.base.stop(); }
@@ -490,9 +511,6 @@ class ServerEndpoint extends ServerBase {
490
511
  capability: "endpoint", operation: "ask", input: { process: this.owner.identity, endpoint: "server", event, payload, timeout: milliseconds }
491
512
  }) };
492
513
  }
493
- async waitReady(timeout) {
494
- await transport(this.system).control({ capability: "endpoint", operation: "waitReady", input: { process: this.owner.identity, endpoint: "server", timeout } });
495
- }
496
514
  }
497
515
  class ClientEndpoint extends ClientBase {
498
516
  endpoint = "client";
@@ -510,6 +528,7 @@ class ClientEndpoint extends ClientBase {
510
528
  }
511
529
  process() { return this.base.process(); }
512
530
  exists() { return this.base.exists(); }
531
+ waitReady(timeout) { return this.base.waitReady(timeout); }
513
532
  isService() { return this.base.isService(); }
514
533
  start(launch) { return this.base.start(launch); }
515
534
  stop() { return this.base.stop(); }
@@ -557,6 +576,9 @@ class ServiceBase {
557
576
  }, signal));
558
577
  }
559
578
  async exists() { return await transport(this.system).api({ capability: "service", operation: "exists", key: this.key }); }
579
+ async waitReady(timeout) {
580
+ await transport(this.system).api({ capability: "service", operation: "waitReady", key: this.key, timeout });
581
+ }
560
582
  publish(event, payload) {
561
583
  void transport(this.system).api({ capability: "service", operation: "publish", key: this.key, event, payload });
562
584
  }
@@ -581,9 +603,7 @@ class ServerServiceHandle extends ServerService {
581
603
  }, signal)));
582
604
  }
583
605
  exists() { return this.base.exists(); }
584
- async waitReady(timeout) {
585
- await transport(this.system).api({ capability: "service", operation: "waitReady", key: this.key, timeout });
586
- }
606
+ waitReady(timeout) { return this.base.waitReady(timeout); }
587
607
  publish = (event, payload) => this.base.publish(event, payload);
588
608
  async ask(event, payload) {
589
609
  return await transport(this.system).api({ capability: "service", operation: "ask", key: this.key, event, payload });
@@ -610,13 +630,14 @@ class ClientServiceHandle extends ClientService {
610
630
  }, signal)));
611
631
  }
612
632
  exists() { return this.base.exists(); }
633
+ waitReady(timeout) { return this.base.waitReady(timeout); }
613
634
  publish = (event, payload) => this.base.publish(event, payload);
614
635
  }
615
- async function listProcesses(system, program) {
636
+ async function listProcesses(system) {
616
637
  const processes = [];
617
638
  let offset = 0;
618
639
  while (true) {
619
- const page = await transport(system).control({ capability: "process", operation: "list", input: { program, limit: 100, offset } });
640
+ const page = await transport(system).control({ capability: "process", operation: "list", input: { limit: 100, offset } });
620
641
  processes.push(...page.data.map(snapshot => processHandle(system, snapshot)));
621
642
  offset += page.data.length;
622
643
  if (!page.truncated || !page.data.length)
@@ -641,10 +662,6 @@ async function waitEndpointLifecycle(system, owner, endpoint, event, signal, tim
641
662
  input: { process: owner.identity, endpoint, event, timeout }
642
663
  }, signal);
643
664
  }
644
- function programEntityEvent(event, value) {
645
- const payload = value.payload;
646
- return event === "uninstall" ? payload?.everything === true : undefined;
647
- }
648
665
  function processEvent(system, value) {
649
666
  const waited = value;
650
667
  const payload = waited.payload;
@@ -659,6 +676,17 @@ function processEvent(system, value) {
659
676
  return processHandle(system, payload);
660
677
  return payload;
661
678
  }
679
+ function programProcessEvent(system, event, value) {
680
+ if (event === "create")
681
+ return processHandle(system, value);
682
+ const exit = value;
683
+ return {
684
+ process: processHandle(system, required(exit.process)),
685
+ status: exit.status,
686
+ code: exit.code,
687
+ signal: exit.signal
688
+ };
689
+ }
662
690
  function exactProcessEvent(value) {
663
691
  const payload = value.payload;
664
692
  if (!payload)
@@ -680,8 +708,8 @@ function eventsOf(events) {
680
708
  };
681
709
  }
682
710
  function chronological(left, right) { return left.startedAt.getTime() - right.startedAt.getTime(); }
683
- async function programStoragePath(system, program, area) {
684
- const value = await transport(system).api({ capability: "program", operation: "storagePath", program, area });
711
+ async function programStoragePath(system, handle, area) {
712
+ const value = await transport(system).api({ capability: "program", operation: "storagePath", handle, area });
685
713
  if (typeof value !== "string")
686
714
  throw new Error("The System returned an invalid Program storage path");
687
715
  return value;
package/dist/traffic.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import type { AnswerSubscriber, AskSubscriber, Cleanup, Endpoint, EventOptions, ServerTraffic, TrafficEvents, TrafficMessage } from "@phreshos/core";
1
+ import type { AnswerSubscriber, AskSubscriber, Cleanup, Endpoint, EventOptions, ServerTraffic, TrafficEvents } from "@phreshos/core";
2
2
  import Events from "./events.js";
3
3
  type Kind = "publish" | "ask" | "answer";
4
4
  type Request = (value: object, signal?: AbortSignal) => Promise<unknown>;
5
5
  type ResolveEndpoint = (value: unknown) => Endpoint;
6
6
  /** Directed traffic originating from one canonical Endpoint. */
7
- export declare class EndpointTrafficHandle<Definitions extends object = {}> extends Events<TrafficEvents<Definitions>, keyof Definitions extends never ? TrafficMessage : never> {
7
+ export declare class EndpointTrafficHandle<Definitions extends object = {}> extends Events<TrafficEvents<Definitions>, never> {
8
8
  private readonly request;
9
9
  private readonly process;
10
10
  private readonly endpoint;
@@ -15,7 +15,7 @@ export declare class EndpointTrafficHandle<Definitions extends object = {}> exte
15
15
  event: string;
16
16
  questionId: string;
17
17
  message: Readonly<{
18
- to: import("@phreshos/core").Server<{}> | null;
18
+ to: import("@phreshos/core").Server<{}, unknown> | null;
19
19
  payload: Payload;
20
20
  }>;
21
21
  }>>;
@@ -28,7 +28,7 @@ export declare class ServerTrafficHandle<Definitions extends object = {}> extend
28
28
  event: string;
29
29
  questionId: string;
30
30
  message: Readonly<{
31
- to: Endpoint<{}> | null;
31
+ to: Endpoint<{}, unknown> | null;
32
32
  outcome: import("@phreshos/core").Outcome<Result>;
33
33
  }>;
34
34
  }>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phreshos/node",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "Node.js access to PhreshOS and Program projects.",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",
@@ -29,14 +29,14 @@
29
29
  "packageManager": "bun@1.3.14",
30
30
  "scripts": {
31
31
  "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
32
- "check": "tsc --noEmit",
32
+ "check": "tsc --noEmit && tsc -p tsconfig.test.json",
33
33
  "build": "node --run clean && tsc --noEmit false --outDir dist --rootDir source",
34
34
  "test": "node --run build && node --test tests/*.test.mjs",
35
35
  "verify": "node --run check && node --run test",
36
36
  "prepack": "node --run build"
37
37
  },
38
38
  "dependencies": {
39
- "@phreshos/core": "^0.1.32",
39
+ "@phreshos/core": "^0.1.36",
40
40
  "adm-zip": "^0.6.0",
41
41
  "jiti": "^2.7.0"
42
42
  },