@hot-updater/server 1.0.0-rc.2 → 1.0.0-rc.21
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/LICENSE +12 -14
- package/dist/adapters/drizzle.cjs +32 -75
- package/dist/adapters/drizzle.d.cts +13 -5
- package/dist/adapters/drizzle.d.mts +13 -5
- package/dist/adapters/drizzle.mjs +32 -77
- package/dist/adapters/drizzleExecutor.cjs +114 -0
- package/dist/adapters/drizzleExecutor.d.cts +9 -0
- package/dist/adapters/drizzleExecutor.d.mts +9 -0
- package/dist/adapters/drizzleExecutor.mjs +112 -0
- package/dist/adapters/kysely.cjs +22 -31
- package/dist/adapters/kysely.d.cts +10 -6
- package/dist/adapters/kysely.d.mts +10 -6
- package/dist/adapters/kysely.mjs +23 -33
- package/dist/adapters/kyselyExecutor.cjs +32 -0
- package/dist/adapters/kyselyExecutor.d.cts +11 -0
- package/dist/adapters/kyselyExecutor.d.mts +11 -0
- package/dist/adapters/kyselyExecutor.mjs +32 -0
- package/dist/adapters/mongodb.cjs +18 -54
- package/dist/adapters/mongodb.d.cts +10 -5
- package/dist/adapters/mongodb.d.mts +10 -5
- package/dist/adapters/mongodb.mjs +19 -56
- package/dist/adapters/mongodbAdapter.cjs +192 -0
- package/dist/adapters/mongodbAdapter.d.cts +9 -0
- package/dist/adapters/mongodbAdapter.d.mts +9 -0
- package/dist/adapters/mongodbAdapter.mjs +191 -0
- package/dist/adapters/prisma.cjs +35 -267
- package/dist/adapters/prisma.d.cts +12 -7
- package/dist/adapters/prisma.d.mts +12 -7
- package/dist/adapters/prisma.mjs +36 -268
- package/dist/adapters/prismaExecutor.cjs +63 -0
- package/dist/adapters/prismaExecutor.mjs +63 -0
- package/dist/adapters/sqlProviders.cjs +14 -0
- package/dist/adapters/sqlProviders.mjs +14 -0
- package/dist/assembly/assemblePlugins.cjs +144 -0
- package/dist/assembly/assemblePlugins.d.cts +5 -0
- package/dist/assembly/assemblePlugins.d.mts +5 -0
- package/dist/assembly/assemblePlugins.mjs +139 -0
- package/dist/assembly/clientPlugins.cjs +88 -0
- package/dist/assembly/clientPlugins.mjs +88 -0
- package/dist/assembly/configError.d.cts +2 -0
- package/dist/assembly/configError.d.mts +2 -0
- package/dist/assembly/configError.mjs +2 -0
- package/dist/core/api.cjs +51 -0
- package/dist/core/api.d.cts +54 -0
- package/dist/core/api.d.mts +54 -0
- package/dist/core/api.mjs +51 -0
- package/dist/core/baseCandidates.cjs +28 -0
- package/dist/core/baseCandidates.mjs +28 -0
- package/dist/core/operations.cjs +351 -0
- package/dist/core/operations.mjs +351 -0
- package/dist/core/reads.cjs +273 -0
- package/dist/core/reads.d.cts +9 -0
- package/dist/core/reads.d.mts +9 -0
- package/dist/core/reads.mjs +267 -0
- package/dist/core/releases.cjs +193 -0
- package/dist/core/releases.mjs +190 -0
- package/dist/core/writes.cjs +96 -0
- package/dist/core/writes.mjs +91 -0
- package/dist/createHotUpdaterCore.cjs +72 -91
- package/dist/createHotUpdaterCore.d.cts +106 -38
- package/dist/createHotUpdaterCore.d.mts +106 -38
- package/dist/createHotUpdaterCore.mjs +74 -89
- package/dist/db/engineDrizzleSchema.cjs +53 -0
- package/dist/db/engineDrizzleSchema.mjs +53 -0
- package/dist/db/enginePrismaSchema.cjs +84 -0
- package/dist/db/enginePrismaSchema.d.cts +5 -0
- package/dist/db/enginePrismaSchema.d.mts +5 -0
- package/dist/db/enginePrismaSchema.mjs +83 -0
- package/dist/db/releaseCatalog.cjs +24 -47
- package/dist/db/releaseCatalog.mjs +20 -44
- package/dist/db/updateArtifacts.cjs +43 -72
- package/dist/db/updateArtifacts.mjs +40 -69
- package/dist/handler.cjs +59 -43
- package/dist/handler.d.cts +3 -5
- package/dist/handler.d.mts +3 -5
- package/dist/handler.mjs +61 -43
- package/dist/handlerAdminRoutes.cjs +374 -0
- package/dist/handlerAdminRoutes.mjs +372 -0
- package/dist/handlerParameters.cjs +6 -11
- package/dist/handlerParameters.mjs +6 -10
- package/dist/handlerReleaseCatalogRoutes.cjs +32 -15
- package/dist/handlerReleaseCatalogRoutes.mjs +32 -15
- package/dist/handlerTypes.d.cts +2 -55
- package/dist/handlerTypes.d.mts +2 -55
- package/dist/handlerVersionRoutes.cjs +20 -4
- package/dist/handlerVersionRoutes.mjs +20 -4
- package/dist/index.cjs +9 -9
- package/dist/index.d.cts +8 -9
- package/dist/index.d.mts +8 -9
- package/dist/index.mjs +3 -4
- package/dist/node.cjs +3 -6
- package/dist/node.d.cts +2 -2
- package/dist/node.d.mts +2 -2
- package/dist/node.mjs +4 -4
- package/dist/package.cjs +1 -1
- package/dist/package.mjs +1 -1
- package/dist/plugins/api-keys/index.cjs +9 -0
- package/dist/plugins/api-keys/index.d.cts +1 -0
- package/dist/plugins/api-keys/index.d.mts +1 -0
- package/dist/plugins/api-keys/index.mjs +2 -0
- package/dist/plugins/definePlugin.d.cts +2 -0
- package/dist/plugins/definePlugin.d.mts +2 -0
- package/dist/plugins/insights/index.cjs +9 -0
- package/dist/plugins/insights/index.d.cts +1 -0
- package/dist/plugins/insights/index.d.mts +1 -0
- package/dist/plugins/insights/index.mjs +2 -0
- package/dist/plugins/official.cjs +30 -0
- package/dist/plugins/official.mjs +29 -0
- package/dist/storageAccess.cjs +13 -10
- package/dist/storageAccess.mjs +13 -10
- package/dist/types/index.d.cts +2 -28
- package/dist/types/index.d.mts +2 -28
- package/package.json +26 -14
- package/dist/_virtual/_rolldown/runtime.cjs +0 -23
- package/dist/adapters/databaseConstraintErrors.cjs +0 -22
- package/dist/adapters/databaseConstraintErrors.mjs +0 -21
- package/dist/adapters/databasePluginUtils.cjs +0 -116
- package/dist/adapters/databasePluginUtils.mjs +0 -106
- package/dist/adapters/drizzleCrud.cjs +0 -311
- package/dist/adapters/drizzleCrud.mjs +0 -308
- package/dist/adapters/drizzleLazyDB.cjs +0 -106
- package/dist/adapters/drizzleLazyDB.mjs +0 -106
- package/dist/adapters/drizzleQuery.cjs +0 -69
- package/dist/adapters/drizzleQuery.mjs +0 -69
- package/dist/adapters/insightsTransaction.cjs +0 -22
- package/dist/adapters/insightsTransaction.mjs +0 -22
- package/dist/adapters/kyselyCrud.cjs +0 -305
- package/dist/adapters/kyselyCrud.mjs +0 -304
- package/dist/adapters/kyselyQuery.cjs +0 -56
- package/dist/adapters/kyselyQuery.mjs +0 -56
- package/dist/adapters/mongodbCollections.cjs +0 -38
- package/dist/adapters/mongodbCollections.mjs +0 -32
- package/dist/adapters/mongodbQuery.cjs +0 -94
- package/dist/adapters/mongodbQuery.mjs +0 -86
- package/dist/adapters/mongodbReads.cjs +0 -210
- package/dist/adapters/mongodbReads.mjs +0 -210
- package/dist/adapters/mongodbWrites.cjs +0 -148
- package/dist/adapters/mongodbWrites.mjs +0 -148
- package/dist/adapters/prismaQuery.cjs +0 -57
- package/dist/adapters/prismaQuery.mjs +0 -56
- package/dist/adapters/prismaRows.cjs +0 -219
- package/dist/adapters/prismaRows.mjs +0 -209
- package/dist/apiKeys.cjs +0 -143
- package/dist/apiKeys.d.cts +0 -49
- package/dist/apiKeys.d.mts +0 -49
- package/dist/apiKeys.mjs +0 -133
- package/dist/db/createBundleDiff.cjs +0 -144
- package/dist/db/createBundleDiff.d.cts +0 -16
- package/dist/db/createBundleDiff.d.mts +0 -16
- package/dist/db/createBundleDiff.mjs +0 -141
- package/dist/db/databasePluginCore.cjs +0 -137
- package/dist/db/databasePluginCore.mjs +0 -137
- package/dist/db/fixedMigrator.cjs +0 -79
- package/dist/db/fixedMigrator.mjs +0 -78
- package/dist/db/fixedMigratorMongo.cjs +0 -321
- package/dist/db/fixedMigratorMongo.mjs +0 -321
- package/dist/db/fixedMigratorShared.cjs +0 -23
- package/dist/db/fixedMigratorShared.mjs +0 -18
- package/dist/db/index.cjs +0 -27
- package/dist/db/index.d.cts +0 -12
- package/dist/db/index.d.mts +0 -12
- package/dist/db/index.mjs +0 -22
- package/dist/db/mongoMigrationExecution.cjs +0 -11
- package/dist/db/mongoMigrationExecution.mjs +0 -11
- package/dist/db/releaseCatalog.d.cts +0 -16
- package/dist/db/releaseCatalog.d.mts +0 -16
- package/dist/db/schema/insightsCollation.cjs +0 -14
- package/dist/db/schema/insightsCollation.mjs +0 -14
- package/dist/db/schema/mongodb.cjs +0 -25
- package/dist/db/schema/mongodb.mjs +0 -25
- package/dist/db/schema/registry.cjs +0 -21
- package/dist/db/schema/registry.mjs +0 -17
- package/dist/db/schema/sql.cjs +0 -105
- package/dist/db/schema/sql.mjs +0 -97
- package/dist/db/schema/sqlOperations.cjs +0 -27
- package/dist/db/schema/sqlOperations.mjs +0 -26
- package/dist/db/schemaGenerators.cjs +0 -275
- package/dist/db/schemaGenerators.mjs +0 -273
- package/dist/db/schemaReadiness.cjs +0 -26
- package/dist/db/schemaReadiness.d.cts +0 -9
- package/dist/db/schemaReadiness.d.mts +0 -9
- package/dist/db/schemaReadiness.mjs +0 -25
- package/dist/db/sqlMigrationExecution.cjs +0 -67
- package/dist/db/sqlMigrationExecution.mjs +0 -67
- package/dist/db/types.cjs +0 -22
- package/dist/db/types.d.cts +0 -118
- package/dist/db/types.d.mts +0 -118
- package/dist/db/types.mjs +0 -19
- package/dist/handlerBundleRoutes.cjs +0 -155
- package/dist/handlerBundleRoutes.mjs +0 -155
- package/dist/handlerReleaseManagementRoutes.cjs +0 -124
- package/dist/handlerReleaseManagementRoutes.mjs +0 -124
- package/dist/insights/domain.d.cts +0 -89
- package/dist/insights/domain.d.mts +0 -89
- package/dist/insights/errors.cjs +0 -15
- package/dist/insights/errors.mjs +0 -14
- package/dist/insights/eventInput.cjs +0 -155
- package/dist/insights/eventInput.mjs +0 -153
- package/dist/insights/provider.cjs +0 -314
- package/dist/insights/provider.d.cts +0 -6
- package/dist/insights/provider.d.mts +0 -6
- package/dist/insights/provider.mjs +0 -314
- package/dist/insights/queryInput.cjs +0 -93
- package/dist/insights/queryInput.mjs +0 -91
- package/dist/insights/routes.cjs +0 -58
- package/dist/insights/routes.mjs +0 -56
- package/dist/insights/types.d.cts +0 -32
- package/dist/insights/types.d.mts +0 -32
- package/dist/schema/dsl.cjs +0 -103
- package/dist/schema/dsl.mjs +0 -87
- package/dist/schema/index.cjs +0 -20
- package/dist/schema/index.mjs +0 -7
- package/dist/schema/settings.cjs +0 -9
- package/dist/schema/settings.mjs +0 -9
- package/dist/schema/types.cjs +0 -8
- package/dist/schema/types.mjs +0 -6
- package/dist/schema/v1_0_0.cjs +0 -406
- package/dist/schema/v1_0_0.mjs +0 -398
- package/src/adapters/databaseConstraintErrors.ts +0 -25
- package/src/adapters/databasePluginTestDatabase.ts +0 -120
- package/src/adapters/databasePluginUtils.spec.ts +0 -29
- package/src/adapters/databasePluginUtils.ts +0 -214
- package/src/adapters/drizzle.spec.ts +0 -336
- package/src/adapters/drizzle.ts +0 -162
- package/src/adapters/drizzleCrud.ts +0 -571
- package/src/adapters/drizzleLazyDB.ts +0 -271
- package/src/adapters/drizzleQuery.ts +0 -164
- package/src/adapters/insightsTransaction.ts +0 -32
- package/src/adapters/kysely.spec.ts +0 -174
- package/src/adapters/kysely.ts +0 -110
- package/src/adapters/kyselyCrud.ts +0 -709
- package/src/adapters/kyselyQuery.ts +0 -128
- package/src/adapters/mongodb.integration.spec.ts +0 -210
- package/src/adapters/mongodb.spec.ts +0 -209
- package/src/adapters/mongodb.ts +0 -138
- package/src/adapters/mongodbCollections.ts +0 -67
- package/src/adapters/mongodbQuery.ts +0 -255
- package/src/adapters/mongodbReads.ts +0 -380
- package/src/adapters/mongodbRows.spec.ts +0 -64
- package/src/adapters/mongodbRows.ts +0 -118
- package/src/adapters/mongodbTestClient.ts +0 -377
- package/src/adapters/mongodbTestFilter.ts +0 -169
- package/src/adapters/mongodbWrites.ts +0 -287
- package/src/adapters/prisma.spec.ts +0 -293
- package/src/adapters/prisma.ts +0 -565
- package/src/adapters/prismaQuery.ts +0 -129
- package/src/adapters/prismaRows.spec.ts +0 -98
- package/src/adapters/prismaRows.ts +0 -337
- package/src/adapters/prismaTestClient.ts +0 -413
- package/src/apiKeys.integration.spec.ts +0 -192
- package/src/apiKeys.spec.ts +0 -162
- package/src/apiKeys.ts +0 -220
- package/src/calculatePagination.ts +0 -34
- package/src/createHotUpdaterCore.ts +0 -246
- package/src/db/bundleRows.spec.ts +0 -164
- package/src/db/bundleRows.ts +0 -10
- package/src/db/createBundleDiff.spec.ts +0 -450
- package/src/db/createBundleDiff.ts +0 -364
- package/src/db/databasePluginCore.spec.ts +0 -62
- package/src/db/databasePluginCore.testFixtures.ts +0 -76
- package/src/db/databasePluginCore.ts +0 -185
- package/src/db/databasePluginUpdateCheck.bench.ts +0 -110
- package/src/db/fixedMigrator.spec.ts +0 -296
- package/src/db/fixedMigrator.ts +0 -147
- package/src/db/fixedMigratorMongo.spec.ts +0 -239
- package/src/db/fixedMigratorMongo.ts +0 -425
- package/src/db/fixedMigratorShared.ts +0 -36
- package/src/db/hotUpdaterSchema.ts +0 -5
- package/src/db/index.spec.ts +0 -1269
- package/src/db/index.ts +0 -47
- package/src/db/mongoMigrationExecution.ts +0 -23
- package/src/db/node-sqlite.d.ts +0 -25
- package/src/db/releaseCatalog.ts +0 -148
- package/src/db/schema/definitions.ts +0 -1
- package/src/db/schema/insightsCollation.ts +0 -21
- package/src/db/schema/mongodb.ts +0 -40
- package/src/db/schema/registry.ts +0 -55
- package/src/db/schema/sql.ts +0 -244
- package/src/db/schema/sqlOperations.ts +0 -63
- package/src/db/schema/types.ts +0 -1
- package/src/db/schemaGenerators.ts +0 -494
- package/src/db/schemaReadiness.ts +0 -34
- package/src/db/sqlMigrationExecution.spec.ts +0 -65
- package/src/db/sqlMigrationExecution.ts +0 -108
- package/src/db/types.spec.ts +0 -63
- package/src/db/types.ts +0 -228
- package/src/db/updateArtifacts.spec.ts +0 -359
- package/src/db/updateArtifacts.ts +0 -541
- package/src/handler-standalone.integration.spec.ts +0 -528
- package/src/handler.spec.ts +0 -190
- package/src/handler.testFixtures.ts +0 -30
- package/src/handler.ts +0 -245
- package/src/handlerAuth.integration.spec.ts +0 -33
- package/src/handlerBundleRoutes.ts +0 -259
- package/src/handlerErrors.ts +0 -7
- package/src/handlerManagement.spec.ts +0 -262
- package/src/handlerParameters.ts +0 -105
- package/src/handlerReleaseCatalogRoutes.ts +0 -154
- package/src/handlerReleaseManagementRoutes.ts +0 -213
- package/src/handlerTypes.ts +0 -96
- package/src/handlerVersionRoutes.ts +0 -12
- package/src/index.ts +0 -30
- package/src/insights/domain.ts +0 -103
- package/src/insights/errors.ts +0 -11
- package/src/insights/eventInput.ts +0 -225
- package/src/insights/insights.integration.spec.ts +0 -381
- package/src/insights/provider.spec.ts +0 -385
- package/src/insights/provider.ts +0 -591
- package/src/insights/queryInput.ts +0 -141
- package/src/insights/routes.ts +0 -104
- package/src/insights/types.ts +0 -55
- package/src/internalRouter.ts +0 -104
- package/src/node.spec.ts +0 -119
- package/src/node.ts +0 -111
- package/src/releaseCatalogRoutes.integration.spec.ts +0 -238
- package/src/runtime.spec.ts +0 -194
- package/src/runtime.testFixtures.ts +0 -71
- package/src/schema/dsl-all-versions.spec.ts +0 -37
- package/src/schema/dsl.ts +0 -187
- package/src/schema/index.ts +0 -10
- package/src/schema/settings.ts +0 -15
- package/src/schema/types.ts +0 -79
- package/src/schema/v1_0_0.spec.ts +0 -220
- package/src/schema/v1_0_0.ts +0 -529
- package/src/storageAccess.spec.ts +0 -152
- package/src/storageAccess.ts +0 -141
- package/src/types/index.ts +0 -34
- package/src/version.ts +0 -3
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
BundleRow,
|
|
3
|
-
ReleaseCatalogRow,
|
|
4
|
-
ReleaseRow,
|
|
5
|
-
ReleaseRowUpdate,
|
|
6
|
-
} from "@hot-updater/plugin-core";
|
|
7
|
-
import { isDatabaseMetadataObject } from "@hot-updater/plugin-core";
|
|
8
|
-
import type {
|
|
9
|
-
DatabaseModel,
|
|
10
|
-
DatabaseOrderBy,
|
|
11
|
-
DatabaseSortBy,
|
|
12
|
-
} from "@hot-updater/plugin-core/internal";
|
|
13
|
-
|
|
14
|
-
import type { ORMSQLProvider } from "../db/types";
|
|
15
|
-
|
|
16
|
-
export type StoredBundleRow = Omit<BundleRow, "metadata"> & {
|
|
17
|
-
readonly metadata: unknown;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export type StoredReleaseRow = Omit<ReleaseRow, "target_cohorts"> & {
|
|
21
|
-
readonly target_cohorts: unknown;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export type StoredReleaseCatalogRow = Omit<
|
|
25
|
-
ReleaseCatalogRow,
|
|
26
|
-
"is_tombstone"
|
|
27
|
-
> & {
|
|
28
|
-
readonly is_tombstone: unknown;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
type AnyDatabaseSortBy = {
|
|
32
|
-
readonly [TModel in DatabaseModel]: DatabaseSortBy<TModel>;
|
|
33
|
-
}[DatabaseModel];
|
|
34
|
-
type AnyDatabaseOrderBy = {
|
|
35
|
-
readonly [TModel in DatabaseModel]: DatabaseOrderBy<TModel>;
|
|
36
|
-
}[DatabaseModel];
|
|
37
|
-
type AnyDatabaseOrderClause = AnyDatabaseSortBy;
|
|
38
|
-
|
|
39
|
-
class StoredBundleRowError extends Error {
|
|
40
|
-
readonly name = "StoredBundleRowError";
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const parseStoredBoolean = (value: unknown, field: string): boolean => {
|
|
44
|
-
if (value === true || value === 1) return true;
|
|
45
|
-
if (value === false || value === 0) return false;
|
|
46
|
-
throw new StoredBundleRowError(`Invalid boolean value for ${field}.`);
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const parseJson = (value: string): unknown => {
|
|
50
|
-
try {
|
|
51
|
-
return JSON.parse(value);
|
|
52
|
-
} catch (error) {
|
|
53
|
-
if (error instanceof SyntaxError) return value;
|
|
54
|
-
throw error;
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const parseTargetCohorts = (value: unknown): readonly string[] | null => {
|
|
59
|
-
if (value === null) return null;
|
|
60
|
-
const parsed = typeof value === "string" ? parseJson(value) : value;
|
|
61
|
-
if (
|
|
62
|
-
!Array.isArray(parsed) ||
|
|
63
|
-
!parsed.every((item) => typeof item === "string")
|
|
64
|
-
) {
|
|
65
|
-
throw new StoredBundleRowError("Invalid target_cohorts field.");
|
|
66
|
-
}
|
|
67
|
-
return parsed;
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const parseMetadata = (value: unknown) => {
|
|
71
|
-
const parsed = typeof value === "string" ? parseJson(value) : value;
|
|
72
|
-
if (!isDatabaseMetadataObject(parsed)) {
|
|
73
|
-
throw new StoredBundleRowError("Invalid metadata field.");
|
|
74
|
-
}
|
|
75
|
-
return parsed;
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const compareOrderValues = (left: unknown, right: unknown): number => {
|
|
79
|
-
if (typeof left === "number" && typeof right === "number") {
|
|
80
|
-
return left - right;
|
|
81
|
-
}
|
|
82
|
-
if (typeof left === "string" && typeof right === "string") {
|
|
83
|
-
return left.localeCompare(right);
|
|
84
|
-
}
|
|
85
|
-
if (typeof left === "boolean" && typeof right === "boolean") {
|
|
86
|
-
return Number(left) - Number(right);
|
|
87
|
-
}
|
|
88
|
-
if (left === right) {
|
|
89
|
-
return 0;
|
|
90
|
-
}
|
|
91
|
-
return String(left).localeCompare(String(right));
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const normalizeOrderBy = (
|
|
95
|
-
orderBy: AnyDatabaseOrderBy | readonly AnyDatabaseSortBy[] | undefined,
|
|
96
|
-
): readonly AnyDatabaseOrderClause[] => {
|
|
97
|
-
if (orderBy === undefined) {
|
|
98
|
-
return [];
|
|
99
|
-
}
|
|
100
|
-
return (
|
|
101
|
-
Array.isArray(orderBy) ? orderBy : [orderBy]
|
|
102
|
-
) as readonly AnyDatabaseOrderClause[];
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
export const hasNullOrderOverrides = (
|
|
106
|
-
orderBy: AnyDatabaseOrderBy | readonly AnyDatabaseSortBy[] | undefined,
|
|
107
|
-
): boolean =>
|
|
108
|
-
normalizeOrderBy(orderBy).some((clause) => clause.nulls !== undefined);
|
|
109
|
-
|
|
110
|
-
export const sortRowsByOrder = <TRow extends object>(
|
|
111
|
-
rows: readonly TRow[],
|
|
112
|
-
orderBy: AnyDatabaseOrderBy | readonly AnyDatabaseSortBy[] | undefined,
|
|
113
|
-
): TRow[] => {
|
|
114
|
-
const clauses = normalizeOrderBy(orderBy);
|
|
115
|
-
if (clauses.length === 0) {
|
|
116
|
-
return [...rows];
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return [...rows].toSorted((left, right) => {
|
|
120
|
-
for (const clause of clauses) {
|
|
121
|
-
const leftValue = Reflect.get(left, clause.field);
|
|
122
|
-
const rightValue = Reflect.get(right, clause.field);
|
|
123
|
-
|
|
124
|
-
if (leftValue == null || rightValue == null) {
|
|
125
|
-
if (leftValue == null && rightValue == null) {
|
|
126
|
-
continue;
|
|
127
|
-
}
|
|
128
|
-
const nulls =
|
|
129
|
-
clause.nulls ?? (clause.direction === "asc" ? "last" : "first");
|
|
130
|
-
const order = leftValue == null ? -1 : 1;
|
|
131
|
-
return nulls === "first" ? order : -order;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const result = compareOrderValues(leftValue, rightValue);
|
|
135
|
-
if (result !== 0) {
|
|
136
|
-
return clause.direction === "desc" ? -result : result;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
return 0;
|
|
140
|
-
});
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
export const fromStoredBundleRow = (row: StoredBundleRow): BundleRow => ({
|
|
144
|
-
...row,
|
|
145
|
-
metadata: parseMetadata(row.metadata),
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
export const toStoredBundleRow = (
|
|
149
|
-
row: BundleRow,
|
|
150
|
-
provider: ORMSQLProvider,
|
|
151
|
-
): StoredBundleRow => {
|
|
152
|
-
if (provider !== "mysql" && provider !== "sqlite") return row;
|
|
153
|
-
return {
|
|
154
|
-
...row,
|
|
155
|
-
metadata: JSON.stringify(row.metadata),
|
|
156
|
-
};
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
export const toStoredBundleUpdate = (
|
|
160
|
-
update: Partial<Omit<BundleRow, "id">>,
|
|
161
|
-
provider: ORMSQLProvider,
|
|
162
|
-
): Partial<Omit<StoredBundleRow, "id">> => {
|
|
163
|
-
if (provider !== "mysql" && provider !== "sqlite") return update;
|
|
164
|
-
return {
|
|
165
|
-
...update,
|
|
166
|
-
...("metadata" in update
|
|
167
|
-
? { metadata: JSON.stringify(update.metadata) }
|
|
168
|
-
: {}),
|
|
169
|
-
};
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
export const fromStoredReleaseRow = (row: StoredReleaseRow): ReleaseRow => ({
|
|
173
|
-
...row,
|
|
174
|
-
enabled: parseStoredBoolean(row.enabled, "enabled"),
|
|
175
|
-
should_force_update: parseStoredBoolean(
|
|
176
|
-
row.should_force_update,
|
|
177
|
-
"should_force_update",
|
|
178
|
-
),
|
|
179
|
-
target_cohorts: parseTargetCohorts(row.target_cohorts) ?? [],
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
export const toStoredReleaseRow = (
|
|
183
|
-
row: ReleaseRow,
|
|
184
|
-
provider: ORMSQLProvider,
|
|
185
|
-
): StoredReleaseRow => {
|
|
186
|
-
if (provider !== "mysql" && provider !== "sqlite") return row;
|
|
187
|
-
return { ...row, target_cohorts: JSON.stringify(row.target_cohorts) };
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
export const toStoredReleaseUpdate = (
|
|
191
|
-
update: ReleaseRowUpdate,
|
|
192
|
-
provider: ORMSQLProvider,
|
|
193
|
-
): Partial<Omit<StoredReleaseRow, "id">> => {
|
|
194
|
-
if (provider !== "mysql" && provider !== "sqlite") return update;
|
|
195
|
-
return {
|
|
196
|
-
...update,
|
|
197
|
-
...(update.target_cohorts === undefined
|
|
198
|
-
? {}
|
|
199
|
-
: { target_cohorts: JSON.stringify(update.target_cohorts) }),
|
|
200
|
-
};
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
export const fromStoredReleaseCatalogRow = (
|
|
204
|
-
row: StoredReleaseCatalogRow,
|
|
205
|
-
): ReleaseCatalogRow => ({
|
|
206
|
-
...row,
|
|
207
|
-
is_tombstone: parseStoredBoolean(row.is_tombstone, "is_tombstone"),
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
export const escapeLikePattern = (value: string): string =>
|
|
211
|
-
value.replaceAll("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_");
|
|
212
|
-
|
|
213
|
-
export const escapeGlobPattern = (value: string): string =>
|
|
214
|
-
value.replaceAll("[", "[[]").replaceAll("*", "[*]").replaceAll("?", "[?]");
|
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
import { PGlite } from "@electric-sql/pglite";
|
|
2
|
-
import { toInsightsInstallationRow } from "@hot-updater/plugin-core";
|
|
3
|
-
import {
|
|
4
|
-
boolean,
|
|
5
|
-
doublePrecision,
|
|
6
|
-
integer,
|
|
7
|
-
jsonb,
|
|
8
|
-
pgTable,
|
|
9
|
-
text,
|
|
10
|
-
varchar,
|
|
11
|
-
} from "drizzle-orm/pg-core";
|
|
12
|
-
import { drizzle } from "drizzle-orm/pglite";
|
|
13
|
-
import { describe, expect, it, vi } from "vitest";
|
|
14
|
-
|
|
15
|
-
import { createBundleEventRowFixture } from "../../../test-utils/src/databaseTestFixtures";
|
|
16
|
-
import { setupDatabasePluginTestSuite } from "../../../test-utils/src/setupDatabasePluginTestSuite";
|
|
17
|
-
import type { DatabaseAdapterWithCapabilities } from "../db/types";
|
|
18
|
-
import {
|
|
19
|
-
DATABASE_PLUGIN_TEST_RESET_SQL,
|
|
20
|
-
DATABASE_PLUGIN_TEST_SCHEMA_SQL,
|
|
21
|
-
} from "./databasePluginTestDatabase";
|
|
22
|
-
import { drizzleAdapter } from "./drizzle";
|
|
23
|
-
|
|
24
|
-
const bundles = pgTable("bundles", {
|
|
25
|
-
id: text("id").primaryKey(),
|
|
26
|
-
platform: text("platform").notNull(),
|
|
27
|
-
file_hash: text("file_hash").notNull(),
|
|
28
|
-
git_commit_hash: text("git_commit_hash"),
|
|
29
|
-
storage_uri: text("storage_uri").notNull(),
|
|
30
|
-
archive_byte_size: doublePrecision("archive_byte_size").notNull(),
|
|
31
|
-
metadata: jsonb("metadata").notNull(),
|
|
32
|
-
manifest_storage_uri: text("manifest_storage_uri"),
|
|
33
|
-
manifest_file_hash: text("manifest_file_hash"),
|
|
34
|
-
asset_base_storage_uri: text("asset_base_storage_uri"),
|
|
35
|
-
});
|
|
36
|
-
const channels = pgTable("channels", {
|
|
37
|
-
id: text("id").primaryKey(),
|
|
38
|
-
name: text("name").notNull().unique(),
|
|
39
|
-
});
|
|
40
|
-
const releases = pgTable("releases", {
|
|
41
|
-
id: text("id").primaryKey(),
|
|
42
|
-
revision: integer("revision").notNull(),
|
|
43
|
-
scope_key: text("scope_key").notNull(),
|
|
44
|
-
channel_id: text("channel_id").notNull(),
|
|
45
|
-
platform: text("platform").notNull(),
|
|
46
|
-
kind: text("kind").notNull(),
|
|
47
|
-
bundle_id: text("bundle_id"),
|
|
48
|
-
strategy: text("strategy").notNull(),
|
|
49
|
-
target_app_version: text("target_app_version"),
|
|
50
|
-
fingerprint_hash: text("fingerprint_hash"),
|
|
51
|
-
enabled: boolean("enabled").notNull(),
|
|
52
|
-
should_force_update: boolean("should_force_update").notNull(),
|
|
53
|
-
message: text("message"),
|
|
54
|
-
rollout_cohort_count: integer("rollout_cohort_count").notNull(),
|
|
55
|
-
target_cohorts: jsonb("target_cohorts").notNull(),
|
|
56
|
-
operation: text("operation").notNull(),
|
|
57
|
-
source_release_id: text("source_release_id"),
|
|
58
|
-
created_at_ms: integer("created_at_ms").notNull(),
|
|
59
|
-
updated_at_ms: integer("updated_at_ms").notNull(),
|
|
60
|
-
});
|
|
61
|
-
const releaseCatalogs = pgTable("release_catalogs", {
|
|
62
|
-
scope_key: text("scope_key").primaryKey(),
|
|
63
|
-
catalog_id: text("catalog_id").notNull(),
|
|
64
|
-
strategy: text("strategy").notNull(),
|
|
65
|
-
channel_id: text("channel_id").notNull(),
|
|
66
|
-
channel_key: text("channel_key").notNull(),
|
|
67
|
-
platform: text("platform").notNull(),
|
|
68
|
-
fingerprint_hash: text("fingerprint_hash"),
|
|
69
|
-
generation: integer("generation").notNull(),
|
|
70
|
-
payload: text("payload").notNull(),
|
|
71
|
-
catalog_hash: text("catalog_hash").notNull(),
|
|
72
|
-
byte_size: integer("byte_size").notNull(),
|
|
73
|
-
is_tombstone: boolean("is_tombstone").notNull(),
|
|
74
|
-
updated_at_ms: integer("updated_at_ms").notNull(),
|
|
75
|
-
});
|
|
76
|
-
const bundlePatches = pgTable("bundle_patches", {
|
|
77
|
-
id: varchar("id", { length: 255 }).primaryKey(),
|
|
78
|
-
bundle_id: text("bundle_id").notNull(),
|
|
79
|
-
base_bundle_id: text("base_bundle_id").notNull(),
|
|
80
|
-
base_file_hash: text("base_file_hash").notNull(),
|
|
81
|
-
patch_file_hash: text("patch_file_hash").notNull(),
|
|
82
|
-
patch_storage_uri: text("patch_storage_uri").notNull(),
|
|
83
|
-
byte_size: doublePrecision("byte_size").notNull(),
|
|
84
|
-
order_index: integer("order_index").notNull(),
|
|
85
|
-
});
|
|
86
|
-
const bundleEvents = pgTable("bundle_events", {
|
|
87
|
-
id: text("id").primaryKey(),
|
|
88
|
-
type: text("type").notNull(),
|
|
89
|
-
install_id: text("install_id").notNull(),
|
|
90
|
-
user_id: text("user_id"),
|
|
91
|
-
username: text("username"),
|
|
92
|
-
from_release_id: text("from_release_id"),
|
|
93
|
-
from_bundle_id: text("from_bundle_id"),
|
|
94
|
-
to_release_id: text("to_release_id"),
|
|
95
|
-
to_bundle_id: text("to_bundle_id").notNull(),
|
|
96
|
-
platform: text("platform").notNull(),
|
|
97
|
-
app_version: text("app_version").notNull(),
|
|
98
|
-
channel: text("channel").notNull(),
|
|
99
|
-
cohort: text("cohort").notNull(),
|
|
100
|
-
update_strategy: text("update_strategy"),
|
|
101
|
-
fingerprint_hash: text("fingerprint_hash"),
|
|
102
|
-
sdk_version: text("sdk_version"),
|
|
103
|
-
received_at_ms: integer("received_at_ms").notNull(),
|
|
104
|
-
});
|
|
105
|
-
const bundleInstallations = pgTable("bundle_installations", {
|
|
106
|
-
install_id: varchar("install_id", { length: 255 }).primaryKey(),
|
|
107
|
-
id: text("id").notNull(),
|
|
108
|
-
user_id: text("user_id"),
|
|
109
|
-
username: text("username"),
|
|
110
|
-
to_bundle_id: text("to_bundle_id").notNull(),
|
|
111
|
-
type: text("type").notNull(),
|
|
112
|
-
platform: text("platform").notNull(),
|
|
113
|
-
app_version: text("app_version").notNull(),
|
|
114
|
-
channel: text("channel").notNull(),
|
|
115
|
-
cohort: text("cohort").notNull(),
|
|
116
|
-
received_at_ms: integer("received_at_ms").notNull(),
|
|
117
|
-
});
|
|
118
|
-
const apiKeys = pgTable("api_keys", {
|
|
119
|
-
id: text("id").primaryKey(),
|
|
120
|
-
hash: text("hash").notNull().unique(),
|
|
121
|
-
name: text("name").notNull(),
|
|
122
|
-
prefix: text("prefix").notNull(),
|
|
123
|
-
role: text("role").notNull(),
|
|
124
|
-
created_at_ms: integer("created_at_ms").notNull(),
|
|
125
|
-
revoked_at_ms: integer("revoked_at_ms"),
|
|
126
|
-
});
|
|
127
|
-
const schema = {
|
|
128
|
-
bundle_events: bundleEvents,
|
|
129
|
-
bundle_installations: bundleInstallations,
|
|
130
|
-
bundle_patches: bundlePatches,
|
|
131
|
-
bundles,
|
|
132
|
-
channels,
|
|
133
|
-
api_keys: apiKeys,
|
|
134
|
-
release_catalogs: releaseCatalogs,
|
|
135
|
-
releases,
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
class DrizzleTestStateError extends Error {
|
|
139
|
-
readonly name = "DrizzleTestStateError";
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
let client: PGlite | undefined;
|
|
143
|
-
let database: ReturnType<typeof drizzle<typeof schema>> | undefined;
|
|
144
|
-
|
|
145
|
-
const getClient = (): PGlite => {
|
|
146
|
-
if (client === undefined) throw new DrizzleTestStateError();
|
|
147
|
-
return client;
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
const getDatabase = (): ReturnType<typeof drizzle<typeof schema>> => {
|
|
151
|
-
if (database === undefined) throw new DrizzleTestStateError();
|
|
152
|
-
return database;
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
setupDatabasePluginTestSuite({
|
|
156
|
-
name: "drizzleAdapter PostgreSQL",
|
|
157
|
-
migrate: async () => {
|
|
158
|
-
client = new PGlite();
|
|
159
|
-
await client.exec(DATABASE_PLUGIN_TEST_SCHEMA_SQL);
|
|
160
|
-
database = drizzle(client, { schema });
|
|
161
|
-
},
|
|
162
|
-
createPlugin: (): DatabaseAdapterWithCapabilities =>
|
|
163
|
-
drizzleAdapter({ db: getDatabase(), provider: "postgresql" }),
|
|
164
|
-
reset: async () => {
|
|
165
|
-
await getClient().exec(DATABASE_PLUGIN_TEST_RESET_SQL);
|
|
166
|
-
},
|
|
167
|
-
dispose: async () => {
|
|
168
|
-
await getClient().close();
|
|
169
|
-
database = undefined;
|
|
170
|
-
client = undefined;
|
|
171
|
-
},
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
describe("drizzleAdapter schema requirements", () => {
|
|
175
|
-
it("keeps Bun SQLite event and snapshot writes inside its synchronous transaction", async () => {
|
|
176
|
-
const { stdout } = await promisify(execFile)(
|
|
177
|
-
new URL("../../../../node_modules/.bin/bun", import.meta.url).pathname,
|
|
178
|
-
[
|
|
179
|
-
"-e",
|
|
180
|
-
`
|
|
181
|
-
import { Database } from "bun:sqlite";
|
|
182
|
-
import { drizzle } from "drizzle-orm/bun-sqlite";
|
|
183
|
-
import { toInsightsInstallationRow } from "@hot-updater/plugin-core";
|
|
184
|
-
import { drizzleAdapter } from "./src/adapters/drizzle.ts";
|
|
185
|
-
import { createTableSql } from "./src/db/schema/sql.ts";
|
|
186
|
-
import { createBundleEventRowFixture } from "../test-utils/src/databaseTestFixtures.ts";
|
|
187
|
-
import * as schema from "../../examples-server/elysia-drizzle-libsql/hot-updater-schema.ts";
|
|
188
|
-
const db = new Database(":memory:");
|
|
189
|
-
db.exec(createTableSql("sqlite").join(";"));
|
|
190
|
-
db.exec("create trigger reject_snapshot before insert on bundle_installations begin select raise(abort, 'injected snapshot failure'); end;");
|
|
191
|
-
const plugin = drizzleAdapter({ db: drizzle(db, { schema }), provider: "sqlite" });
|
|
192
|
-
const event = createBundleEventRowFixture("708", 100);
|
|
193
|
-
const input = { event, installation: toInsightsInstallationRow(event) };
|
|
194
|
-
let rejected = false;
|
|
195
|
-
try { await plugin.models.insights.record(input); } catch { rejected = true; }
|
|
196
|
-
if (!rejected || db.query("select count(*) as total from bundle_events").get().total !== 0) throw new Error("transaction failed to roll back");
|
|
197
|
-
db.exec("drop trigger reject_snapshot");
|
|
198
|
-
await plugin.models.insights.record(input);
|
|
199
|
-
await plugin.models.insights.record(input);
|
|
200
|
-
if (db.query("select count(*) as total from bundle_events").get().total !== 1 || db.query("select count(*) as total from bundle_installations").get().total !== 1) throw new Error("retry did not commit exactly one report");
|
|
201
|
-
db.close();
|
|
202
|
-
console.log("atomic retry verified");
|
|
203
|
-
`,
|
|
204
|
-
],
|
|
205
|
-
{ cwd: new URL("../..", import.meta.url).pathname },
|
|
206
|
-
);
|
|
207
|
-
expect(stdout).toContain("atomic retry verified");
|
|
208
|
-
});
|
|
209
|
-
it("rolls back the event when the installation write fails and permits retry", async () => {
|
|
210
|
-
const db = new PGlite();
|
|
211
|
-
await db.exec(DATABASE_PLUGIN_TEST_SCHEMA_SQL);
|
|
212
|
-
await db.exec(
|
|
213
|
-
"alter table bundle_installations add constraint reject_snapshot check (install_id <> 'install-701')",
|
|
214
|
-
);
|
|
215
|
-
const plugin = drizzleAdapter({
|
|
216
|
-
db: drizzle(db, { schema }),
|
|
217
|
-
provider: "postgresql",
|
|
218
|
-
});
|
|
219
|
-
const event = createBundleEventRowFixture("701", 100);
|
|
220
|
-
const input = { event, installation: toInsightsInstallationRow(event) };
|
|
221
|
-
try {
|
|
222
|
-
await expect(plugin.models.insights.record(input)).rejects.toThrow();
|
|
223
|
-
expect((await db.query("select id from bundle_events")).rows).toEqual([]);
|
|
224
|
-
await db.exec(
|
|
225
|
-
"alter table bundle_installations drop constraint reject_snapshot",
|
|
226
|
-
);
|
|
227
|
-
await plugin.models.insights.record(input);
|
|
228
|
-
await expect(
|
|
229
|
-
plugin.models.insights.findInstallations({
|
|
230
|
-
installId: event.install_id,
|
|
231
|
-
}),
|
|
232
|
-
).resolves.toEqual([input.installation]);
|
|
233
|
-
} finally {
|
|
234
|
-
await db.close();
|
|
235
|
-
}
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
it("requires transaction support before recording on a lazy database", async () => {
|
|
239
|
-
const getDB = vi.fn(() => {
|
|
240
|
-
throw new DrizzleTestStateError();
|
|
241
|
-
});
|
|
242
|
-
const plugin = drizzleAdapter({
|
|
243
|
-
db: getDB,
|
|
244
|
-
provider: "postgresql",
|
|
245
|
-
schema,
|
|
246
|
-
});
|
|
247
|
-
const event = createBundleEventRowFixture("702", 100);
|
|
248
|
-
await expect(
|
|
249
|
-
plugin.models.insights.record({
|
|
250
|
-
event,
|
|
251
|
-
installation: toInsightsInstallationRow(event),
|
|
252
|
-
}),
|
|
253
|
-
).rejects.toThrow("transaction support");
|
|
254
|
-
expect(getDB).not.toHaveBeenCalled();
|
|
255
|
-
});
|
|
256
|
-
it("does not resolve a lazy database while generating a schema", () => {
|
|
257
|
-
const getDB = vi.fn(() => {
|
|
258
|
-
throw new DrizzleTestStateError();
|
|
259
|
-
});
|
|
260
|
-
const plugin = drizzleAdapter({
|
|
261
|
-
db: getDB,
|
|
262
|
-
provider: "postgresql",
|
|
263
|
-
schema,
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
const generated = plugin.generateSchema?.("latest");
|
|
267
|
-
|
|
268
|
-
expect(generated?.code).toContain("pgTable");
|
|
269
|
-
expect(getDB).not.toHaveBeenCalled();
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
it("resolves a lazy database on the first database operation", async () => {
|
|
273
|
-
const lazyClient = new PGlite();
|
|
274
|
-
await lazyClient.exec(DATABASE_PLUGIN_TEST_SCHEMA_SQL);
|
|
275
|
-
const lazyDatabase = drizzle(lazyClient, { schema });
|
|
276
|
-
const getDB = vi.fn(async () => lazyDatabase);
|
|
277
|
-
const plugin = drizzleAdapter({
|
|
278
|
-
db: getDB,
|
|
279
|
-
provider: "postgresql",
|
|
280
|
-
schema,
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
try {
|
|
284
|
-
expect(getDB).not.toHaveBeenCalled();
|
|
285
|
-
await expect(plugin.models.channels.list({})).resolves.toEqual({
|
|
286
|
-
channels: [],
|
|
287
|
-
});
|
|
288
|
-
expect(getDB).toHaveBeenCalledOnce();
|
|
289
|
-
} finally {
|
|
290
|
-
await lazyClient.close();
|
|
291
|
-
}
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
it("rejects a lazy database without a schema on first use", () => {
|
|
295
|
-
const getDB = vi.fn(() => {
|
|
296
|
-
throw new DrizzleTestStateError();
|
|
297
|
-
});
|
|
298
|
-
const plugin = drizzleAdapter({ db: getDB, provider: "postgresql" });
|
|
299
|
-
|
|
300
|
-
expect(() => plugin.models.channels.list({})).toThrow(
|
|
301
|
-
"[hot-updater] Drizzle adapter requires schema when db is lazy.",
|
|
302
|
-
);
|
|
303
|
-
expect(getDB).not.toHaveBeenCalled();
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
it("rejects an invalid lazy database schema on first use", () => {
|
|
307
|
-
const getDB = vi.fn(() => {
|
|
308
|
-
throw new DrizzleTestStateError();
|
|
309
|
-
});
|
|
310
|
-
const plugin = drizzleAdapter({
|
|
311
|
-
db: getDB,
|
|
312
|
-
provider: "postgresql",
|
|
313
|
-
schema: { ...schema, bundles: null },
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
expect(() => plugin.models.channels.list({})).toThrow(
|
|
317
|
-
'[hot-updater] Drizzle schema table "bundles" is invalid.',
|
|
318
|
-
);
|
|
319
|
-
expect(getDB).not.toHaveBeenCalled();
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
it("requires all fixed table objects on first use", () => {
|
|
323
|
-
const incompleteSchema = { bundles };
|
|
324
|
-
const plugin = drizzleAdapter({
|
|
325
|
-
db: () => getDatabase(),
|
|
326
|
-
provider: "postgresql",
|
|
327
|
-
schema: incompleteSchema,
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
expect(() => plugin.models.channels.list({})).toThrow(
|
|
331
|
-
'Drizzle schema is missing table "bundle_patches".',
|
|
332
|
-
);
|
|
333
|
-
});
|
|
334
|
-
});
|
|
335
|
-
import { execFile } from "node:child_process";
|
|
336
|
-
import { promisify } from "node:util";
|