@freestyle-sh/with-deno 0.0.1 → 0.0.3
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/README.md +81 -5
- package/dist/index.d.ts +48 -5
- package/dist/index.js +137 -42
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -14,11 +14,8 @@ npm install @freestyle-sh/with-deno freestyle-sandboxes
|
|
|
14
14
|
import { freestyle, VmSpec } from "freestyle-sandboxes";
|
|
15
15
|
import { VmDeno } from "@freestyle-sh/with-deno";
|
|
16
16
|
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
deno: new VmDeno(),
|
|
20
|
-
},
|
|
21
|
-
});
|
|
17
|
+
const deno = new VmDeno();
|
|
18
|
+
const spec = new VmSpec().with("deno", deno);
|
|
22
19
|
|
|
23
20
|
const { vm } = await freestyle.vms.create({ spec });
|
|
24
21
|
|
|
@@ -101,6 +98,10 @@ type InstallResult = {
|
|
|
101
98
|
Deno has native support for [JSR](https://jsr.io) (JavaScript Registry), which hosts TypeScript-first packages including the Deno standard library.
|
|
102
99
|
|
|
103
100
|
```typescript
|
|
101
|
+
const deno = new VmDeno();
|
|
102
|
+
const spec = new VmSpec().with("deno", deno);
|
|
103
|
+
const { vm } = await freestyle.vms.create({ spec });
|
|
104
|
+
|
|
104
105
|
// Install @std/path from JSR
|
|
105
106
|
await vm.deno.install({ deps: ["jsr:@std/path"] });
|
|
106
107
|
|
|
@@ -116,6 +117,81 @@ const res = await vm.deno.runCode({
|
|
|
116
117
|
});
|
|
117
118
|
```
|
|
118
119
|
|
|
120
|
+
## Workspaces and Tasks
|
|
121
|
+
|
|
122
|
+
Use the Deno builder to attach a workspace and run a Deno task as a managed systemd service.
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
import { Freestyle, VmSpec } from "freestyle-sandboxes";
|
|
126
|
+
import { VmDeno } from "@freestyle-sh/with-deno";
|
|
127
|
+
|
|
128
|
+
const freestyle = new Freestyle();
|
|
129
|
+
|
|
130
|
+
const deno = new VmDeno();
|
|
131
|
+
const workspace = deno.workspace({ path: "/root/app", install: true });
|
|
132
|
+
const appTask = workspace.task("start", {
|
|
133
|
+
env: {
|
|
134
|
+
HOST: "0.0.0.0",
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const spec = new VmSpec()
|
|
139
|
+
.with("deno", deno)
|
|
140
|
+
.repo("https://github.com/deco-sites/storefront", "/root/app")
|
|
141
|
+
.with("workspace", workspace)
|
|
142
|
+
.with("app", appTask)
|
|
143
|
+
.snapshot()
|
|
144
|
+
.waitFor("curl http://localhost:8000")
|
|
145
|
+
.snapshot();
|
|
146
|
+
|
|
147
|
+
const { repoId } = await freestyle.git.repos.create({
|
|
148
|
+
source: {
|
|
149
|
+
url: "https://github.com/deco-sites/storefront",
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
const domain = `${crypto.randomUUID()}.style.dev`;
|
|
154
|
+
|
|
155
|
+
const { vm } = await freestyle.vms.create({
|
|
156
|
+
spec,
|
|
157
|
+
domains: [{ domain, vmPort: 8000 }],
|
|
158
|
+
git: {
|
|
159
|
+
repos: [{ repo: repoId, path: "/root/app" }],
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// Task instance comes from .with("app", appTask)
|
|
164
|
+
const recentLogs = await vm.app.logs();
|
|
165
|
+
console.log(recentLogs);
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Workspace API
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
const workspace = deno.workspace({
|
|
172
|
+
path: "/root/app",
|
|
173
|
+
install: true,
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
- `path`: Working directory for `deno install` and task execution.
|
|
178
|
+
- `install`: When true, runs `deno install` in the workspace during VM startup.
|
|
179
|
+
|
|
180
|
+
### Task API
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
const task = workspace.task("start", {
|
|
184
|
+
env: { HOST: "0.0.0.0" },
|
|
185
|
+
serviceName: "my-deno-app",
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
- `name`: Task name from `deno.json`.
|
|
190
|
+
- `env`: Optional environment variables for the task service.
|
|
191
|
+
- `serviceName`: Optional explicit systemd service name.
|
|
192
|
+
|
|
193
|
+
When added to the spec with `.with("app", task)`, you can access task logs with `vm.app.logs()`.
|
|
194
|
+
|
|
119
195
|
## Documentation
|
|
120
196
|
|
|
121
197
|
- [Freestyle Documentation](https://docs.freestyle.sh)
|
package/dist/index.d.ts
CHANGED
|
@@ -1,23 +1,66 @@
|
|
|
1
|
-
import { VmWith, VmWithInstance, VmSpec } from 'freestyle-sandboxes';
|
|
1
|
+
import { VmWith, VmWithInstance, VmSpec, VmBaseImage } from 'freestyle-sandboxes';
|
|
2
2
|
import { VmJavaScriptRuntimeInstance, JSONValue, RunCodeResponse, InstallOptions, InstallResult, VmJavaScriptRuntime } from '@freestyle-sh/with-type-js';
|
|
3
3
|
|
|
4
4
|
type DenoOptions = {
|
|
5
5
|
version?: string;
|
|
6
6
|
workdir?: string;
|
|
7
|
-
deleteAfterSuccess?: boolean;
|
|
8
7
|
};
|
|
9
8
|
type DenoResolvedOptions = {
|
|
10
9
|
version?: string;
|
|
11
10
|
workdir?: string;
|
|
12
|
-
deleteAfterSuccess: boolean;
|
|
13
11
|
};
|
|
14
12
|
declare class VmDeno extends VmWith<VmDenoInstance> implements VmJavaScriptRuntime<VmJavaScriptRuntimeInstance> {
|
|
15
13
|
options: DenoResolvedOptions;
|
|
14
|
+
workspaces: DenoWorkspace[];
|
|
16
15
|
constructor(options?: DenoOptions);
|
|
17
|
-
|
|
16
|
+
configureBaseImage(image: VmBaseImage): VmBaseImage | Promise<VmBaseImage>;
|
|
17
|
+
configureSpec(spec: VmSpec): VmSpec;
|
|
18
|
+
workspace(options: {
|
|
19
|
+
path: string;
|
|
20
|
+
install?: boolean;
|
|
21
|
+
}): DenoWorkspace;
|
|
18
22
|
createInstance(): VmDenoInstance;
|
|
19
23
|
installServiceName(): string;
|
|
20
24
|
}
|
|
25
|
+
declare class DenoWorkspace extends VmWith<DenoWorkspaceInstance> {
|
|
26
|
+
options: {
|
|
27
|
+
path: string;
|
|
28
|
+
install?: boolean;
|
|
29
|
+
};
|
|
30
|
+
env?: Record<string, string>;
|
|
31
|
+
constructor(options: {
|
|
32
|
+
path: string;
|
|
33
|
+
install?: boolean;
|
|
34
|
+
}, env?: Record<string, string>);
|
|
35
|
+
task(name: string, options?: {
|
|
36
|
+
env?: Record<string, string>;
|
|
37
|
+
serviceName?: string;
|
|
38
|
+
}): DenoWorkspaceTask;
|
|
39
|
+
getInstallServiceName(): string;
|
|
40
|
+
configureSpec(spec: VmSpec): VmSpec;
|
|
41
|
+
createInstance(): DenoWorkspaceInstance;
|
|
42
|
+
}
|
|
43
|
+
declare class DenoWorkspaceInstance extends VmWithInstance {
|
|
44
|
+
}
|
|
45
|
+
declare class DenoWorkspaceTask extends VmWith<DenoWorkspaceTaskInstance> {
|
|
46
|
+
name: string;
|
|
47
|
+
workspace: DenoWorkspace;
|
|
48
|
+
env?: Record<string, string>;
|
|
49
|
+
serviceName?: string;
|
|
50
|
+
constructor(name: string, workspace: DenoWorkspace, env?: Record<string, string>, serviceName?: string);
|
|
51
|
+
getServiceName(): string;
|
|
52
|
+
configureSpec(spec: VmSpec): VmSpec;
|
|
53
|
+
createInstance(): DenoWorkspaceTaskInstance;
|
|
54
|
+
}
|
|
55
|
+
declare class DenoWorkspaceTaskInstance extends VmWithInstance {
|
|
56
|
+
name: string;
|
|
57
|
+
workspace: DenoWorkspace;
|
|
58
|
+
env?: Record<string, string>;
|
|
59
|
+
serviceName?: string;
|
|
60
|
+
constructor(name: string, workspace: DenoWorkspace, env?: Record<string, string>, serviceName?: string);
|
|
61
|
+
getServiceName(): string;
|
|
62
|
+
logs(): Promise<string[] | undefined>;
|
|
63
|
+
}
|
|
21
64
|
declare class VmDenoInstance extends VmWithInstance implements VmJavaScriptRuntimeInstance {
|
|
22
65
|
builder: VmDeno;
|
|
23
66
|
constructor(builder: VmDeno);
|
|
@@ -30,4 +73,4 @@ declare class VmDenoInstance extends VmWithInstance implements VmJavaScriptRunti
|
|
|
30
73
|
install(options?: InstallOptions): Promise<InstallResult>;
|
|
31
74
|
}
|
|
32
75
|
|
|
33
|
-
export { VmDeno };
|
|
76
|
+
export { DenoWorkspace, DenoWorkspaceInstance, DenoWorkspaceTask, DenoWorkspaceTaskInstance, VmDeno };
|
package/dist/index.js
CHANGED
|
@@ -1,53 +1,40 @@
|
|
|
1
|
-
import { VmWith,
|
|
1
|
+
import { VmWith, VmWithInstance } from 'freestyle-sandboxes';
|
|
2
2
|
|
|
3
3
|
class VmDeno extends VmWith {
|
|
4
4
|
options;
|
|
5
|
+
workspaces = [];
|
|
5
6
|
constructor(options) {
|
|
6
7
|
super();
|
|
7
8
|
this.options = {
|
|
8
9
|
version: options?.version,
|
|
9
|
-
workdir: options?.workdir
|
|
10
|
-
deleteAfterSuccess: options?.deleteAfterSuccess ?? true
|
|
10
|
+
workdir: options?.workdir
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
-
|
|
13
|
+
configureBaseImage(image) {
|
|
14
14
|
const versionArg = this.options.version ? ` v${this.options.version}` : "";
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
name: "install-deno",
|
|
39
|
-
mode: "oneshot",
|
|
40
|
-
deleteAfterSuccess: this.options.deleteAfterSuccess,
|
|
41
|
-
env: {
|
|
42
|
-
HOME: "/root"
|
|
43
|
-
},
|
|
44
|
-
exec: ["bash /opt/install-deno.sh"],
|
|
45
|
-
timeoutSec: 300
|
|
46
|
-
}
|
|
47
|
-
]
|
|
48
|
-
}
|
|
49
|
-
})
|
|
50
|
-
);
|
|
15
|
+
return image.runCommands(`
|
|
16
|
+
apt-get update
|
|
17
|
+
apt-get install -y --no-install-recommends ca-certificates curl unzip
|
|
18
|
+
rm -rf /var/lib/apt/lists/*
|
|
19
|
+
curl -fsSL https://deno.land/install.sh | DENO_INSTALL="/opt/deno" sh -s -- --yes${versionArg}
|
|
20
|
+
/opt/deno/bin/deno --version`);
|
|
21
|
+
}
|
|
22
|
+
configureSpec(spec) {
|
|
23
|
+
spec.systemdService({
|
|
24
|
+
name: "install-deno",
|
|
25
|
+
mode: "oneshot",
|
|
26
|
+
env: {
|
|
27
|
+
HOME: "/root"
|
|
28
|
+
},
|
|
29
|
+
exec: ["/opt/deno/bin/deno --version"],
|
|
30
|
+
timeoutSec: 30
|
|
31
|
+
});
|
|
32
|
+
return spec;
|
|
33
|
+
}
|
|
34
|
+
workspace(options) {
|
|
35
|
+
const workspace = new DenoWorkspace(options);
|
|
36
|
+
this.workspaces.push(workspace);
|
|
37
|
+
return workspace;
|
|
51
38
|
}
|
|
52
39
|
createInstance() {
|
|
53
40
|
return new VmDenoInstance(this);
|
|
@@ -56,6 +43,112 @@ export PATH="$DENO_INSTALL/bin:$PATH"
|
|
|
56
43
|
return "install-deno.service";
|
|
57
44
|
}
|
|
58
45
|
}
|
|
46
|
+
class DenoWorkspace extends VmWith {
|
|
47
|
+
options;
|
|
48
|
+
env;
|
|
49
|
+
constructor(options, env) {
|
|
50
|
+
super();
|
|
51
|
+
this.options = options;
|
|
52
|
+
this.env = env;
|
|
53
|
+
}
|
|
54
|
+
task(name, options) {
|
|
55
|
+
return new DenoWorkspaceTask(
|
|
56
|
+
name,
|
|
57
|
+
this,
|
|
58
|
+
{
|
|
59
|
+
...this.env,
|
|
60
|
+
...options?.env
|
|
61
|
+
},
|
|
62
|
+
options?.serviceName
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
getInstallServiceName() {
|
|
66
|
+
return `deno-install-${this.options.path.replace(/\//g, "-")}`;
|
|
67
|
+
}
|
|
68
|
+
configureSpec(spec) {
|
|
69
|
+
if (this.options.install) {
|
|
70
|
+
spec.systemdService({
|
|
71
|
+
name: this.getInstallServiceName(),
|
|
72
|
+
mode: "oneshot",
|
|
73
|
+
bash: "/opt/deno/bin/deno install",
|
|
74
|
+
workdir: this.options.path,
|
|
75
|
+
env: {
|
|
76
|
+
HOME: "/root",
|
|
77
|
+
DENO_DIR: "/root/.cache/deno",
|
|
78
|
+
...this.env
|
|
79
|
+
},
|
|
80
|
+
user: "root"
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return spec;
|
|
84
|
+
}
|
|
85
|
+
createInstance() {
|
|
86
|
+
return new DenoWorkspaceInstance();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
class DenoWorkspaceInstance extends VmWithInstance {
|
|
90
|
+
}
|
|
91
|
+
class DenoWorkspaceTask extends VmWith {
|
|
92
|
+
name;
|
|
93
|
+
workspace;
|
|
94
|
+
env;
|
|
95
|
+
serviceName;
|
|
96
|
+
constructor(name, workspace, env, serviceName) {
|
|
97
|
+
super();
|
|
98
|
+
this.name = name;
|
|
99
|
+
this.workspace = workspace;
|
|
100
|
+
this.env = env;
|
|
101
|
+
this.serviceName = serviceName;
|
|
102
|
+
}
|
|
103
|
+
getServiceName() {
|
|
104
|
+
return this.serviceName ?? `deno-workspace-${this.workspace.options.path.replace(/\//g, "-")}-task-${this.name}`;
|
|
105
|
+
}
|
|
106
|
+
configureSpec(spec) {
|
|
107
|
+
spec.systemdService({
|
|
108
|
+
name: this.getServiceName(),
|
|
109
|
+
bash: `/opt/deno/bin/deno task ${this.name}`,
|
|
110
|
+
workdir: this.workspace.options.path,
|
|
111
|
+
after: [this.workspace.getInstallServiceName()],
|
|
112
|
+
requires: [this.workspace.getInstallServiceName()],
|
|
113
|
+
env: {
|
|
114
|
+
HOME: "/root",
|
|
115
|
+
DENO_DIR: "/root/.cache/deno",
|
|
116
|
+
...this.env
|
|
117
|
+
},
|
|
118
|
+
user: "root"
|
|
119
|
+
});
|
|
120
|
+
return spec;
|
|
121
|
+
}
|
|
122
|
+
createInstance() {
|
|
123
|
+
return new DenoWorkspaceTaskInstance(
|
|
124
|
+
this.name,
|
|
125
|
+
this.workspace,
|
|
126
|
+
this.env,
|
|
127
|
+
this.serviceName
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
class DenoWorkspaceTaskInstance extends VmWithInstance {
|
|
132
|
+
name;
|
|
133
|
+
workspace;
|
|
134
|
+
env;
|
|
135
|
+
serviceName;
|
|
136
|
+
constructor(name, workspace, env, serviceName) {
|
|
137
|
+
super();
|
|
138
|
+
this.name = name;
|
|
139
|
+
this.workspace = workspace;
|
|
140
|
+
this.env = env;
|
|
141
|
+
this.serviceName = serviceName;
|
|
142
|
+
}
|
|
143
|
+
getServiceName() {
|
|
144
|
+
return this.serviceName ?? `deno-workspace-${this.workspace.options.path.replace(/\//g, "-")}-task-${this.name}`;
|
|
145
|
+
}
|
|
146
|
+
logs() {
|
|
147
|
+
return this.vm.exec({
|
|
148
|
+
command: `journalctl -u ${this.getServiceName()} --no-pager -n 30`
|
|
149
|
+
}).then((result) => result.stdout?.trim().split("\n"));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
59
152
|
class VmDenoInstance extends VmWithInstance {
|
|
60
153
|
builder;
|
|
61
154
|
constructor(builder) {
|
|
@@ -107,7 +200,9 @@ class VmDenoInstance extends VmWithInstance {
|
|
|
107
200
|
if (!options?.deps) {
|
|
108
201
|
command = `${cdPrefix}/opt/deno/bin/deno install`;
|
|
109
202
|
} else {
|
|
110
|
-
const deps = Array.isArray(options.deps) ? options.deps.map(prefixDep) : Object.entries(options.deps).map(
|
|
203
|
+
const deps = Array.isArray(options.deps) ? options.deps.map(prefixDep) : Object.entries(options.deps).map(
|
|
204
|
+
([pkg, ver]) => `${prefixDep(pkg)}@${ver}`
|
|
205
|
+
);
|
|
111
206
|
const devFlag = options.dev ? " --dev" : "";
|
|
112
207
|
command = `${cdPrefix}/opt/deno/bin/deno add${devFlag} ${deps.join(" ")}`;
|
|
113
208
|
}
|
|
@@ -121,4 +216,4 @@ class VmDenoInstance extends VmWithInstance {
|
|
|
121
216
|
}
|
|
122
217
|
}
|
|
123
218
|
|
|
124
|
-
export { VmDeno };
|
|
219
|
+
export { DenoWorkspace, DenoWorkspaceInstance, DenoWorkspaceTask, DenoWorkspaceTaskInstance, VmDeno };
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@freestyle-sh/with-deno",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"freestyle-sandboxes": "^0.1.
|
|
7
|
-
"@freestyle-sh/with-type-js": "0.2.
|
|
6
|
+
"freestyle-sandboxes": "^0.1.43",
|
|
7
|
+
"@freestyle-sh/with-type-js": "0.2.9"
|
|
8
8
|
},
|
|
9
9
|
"devDependencies": {
|
|
10
10
|
"@types/node": "^22.0.0",
|