@freestyle-sh/with-postgres 0.2.8 → 0.2.10

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 CHANGED
@@ -1,109 +1,101 @@
1
1
  # @freestyle-sh/with-postgres
2
2
 
3
- PostgreSQL runtime extension for Freestyle VMs. Provides a fully configured PostgreSQL database server in your Freestyle VM.
3
+ PostgreSQL runtime extension for Freestyle VMs. Declaratively configure a PostgreSQL server, databases, and schema/seed scripts that run during VM snapshot setup.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- npm install @freestyle-sh/with-postgres freestyle-sandboxes
8
+ npm install @freestyle-sh/with-postgres freestyle
9
9
  ```
10
10
 
11
11
  ## Usage
12
12
 
13
13
  ```typescript
14
- import { freestyle } from "freestyle-sandboxes";
14
+ import { freestyle, VmSpec } from "freestyle";
15
15
  import { VmPostgres } from "@freestyle-sh/with-postgres";
16
16
 
17
- const { vm } = await freestyle.vms.create({
18
- with: {
19
- postgres: new VmPostgres({
20
- password: "mypassword",
21
- database: "mydb",
22
- version: "16", // Optional, defaults to "16"
23
- user: "postgres", // Optional, defaults to "postgres"
24
- }),
25
- },
17
+ const pg = new VmPostgres({ password: "secret" });
18
+
19
+ const db = pg.database({ name: "myapp", create: true });
20
+
21
+ const schema = db.script("schema", {
22
+ sql: `
23
+ CREATE TABLE users (
24
+ id SERIAL PRIMARY KEY,
25
+ name VARCHAR(100)
26
+ );
27
+ `,
26
28
  });
27
29
 
28
- // Create a table
29
- await vm.postgres.exec(`
30
- CREATE TABLE users (
31
- id SERIAL PRIMARY KEY,
32
- name VARCHAR(100),
33
- email VARCHAR(100)
34
- )
35
- `);
36
-
37
- // Insert data
38
- await vm.postgres.exec(`
39
- INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com')
40
- `);
41
-
42
- // Query data
43
- const result = await vm.postgres.query<{ id: number; name: string; email: string }>(`
44
- SELECT * FROM users
45
- `);
46
-
47
- console.log(result.rows); // [{ id: 1, name: 'Alice', email: 'alice@example.com' }]
48
- ```
30
+ const seed = db.script("seed", {
31
+ sql: `INSERT INTO users (name) VALUES ('Alice'), ('Bob');`,
32
+ after: [schema],
33
+ });
49
34
 
50
- ## API
35
+ const spec = new VmSpec()
36
+ .with("postgres", pg)
37
+ .with("db", db)
38
+ .with("schema", schema)
39
+ .with("seed", seed)
40
+ .snapshot();
51
41
 
52
- ### Constructor Options
42
+ const { vm } = await freestyle.vms.create({ spec });
53
43
 
54
- - `version?: string` - PostgreSQL version to install (default: "16")
55
- - `password?: string` - Password for the postgres user (default: "postgres")
56
- - `database?: string` - Default database to create (default: "postgres")
57
- - `user?: string` - PostgreSQL user (default: "postgres")
44
+ const result = await vm.db.query<{ id: number; name: string }>(
45
+ `SELECT * FROM users`
46
+ );
47
+ console.log(result.rows); // [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]
48
+ ```
58
49
 
59
- ### Methods
50
+ The install, database creation, and each script run as ordered systemd oneshot services during snapshot setup, so everything is baked into the snapshot.
60
51
 
61
- #### `query<T>(sql: string): Promise<QueryResult<T>>`
52
+ ## API
62
53
 
63
- Execute a SQL query and return results as JSON.
54
+ ### `new VmPostgres(options?)`
64
55
 
65
- **Returns:** `{ rows: T[], rowCount: number, error?: string }`
56
+ Configures the PostgreSQL server. Pure config has no runtime methods.
66
57
 
67
- ```typescript
68
- const result = await vm.postgres.query<{ id: number; name: string }>(`
69
- SELECT id, name FROM users WHERE id = 1
70
- `);
71
- ```
58
+ | Option | Type | Default | Description |
59
+ |--------|------|---------|-------------|
60
+ | `version` | `string` | `"18"` | PostgreSQL major version (installed from the official PGDG apt repo) |
61
+ | `password` | `string` | `"postgres"` | Password for the postgres superuser |
62
+ | `user` | `string` | `"postgres"` | PostgreSQL superuser name |
72
63
 
73
- #### `exec(sql: string): Promise<{ success: boolean, error?: string }>`
64
+ ### `pg.database({ name, create? })`
74
65
 
75
- Execute a SQL command without returning results (for CREATE, INSERT, UPDATE, DELETE, etc.).
66
+ Declares a database. Returns a `Database` you can attach scripts to and query at runtime.
76
67
 
77
- ```typescript
78
- const result = await vm.postgres.exec(`
79
- UPDATE users SET name = 'Bob' WHERE id = 1
80
- `);
81
- ```
68
+ | Option | Type | Default | Description |
69
+ |--------|------|---------|-------------|
70
+ | `name` | `string` | | Database name |
71
+ | `create` | `boolean` | `false` | If true, idempotently creates the database during snapshot setup |
82
72
 
83
- #### `createDatabase(dbName: string): Promise<{ success: boolean, error?: string }>`
73
+ #### `vm.<name>.query<T>(sql)`
84
74
 
85
- Create a new database.
75
+ Run a SQL query against this database. Returns `{ rows: T[], rowCount, error? }`. Results are returned as a JSON array (psql wraps the query in `json_agg(row_to_json(...))`).
86
76
 
87
- ```typescript
88
- await vm.postgres.createDatabase("newdb");
89
- ```
77
+ #### `vm.<name>.exec(sql)`
90
78
 
91
- #### `dropDatabase(dbName: string): Promise<{ success: boolean, error?: string }>`
79
+ Run a SQL command without returning rows. Returns `{ success, error? }`.
92
80
 
93
- Drop a database.
81
+ ### `db.script(name, { sql, after? })`
94
82
 
95
- ```typescript
96
- await vm.postgres.dropDatabase("olddb");
97
- ```
83
+ Declares a SQL script that runs once during snapshot setup against this database.
84
+
85
+ | Option | Type | Default | Description |
86
+ |--------|------|---------|-------------|
87
+ | `sql` | `string` | — | Inline SQL to execute |
88
+ | `after` | `DatabaseScript[]` | `[]` | Scripts that must run before this one |
89
+
90
+ Each script becomes a systemd oneshot with `ON_ERROR_STOP=1`, so the snapshot fails fast if any SQL errors. Scripts depend automatically on the database's create service (or on `install-postgres` if `create: false`), and on every script listed in `after`.
98
91
 
99
- ## How It Works
92
+ #### `vm.<name>.logs()`
100
93
 
101
- The package uses a systemd oneshot service to install and configure PostgreSQL during VM creation:
94
+ Returns the journalctl output for the script's systemd service as `string[]`.
102
95
 
103
- 1. Installs PostgreSQL from apt repositories
104
- 2. Configures password authentication
105
- 3. Creates the default database (if specified)
106
- 4. Enables network connections
107
- 5. Starts PostgreSQL as a system service
96
+ ## How it works
108
97
 
109
- The installation is fully automated and completes during VM initialization.
98
+ 1. `VmPostgres` adds the official PGDG apt repository and installs the requested PostgreSQL version (see https://www.postgresql.org/download/linux/debian/), then sets the superuser password and enables md5 password auth on TCP and the local socket.
99
+ 2. Each `database({ create: true })` adds a oneshot that creates the database if it doesn't exist.
100
+ 3. Each `script(...)` writes its SQL to `/opt/pg-scripts/<db>/<name>.sql` and adds a oneshot that runs `psql -f` against the right database, in the order you declared via `after`.
101
+ 4. All setup oneshots use `deleteAfterSuccess: true`, so they don't re-run on reboot from the snapshot.
package/dist/index.d.ts CHANGED
@@ -1,54 +1,83 @@
1
- import { VmWithInstance, VmWith, VmSpec } from 'freestyle-sandboxes';
1
+ import { VmWith, VmWithInstance, VmSpec } from 'freestyle';
2
2
 
3
3
  interface PostgresOptions {
4
4
  version?: string;
5
5
  password?: string;
6
- database?: string;
7
6
  user?: string;
8
7
  }
8
+ interface ResolvedPostgresOptions {
9
+ version: string;
10
+ password: string;
11
+ user: string;
12
+ }
9
13
  interface QueryResult<T = any> {
10
14
  rows: T[];
11
15
  rowCount: number;
12
16
  error?: string;
13
17
  }
18
+ interface DatabaseOptions {
19
+ name: string;
20
+ create?: boolean;
21
+ }
22
+ interface ScriptOptions {
23
+ sql: string;
24
+ after?: DatabaseScript[];
25
+ }
26
+ declare class VmPostgres extends VmWith<VmPostgresInstance> {
27
+ options: ResolvedPostgresOptions;
28
+ constructor(options?: PostgresOptions);
29
+ database(options: DatabaseOptions): Database;
30
+ installServiceName(): string;
31
+ configureSnapshotSpec(spec: VmSpec): VmSpec;
32
+ createInstance(): VmPostgresInstance;
33
+ }
14
34
  declare class VmPostgresInstance extends VmWithInstance {
15
- private password;
35
+ }
36
+ declare class Database extends VmWith<DatabaseInstance> {
37
+ options: DatabaseOptions;
38
+ postgres: VmPostgres;
39
+ constructor(options: DatabaseOptions, postgres: VmPostgres);
40
+ script(name: string, options: ScriptOptions): DatabaseScript;
41
+ getCreateServiceName(): string;
42
+ configureSnapshotSpec(spec: VmSpec): VmSpec;
43
+ createInstance(): DatabaseInstance;
44
+ }
45
+ declare class DatabaseInstance extends VmWithInstance {
16
46
  private database;
17
47
  private user;
18
- constructor(options: Required<PostgresOptions>);
48
+ private password;
49
+ constructor(opts: {
50
+ database: string;
51
+ user: string;
52
+ password: string;
53
+ });
19
54
  /**
20
- * Execute a SQL query and return the results
55
+ * Execute a SQL query against this database and return the results.
21
56
  */
22
57
  query<T = any>(sql: string): Promise<QueryResult<T>>;
23
58
  /**
24
- * Execute a SQL command without returning results (e.g., CREATE, INSERT, UPDATE, DELETE)
59
+ * Execute a SQL command without returning results (CREATE, INSERT, UPDATE, DELETE, etc.).
25
60
  */
26
61
  exec(sql: string): Promise<{
27
62
  success: boolean;
28
63
  error?: string;
29
64
  }>;
30
- /**
31
- * Create a new database
32
- */
33
- createDatabase(dbName: string): Promise<{
34
- success: boolean;
35
- error?: string;
36
- }>;
37
- /**
38
- * Drop a database
39
- */
40
- dropDatabase(dbName: string): Promise<{
41
- success: boolean;
42
- error?: string;
43
- }>;
44
65
  }
45
- declare class VmPostgres extends VmWith<VmPostgresInstance> {
46
- private options;
47
- constructor(options?: PostgresOptions);
66
+ declare class DatabaseScript extends VmWith<DatabaseScriptInstance> {
67
+ name: string;
68
+ database: Database;
69
+ options: ScriptOptions;
70
+ constructor(name: string, database: Database, options: ScriptOptions);
71
+ getServiceName(): string;
72
+ getScriptPath(): string;
48
73
  configureSnapshotSpec(spec: VmSpec): VmSpec;
49
- createInstance(): VmPostgresInstance;
50
- installServiceName(): string;
74
+ createInstance(): DatabaseScriptInstance;
75
+ }
76
+ declare class DatabaseScriptInstance extends VmWithInstance {
77
+ private serviceName;
78
+ constructor(serviceName: string);
79
+ logs(): Promise<string[] | undefined>;
51
80
  }
52
81
 
53
- export { VmPostgres, VmPostgresInstance };
54
- export type { PostgresOptions, QueryResult };
82
+ export { Database, DatabaseInstance, DatabaseScript, DatabaseScriptInstance, VmPostgres, VmPostgresInstance };
83
+ export type { DatabaseOptions, PostgresOptions, QueryResult, ScriptOptions };
package/dist/index.js CHANGED
@@ -1,24 +1,149 @@
1
- import { VmWithInstance, VmWith, VmSpec } from 'freestyle-sandboxes';
1
+ import { VmWith, VmSpec, VmWithInstance } from 'freestyle';
2
2
 
3
+ class VmPostgres extends VmWith {
4
+ options;
5
+ constructor(options = {}) {
6
+ super();
7
+ this.options = {
8
+ version: options.version || "18",
9
+ password: options.password || "postgres",
10
+ user: options.user || "postgres"
11
+ };
12
+ }
13
+ database(options) {
14
+ return new Database(options, this);
15
+ }
16
+ installServiceName() {
17
+ return "install-postgres.service";
18
+ }
19
+ configureSnapshotSpec(spec) {
20
+ const installScript = `#!/bin/bash
21
+ set -e
22
+
23
+ # Add the official PostgreSQL apt repository (PGDG) so any
24
+ # PostgreSQL version is available on any Debian release.
25
+ # See https://www.postgresql.org/download/linux/debian/
26
+ sudo apt-get update
27
+ sudo apt-get install -y curl ca-certificates
28
+ sudo install -d /usr/share/postgresql-common/pgdg
29
+ sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc
30
+ . /etc/os-release
31
+ sudo sh -c "echo 'deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt $VERSION_CODENAME-pgdg main' > /etc/apt/sources.list.d/pgdg.list"
32
+
33
+ # Install PostgreSQL
34
+ sudo apt-get update
35
+ sudo apt-get install -y postgresql-${this.options.version} postgresql-client-${this.options.version}
36
+
37
+ # Start PostgreSQL
38
+ sudo systemctl start postgresql
39
+
40
+ # Set password for postgres user
41
+ sudo -u postgres psql -c "ALTER USER postgres PASSWORD '${this.options.password}';"
42
+
43
+ # Configure PostgreSQL to accept password authentication
44
+ echo "host all all 0.0.0.0/0 md5" | sudo tee -a /etc/postgresql/${this.options.version}/main/pg_hba.conf
45
+ echo "local all all md5" | sudo tee -a /etc/postgresql/${this.options.version}/main/pg_hba.conf
46
+
47
+ # Allow connections from all addresses
48
+ sudo sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/" /etc/postgresql/${this.options.version}/main/postgresql.conf
49
+
50
+ # Restart PostgreSQL to apply changes
51
+ sudo systemctl restart postgresql
52
+
53
+ # Enable PostgreSQL to start on boot
54
+ sudo systemctl enable postgresql
55
+ `;
56
+ return this.composeSpecs(
57
+ spec,
58
+ new VmSpec({
59
+ additionalFiles: {
60
+ "/opt/install-postgres.sh": { content: installScript }
61
+ },
62
+ systemd: {
63
+ services: [
64
+ {
65
+ name: "install-postgres",
66
+ mode: "oneshot",
67
+ deleteAfterSuccess: true,
68
+ exec: ["bash /opt/install-postgres.sh"],
69
+ timeoutSec: 600
70
+ }
71
+ ]
72
+ }
73
+ })
74
+ );
75
+ }
76
+ createInstance() {
77
+ return new VmPostgresInstance();
78
+ }
79
+ }
3
80
  class VmPostgresInstance extends VmWithInstance {
4
- password;
81
+ }
82
+ class Database extends VmWith {
83
+ options;
84
+ postgres;
85
+ constructor(options, postgres) {
86
+ super();
87
+ this.options = options;
88
+ this.postgres = postgres;
89
+ }
90
+ script(name, options) {
91
+ return new DatabaseScript(name, this, options);
92
+ }
93
+ getCreateServiceName() {
94
+ return `pg-create-${this.options.name}`;
95
+ }
96
+ configureSnapshotSpec(spec) {
97
+ if (!this.options.create) return spec;
98
+ const { password, user } = this.postgres.options;
99
+ const dbName = this.options.name;
100
+ const psqlBase = `PGPASSWORD='${password}' psql -h 127.0.0.1 -U ${user} -d postgres`;
101
+ const createCmd = `${psqlBase} -tAc "SELECT 1 FROM pg_database WHERE datname='${dbName}'" | grep -q 1 || ${psqlBase} -c 'CREATE DATABASE ${dbName}'`;
102
+ return this.composeSpecs(
103
+ spec,
104
+ new VmSpec({
105
+ systemd: {
106
+ services: [
107
+ {
108
+ name: this.getCreateServiceName(),
109
+ mode: "oneshot",
110
+ deleteAfterSuccess: true,
111
+ after: [this.postgres.installServiceName()],
112
+ requires: [this.postgres.installServiceName()],
113
+ bash: createCmd,
114
+ timeoutSec: 60
115
+ }
116
+ ]
117
+ }
118
+ })
119
+ );
120
+ }
121
+ createInstance() {
122
+ return new DatabaseInstance({
123
+ database: this.options.name,
124
+ user: this.postgres.options.user,
125
+ password: this.postgres.options.password
126
+ });
127
+ }
128
+ }
129
+ class DatabaseInstance extends VmWithInstance {
5
130
  database;
6
131
  user;
7
- constructor(options) {
132
+ password;
133
+ constructor(opts) {
8
134
  super();
9
- this.password = options.password;
10
- this.database = options.database;
11
- this.user = options.user;
135
+ this.database = opts.database;
136
+ this.user = opts.user;
137
+ this.password = opts.password;
12
138
  }
13
139
  /**
14
- * Execute a SQL query and return the results
140
+ * Execute a SQL query against this database and return the results.
15
141
  */
16
142
  async query(sql) {
17
- const escapedSql = sql.replace(/'/g, "'\\''");
18
- const command = `PGPASSWORD='${this.password}' psql -U ${this.user} -d ${this.database} -t -A -F',' -c '${escapedSql}' --json`;
19
- const result = await this.vm.exec({
20
- command
21
- });
143
+ const wrappedSql = `SELECT COALESCE(json_agg(row_to_json(t)), '[]'::json) FROM (${sql}) t`;
144
+ const escapedSql = wrappedSql.replace(/'/g, "'\\''");
145
+ const command = `PGPASSWORD='${this.password}' psql -h 127.0.0.1 -U ${this.user} -d ${this.database} -t -A -c '${escapedSql}'`;
146
+ const result = await this.vm.exec({ command });
22
147
  if (result.statusCode !== 0) {
23
148
  return {
24
149
  rows: [],
@@ -41,14 +166,12 @@ class VmPostgresInstance extends VmWithInstance {
41
166
  }
42
167
  }
43
168
  /**
44
- * Execute a SQL command without returning results (e.g., CREATE, INSERT, UPDATE, DELETE)
169
+ * Execute a SQL command without returning results (CREATE, INSERT, UPDATE, DELETE, etc.).
45
170
  */
46
171
  async exec(sql) {
47
172
  const escapedSql = sql.replace(/'/g, "'\\''");
48
- const command = `PGPASSWORD='${this.password}' psql -U ${this.user} -d ${this.database} -c '${escapedSql}'`;
49
- const result = await this.vm.exec({
50
- command
51
- });
173
+ const command = `PGPASSWORD='${this.password}' psql -h 127.0.0.1 -U ${this.user} -d ${this.database} -c '${escapedSql}'`;
174
+ const result = await this.vm.exec({ command });
52
175
  if (result.statusCode !== 0) {
53
176
  return {
54
177
  success: false,
@@ -57,98 +180,53 @@ class VmPostgresInstance extends VmWithInstance {
57
180
  }
58
181
  return { success: true };
59
182
  }
60
- /**
61
- * Create a new database
62
- */
63
- async createDatabase(dbName) {
64
- const command = `PGPASSWORD='${this.password}' psql -U ${this.user} -d postgres -c 'CREATE DATABASE ${dbName}'`;
65
- const result = await this.vm.exec({
66
- command
67
- });
68
- if (result.statusCode !== 0) {
69
- return {
70
- success: false,
71
- error: result.stderr || "Database creation failed"
72
- };
73
- }
74
- return { success: true };
75
- }
76
- /**
77
- * Drop a database
78
- */
79
- async dropDatabase(dbName) {
80
- const command = `PGPASSWORD='${this.password}' psql -U ${this.user} -d postgres -c 'DROP DATABASE IF EXISTS ${dbName}'`;
81
- const result = await this.vm.exec({
82
- command
83
- });
84
- if (result.statusCode !== 0) {
85
- return {
86
- success: false,
87
- error: result.stderr || "Database drop failed"
88
- };
89
- }
90
- return { success: true };
91
- }
92
183
  }
93
- class VmPostgres extends VmWith {
184
+ class DatabaseScript extends VmWith {
185
+ name;
186
+ database;
94
187
  options;
95
- constructor(options = {}) {
188
+ constructor(name, database, options) {
96
189
  super();
97
- this.options = {
98
- version: options.version || "16",
99
- password: options.password || "postgres",
100
- database: options.database || "postgres",
101
- user: options.user || "postgres"
102
- };
190
+ this.name = name;
191
+ this.database = database;
192
+ this.options = options;
193
+ }
194
+ getServiceName() {
195
+ return `pg-script-${this.database.options.name}-${this.name}`;
196
+ }
197
+ getScriptPath() {
198
+ return `/opt/pg-scripts/${this.database.options.name}/${this.name}.sql`;
103
199
  }
104
200
  configureSnapshotSpec(spec) {
105
- const installScript = `#!/bin/bash
106
- set -e
107
-
108
- # Install PostgreSQL
109
- sudo apt-get update
110
- sudo apt-get install -y postgresql-${this.options.version} postgresql-client-${this.options.version}
111
-
112
- # Start PostgreSQL
113
- sudo systemctl start postgresql
114
-
115
- # Set password for postgres user
116
- sudo -u postgres psql -c "ALTER USER postgres PASSWORD '${this.options.password}';"
117
-
118
- # Create default database if not postgres
119
- if [ "${this.options.database}" != "postgres" ]; then
120
- sudo -u postgres psql -c "CREATE DATABASE ${this.options.database};"
121
- fi
122
-
123
- # Configure PostgreSQL to accept password authentication
124
- echo "host all all 0.0.0.0/0 md5" | sudo tee -a /etc/postgresql/${this.options.version}/main/pg_hba.conf
125
- echo "local all all md5" | sudo tee -a /etc/postgresql/${this.options.version}/main/pg_hba.conf
126
-
127
- # Allow connections from all addresses
128
- sudo sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/" /etc/postgresql/${this.options.version}/main/postgresql.conf
129
-
130
- # Restart PostgreSQL to apply changes
131
- sudo systemctl restart postgresql
132
-
133
- # Enable PostgreSQL to start on boot
134
- sudo systemctl enable postgresql
135
- `;
201
+ const { password, user } = this.database.postgres.options;
202
+ const dbName = this.database.options.name;
203
+ const scriptPath = this.getScriptPath();
204
+ const deps = [];
205
+ if (this.database.options.create) {
206
+ deps.push(this.database.getCreateServiceName());
207
+ } else {
208
+ deps.push(this.database.postgres.installServiceName());
209
+ }
210
+ for (const dep of this.options.after ?? []) {
211
+ deps.push(dep.getServiceName());
212
+ }
213
+ const command = `PGPASSWORD='${password}' psql -h 127.0.0.1 -U ${user} -d ${dbName} -v ON_ERROR_STOP=1 -f ${scriptPath}`;
136
214
  return this.composeSpecs(
137
215
  spec,
138
216
  new VmSpec({
139
217
  additionalFiles: {
140
- "/opt/install-postgres.sh": {
141
- content: installScript
142
- }
218
+ [scriptPath]: { content: this.options.sql }
143
219
  },
144
220
  systemd: {
145
221
  services: [
146
222
  {
147
- name: "install-postgres",
223
+ name: this.getServiceName(),
148
224
  mode: "oneshot",
149
225
  deleteAfterSuccess: true,
150
- exec: ["bash /opt/install-postgres.sh"],
151
- timeoutSec: 600
226
+ after: deps,
227
+ requires: deps,
228
+ bash: command,
229
+ timeoutSec: 300
152
230
  }
153
231
  ]
154
232
  }
@@ -156,11 +234,20 @@ sudo systemctl enable postgresql
156
234
  );
157
235
  }
158
236
  createInstance() {
159
- return new VmPostgresInstance(this.options);
237
+ return new DatabaseScriptInstance(this.getServiceName());
160
238
  }
161
- installServiceName() {
162
- return "install-postgres.service";
239
+ }
240
+ class DatabaseScriptInstance extends VmWithInstance {
241
+ serviceName;
242
+ constructor(serviceName) {
243
+ super();
244
+ this.serviceName = serviceName;
245
+ }
246
+ logs() {
247
+ return this.vm.exec({
248
+ command: `journalctl -u ${this.serviceName} --no-pager -n 100`
249
+ }).then((result) => result.stdout?.trim().split("\n"));
163
250
  }
164
251
  }
165
252
 
166
- export { VmPostgres, VmPostgresInstance };
253
+ export { Database, DatabaseInstance, DatabaseScript, DatabaseScriptInstance, VmPostgres, VmPostgresInstance };
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@freestyle-sh/with-postgres",
3
- "version": "0.2.8",
3
+ "version": "0.2.10",
4
4
  "private": false,
5
5
  "dependencies": {
6
- "freestyle-sandboxes": "^0.1.28"
6
+ "freestyle": "^0.1.46"
7
7
  },
8
8
  "type": "module",
9
9
  "main": "./dist/index.js",