@freestyle-sh/with-ruby 0.1.0

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 ADDED
@@ -0,0 +1,64 @@
1
+ # @freestyle-sh/with-ruby
2
+
3
+ Ruby runtime via [RVM](https://rvm.io) for [Freestyle](https://freestyle.sh) VMs.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @freestyle-sh/with-ruby freestyle-sandboxes
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```typescript
14
+ import { freestyle } from "freestyle-sandboxes";
15
+ import { VmRuby } from "@freestyle-sh/with-ruby";
16
+
17
+ const { vm } = await freestyle.vms.create({
18
+ with: {
19
+ ruby: new VmRuby(),
20
+ },
21
+ });
22
+
23
+ const res = await vm.ruby.runCode(
24
+ "require 'json'; puts JSON.generate({ hello: 'world' })"
25
+ );
26
+
27
+ console.log(res);
28
+ // { result: { hello: 'world' }, stdout: '{"hello":"world"}\n', statusCode: 0 }
29
+ ```
30
+
31
+ ## Options
32
+
33
+ ```typescript
34
+ new VmRuby({
35
+ version: "3.3.6", // Optional: specific Ruby version (default: "3.4.8")
36
+ })
37
+ ```
38
+
39
+ | Option | Type | Default | Description |
40
+ |--------|------|---------|-------------|
41
+ | `version` | `string` | `"3.4.8"` | Ruby version to install via RVM. |
42
+
43
+ ## API
44
+
45
+ ### `vm.ruby.runCode(code: string)`
46
+
47
+ Executes Ruby code in the RVM-managed Ruby runtime.
48
+
49
+ **Returns:** `Promise<RunCodeResponse>`
50
+
51
+ ```typescript
52
+ type RunCodeResponse<Result> = {
53
+ result: Result; // Parsed JSON from stdout (if valid JSON)
54
+ stdout?: string; // Raw stdout output
55
+ stderr?: string; // Raw stderr output
56
+ statusCode?: number; // Exit code
57
+ };
58
+ ```
59
+
60
+ ## Documentation
61
+
62
+ - [Freestyle Documentation](https://docs.freestyle.sh)
63
+ - [Ruby Documentation](https://www.ruby-lang.org/en/documentation/)
64
+ - [RVM Documentation](https://rvm.io)
@@ -0,0 +1,23 @@
1
+ import { VmWith, VmWithInstance, CreateVmOptions } from 'freestyle-sandboxes';
2
+ import { VmRunCodeInstance, JSONValue, RunCodeResponse, VmRunCode } from '@freestyle-sh/with-type-run-code';
3
+
4
+ type RubyOptions = {
5
+ version?: string;
6
+ };
7
+ type RubyResolvedOptions = {
8
+ version: string;
9
+ };
10
+ declare class VmRuby extends VmWith<RubyRuntimeInstance> implements VmRunCode<VmRunCodeInstance> {
11
+ options: RubyResolvedOptions;
12
+ constructor(options?: RubyOptions);
13
+ configure(existingConfig: CreateVmOptions): CreateVmOptions | Promise<CreateVmOptions>;
14
+ createInstance(): RubyRuntimeInstance;
15
+ installServiceName(): string;
16
+ }
17
+ declare class RubyRuntimeInstance extends VmWithInstance implements VmRunCodeInstance {
18
+ builder: VmRuby;
19
+ constructor(builder: VmRuby);
20
+ runCode<Result extends JSONValue = any>(code: string): Promise<RunCodeResponse<Result>>;
21
+ }
22
+
23
+ export { VmRuby };
package/dist/index.js ADDED
@@ -0,0 +1,76 @@
1
+ import { VmWith, VmTemplate, VmWithInstance } from 'freestyle-sandboxes';
2
+
3
+ class VmRuby extends VmWith {
4
+ options;
5
+ constructor(options) {
6
+ super();
7
+ this.options = {
8
+ version: options?.version ?? "3.4.8"
9
+ };
10
+ }
11
+ configure(existingConfig) {
12
+ const installScript = `#!/bin/bash
13
+ set -e
14
+ curl -sSL https://get.rvm.io | bash -s -- head
15
+ source /etc/profile.d/rvm.sh
16
+ rvm install ${this.options.version}
17
+ rvm use ${this.options.version} --default
18
+ ruby --version
19
+ `;
20
+ const rubyConfig = {
21
+ template: new VmTemplate({
22
+ aptDeps: ["curl", "gnupg2", "ca-certificates"],
23
+ additionalFiles: {
24
+ "/opt/install-ruby.sh": {
25
+ content: installScript
26
+ }
27
+ },
28
+ systemd: {
29
+ services: [
30
+ {
31
+ name: "install-ruby",
32
+ mode: "oneshot",
33
+ deleteAfterSuccess: true,
34
+ exec: ["bash /opt/install-ruby.sh"],
35
+ timeoutSec: 300
36
+ }
37
+ ]
38
+ }
39
+ })
40
+ };
41
+ return this.compose(existingConfig, rubyConfig);
42
+ }
43
+ createInstance() {
44
+ return new RubyRuntimeInstance(this);
45
+ }
46
+ installServiceName() {
47
+ return "install-ruby.service";
48
+ }
49
+ }
50
+ class RubyRuntimeInstance extends VmWithInstance {
51
+ builder;
52
+ constructor(builder) {
53
+ super();
54
+ this.builder = builder;
55
+ }
56
+ async runCode(code) {
57
+ const result = await this.vm.exec({
58
+ command: `/usr/local/rvm/rubies/ruby-${this.builder.options.version}/bin/ruby -e "${code.replace(/"/g, '\\"')}"`
59
+ });
60
+ let parsedResult = void 0;
61
+ if (result.stdout) {
62
+ try {
63
+ parsedResult = JSON.parse(result.stdout);
64
+ } catch (e) {
65
+ }
66
+ }
67
+ return {
68
+ result: parsedResult,
69
+ stdout: result.stdout ?? void 0,
70
+ stderr: result.stderr ?? void 0,
71
+ statusCode: result.statusCode ?? -1
72
+ };
73
+ }
74
+ }
75
+
76
+ export { VmRuby };
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@freestyle-sh/with-ruby",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "dependencies": {
6
+ "freestyle-sandboxes": "^0.1.2",
7
+ "@freestyle-sh/with-type-run-code": "^0.1.0"
8
+ },
9
+ "type": "module",
10
+ "main": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js"
16
+ }
17
+ },
18
+ "source": "./src/index.ts",
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "scripts": {
23
+ "build": "pkgroll"
24
+ }
25
+ }