Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@freestyle-sh/with-nodejs

Package Overview
Dependencies
Maintainers
2
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@freestyle-sh/with-nodejs - npm Package Compare versions

Comparing version
0.2.8
to
0.2.9
+45
-1
dist/index.d.ts

@@ -14,7 +14,51 @@ import { VmWith, VmWithInstance, VmSpec } from 'freestyle-sandboxes';

options: NodeJsResolvedOptions;
workspaces: NodeJsWorkspace[];
constructor(options?: NodeJsOptions);
configureSnapshotSpec(spec: VmSpec): VmSpec;
createInstance(): NodeJsRuntimeInstance;
workspace(options: {
path: string;
install?: boolean;
}): NodeJsWorkspace;
installServiceName(): string;
}
declare class NodeJsWorkspace extends VmWith<NodeJsWorkspaceInstance> {
options: {
path: string;
install?: boolean;
};
env?: Record<string, string>;
constructor(options: {
path: string;
install?: boolean;
}, env?: Record<string, string>);
task(name: string, options?: {
env?: Record<string, string>;
serviceName?: string;
}): NodeJsWorkspaceTask;
getInstallServiceName(): string;
configureSpec(spec: VmSpec): VmSpec;
createInstance(): NodeJsWorkspaceInstance;
}
declare class NodeJsWorkspaceInstance extends VmWithInstance {
}
declare class NodeJsWorkspaceTask extends VmWith<NodeJsWorkspaceTaskInstance> {
name: string;
workspace: NodeJsWorkspace;
env?: Record<string, string>;
serviceName?: string;
constructor(name: string, workspace: NodeJsWorkspace, env?: Record<string, string>, serviceName?: string);
getServiceName(): string;
configureSpec(spec: VmSpec): VmSpec;
createInstance(): NodeJsWorkspaceTaskInstance;
}
declare class NodeJsWorkspaceTaskInstance extends VmWithInstance {
name: string;
workspace: NodeJsWorkspace;
env?: Record<string, string>;
serviceName?: string;
constructor(name: string, workspace: NodeJsWorkspace, env?: Record<string, string>, serviceName?: string);
getServiceName(): string;
logs(): Promise<string[] | undefined>;
}
declare class NodeJsRuntimeInstance extends VmWithInstance implements VmJavaScriptRuntimeInstance {

@@ -32,2 +76,2 @@ builder: VmNodeJs;

export { VmNodeJs };
export { NodeJsWorkspace, NodeJsWorkspaceInstance, NodeJsWorkspaceTask, NodeJsWorkspaceTaskInstance, VmNodeJs };

@@ -5,2 +5,3 @@ import { VmWith, VmSpec, VmWithInstance } from 'freestyle-sandboxes';

options;
workspaces = [];
constructor(options) {

@@ -57,2 +58,7 @@ super();

}
workspace(options) {
const workspace = new NodeJsWorkspace(options);
this.workspaces.push(workspace);
return workspace;
}
installServiceName() {

@@ -62,2 +68,127 @@ return `install-nodejs.service`;

}
class NodeJsWorkspace extends VmWith {
options;
env;
constructor(options, env) {
super();
this.options = options;
this.env = env;
}
task(name, options) {
return new NodeJsWorkspaceTask(
name,
this,
{
...this.env,
...options?.env
},
options?.serviceName
);
}
getInstallServiceName() {
return `nodejs-install-${this.options.path.replace(/\//g, "-")}`;
}
configureSpec(spec) {
if (this.options.install) {
return this.composeSpecs(
spec,
new VmSpec({
systemd: {
services: [
{
name: this.getInstallServiceName(),
mode: "oneshot",
exec: ['bash -lc "source /opt/nvm/nvm.sh && npm install"'],
workdir: this.options.path,
env: {
HOME: "/root",
NVM_DIR: "/opt/nvm",
...this.env
},
user: "root"
}
]
}
})
);
}
return spec;
}
createInstance() {
return new NodeJsWorkspaceInstance();
}
}
class NodeJsWorkspaceInstance extends VmWithInstance {
}
class NodeJsWorkspaceTask extends VmWith {
name;
workspace;
env;
serviceName;
constructor(name, workspace, env, serviceName) {
super();
this.name = name;
this.workspace = workspace;
this.env = env;
this.serviceName = serviceName;
}
getServiceName() {
return this.serviceName ?? `nodejs-workspace-${this.workspace.options.path.replace(/\//g, "-")}-task-${this.name}`;
}
configureSpec(spec) {
return this.composeSpecs(
spec,
new VmSpec({
systemd: {
services: [
{
name: this.getServiceName(),
exec: [
`bash -lc "source /opt/nvm/nvm.sh && npm run ${this.name}"`
],
workdir: this.workspace.options.path,
after: this.workspace.options.install ? [this.workspace.getInstallServiceName()] : void 0,
requires: this.workspace.options.install ? [this.workspace.getInstallServiceName()] : void 0,
env: {
HOME: "/root",
NVM_DIR: "/opt/nvm",
...this.env
},
user: "root"
}
]
}
})
);
}
createInstance() {
return new NodeJsWorkspaceTaskInstance(
this.name,
this.workspace,
this.env,
this.serviceName
);
}
}
class NodeJsWorkspaceTaskInstance extends VmWithInstance {
name;
workspace;
env;
serviceName;
constructor(name, workspace, env, serviceName) {
super();
this.name = name;
this.workspace = workspace;
this.env = env;
this.serviceName = serviceName;
}
getServiceName() {
return this.serviceName ?? `nodejs-workspace-${this.workspace.options.path.replace(/\//g, "-")}-task-${this.name}`;
}
logs() {
return this.vm.exec({
command: `journalctl -u ${this.getServiceName()} --no-pager -n 30`
}).then((result) => result.stdout?.trim().split("\n"));
}
}
class NodeJsRuntimeInstance extends VmWithInstance {

@@ -124,2 +255,2 @@ builder;

export { VmNodeJs };
export { NodeJsWorkspace, NodeJsWorkspaceInstance, NodeJsWorkspaceTask, NodeJsWorkspaceTaskInstance, VmNodeJs };
+3
-3
{
"name": "@freestyle-sh/with-nodejs",
"version": "0.2.8",
"version": "0.2.9",
"private": false,
"dependencies": {
"freestyle-sandboxes": "^0.1.28",
"@freestyle-sh/with-type-js": "^0.2.8"
"freestyle-sandboxes": "^0.1.41",
"@freestyle-sh/with-type-js": "^0.2.9"
},

@@ -9,0 +9,0 @@ "type": "module",

@@ -94,2 +94,79 @@ # @freestyle-sh/with-nodejs

## Workspaces and Tasks
Use the Node.js builder to attach a workspace and run an npm script as a managed systemd service.
```typescript
import { freestyle, VmSpec } from "freestyle-sandboxes";
import { VmNodeJs } from "@freestyle-sh/with-nodejs";
const SOURCE_REPO = "https://github.com/freestyle-sh/freestyle-next";
const node = new VmNodeJs();
const workspace = node.workspace({ path: "/root/app", install: true });
const appTask = workspace.task("dev", {
env: {
HOST: "0.0.0.0",
PORT: "3000",
},
});
const spec = new VmSpec()
.with("node", node)
.repo(SOURCE_REPO, "/root/app")
.with("workspace", workspace)
.with("app", appTask)
.snapshot()
.waitFor("curl http://localhost:3000")
.snapshot();
const { repoId } = await freestyle.git.repos.create({
source: {
url: SOURCE_REPO,
},
});
const domain = `${repoId}.style.dev`;
const { vm } = await freestyle.vms.create({
spec,
domains: [{ domain, vmPort: 3000 }],
git: {
repos: [{ repo: repoId, path: "/root/app" }],
},
});
console.log(await vm.app.logs());
```
### Workspace API
```typescript
const workspace = node.workspace({
path: "/root/app",
install: true,
});
```
- `path`: Working directory for `npm install` and task execution.
- `install`: When true, runs `npm install` in the workspace during VM startup.
### Task API
```typescript
const task = workspace.task("dev", {
env: {
HOST: "0.0.0.0",
PORT: "3000",
},
serviceName: "my-node-app",
});
```
- `name`: Script name from `package.json`.
- `env`: Optional environment variables for the task service.
- `serviceName`: Optional explicit systemd service name.
When added to the spec with `.with("app", task)`, you can access task logs with `vm.app.logs()`.
## Documentation

@@ -96,0 +173,0 @@