@highstate/backend 0.17.0 → 0.19.1
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/dist/{chunk-JT4KWE3B.js → chunk-V2NILDHS.js} +3 -2
- package/dist/chunk-V2NILDHS.js.map +1 -0
- package/dist/highstate.manifest.json +3 -4
- package/dist/index.js +190 -280
- package/dist/index.js.map +1 -1
- package/dist/shared/index.js +1 -1
- package/package.json +9 -10
- package/prisma/backend/postgresql/main.prisma +0 -2
- package/prisma/backend/sqlite/main.prisma +0 -2
- package/prisma/project/main.prisma +0 -1
- package/src/business/project.ts +1 -2
- package/src/database/_generated/backend/postgresql/browser.ts +54 -0
- package/src/database/_generated/backend/postgresql/client.ts +7 -8
- package/src/database/_generated/backend/postgresql/commonInputTypes.ts +3 -2
- package/src/database/_generated/backend/postgresql/enums.ts +3 -1
- package/src/database/_generated/backend/postgresql/internal/class.ts +24 -71
- package/src/database/_generated/backend/postgresql/internal/prismaNamespace.ts +41 -43
- package/src/database/_generated/backend/postgresql/internal/prismaNamespaceBrowser.ts +191 -0
- package/src/database/_generated/backend/postgresql/models/BackendUnlockMethod.ts +12 -11
- package/src/database/_generated/backend/postgresql/models/Library.ts +29 -28
- package/src/database/_generated/backend/postgresql/models/Project.ts +69 -68
- package/src/database/_generated/backend/postgresql/models/ProjectModelStorage.ts +29 -28
- package/src/database/_generated/backend/postgresql/models/ProjectSpace.ts +26 -25
- package/src/database/_generated/backend/postgresql/models/PulumiBackend.ts +29 -28
- package/src/database/_generated/backend/postgresql/models/UserWorkspaceLayout.ts +12 -11
- package/src/database/_generated/backend/postgresql/models.ts +2 -1
- package/src/database/_generated/backend/postgresql/pjtg.ts +1 -0
- package/src/database/_generated/backend/sqlite/browser.ts +54 -0
- package/src/database/_generated/backend/sqlite/client.ts +7 -8
- package/src/database/_generated/backend/sqlite/commonInputTypes.ts +3 -2
- package/src/database/_generated/backend/sqlite/enums.ts +3 -1
- package/src/database/_generated/backend/sqlite/internal/class.ts +24 -71
- package/src/database/_generated/backend/sqlite/internal/prismaNamespace.ts +41 -43
- package/src/database/_generated/backend/sqlite/internal/prismaNamespaceBrowser.ts +188 -0
- package/src/database/_generated/backend/sqlite/models/BackendUnlockMethod.ts +12 -11
- package/src/database/_generated/backend/sqlite/models/Library.ts +29 -28
- package/src/database/_generated/backend/sqlite/models/Project.ts +69 -68
- package/src/database/_generated/backend/sqlite/models/ProjectModelStorage.ts +29 -28
- package/src/database/_generated/backend/sqlite/models/ProjectSpace.ts +26 -25
- package/src/database/_generated/backend/sqlite/models/PulumiBackend.ts +29 -28
- package/src/database/_generated/backend/sqlite/models/UserWorkspaceLayout.ts +12 -11
- package/src/database/_generated/backend/sqlite/models.ts +2 -1
- package/src/database/_generated/backend/sqlite/pjtg.ts +1 -0
- package/src/database/_generated/project/browser.ts +1 -0
- package/src/database/_generated/project/client.ts +4 -5
- package/src/database/_generated/project/commonInputTypes.ts +1 -0
- package/src/database/_generated/project/enums.ts +1 -0
- package/src/database/_generated/project/internal/class.ts +20 -62
- package/src/database/_generated/project/internal/prismaNamespace.ts +40 -36
- package/src/database/_generated/project/internal/prismaNamespaceBrowser.ts +9 -6
- package/src/database/_generated/project/models/ApiKey.ts +1 -0
- package/src/database/_generated/project/models/Artifact.ts +1 -0
- package/src/database/_generated/project/models/HubModel.ts +1 -0
- package/src/database/_generated/project/models/InstanceCustomStatus.ts +1 -0
- package/src/database/_generated/project/models/InstanceEvaluationState.ts +1 -0
- package/src/database/_generated/project/models/InstanceLock.ts +1 -0
- package/src/database/_generated/project/models/InstanceModel.ts +1 -0
- package/src/database/_generated/project/models/InstanceOperationState.ts +1 -0
- package/src/database/_generated/project/models/InstanceState.ts +1 -0
- package/src/database/_generated/project/models/Operation.ts +1 -0
- package/src/database/_generated/project/models/OperationLog.ts +1 -0
- package/src/database/_generated/project/models/Page.ts +1 -0
- package/src/database/_generated/project/models/Secret.ts +1 -0
- package/src/database/_generated/project/models/ServiceAccount.ts +1 -0
- package/src/database/_generated/project/models/Terminal.ts +1 -0
- package/src/database/_generated/project/models/TerminalSession.ts +1 -0
- package/src/database/_generated/project/models/TerminalSessionLog.ts +1 -0
- package/src/database/_generated/project/models/Trigger.ts +1 -0
- package/src/database/_generated/project/models/UnlockMethod.ts +1 -0
- package/src/database/_generated/project/models/UserCompositeViewport.ts +1 -0
- package/src/database/_generated/project/models/UserProjectViewport.ts +1 -0
- package/src/database/_generated/project/models/Worker.ts +1 -0
- package/src/database/_generated/project/models/WorkerUnitRegistration.ts +1 -0
- package/src/database/_generated/project/models/WorkerVersion.ts +1 -0
- package/src/database/_generated/project/models/WorkerVersionLog.ts +1 -0
- package/src/database/_generated/project/models.ts +1 -0
- package/src/database/abstractions.ts +1 -7
- package/src/database/index.ts +1 -0
- package/src/database/local/backend.ts +19 -30
- package/src/database/local/project.ts +4 -9
- package/src/database/manager.ts +28 -34
- package/src/database/migration.ts +126 -0
- package/src/shared/resolvers/input.ts +2 -0
- package/src/test-utils/database.ts +28 -14
- package/dist/chunk-JT4KWE3B.js.map +0 -1
- package/dist/database/local/prisma.config.js +0 -26
- package/dist/database/local/prisma.config.js.map +0 -1
- package/src/database/local/prisma.config.ts +0 -25
- package/src/database/migrate.ts +0 -35
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
|
3
3
|
/* eslint-disable */
|
|
4
|
+
// biome-ignore-all lint: generated file
|
|
4
5
|
// @ts-nocheck
|
|
5
6
|
/*
|
|
6
7
|
* WARNING: This is an internal file that is subject to change!
|
|
@@ -23,28 +24,30 @@ export const Decimal = runtime.Decimal
|
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
export const NullTypes = {
|
|
26
|
-
DbNull: runtime.
|
|
27
|
-
JsonNull: runtime.
|
|
28
|
-
AnyNull: runtime.
|
|
27
|
+
DbNull: runtime.NullTypes.DbNull as (new (secret: never) => typeof runtime.DbNull),
|
|
28
|
+
JsonNull: runtime.NullTypes.JsonNull as (new (secret: never) => typeof runtime.JsonNull),
|
|
29
|
+
AnyNull: runtime.NullTypes.AnyNull as (new (secret: never) => typeof runtime.AnyNull),
|
|
29
30
|
}
|
|
30
31
|
/**
|
|
31
32
|
* Helper for filtering JSON entries that have `null` on the database (empty on the db)
|
|
32
33
|
*
|
|
33
34
|
* @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
|
|
34
35
|
*/
|
|
35
|
-
export const DbNull = runtime.
|
|
36
|
+
export const DbNull = runtime.DbNull
|
|
37
|
+
|
|
36
38
|
/**
|
|
37
39
|
* Helper for filtering JSON entries that have JSON `null` values (not empty on the db)
|
|
38
40
|
*
|
|
39
41
|
* @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
|
|
40
42
|
*/
|
|
41
|
-
export const JsonNull = runtime.
|
|
43
|
+
export const JsonNull = runtime.JsonNull
|
|
44
|
+
|
|
42
45
|
/**
|
|
43
46
|
* Helper for filtering JSON entries that are `Prisma.DbNull` or `Prisma.JsonNull`
|
|
44
47
|
*
|
|
45
48
|
* @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
|
|
46
49
|
*/
|
|
47
|
-
export const AnyNull = runtime.
|
|
50
|
+
export const AnyNull = runtime.AnyNull
|
|
48
51
|
|
|
49
52
|
|
|
50
53
|
export const ModelName = {
|
|
@@ -31,11 +31,5 @@ export interface ProjectDatabaseBackend {
|
|
|
31
31
|
* @param projectId The ID of the project to open the database for.
|
|
32
32
|
* @param masterKey The master key to decrypt the project database. If not provided, the encryption is assumed to be disabled.
|
|
33
33
|
*/
|
|
34
|
-
openProjectDatabase(
|
|
35
|
-
projectId: string,
|
|
36
|
-
masterKey?: string,
|
|
37
|
-
): Promise<[database: ProjectDatabase, url: string]>
|
|
34
|
+
openProjectDatabase(projectId: string, masterKey?: string): Promise<ProjectDatabase>
|
|
38
35
|
}
|
|
39
|
-
|
|
40
|
-
export const backendDatabaseVersion = 1
|
|
41
|
-
export const projectDatabaseVersion = 2
|
package/src/database/index.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type { Logger } from "pino"
|
|
2
|
+
import type { BackendDatabaseBackend } from "../abstractions"
|
|
2
3
|
import type { BackendDatabase } from "../prisma"
|
|
3
4
|
import { randomBytes } from "node:crypto"
|
|
4
5
|
import { hostname } from "node:os"
|
|
5
|
-
import {
|
|
6
|
+
import { PrismaLibSql } from "@prisma/adapter-libsql"
|
|
6
7
|
import { armor, Decrypter, Encrypter, identityToRecipient } from "age-encryption"
|
|
7
8
|
import { z } from "zod"
|
|
8
9
|
import { codebaseConfig, getCodebaseHighstatePath } from "../../common"
|
|
9
10
|
import { PrismaClient } from "../_generated/backend/sqlite/client"
|
|
10
|
-
import {
|
|
11
|
-
import { migrateDatabase } from "../migrate"
|
|
11
|
+
import { migrateDatabase, migrationPacks } from "../migration"
|
|
12
12
|
import { ensureWellKnownEntitiesCreated } from "../well-known"
|
|
13
13
|
import {
|
|
14
14
|
type BackendIdentityConfig,
|
|
@@ -94,7 +94,6 @@ async function createMasterKey(config: BackendIdentityConfig, logger: Logger) {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
type DatabaseInitializationResult = {
|
|
97
|
-
shouldMigrate: boolean
|
|
98
97
|
masterKey?: string
|
|
99
98
|
metaFile: DatabaseMetaFile
|
|
100
99
|
created: boolean
|
|
@@ -115,12 +114,11 @@ async function ensureDatabaseInitialized(
|
|
|
115
114
|
const masterKey = encryptionEnabled ? await createMasterKey(config, logger) : undefined
|
|
116
115
|
|
|
117
116
|
const metaFile: DatabaseMetaFile = {
|
|
118
|
-
version:
|
|
117
|
+
version: 0,
|
|
119
118
|
masterKey: masterKey?.armoredMasterKey,
|
|
120
119
|
}
|
|
121
120
|
|
|
122
121
|
return {
|
|
123
|
-
shouldMigrate: true,
|
|
124
122
|
masterKey: masterKey?.masterKey,
|
|
125
123
|
metaFile,
|
|
126
124
|
created: true,
|
|
@@ -128,15 +126,8 @@ async function ensureDatabaseInitialized(
|
|
|
128
126
|
}
|
|
129
127
|
}
|
|
130
128
|
|
|
131
|
-
if (meta.version > backendDatabaseVersion) {
|
|
132
|
-
throw new Error(
|
|
133
|
-
`Database version (${meta.version}) is newer than expected (${backendDatabaseVersion}). You likely need to update the Highstate.`,
|
|
134
|
-
)
|
|
135
|
-
}
|
|
136
|
-
|
|
137
129
|
if (!encryptionEnabled) {
|
|
138
130
|
return {
|
|
139
|
-
shouldMigrate: meta.version < backendDatabaseVersion,
|
|
140
131
|
masterKey: undefined,
|
|
141
132
|
metaFile: meta,
|
|
142
133
|
created: false,
|
|
@@ -158,7 +149,6 @@ async function ensureDatabaseInitialized(
|
|
|
158
149
|
const masterKey = await decrypter.decrypt(encryptedMasterKey, "text")
|
|
159
150
|
|
|
160
151
|
return {
|
|
161
|
-
shouldMigrate: meta.version < backendDatabaseVersion,
|
|
162
152
|
masterKey,
|
|
163
153
|
metaFile: meta,
|
|
164
154
|
created: false,
|
|
@@ -183,23 +173,16 @@ export async function createLocalBackendDatabaseBackend(
|
|
|
183
173
|
let databasePath = config.HIGHSTATE_BACKEND_DATABASE_LOCAL_PATH
|
|
184
174
|
databasePath ??= await getCodebaseHighstatePath(config, logger)
|
|
185
175
|
|
|
186
|
-
const {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
)
|
|
176
|
+
const { masterKey, metaFile, created, initialRecipient } = await ensureDatabaseInitialized(
|
|
177
|
+
databasePath,
|
|
178
|
+
config.HIGHSTATE_ENCRYPTION_ENABLED,
|
|
179
|
+
config,
|
|
180
|
+
logger,
|
|
181
|
+
)
|
|
193
182
|
|
|
194
183
|
const databaseUrl = `file:${databasePath}/backend.db`
|
|
195
184
|
|
|
196
|
-
|
|
197
|
-
await migrateDatabase(databaseUrl, "backend/sqlite", masterKey, logger)
|
|
198
|
-
|
|
199
|
-
await writeMetaFile(databasePath, { ...metaFile, version: backendDatabaseVersion })
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
const adapter = new PrismaLibSQL({
|
|
185
|
+
const adapter = new PrismaLibSql({
|
|
203
186
|
url: databaseUrl,
|
|
204
187
|
encryptionKey: masterKey,
|
|
205
188
|
})
|
|
@@ -208,6 +191,14 @@ export async function createLocalBackendDatabaseBackend(
|
|
|
208
191
|
adapter,
|
|
209
192
|
})
|
|
210
193
|
|
|
194
|
+
await migrateDatabase(
|
|
195
|
+
prismaClient,
|
|
196
|
+
migrationPacks["backend/sqlite"],
|
|
197
|
+
metaFile.version,
|
|
198
|
+
async version => await writeMetaFile(databasePath, { ...metaFile, version }),
|
|
199
|
+
logger,
|
|
200
|
+
)
|
|
201
|
+
|
|
211
202
|
const database = prismaClient as BackendDatabase
|
|
212
203
|
|
|
213
204
|
await ensureWellKnownEntitiesCreated(database)
|
|
@@ -216,8 +207,6 @@ export async function createLocalBackendDatabaseBackend(
|
|
|
216
207
|
|
|
217
208
|
await ensureInitialUnlockMethod(database, created, initialRecipient, backendLogger)
|
|
218
209
|
|
|
219
|
-
backendLogger.info("database is ready")
|
|
220
|
-
|
|
221
210
|
return new LocalBackendDatabaseBackend(
|
|
222
211
|
database,
|
|
223
212
|
databasePath,
|
|
@@ -2,30 +2,25 @@ import type { Logger } from "pino"
|
|
|
2
2
|
import type { z } from "zod"
|
|
3
3
|
import type { ProjectDatabaseBackend } from "../abstractions"
|
|
4
4
|
import { mkdir } from "node:fs/promises"
|
|
5
|
-
import {
|
|
5
|
+
import { PrismaLibSql } from "@prisma/adapter-libsql"
|
|
6
6
|
import { type codebaseConfig, getCodebaseHighstatePath } from "../../common"
|
|
7
7
|
import { ProjectDatabase } from "../prisma"
|
|
8
8
|
|
|
9
9
|
export class LocalProjectDatabaseBackend implements ProjectDatabaseBackend {
|
|
10
10
|
constructor(private readonly highstatePath: string) {}
|
|
11
11
|
|
|
12
|
-
async openProjectDatabase(
|
|
13
|
-
projectId: string,
|
|
14
|
-
masterKey?: string,
|
|
15
|
-
): Promise<[database: ProjectDatabase, url: string]> {
|
|
12
|
+
async openProjectDatabase(projectId: string, masterKey?: string): Promise<ProjectDatabase> {
|
|
16
13
|
const databasePath = `${this.highstatePath}/projects/${projectId}`
|
|
17
14
|
await mkdir(databasePath, { recursive: true })
|
|
18
15
|
|
|
19
16
|
const databaseUrl = `file:${databasePath}/project.db`
|
|
20
17
|
|
|
21
|
-
const adapter = new
|
|
18
|
+
const adapter = new PrismaLibSql({
|
|
22
19
|
url: databaseUrl,
|
|
23
20
|
encryptionKey: masterKey,
|
|
24
21
|
})
|
|
25
22
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return [database, databaseUrl]
|
|
23
|
+
return new ProjectDatabase({ adapter })
|
|
29
24
|
}
|
|
30
25
|
|
|
31
26
|
static async create(
|
package/src/database/manager.ts
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
import type { Logger } from "pino"
|
|
2
2
|
import type { ProjectUnlockBackend } from "../unlock"
|
|
3
|
+
import type { BackendDatabaseBackend, ProjectDatabaseBackend } from "./abstractions"
|
|
3
4
|
import type { BackendDatabase, ProjectDatabase } from "./prisma"
|
|
4
5
|
import { LRUCache } from "lru-cache"
|
|
5
6
|
import z from "zod"
|
|
6
7
|
import { createProjectLogger } from "../common"
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
type BackendDatabaseBackend,
|
|
10
|
-
type ProjectDatabaseBackend,
|
|
11
|
-
projectDatabaseVersion,
|
|
12
|
-
} from "./abstractions"
|
|
13
|
-
import { migrateDatabase } from "./migrate"
|
|
8
|
+
import { ProjectLockedError, ProjectNotFoundError } from "../shared"
|
|
9
|
+
import { migrateDatabase, migrationPacks } from "./migration"
|
|
14
10
|
|
|
15
11
|
export const databaseManagerConfig = z.object({
|
|
16
12
|
HIGHSTATE_ENCRYPTION_ENABLED: z.stringbool().default(true),
|
|
@@ -132,13 +128,16 @@ export class DatabaseManagerImpl implements DatabaseManager {
|
|
|
132
128
|
const masterKey = await this.getProjectMasterKey(projectId)
|
|
133
129
|
const hexMasterKey = masterKey?.toString("hex")
|
|
134
130
|
|
|
135
|
-
const
|
|
136
|
-
projectId,
|
|
137
|
-
hexMasterKey,
|
|
138
|
-
)
|
|
131
|
+
const database = await this.projectDatabaseBackend.openProjectDatabase(projectId, hexMasterKey)
|
|
139
132
|
|
|
140
133
|
// can safely apply migrations here, because no one knows about the database yet
|
|
141
|
-
await migrateDatabase(
|
|
134
|
+
await migrateDatabase(
|
|
135
|
+
database,
|
|
136
|
+
migrationPacks.project,
|
|
137
|
+
0, // current version
|
|
138
|
+
() => Promise.resolve(), // project will be created later
|
|
139
|
+
logger,
|
|
140
|
+
)
|
|
142
141
|
|
|
143
142
|
this.projectDatabases.set(projectId, database)
|
|
144
143
|
|
|
@@ -151,50 +150,45 @@ export class DatabaseManagerImpl implements DatabaseManager {
|
|
|
151
150
|
return cachedDatabase
|
|
152
151
|
}
|
|
153
152
|
|
|
153
|
+
const logger = createProjectLogger(this.logger, projectId)
|
|
154
154
|
const masterKey = await this.getProjectMasterKey(projectId)
|
|
155
155
|
const hexMasterKey = masterKey?.toString("hex")
|
|
156
156
|
|
|
157
157
|
// TODO: is it really necessary to migrate the database inside the transaction?
|
|
158
158
|
let database = await this.backend.$transaction(async tx => {
|
|
159
|
-
const
|
|
159
|
+
const project = await tx.project.findUnique({
|
|
160
160
|
where: { id: projectId },
|
|
161
161
|
select: { databaseVersion: true },
|
|
162
162
|
})
|
|
163
163
|
|
|
164
|
-
if (!
|
|
164
|
+
if (!project) {
|
|
165
165
|
throw new ProjectNotFoundError(projectId)
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
-
|
|
169
|
-
throw new BackendError(
|
|
170
|
-
`Project database version (${databaseEntity.databaseVersion}) is newer than expected (${projectDatabaseVersion}).`,
|
|
171
|
-
)
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
if (databaseEntity.databaseVersion === projectDatabaseVersion) {
|
|
175
|
-
return
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const [database, databaseUrl] = await this.projectDatabaseBackend.openProjectDatabase(
|
|
168
|
+
const database = await this.projectDatabaseBackend.openProjectDatabase(
|
|
179
169
|
projectId,
|
|
180
170
|
hexMasterKey,
|
|
181
171
|
)
|
|
182
172
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
173
|
+
await migrateDatabase(
|
|
174
|
+
database,
|
|
175
|
+
migrationPacks.project,
|
|
176
|
+
project.databaseVersion,
|
|
177
|
+
async version => {
|
|
178
|
+
await tx.project.update({
|
|
179
|
+
where: { id: projectId },
|
|
180
|
+
data: { databaseVersion: version },
|
|
181
|
+
})
|
|
182
|
+
},
|
|
183
|
+
logger,
|
|
184
|
+
)
|
|
191
185
|
|
|
192
186
|
return database
|
|
193
187
|
})
|
|
194
188
|
|
|
195
189
|
if (!database) {
|
|
196
190
|
// open database if was not migrated in the transaction
|
|
197
|
-
const
|
|
191
|
+
const _database = await this.projectDatabaseBackend.openProjectDatabase(
|
|
198
192
|
projectId,
|
|
199
193
|
hexMasterKey,
|
|
200
194
|
)
|