nylorun 0.2.1-beta → 0.4.0-beta
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/CHANGELOG.md +126 -0
- package/README.md +156 -46
- package/dist/cli.js +13 -11
- package/dist/doctor.d.ts +3 -1
- package/dist/doctor.js +42 -13
- package/dist/project/derived-key.d.ts +8 -0
- package/dist/project/derived-key.js +18 -0
- package/dist/project/link.d.ts +32 -4
- package/dist/project/link.js +83 -14
- package/dist/project/seed.d.ts +27 -0
- package/dist/project/seed.js +111 -0
- package/dist/stack/commands.d.ts +45 -15
- package/dist/stack/commands.js +577 -125
- package/dist/stack/compose-file.d.ts +30 -8
- package/dist/stack/compose-file.js +99 -15
- package/dist/stack/env-file.d.ts +32 -4
- package/dist/stack/env-file.js +71 -3
- package/dist/stack/host-files.d.ts +16 -3
- package/dist/stack/host-files.js +29 -4
- package/dist/stack/images.d.ts +2 -0
- package/dist/stack/images.js +10 -6
- package/dist/stack/index.d.ts +3 -3
- package/dist/stack/index.js +8 -3
- package/dist/stack/paths.d.ts +11 -3
- package/dist/stack/paths.js +9 -6
- package/dist/stack/ports.d.ts +2 -0
- package/dist/stack/ports.js +2 -0
- package/dist/stack/prepare.d.ts +20 -4
- package/dist/stack/prepare.js +39 -10
- package/dist/stack/restate-identity.d.ts +1 -1
- package/dist/stack/restate-identity.js +1 -1
- package/dist/stack/stacks.d.ts +47 -0
- package/dist/stack/stacks.js +116 -0
- package/package.json +4 -4
package/dist/stack/paths.js
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import { join, resolve } from "node:path";
|
|
2
2
|
export function stackPaths(hostRoot) {
|
|
3
3
|
const root = resolve(hostRoot);
|
|
4
|
-
const
|
|
4
|
+
const docker = join(root, "docker");
|
|
5
5
|
return {
|
|
6
6
|
root,
|
|
7
7
|
config: join(root, "host.json"),
|
|
8
8
|
credentials: join(root, "host-credentials.json"),
|
|
9
9
|
state: join(root, "host-state.json"),
|
|
10
|
-
|
|
10
|
+
record: join(root, "stack.json"),
|
|
11
|
+
tenant: join(root, "tenant"),
|
|
12
|
+
keys: join(root, "keys"),
|
|
13
|
+
vaultKey: join(root, "keys", "vault-kek"),
|
|
11
14
|
home: join(root, "home"),
|
|
12
15
|
tmp: join(root, "tmp"),
|
|
13
|
-
|
|
14
|
-
compose: join(
|
|
15
|
-
env: join(
|
|
16
|
-
restateIdentity: join(
|
|
16
|
+
docker,
|
|
17
|
+
compose: join(docker, "compose.yaml"),
|
|
18
|
+
env: join(docker, ".env"),
|
|
19
|
+
restateIdentity: join(docker, "restate-identity.pem"),
|
|
17
20
|
};
|
|
18
21
|
}
|
package/dist/stack/ports.d.ts
CHANGED
package/dist/stack/ports.js
CHANGED
package/dist/stack/prepare.d.ts
CHANGED
|
@@ -11,18 +11,34 @@ export interface PreparedStack {
|
|
|
11
11
|
firstRun: boolean;
|
|
12
12
|
}
|
|
13
13
|
/** Read the persisted stack settings without writing anything. */
|
|
14
|
-
export declare function readStackEnv(paths: StackPaths): Promise<import("./env-file.js").PersistedStackEnv | undefined>;
|
|
14
|
+
export declare function readStackEnv(paths: Pick<StackPaths, "env">): Promise<import("./env-file.js").PersistedStackEnv | undefined>;
|
|
15
15
|
/**
|
|
16
16
|
* Write everything `docker compose up` needs under the Host root:
|
|
17
|
-
* host.json, host-credentials.json (0600),
|
|
18
|
-
*
|
|
17
|
+
* host.json, host-credentials.json (0600), docker/compose.yaml,
|
|
18
|
+
* docker/.env (0600) and docker/restate-identity.pem (0600). Ports and the
|
|
19
19
|
* Postgres password persist in .env; the identity key persists in its PEM.
|
|
20
20
|
*/
|
|
21
21
|
export declare function prepareStack(input: {
|
|
22
22
|
paths: StackPaths;
|
|
23
|
+
/** The stack's name (its Tenant's name) and its Compose project. */
|
|
24
|
+
name: string;
|
|
25
|
+
project: string;
|
|
23
26
|
images: StackImages;
|
|
24
27
|
uid: number;
|
|
25
28
|
gid: number;
|
|
26
|
-
|
|
29
|
+
/** Recorded in host.json; undefined keeps the recorded version. */
|
|
30
|
+
runtimeVersion: string | undefined;
|
|
27
31
|
ports: PortProbe;
|
|
32
|
+
/** Ports other stacks keep in their `.env`: never chosen for a port not chosen yet. */
|
|
33
|
+
reserved?: ReadonlySet<number>;
|
|
34
|
+
/** `NYLORUN_DERIVED_PRINCIPALS` from the environment of `nylorun start`; else kept. */
|
|
35
|
+
derivedPrincipals?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Changes to the origins that may embed Studio: `reset` goes back to the
|
|
38
|
+
* defaults, `add` appends (for example a desktop app's dev server).
|
|
39
|
+
*/
|
|
40
|
+
studioEmbedOrigins?: {
|
|
41
|
+
add?: readonly string[];
|
|
42
|
+
reset?: boolean;
|
|
43
|
+
};
|
|
28
44
|
}): Promise<PreparedStack>;
|
package/dist/stack/prepare.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
2
|
import { chmod, readFile, rename, writeFile } from "node:fs/promises";
|
|
3
3
|
import { renderComposeFile } from "./compose-file.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { parseFrameAncestors } from "@nylorun/core/contracts";
|
|
5
|
+
import { CliError } from "../errors.js";
|
|
6
|
+
import { DEFAULT_STUDIO_FRAME_ANCESTORS, parseDerivedPrincipals, parsePersisted, renderEnvFile, } from "./env-file.js";
|
|
7
|
+
import { ensureHostCredentials, ensureVaultKey, ensureHostLayout, writeStackHostConfig, } from "./host-files.js";
|
|
6
8
|
import { choosePort, DEFAULT_PORTS } from "./ports.js";
|
|
7
9
|
import { ensureIdentityKey } from "./restate-identity.js";
|
|
8
10
|
async function writeFileMode(path, text, mode) {
|
|
@@ -26,8 +28,8 @@ export async function readStackEnv(paths) {
|
|
|
26
28
|
}
|
|
27
29
|
/**
|
|
28
30
|
* Write everything `docker compose up` needs under the Host root:
|
|
29
|
-
* host.json, host-credentials.json (0600),
|
|
30
|
-
*
|
|
31
|
+
* host.json, host-credentials.json (0600), docker/compose.yaml,
|
|
32
|
+
* docker/.env (0600) and docker/restate-identity.pem (0600). Ports and the
|
|
31
33
|
* Postgres password persist in .env; the identity key persists in its PEM.
|
|
32
34
|
*/
|
|
33
35
|
export async function prepareStack(input) {
|
|
@@ -36,30 +38,57 @@ export async function prepareStack(input) {
|
|
|
36
38
|
const persisted = (await readStackEnv(paths)) ?? {};
|
|
37
39
|
const firstRun = persisted.runtimePort === undefined;
|
|
38
40
|
const taken = new Set();
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
const reserved = input.reserved ?? new Set();
|
|
42
|
+
const pick = async (preferred, persistedPort) => {
|
|
43
|
+
const avoid = persistedPort === undefined ? new Set([...taken, ...reserved]) : taken;
|
|
44
|
+
const port = await choosePort(input.ports, preferred, persistedPort, avoid);
|
|
45
|
+
taken.add(port);
|
|
46
|
+
return port;
|
|
47
|
+
};
|
|
48
|
+
const runtimePort = await pick(DEFAULT_PORTS.runtime, persisted.runtimePort);
|
|
49
|
+
const adminPort = await pick(DEFAULT_PORTS.admin, persisted.adminPort);
|
|
50
|
+
const studioPort = await pick(DEFAULT_PORTS.studio, persisted.studioPort);
|
|
51
|
+
const restatePort = await pick(DEFAULT_PORTS.restate, persisted.restatePort);
|
|
44
52
|
const identity = await ensureIdentityKey(paths.restateIdentity, writeFileMode);
|
|
53
|
+
let added;
|
|
54
|
+
try {
|
|
55
|
+
added = parseFrameAncestors((input.studioEmbedOrigins?.add ?? []).join(" "));
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
throw new CliError(`--studio-embed-origin: ${error instanceof Error ? error.message : String(error)}`, 2);
|
|
59
|
+
}
|
|
60
|
+
const base = input.studioEmbedOrigins?.reset || persisted.studioFrameAncestors === undefined
|
|
61
|
+
? [...DEFAULT_STUDIO_FRAME_ANCESTORS]
|
|
62
|
+
: persisted.studioFrameAncestors;
|
|
63
|
+
const studioFrameAncestors = [...new Set([...base, ...added])].join(" ");
|
|
45
64
|
const env = {
|
|
46
65
|
runtimePort,
|
|
66
|
+
adminPort,
|
|
47
67
|
studioPort,
|
|
48
68
|
restatePort,
|
|
49
69
|
postgresPassword: persisted.postgresPassword ?? randomBytes(24).toString("hex"),
|
|
70
|
+
// Kept across starts: a new token would recreate the runtime and gateway containers.
|
|
71
|
+
gatesToken: persisted.gatesToken ?? randomBytes(32).toString("hex"),
|
|
50
72
|
restateIdentityKey: identity.publicKey,
|
|
51
73
|
uid: input.uid,
|
|
52
74
|
gid: input.gid,
|
|
53
75
|
hostRoot: paths.root,
|
|
54
76
|
runtimeImage: input.images.runtime,
|
|
55
77
|
studioImage: input.images.studio,
|
|
78
|
+
studioFrameAncestors,
|
|
79
|
+
stackName: input.name,
|
|
80
|
+
derivedPrincipals: (input.derivedPrincipals?.trim()
|
|
81
|
+
? parseDerivedPrincipals(input.derivedPrincipals, "NYLORUN_DERIVED_PRINCIPALS")
|
|
82
|
+
: (persisted.derivedPrincipals ?? ["project"])).join(","),
|
|
56
83
|
};
|
|
57
84
|
const { adminKey } = await ensureHostCredentials(paths);
|
|
85
|
+
await ensureVaultKey(paths);
|
|
58
86
|
const host = await writeStackHostConfig(paths, {
|
|
59
87
|
port: runtimePort,
|
|
88
|
+
adminPort,
|
|
60
89
|
runtimeVersion: input.runtimeVersion,
|
|
61
90
|
});
|
|
62
91
|
await writeFileMode(paths.env, renderEnvFile(env), 0o600);
|
|
63
|
-
await writeFileMode(paths.compose, renderComposeFile(), 0o644);
|
|
92
|
+
await writeFileMode(paths.compose, renderComposeFile(input.project), 0o644);
|
|
64
93
|
return { env, host, adminKey, firstRun };
|
|
65
94
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* every request to the Worker endpoint with an Ed25519 private key; the
|
|
4
4
|
* Runtime accepts only requests that verify against the public key.
|
|
5
5
|
*
|
|
6
|
-
* - The private key is a PKCS#8 PEM at `
|
|
6
|
+
* - The private key is a PKCS#8 PEM at `docker/restate-identity.pem` (mode
|
|
7
7
|
* 0600), mounted read-only into the restate service as
|
|
8
8
|
* `RESTATE_WORKER__INVOKER__REQUEST_IDENTITY_PRIVATE_KEY_PEM_FILE`.
|
|
9
9
|
* - The public key goes to the Runtime as `NYLORUN_RESTATE_IDENTITY_KEY`, in
|
|
@@ -6,7 +6,7 @@ import { CliError } from "../errors.js";
|
|
|
6
6
|
* every request to the Worker endpoint with an Ed25519 private key; the
|
|
7
7
|
* Runtime accepts only requests that verify against the public key.
|
|
8
8
|
*
|
|
9
|
-
* - The private key is a PKCS#8 PEM at `
|
|
9
|
+
* - The private key is a PKCS#8 PEM at `docker/restate-identity.pem` (mode
|
|
10
10
|
* 0600), mounted read-only into the restate service as
|
|
11
11
|
* `RESTATE_WORKER__INVOKER__REQUEST_IDENTITY_PRIVATE_KEY_PEM_FILE`.
|
|
12
12
|
* - The public key goes to the Runtime as `NYLORUN_RESTATE_IDENTITY_KEY`, in
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The machine's local stacks (tenancy.md §6): one installation per stack, each with its own
|
|
3
|
+
* Host root `~/.nylorun/stacks/<name>/`, Compose project `nylorun-<name>`, ports and volumes.
|
|
4
|
+
* `~/.nylorun` itself held the single stack of older releases (the legacy stack).
|
|
5
|
+
*/
|
|
6
|
+
/** A stack name: also part of its Compose project, so Compose's rules apply. */
|
|
7
|
+
export declare const STACK_NAME: RegExp;
|
|
8
|
+
/** `~/.nylorun`: the stacks, and the legacy stack's files. Tests pass another directory. */
|
|
9
|
+
export declare function defaultNylorunRoot(): string;
|
|
10
|
+
export declare function stacksDir(base: string): string;
|
|
11
|
+
export declare function stackRoot(base: string, name: string): string;
|
|
12
|
+
export declare function assertStackName(name: string, source: string): string;
|
|
13
|
+
/** A directory name as a stack name: lowercased, other characters as `-`, trimmed. */
|
|
14
|
+
export declare function sanitizeStackName(raw: string): string;
|
|
15
|
+
/** `stack.json` in a Host root: the stack's name and the project it was created for. */
|
|
16
|
+
export interface StackRecord {
|
|
17
|
+
format: 1;
|
|
18
|
+
name: string;
|
|
19
|
+
/** The project directory `nylorun start` created the stack in; absent outside a project. */
|
|
20
|
+
project?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare function stackRecordPath(root: string): string;
|
|
23
|
+
export declare function readStackRecord(root: string): Promise<StackRecord | undefined>;
|
|
24
|
+
export declare function writeStackRecord(root: string, record: Omit<StackRecord, "format">): Promise<void>;
|
|
25
|
+
export interface StackEntry {
|
|
26
|
+
name: string;
|
|
27
|
+
root: string;
|
|
28
|
+
record?: StackRecord;
|
|
29
|
+
}
|
|
30
|
+
/** The stacks under `<base>/stacks`, by name. */
|
|
31
|
+
export declare function listStacks(base: string): Promise<StackEntry[]>;
|
|
32
|
+
/**
|
|
33
|
+
* The stack name for a project without a link: the directory's name, or the first `-2`,
|
|
34
|
+
* `-3`, … suffix that no stack of another project directory holds. A stack this project
|
|
35
|
+
* directory created keeps its name.
|
|
36
|
+
*/
|
|
37
|
+
export declare function chooseStackName(base: string, projectDir: string): Promise<string>;
|
|
38
|
+
/** The single stack of older releases: Compose project `nylorun`, Host root `~/.nylorun`. */
|
|
39
|
+
export interface LegacyStack {
|
|
40
|
+
root: string;
|
|
41
|
+
project: "nylorun";
|
|
42
|
+
compose: string;
|
|
43
|
+
env: string;
|
|
44
|
+
}
|
|
45
|
+
export declare function legacyStack(base: string): LegacyStack | undefined;
|
|
46
|
+
/** What `nylorun legacy delete` removes from `~/.nylorun`: the old layout only, never `stacks/`. */
|
|
47
|
+
export declare const LEGACY_ENTRIES: readonly ["host.json", "host-credentials.json", "host-state.json", "stack", "tenants", "home", "tmp", "trash"];
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { readdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
3
|
+
import { randomBytes } from "node:crypto";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import { basename, join, resolve } from "node:path";
|
|
6
|
+
import { CliError } from "../errors.js";
|
|
7
|
+
/**
|
|
8
|
+
* The machine's local stacks (tenancy.md §6): one installation per stack, each with its own
|
|
9
|
+
* Host root `~/.nylorun/stacks/<name>/`, Compose project `nylorun-<name>`, ports and volumes.
|
|
10
|
+
* `~/.nylorun` itself held the single stack of older releases (the legacy stack).
|
|
11
|
+
*/
|
|
12
|
+
/** A stack name: also part of its Compose project, so Compose's rules apply. */
|
|
13
|
+
export const STACK_NAME = /^[a-z0-9][a-z0-9_-]*$/;
|
|
14
|
+
/** `~/.nylorun`: the stacks, and the legacy stack's files. Tests pass another directory. */
|
|
15
|
+
export function defaultNylorunRoot() {
|
|
16
|
+
return resolve(join(homedir(), ".nylorun"));
|
|
17
|
+
}
|
|
18
|
+
export function stacksDir(base) {
|
|
19
|
+
return join(base, "stacks");
|
|
20
|
+
}
|
|
21
|
+
export function stackRoot(base, name) {
|
|
22
|
+
return join(stacksDir(base), name);
|
|
23
|
+
}
|
|
24
|
+
export function assertStackName(name, source) {
|
|
25
|
+
if (!STACK_NAME.test(name))
|
|
26
|
+
throw new CliError(`${source} must be lowercase letters, digits, "-" or "_", starting with a letter or digit: ${name}`, 2);
|
|
27
|
+
return name;
|
|
28
|
+
}
|
|
29
|
+
/** A directory name as a stack name: lowercased, other characters as `-`, trimmed. */
|
|
30
|
+
export function sanitizeStackName(raw) {
|
|
31
|
+
const name = raw
|
|
32
|
+
.toLowerCase()
|
|
33
|
+
.replace(/[^a-z0-9_-]+/g, "-")
|
|
34
|
+
.replace(/-{2,}/g, "-")
|
|
35
|
+
.replace(/^[-_]+|[-_]+$/g, "");
|
|
36
|
+
return name === "" ? "stack" : name;
|
|
37
|
+
}
|
|
38
|
+
export function stackRecordPath(root) {
|
|
39
|
+
return join(root, "stack.json");
|
|
40
|
+
}
|
|
41
|
+
export async function readStackRecord(root) {
|
|
42
|
+
try {
|
|
43
|
+
const value = JSON.parse(await readFile(stackRecordPath(root), "utf8"));
|
|
44
|
+
if (typeof value?.name !== "string" || !STACK_NAME.test(value.name))
|
|
45
|
+
return undefined;
|
|
46
|
+
return {
|
|
47
|
+
format: 1,
|
|
48
|
+
name: value.name,
|
|
49
|
+
...(typeof value.project === "string" ? { project: value.project } : {}),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export async function writeStackRecord(root, record) {
|
|
57
|
+
const path = stackRecordPath(root);
|
|
58
|
+
const temporary = `${path}.${randomBytes(8).toString("hex")}.tmp`;
|
|
59
|
+
const body = { format: 1, name: record.name, ...(record.project ? { project: record.project } : {}) };
|
|
60
|
+
await writeFile(temporary, `${JSON.stringify(body, null, 2)}\n`, { mode: 0o600 });
|
|
61
|
+
await rename(temporary, path);
|
|
62
|
+
}
|
|
63
|
+
/** The stacks under `<base>/stacks`, by name. */
|
|
64
|
+
export async function listStacks(base) {
|
|
65
|
+
let entries;
|
|
66
|
+
try {
|
|
67
|
+
entries = await readdir(stacksDir(base), { withFileTypes: true });
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
const stacks = [];
|
|
73
|
+
for (const entry of entries) {
|
|
74
|
+
if (!entry.isDirectory() || !STACK_NAME.test(entry.name))
|
|
75
|
+
continue;
|
|
76
|
+
const root = stackRoot(base, entry.name);
|
|
77
|
+
const record = await readStackRecord(root);
|
|
78
|
+
stacks.push({ name: entry.name, root, ...(record ? { record } : {}) });
|
|
79
|
+
}
|
|
80
|
+
return stacks.sort((a, b) => a.name.localeCompare(b.name));
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The stack name for a project without a link: the directory's name, or the first `-2`,
|
|
84
|
+
* `-3`, … suffix that no stack of another project directory holds. A stack this project
|
|
85
|
+
* directory created keeps its name.
|
|
86
|
+
*/
|
|
87
|
+
export async function chooseStackName(base, projectDir) {
|
|
88
|
+
const name = sanitizeStackName(basename(projectDir));
|
|
89
|
+
const stacks = await listStacks(base);
|
|
90
|
+
const candidate = new RegExp(`^${name}(?:-[0-9]+)?$`);
|
|
91
|
+
const own = stacks.find((stack) => candidate.test(stack.name) && stack.record?.project === projectDir);
|
|
92
|
+
if (own)
|
|
93
|
+
return own.name;
|
|
94
|
+
for (let suffix = 1;; suffix += 1) {
|
|
95
|
+
const next = suffix === 1 ? name : `${name}-${suffix}`;
|
|
96
|
+
if (!existsSync(stackRoot(base, next)))
|
|
97
|
+
return next;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
export function legacyStack(base) {
|
|
101
|
+
const compose = join(base, "stack", "compose.yaml");
|
|
102
|
+
if (!existsSync(compose))
|
|
103
|
+
return undefined;
|
|
104
|
+
return { root: base, project: "nylorun", compose, env: join(base, "stack", ".env") };
|
|
105
|
+
}
|
|
106
|
+
/** What `nylorun legacy delete` removes from `~/.nylorun`: the old layout only, never `stacks/`. */
|
|
107
|
+
export const LEGACY_ENTRIES = [
|
|
108
|
+
"host.json",
|
|
109
|
+
"host-credentials.json",
|
|
110
|
+
"host-state.json",
|
|
111
|
+
"stack",
|
|
112
|
+
"tenants",
|
|
113
|
+
"home",
|
|
114
|
+
"tmp",
|
|
115
|
+
"trash",
|
|
116
|
+
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nylorun",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0-beta",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"description": "Set up and run the local Nylorun stack (Runtime and Studio) with Docker Compose",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"prepack": "npm run build"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@nylorun/core": "0.
|
|
33
|
+
"@nylorun/core": "0.10.0-beta"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"nylorun": "dist/cli.js"
|
|
42
42
|
},
|
|
43
43
|
"nylorun": {
|
|
44
|
-
"runtime": "0.
|
|
45
|
-
"studio": "0.
|
|
44
|
+
"runtime": "0.15.0-beta",
|
|
45
|
+
"studio": "0.15.0-beta"
|
|
46
46
|
}
|
|
47
47
|
}
|