@hot-updater/server 0.36.7 → 1.0.0-rc.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/adapters/databaseConstraintErrors.cjs +23 -0
- package/dist/adapters/databaseConstraintErrors.mjs +21 -0
- package/dist/adapters/databasePluginUtils.cjs +117 -0
- package/dist/adapters/databasePluginUtils.mjs +106 -0
- package/dist/adapters/drizzle.cjs +53 -176
- package/dist/adapters/drizzle.d.cts +6 -4
- package/dist/adapters/drizzle.d.mts +6 -4
- package/dist/adapters/drizzle.mjs +54 -177
- package/dist/adapters/drizzleCrud.cjs +250 -0
- package/dist/adapters/drizzleCrud.mjs +249 -0
- package/dist/adapters/drizzleLazyDB.cjs +84 -36
- package/dist/adapters/drizzleLazyDB.mjs +84 -36
- package/dist/adapters/drizzleQuery.cjs +68 -0
- package/dist/adapters/drizzleQuery.mjs +67 -0
- package/dist/adapters/kysely.cjs +18 -138
- package/dist/adapters/kysely.d.cts +3 -12
- package/dist/adapters/kysely.d.mts +3 -12
- package/dist/adapters/kysely.mjs +19 -139
- package/dist/adapters/kyselyCrud.cjs +254 -0
- package/dist/adapters/kyselyCrud.mjs +253 -0
- package/dist/adapters/kyselyQuery.cjs +56 -0
- package/dist/adapters/kyselyQuery.mjs +55 -0
- package/dist/adapters/mongodb.cjs +21 -174
- package/dist/adapters/mongodb.d.cts +3 -2
- package/dist/adapters/mongodb.d.mts +3 -2
- package/dist/adapters/mongodb.mjs +21 -174
- package/dist/adapters/mongodbCollections.cjs +36 -0
- package/dist/adapters/mongodbCollections.mjs +30 -0
- package/dist/adapters/mongodbQuery.cjs +77 -0
- package/dist/adapters/mongodbQuery.mjs +70 -0
- package/dist/adapters/mongodbReads.cjs +148 -0
- package/dist/adapters/mongodbReads.mjs +147 -0
- package/dist/adapters/mongodbWrites.cjs +134 -0
- package/dist/adapters/mongodbWrites.mjs +133 -0
- package/dist/adapters/prisma.cjs +205 -180
- package/dist/adapters/prisma.d.cts +3 -3
- package/dist/adapters/prisma.d.mts +3 -3
- package/dist/adapters/prisma.mjs +206 -181
- package/dist/adapters/prismaQuery.cjs +58 -0
- package/dist/adapters/prismaQuery.mjs +56 -0
- package/dist/adapters/prismaRows.cjs +198 -0
- package/dist/adapters/prismaRows.mjs +188 -0
- package/dist/apiKeys.cjs +139 -0
- package/dist/apiKeys.d.cts +50 -0
- package/dist/apiKeys.d.mts +50 -0
- package/dist/apiKeys.mjs +133 -0
- package/dist/createHotUpdaterCore.cjs +48 -26
- package/dist/createHotUpdaterCore.d.cts +49 -17
- package/dist/createHotUpdaterCore.d.mts +49 -17
- package/dist/createHotUpdaterCore.mjs +51 -29
- package/dist/db/createBundleDiff.cjs +45 -68
- package/dist/db/createBundleDiff.d.cts +3 -3
- package/dist/db/createBundleDiff.d.mts +3 -3
- package/dist/db/createBundleDiff.mjs +47 -68
- package/dist/db/databasePluginCore.cjs +138 -0
- package/dist/db/databasePluginCore.mjs +137 -0
- package/dist/db/fixedMigrator.cjs +36 -93
- package/dist/db/fixedMigrator.mjs +36 -93
- package/dist/db/fixedMigratorMongo.cjs +319 -0
- package/dist/db/fixedMigratorMongo.mjs +319 -0
- package/dist/db/fixedMigratorShared.cjs +23 -0
- package/dist/db/fixedMigratorShared.mjs +18 -0
- package/dist/db/mongoMigrationExecution.cjs +11 -0
- package/dist/db/mongoMigrationExecution.mjs +11 -0
- package/dist/db/releaseCatalog.cjs +66 -0
- package/dist/db/releaseCatalog.d.cts +17 -0
- package/dist/db/releaseCatalog.d.mts +17 -0
- package/dist/db/releaseCatalog.mjs +64 -0
- package/dist/db/schema/mongodb.cjs +14 -6
- package/dist/db/schema/mongodb.mjs +14 -6
- package/dist/db/schema/registry.cjs +0 -2
- package/dist/db/schema/registry.mjs +1 -2
- package/dist/db/schema/sql.cjs +31 -14
- package/dist/db/schema/sql.mjs +32 -13
- package/dist/db/schema/sqlOperations.cjs +4 -4
- package/dist/db/schema/sqlOperations.mjs +5 -5
- package/dist/db/schemaGenerators.cjs +52 -18
- package/dist/db/schemaGenerators.mjs +52 -18
- package/dist/db/schemaReadiness.cjs +4 -3
- package/dist/db/schemaReadiness.mjs +4 -3
- package/dist/db/sqlMigrationExecution.cjs +67 -0
- package/dist/db/sqlMigrationExecution.mjs +66 -0
- package/dist/db/types.cjs +2 -6
- package/dist/db/types.d.cts +60 -16
- package/dist/db/types.d.mts +60 -16
- package/dist/db/types.mjs +3 -6
- package/dist/db/updateArtifacts.cjs +114 -60
- package/dist/db/updateArtifacts.mjs +117 -62
- package/dist/handler.cjs +108 -282
- package/dist/handler.d.cts +3 -46
- package/dist/handler.d.mts +3 -46
- package/dist/handler.mjs +107 -281
- package/dist/handlerBundleRoutes.cjs +155 -0
- package/dist/handlerBundleRoutes.mjs +155 -0
- package/dist/handlerErrors.cjs +9 -0
- package/dist/handlerErrors.mjs +9 -0
- package/dist/handlerParameters.cjs +39 -0
- package/dist/handlerParameters.mjs +34 -0
- package/dist/handlerReleaseCatalogRoutes.cjs +111 -0
- package/dist/handlerReleaseCatalogRoutes.mjs +110 -0
- package/dist/handlerReleaseManagementRoutes.cjs +125 -0
- package/dist/handlerReleaseManagementRoutes.mjs +124 -0
- package/dist/handlerTypes.d.cts +63 -0
- package/dist/handlerTypes.d.mts +63 -0
- package/dist/handlerVersionRoutes.cjs +10 -0
- package/dist/handlerVersionRoutes.d.cts +4 -0
- package/dist/handlerVersionRoutes.d.mts +4 -0
- package/dist/handlerVersionRoutes.mjs +9 -0
- package/dist/index.cjs +10 -1
- package/dist/index.d.cts +9 -3
- package/dist/index.d.mts +9 -3
- package/dist/index.mjs +5 -2
- package/dist/insights/bounded/activeOverview.cjs +87 -0
- package/dist/insights/bounded/activeOverview.mjs +85 -0
- package/dist/insights/bounded/installationSearch.cjs +42 -0
- package/dist/insights/bounded/installationSearch.mjs +42 -0
- package/dist/insights/bounded/persistence.cjs +39 -0
- package/dist/insights/bounded/persistence.mjs +38 -0
- package/dist/insights/bounded/provider.cjs +170 -0
- package/dist/insights/bounded/provider.d.cts +7 -0
- package/dist/insights/bounded/provider.d.mts +7 -0
- package/dist/insights/bounded/provider.mjs +170 -0
- package/dist/insights/bounded/scan.cjs +144 -0
- package/dist/insights/bounded/scan.mjs +138 -0
- package/dist/insights/domain.d.cts +121 -0
- package/dist/insights/domain.d.mts +121 -0
- package/dist/insights/errors.cjs +22 -0
- package/dist/insights/errors.mjs +20 -0
- package/dist/insights/eventInput.cjs +111 -0
- package/dist/insights/eventInput.mjs +111 -0
- package/dist/insights/persistence.d.cts +6 -0
- package/dist/insights/persistence.d.mts +6 -0
- package/dist/insights/queryInput.cjs +58 -0
- package/dist/insights/queryInput.mjs +55 -0
- package/dist/insights/routes.cjs +63 -0
- package/dist/insights/routes.mjs +61 -0
- package/dist/insights/types.d.cts +17 -0
- package/dist/insights/types.d.mts +17 -0
- package/dist/node.cjs +19 -12
- package/dist/node.d.cts +15 -10
- package/dist/node.d.mts +15 -10
- package/dist/node.mjs +19 -13
- package/dist/package.cjs +1 -1
- package/dist/package.mjs +1 -1
- package/dist/schema/dsl.cjs +19 -2
- package/dist/schema/dsl.mjs +17 -3
- package/dist/schema/index.cjs +1 -8
- package/dist/schema/index.mjs +2 -8
- package/dist/schema/types.cjs +3 -1
- package/dist/schema/types.mjs +3 -2
- package/dist/schema/v1_0_0.cjs +364 -0
- package/dist/schema/v1_0_0.mjs +357 -0
- package/dist/storageAccess.cjs +69 -25
- package/dist/storageAccess.mjs +68 -25
- package/dist/types/index.d.cts +4 -3
- package/dist/types/index.d.mts +5 -4
- package/package.json +8 -7
- package/src/adapters/databaseConstraintErrors.ts +25 -0
- package/src/adapters/databasePluginTestDatabase.ts +106 -0
- package/src/adapters/databasePluginUtils.spec.ts +29 -0
- package/src/adapters/databasePluginUtils.ts +214 -0
- package/src/adapters/drizzle.spec.ts +208 -47
- package/src/adapters/drizzle.ts +106 -293
- package/src/adapters/drizzleCrud.ts +419 -0
- package/src/adapters/drizzleLazyDB.ts +206 -100
- package/src/adapters/drizzleQuery.ts +164 -0
- package/src/adapters/kysely.spec.ts +126 -88
- package/src/adapters/kysely.ts +76 -334
- package/src/adapters/kyselyCrud.ts +588 -0
- package/src/adapters/kyselyQuery.ts +128 -0
- package/src/adapters/mongodb.spec.ts +141 -0
- package/src/adapters/mongodb.ts +60 -288
- package/src/adapters/mongodbCollections.ts +62 -0
- package/src/adapters/mongodbQuery.ts +226 -0
- package/src/adapters/mongodbReads.ts +311 -0
- package/src/adapters/mongodbRows.spec.ts +64 -0
- package/src/adapters/mongodbRows.ts +118 -0
- package/src/adapters/mongodbTestClient.ts +342 -0
- package/src/adapters/mongodbTestFilter.ts +166 -0
- package/src/adapters/mongodbWrites.ts +260 -0
- package/src/adapters/prisma.spec.ts +196 -0
- package/src/adapters/prisma.ts +417 -292
- package/src/adapters/prismaQuery.ts +129 -0
- package/src/adapters/prismaRows.spec.ts +98 -0
- package/src/adapters/prismaRows.ts +301 -0
- package/src/adapters/prismaTestClient.ts +396 -0
- package/src/apiKeys.integration.spec.ts +192 -0
- package/src/apiKeys.spec.ts +162 -0
- package/src/apiKeys.ts +220 -0
- package/src/createHotUpdaterCore.ts +164 -100
- package/src/db/bundleRows.spec.ts +164 -0
- package/src/db/bundleRows.ts +10 -140
- package/src/db/createBundleDiff.spec.ts +172 -127
- package/src/db/createBundleDiff.ts +91 -110
- package/src/db/databasePluginCore.spec.ts +62 -0
- package/src/db/databasePluginCore.testFixtures.ts +76 -0
- package/src/db/databasePluginCore.ts +185 -0
- package/src/db/databasePluginUpdateCheck.bench.ts +107 -0
- package/src/db/fixedMigrator.spec.ts +184 -42
- package/src/db/fixedMigrator.ts +64 -205
- package/src/db/fixedMigratorMongo.spec.ts +192 -0
- package/src/db/fixedMigratorMongo.ts +425 -0
- package/src/db/fixedMigratorShared.ts +36 -0
- package/src/db/hotUpdaterSchema.ts +0 -1
- package/src/db/index.spec.ts +333 -1025
- package/src/db/mongoMigrationExecution.ts +23 -0
- package/src/db/node-sqlite.d.ts +25 -0
- package/src/db/releaseCatalog.ts +148 -0
- package/src/db/schema/mongodb.ts +20 -6
- package/src/db/schema/sql.ts +52 -11
- package/src/db/schema/sqlOperations.ts +5 -4
- package/src/db/schemaGenerators.ts +107 -23
- package/src/db/schemaReadiness.ts +2 -1
- package/src/db/sqlMigrationExecution.spec.ts +65 -0
- package/src/db/sqlMigrationExecution.ts +108 -0
- package/src/db/types.spec.ts +55 -0
- package/src/db/types.ts +129 -65
- package/src/db/updateArtifacts.spec.ts +359 -0
- package/src/db/updateArtifacts.ts +290 -126
- package/src/handler-standalone.integration.spec.ts +401 -364
- package/src/handler.spec.ts +137 -582
- package/src/handler.testFixtures.ts +30 -0
- package/src/handler.ts +218 -616
- package/src/handlerAuth.integration.spec.ts +33 -0
- package/src/handlerBundleRoutes.ts +259 -0
- package/src/handlerErrors.ts +7 -0
- package/src/handlerManagement.spec.ts +262 -0
- package/src/handlerParameters.ts +105 -0
- package/src/handlerReleaseCatalogRoutes.ts +154 -0
- package/src/handlerReleaseManagementRoutes.ts +213 -0
- package/src/handlerTypes.ts +96 -0
- package/src/handlerVersionRoutes.ts +12 -0
- package/src/index.ts +22 -2
- package/src/insights/bounded/activeOverview.spec.ts +189 -0
- package/src/insights/bounded/activeOverview.ts +148 -0
- package/src/insights/bounded/installationSearch.spec.ts +130 -0
- package/src/insights/bounded/installationSearch.ts +69 -0
- package/src/insights/bounded/persistence.ts +43 -0
- package/src/insights/bounded/provider.spec.ts +219 -0
- package/src/insights/bounded/provider.ts +229 -0
- package/src/insights/bounded/scan.ts +235 -0
- package/src/insights/domain.ts +139 -0
- package/src/insights/errors.ts +18 -0
- package/src/insights/eventInput.ts +168 -0
- package/src/insights/insights.integration.spec.ts +144 -0
- package/src/insights/persistence.ts +10 -0
- package/src/insights/queryInput.ts +102 -0
- package/src/insights/routes.ts +123 -0
- package/src/insights/types.ts +44 -0
- package/src/node.spec.ts +79 -10
- package/src/node.ts +20 -17
- package/src/releaseCatalogRoutes.integration.spec.ts +238 -0
- package/src/runtime.spec.ts +126 -959
- package/src/runtime.testFixtures.ts +71 -0
- package/src/schema/dsl-all-versions.spec.ts +26 -17
- package/src/schema/dsl.ts +41 -2
- package/src/schema/index.ts +3 -9
- package/src/schema/types.ts +9 -3
- package/src/schema/v1_0_0.spec.ts +146 -0
- package/src/schema/v1_0_0.ts +465 -0
- package/src/storageAccess.spec.ts +127 -32
- package/src/storageAccess.ts +106 -55
- package/src/types/index.ts +2 -1
- package/dist/db/bundleRows.cjs +0 -82
- package/dist/db/bundleRows.d.cts +0 -33
- package/dist/db/bundleRows.d.mts +0 -33
- package/dist/db/bundleRows.mjs +0 -79
- package/dist/db/pluginCore.cjs +0 -242
- package/dist/db/pluginCore.mjs +0 -241
- package/dist/db/schema/sqlMigrations.cjs +0 -74
- package/dist/db/schema/sqlMigrations.mjs +0 -73
- package/dist/db/schemaEnhancements.cjs +0 -20
- package/dist/db/schemaEnhancements.mjs +0 -19
- package/dist/route.cjs +0 -7
- package/dist/route.mjs +0 -7
- package/dist/schema/v0_21_0.cjs +0 -38
- package/dist/schema/v0_21_0.mjs +0 -37
- package/dist/schema/v0_29_0.cjs +0 -45
- package/dist/schema/v0_29_0.mjs +0 -44
- package/dist/schema/v0_31_0.cjs +0 -82
- package/dist/schema/v0_31_0.mjs +0 -80
- package/src/db/pluginCore.spec.ts +0 -1095
- package/src/db/pluginCore.ts +0 -475
- package/src/db/pluginUpdateCheck.bench.ts +0 -254
- package/src/db/schema/sqlMigrations.ts +0 -219
- package/src/db/schemaEnhancements.ts +0 -55
- package/src/route.ts +0 -7
- package/src/schema/v0_21_0.ts +0 -52
- package/src/schema/v0_29_0.ts +0 -62
- package/src/schema/v0_31_0.spec.ts +0 -73
- package/src/schema/v0_31_0.ts +0 -120
package/dist/adapters/prisma.mjs
CHANGED
|
@@ -1,201 +1,226 @@
|
|
|
1
1
|
import { getHotUpdaterSchemaVersion, hotUpdaterSchema } from "../db/schema/registry.mjs";
|
|
2
2
|
import { generatePrismaSchema } from "../db/schemaGenerators.mjs";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { isChannelDeleteReferencedError, translateChannelDeleteError } from "./databaseConstraintErrors.mjs";
|
|
4
|
+
import { hasNullOrderOverrides, sortRowsByOrder } from "./databasePluginUtils.mjs";
|
|
5
|
+
import { createPrismaOrderBy, createPrismaWhere } from "./prismaQuery.mjs";
|
|
6
|
+
import { PrismaAdapterError, getPrismaDelegate, parsePrismaApiKeyRow, parsePrismaBundleEventRow, parsePrismaBundleRow, parsePrismaChannelRow, parsePrismaPatchRow, parsePrismaReleaseCatalogRow, parsePrismaReleaseRow, parsePrismaRows } from "./prismaRows.mjs";
|
|
7
|
+
import { DatabasePluginInputError, createDatabasePlugin } from "@hot-updater/plugin-core";
|
|
8
|
+
import { createDatabasePluginAdapter } from "@hot-updater/plugin-core/internal";
|
|
6
9
|
//#region src/adapters/prisma.ts
|
|
7
|
-
const
|
|
8
|
-
|
|
10
|
+
const hasCallbackTransaction = (client) => "$transaction" in client && typeof client.$transaction === "function";
|
|
11
|
+
const runPrismaTransaction = (client, isolationLevel, callback) => {
|
|
12
|
+
const execute = () => isolationLevel === "serializable" ? client.$transaction(callback, { isolationLevel: "Serializable" }) : client.$transaction(callback);
|
|
13
|
+
if (isolationLevel === "default") return execute();
|
|
14
|
+
return (async () => {
|
|
15
|
+
for (let attempt = 0;; attempt += 1) try {
|
|
16
|
+
return await execute();
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if (attempt >= 2 || typeof error !== "object" || error === null || !("code" in error) || error.code !== "P2034") throw error;
|
|
19
|
+
}
|
|
20
|
+
})();
|
|
9
21
|
};
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
if (!delegate || typeof delegate !== "object") throw new Error(`Prisma client is missing model delegate "${model}".`);
|
|
13
|
-
return delegate;
|
|
22
|
+
const assertPrismaProvider = (provider) => {
|
|
23
|
+
if (provider === "mongodb") throw new PrismaAdapterError("Prisma adapter does not support MongoDB; use mongodbAdapter instead");
|
|
14
24
|
};
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
...
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
};
|
|
25
|
+
const findMany = async (client, input, provider) => {
|
|
26
|
+
if (input.distinctOn !== void 0) throw new DatabasePluginInputError("invalid-operation");
|
|
27
|
+
const rawOrderBy = input.orderBy;
|
|
28
|
+
const orderBy = createPrismaOrderBy(rawOrderBy);
|
|
29
|
+
const rows = rawOrderBy !== void 0 && hasNullOrderOverrides(rawOrderBy) ? sortRowsByOrder(await getPrismaDelegate(client, input.model).findMany({ where: createPrismaWhere(input.where, provider) }), rawOrderBy).slice(input.offset, input.offset + input.limit) : await getPrismaDelegate(client, input.model).findMany({
|
|
30
|
+
where: createPrismaWhere(input.where, provider),
|
|
31
|
+
...orderBy ? { orderBy } : {},
|
|
32
|
+
skip: input.offset,
|
|
33
|
+
take: input.limit
|
|
34
|
+
});
|
|
35
|
+
switch (input.model) {
|
|
36
|
+
case "bundles": return parsePrismaRows(rows, parsePrismaBundleRow);
|
|
37
|
+
case "bundle_patches": return parsePrismaRows(rows, parsePrismaPatchRow);
|
|
38
|
+
case "bundle_events": return parsePrismaRows(rows, parsePrismaBundleEventRow);
|
|
39
|
+
case "channels": return parsePrismaRows(rows, parsePrismaChannelRow);
|
|
40
|
+
case "api_keys": return parsePrismaRows(rows, parsePrismaApiKeyRow);
|
|
41
|
+
case "releases": return parsePrismaRows(rows, parsePrismaReleaseRow);
|
|
42
|
+
case "release_catalogs": return parsePrismaRows(rows, parsePrismaReleaseCatalogRow);
|
|
43
|
+
}
|
|
35
44
|
};
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const patchMap = /* @__PURE__ */ new Map();
|
|
47
|
-
if (bundleIds.length === 0) return patchMap;
|
|
48
|
-
const rows = await patches.findMany({
|
|
49
|
-
where: { bundle_id: { in: [...bundleIds] } },
|
|
50
|
-
orderBy: { order_index: "asc" }
|
|
51
|
-
});
|
|
52
|
-
for (const row of rows) {
|
|
53
|
-
const patch = row;
|
|
54
|
-
const current = patchMap.get(patch.bundle_id) ?? [];
|
|
55
|
-
current.push(patch);
|
|
56
|
-
patchMap.set(patch.bundle_id, current);
|
|
57
|
-
}
|
|
58
|
-
return patchMap;
|
|
45
|
+
const assertPatchReferences = async (client, bundleId, baseBundleId) => {
|
|
46
|
+
const ids = Array.from(new Set([bundleId, baseBundleId]));
|
|
47
|
+
if (await getPrismaDelegate(client, "bundles").count({ where: { id: { in: ids } } }) !== ids.length) throw new PrismaAdapterError("patch references a missing bundle");
|
|
48
|
+
};
|
|
49
|
+
const createCrudImplementation = (client, provider, relationMode) => ({
|
|
50
|
+
deleteChannel: async ({ id }) => {
|
|
51
|
+
const channels = getPrismaDelegate(client, "channels");
|
|
52
|
+
if (await channels.findFirst({ where: { id } }) === null) return {
|
|
53
|
+
deleted: false,
|
|
54
|
+
reason: "not_found"
|
|
59
55
|
};
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
56
|
+
if (await getPrismaDelegate(client, "releases").count({ where: { channel_id: id } }) > 0) return {
|
|
57
|
+
deleted: false,
|
|
58
|
+
reason: "not_empty"
|
|
63
59
|
};
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
60
|
+
try {
|
|
61
|
+
await channels.deleteMany({ where: { id } });
|
|
62
|
+
} catch (error) {
|
|
63
|
+
if (isChannelDeleteReferencedError(error)) return {
|
|
64
|
+
deleted: false,
|
|
65
|
+
reason: "not_empty"
|
|
66
|
+
};
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
return { deleted: true };
|
|
70
|
+
},
|
|
71
|
+
insertChannel: async (input) => {
|
|
72
|
+
const delegate = getPrismaDelegate(client, "channels");
|
|
73
|
+
const existing = await delegate.findFirst({ where: { name: input.row.name } });
|
|
74
|
+
if (existing !== null) return {
|
|
75
|
+
row: parsePrismaChannelRow(existing),
|
|
76
|
+
inserted: false
|
|
77
77
|
};
|
|
78
|
+
const row = parsePrismaChannelRow(await delegate.upsert({
|
|
79
|
+
where: { name: input.row.name },
|
|
80
|
+
create: input.row,
|
|
81
|
+
update: {}
|
|
82
|
+
}));
|
|
78
83
|
return {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (!row) return null;
|
|
82
|
-
return rowToBundle(row, (await fetchPatchMap([bundleId])).get(bundleId) ?? []);
|
|
83
|
-
},
|
|
84
|
-
async getBundles(options) {
|
|
85
|
-
const bundles = getDelegate(prisma, "bundles");
|
|
86
|
-
const offset = options.offset ?? 0;
|
|
87
|
-
const orderBy = options.orderBy ?? {
|
|
88
|
-
field: "id",
|
|
89
|
-
direction: "desc"
|
|
90
|
-
};
|
|
91
|
-
const where = prismaWhere(options.where);
|
|
92
|
-
const [total, rows] = await Promise.all([bundles.count({ where }), bundles.findMany({
|
|
93
|
-
where,
|
|
94
|
-
orderBy: { id: orderBy.direction },
|
|
95
|
-
skip: offset,
|
|
96
|
-
take: options.limit
|
|
97
|
-
})]);
|
|
98
|
-
const patchMap = await fetchPatchMap(rows.map((row) => String(row["id"])));
|
|
99
|
-
return {
|
|
100
|
-
data: rows.map((row) => rowToBundle(row, patchMap.get(String(row["id"])) ?? [])),
|
|
101
|
-
pagination: calculatePagination(total, {
|
|
102
|
-
limit: options.limit,
|
|
103
|
-
offset
|
|
104
|
-
})
|
|
105
|
-
};
|
|
106
|
-
},
|
|
107
|
-
async getUpdateInfo(args, context) {
|
|
108
|
-
const bundles = getDelegate(prisma, "bundles");
|
|
109
|
-
if (args._updateStrategy === "appVersion") {
|
|
110
|
-
const channel = args.channel ?? "production";
|
|
111
|
-
const minBundleId = args.minBundleId ?? NIL_UUID;
|
|
112
|
-
const rows = await bundles.findMany({
|
|
113
|
-
select: { target_app_version: true },
|
|
114
|
-
where: {
|
|
115
|
-
enabled: true,
|
|
116
|
-
platform: args.platform,
|
|
117
|
-
channel,
|
|
118
|
-
id: { gte: minBundleId },
|
|
119
|
-
target_app_version: { not: null }
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
const compatibleAppVersions = filterCompatibleAppVersions(Array.from(new Set(rows.map((row) => row["target_app_version"]).filter((value) => typeof value === "string" && value.length > 0))), args.appVersion);
|
|
123
|
-
const updateBundles = compatibleAppVersions.length > 0 ? await bundles.findMany({
|
|
124
|
-
where: {
|
|
125
|
-
enabled: true,
|
|
126
|
-
platform: args.platform,
|
|
127
|
-
channel,
|
|
128
|
-
id: { gte: minBundleId },
|
|
129
|
-
target_app_version: { in: compatibleAppVersions }
|
|
130
|
-
},
|
|
131
|
-
orderBy: { id: "desc" }
|
|
132
|
-
}).then(mapRowsToBundles) : [];
|
|
133
|
-
return resolveUpdateInfoFromBundles({
|
|
134
|
-
args: {
|
|
135
|
-
...args,
|
|
136
|
-
channel,
|
|
137
|
-
minBundleId
|
|
138
|
-
},
|
|
139
|
-
bundles: updateBundles,
|
|
140
|
-
context
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
const channel = args.channel ?? "production";
|
|
144
|
-
const minBundleId = args.minBundleId ?? NIL_UUID;
|
|
145
|
-
const rows = await bundles.findMany({
|
|
146
|
-
where: {
|
|
147
|
-
enabled: true,
|
|
148
|
-
platform: args.platform,
|
|
149
|
-
channel,
|
|
150
|
-
id: { gte: minBundleId },
|
|
151
|
-
fingerprint_hash: args.fingerprintHash
|
|
152
|
-
},
|
|
153
|
-
orderBy: { id: "desc" }
|
|
154
|
-
});
|
|
155
|
-
return resolveUpdateInfoFromBundles({
|
|
156
|
-
args: {
|
|
157
|
-
...args,
|
|
158
|
-
channel,
|
|
159
|
-
minBundleId
|
|
160
|
-
},
|
|
161
|
-
bundles: await mapRowsToBundles(rows),
|
|
162
|
-
context
|
|
163
|
-
});
|
|
164
|
-
},
|
|
165
|
-
async getChannels() {
|
|
166
|
-
const rows = await getDelegate(prisma, "bundles").findMany({
|
|
167
|
-
select: { channel: true },
|
|
168
|
-
orderBy: { channel: "asc" }
|
|
169
|
-
});
|
|
170
|
-
return Array.from(new Set(rows.map((row) => String(row["channel"]))));
|
|
171
|
-
},
|
|
172
|
-
async commitBundle({ changedSets }) {
|
|
173
|
-
await runInTransaction(async (client) => {
|
|
174
|
-
const bundles = getDelegate(client, "bundles");
|
|
175
|
-
const patches = getDelegate(client, "bundle_patches");
|
|
176
|
-
for (const change of changedSets) {
|
|
177
|
-
if (change.operation === "delete") {
|
|
178
|
-
await patches.deleteMany({ where: { bundle_id: change.data.id } });
|
|
179
|
-
await patches.deleteMany({ where: { base_bundle_id: change.data.id } });
|
|
180
|
-
await bundles.deleteMany({ where: { id: change.data.id } });
|
|
181
|
-
continue;
|
|
182
|
-
}
|
|
183
|
-
await upsertBundle(client, change.data);
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
}
|
|
84
|
+
row,
|
|
85
|
+
inserted: row.id === input.row.id
|
|
187
86
|
};
|
|
188
|
-
}
|
|
87
|
+
},
|
|
88
|
+
create: async (input) => {
|
|
89
|
+
if (input.model === "bundle_patches") await assertPatchReferences(client, input.data.bundle_id, input.data.base_bundle_id);
|
|
90
|
+
const delegate = getPrismaDelegate(client, input.model);
|
|
91
|
+
let row;
|
|
92
|
+
if (input.onConflict === "ignore") {
|
|
93
|
+
const where = input.model === "channels" ? { name: input.data.name } : { hash: input.data.hash };
|
|
94
|
+
row = await delegate.upsert({
|
|
95
|
+
where,
|
|
96
|
+
create: input.data,
|
|
97
|
+
update: {}
|
|
98
|
+
});
|
|
99
|
+
} else row = await delegate.create({ data: input.data });
|
|
100
|
+
switch (input.model) {
|
|
101
|
+
case "bundles": return parsePrismaBundleRow(row);
|
|
102
|
+
case "bundle_patches": return parsePrismaPatchRow(row);
|
|
103
|
+
case "bundle_events": return parsePrismaBundleEventRow(row);
|
|
104
|
+
case "channels": return parsePrismaChannelRow(row);
|
|
105
|
+
case "api_keys": return parsePrismaApiKeyRow(row);
|
|
106
|
+
case "releases": return parsePrismaReleaseRow(row);
|
|
107
|
+
case "release_catalogs": return parsePrismaReleaseCatalogRow(row);
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
update: async (input) => {
|
|
111
|
+
const id = input.where[0]?.value;
|
|
112
|
+
if (typeof id !== "string") throw new PrismaAdapterError(`${input.model} update requires a string id`);
|
|
113
|
+
if (input.model === "api_keys") {
|
|
114
|
+
const delegate = getPrismaDelegate(client, "api_keys");
|
|
115
|
+
if (await delegate.findFirst({ where: { id } }) === null) return null;
|
|
116
|
+
await delegate.update({
|
|
117
|
+
where: { id },
|
|
118
|
+
data: input.update
|
|
119
|
+
});
|
|
120
|
+
const stored = await delegate.findFirst({ where: { id } });
|
|
121
|
+
return stored === null ? null : parsePrismaApiKeyRow(stored);
|
|
122
|
+
}
|
|
123
|
+
if (input.model === "releases") {
|
|
124
|
+
const delegate = getPrismaDelegate(client, "releases");
|
|
125
|
+
if (await delegate.findFirst({ where: { id } }) === null) return null;
|
|
126
|
+
await delegate.update({
|
|
127
|
+
where: { id },
|
|
128
|
+
data: input.update
|
|
129
|
+
});
|
|
130
|
+
const stored = await delegate.findFirst({ where: { id } });
|
|
131
|
+
return stored === null ? null : parsePrismaReleaseRow(stored);
|
|
132
|
+
}
|
|
133
|
+
if (input.model === "release_catalogs") {
|
|
134
|
+
const delegate = getPrismaDelegate(client, "release_catalogs");
|
|
135
|
+
if (await delegate.findFirst({ where: { scope_key: id } }) === null) return null;
|
|
136
|
+
await delegate.update({
|
|
137
|
+
where: { scope_key: id },
|
|
138
|
+
data: input.update
|
|
139
|
+
});
|
|
140
|
+
const stored = await delegate.findFirst({ where: { scope_key: id } });
|
|
141
|
+
return stored === null ? null : parsePrismaReleaseCatalogRow(stored);
|
|
142
|
+
}
|
|
143
|
+
const delegate = getPrismaDelegate(client, "bundles");
|
|
144
|
+
if (delegate.updateMany === void 0) throw new PrismaAdapterError("model delegate \"bundles\" requires updateMany");
|
|
145
|
+
if (await delegate.findFirst({ where: { id } }) === null) return null;
|
|
146
|
+
await delegate.updateMany({
|
|
147
|
+
where: { id },
|
|
148
|
+
data: input.update
|
|
149
|
+
});
|
|
150
|
+
const stored = await delegate.findFirst({ where: { id } });
|
|
151
|
+
if (stored === null) return null;
|
|
152
|
+
return parsePrismaBundleRow(stored);
|
|
153
|
+
},
|
|
154
|
+
delete: async (input) => {
|
|
155
|
+
if (input.model === "bundles" && relationMode === "prisma") {
|
|
156
|
+
const ids = parsePrismaRows(await getPrismaDelegate(client, "bundles").findMany({ where: createPrismaWhere(input.where, provider) }), parsePrismaBundleRow).map(({ id }) => id);
|
|
157
|
+
if (ids.length === 0) return;
|
|
158
|
+
await getPrismaDelegate(client, "bundle_patches").deleteMany({ where: { OR: [{ bundle_id: { in: ids } }, { base_bundle_id: { in: ids } }] } });
|
|
159
|
+
}
|
|
160
|
+
try {
|
|
161
|
+
await getPrismaDelegate(client, input.model).deleteMany({ where: createPrismaWhere(input.where, provider) });
|
|
162
|
+
} catch (error) {
|
|
163
|
+
if (input.model === "channels") translateChannelDeleteError(error);
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
count: async (input) => {
|
|
168
|
+
if (input.distinct !== void 0) throw new DatabasePluginInputError("invalid-operation");
|
|
169
|
+
return getPrismaDelegate(client, input.model).count({ where: createPrismaWhere(input.where, provider) });
|
|
170
|
+
},
|
|
171
|
+
findOne: async (input) => {
|
|
172
|
+
const row = await getPrismaDelegate(client, input.model).findFirst({ where: createPrismaWhere(input.where, provider) });
|
|
173
|
+
if (row === null) return null;
|
|
174
|
+
switch (input.model) {
|
|
175
|
+
case "bundles": return parsePrismaBundleRow(row);
|
|
176
|
+
case "bundle_patches": return parsePrismaPatchRow(row);
|
|
177
|
+
case "channels": return parsePrismaChannelRow(row);
|
|
178
|
+
case "api_keys": return parsePrismaApiKeyRow(row);
|
|
179
|
+
case "releases": return parsePrismaReleaseRow(row);
|
|
180
|
+
case "release_catalogs": return parsePrismaReleaseCatalogRow(row);
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
findMany: (input) => findMany(client, input, provider)
|
|
189
184
|
});
|
|
185
|
+
const createPrismaImplementation = (client, relationMode, provider) => {
|
|
186
|
+
const crud = createCrudImplementation(client, provider, relationMode);
|
|
187
|
+
const implementation = {
|
|
188
|
+
...crud,
|
|
189
|
+
deleteChannel: (input) => {
|
|
190
|
+
if (!hasCallbackTransaction(client)) throw new PrismaAdapterError("channel deletion requires callback transactions");
|
|
191
|
+
return runPrismaTransaction(client, "serializable", (transactionClient) => createCrudImplementation(transactionClient, provider, relationMode).deleteChannel(input));
|
|
192
|
+
},
|
|
193
|
+
delete: (input) => {
|
|
194
|
+
if (input.model !== "bundles" || relationMode === "foreign-keys") return crud.delete(input);
|
|
195
|
+
if (!hasCallbackTransaction(client)) throw new PrismaAdapterError("relation mode \"prisma\" requires callback transactions");
|
|
196
|
+
return runPrismaTransaction(client, "serializable", (transactionClient) => createCrudImplementation(transactionClient, provider, relationMode).delete(input));
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
if (relationMode === "prisma" && !hasCallbackTransaction(client)) throw new PrismaAdapterError("relation mode \"prisma\" requires callback transactions");
|
|
200
|
+
if (!hasCallbackTransaction(client)) return implementation;
|
|
201
|
+
if (relationMode === "prisma") implementation.create = (input) => runPrismaTransaction(client, "serializable", (transactionClient) => createCrudImplementation(transactionClient, provider, relationMode).create(input));
|
|
202
|
+
implementation.update = (input) => runPrismaTransaction(client, relationMode === "prisma" ? "serializable" : "default", (transactionClient) => createCrudImplementation(transactionClient, provider, relationMode).update(input));
|
|
203
|
+
return {
|
|
204
|
+
...implementation,
|
|
205
|
+
transaction: (callback) => runPrismaTransaction(client, "serializable", async (transactionClient) => {
|
|
206
|
+
return callback(createCrudImplementation(transactionClient, provider, relationMode));
|
|
207
|
+
})
|
|
208
|
+
};
|
|
209
|
+
};
|
|
190
210
|
const prismaAdapter = (config) => {
|
|
191
|
-
|
|
192
|
-
|
|
211
|
+
assertPrismaProvider(config.provider);
|
|
212
|
+
const adapter = createDatabasePluginAdapter("prisma", createPrismaImplementation(config.prisma, config.relationMode ?? "foreign-keys", config.provider));
|
|
213
|
+
return Object.assign(createDatabasePlugin({
|
|
214
|
+
name: "prisma",
|
|
215
|
+
models: adapter.models,
|
|
216
|
+
commit: adapter.commit
|
|
217
|
+
}), {
|
|
193
218
|
adapterName: "prisma",
|
|
194
219
|
provider: config.provider,
|
|
195
|
-
generateSchema: (version) => ({
|
|
220
|
+
generateSchema: ((version) => ({
|
|
196
221
|
code: generatePrismaSchema(config.provider, version === "latest" ? hotUpdaterSchema : getHotUpdaterSchemaVersion(version)),
|
|
197
222
|
path: "./prisma/schema/hot_updater.prisma"
|
|
198
|
-
})
|
|
223
|
+
}))
|
|
199
224
|
});
|
|
200
225
|
};
|
|
201
226
|
//#endregion
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require("../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
3
|
+
//#region src/adapters/prismaQuery.ts
|
|
4
|
+
const stringFilter = (operator, value, mode) => {
|
|
5
|
+
return {
|
|
6
|
+
[operator === "starts_with" ? "startsWith" : operator === "ends_with" ? "endsWith" : "contains"]: value,
|
|
7
|
+
...mode ? { mode } : {}
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
const SQL_PATTERN_METACHARACTERS = /[%_\\]/u;
|
|
11
|
+
const MONGODB_PATTERN_METACHARACTERS = /[.*+?^${}()|[\]\\]/u;
|
|
12
|
+
const prismaMode = (mode, provider) => {
|
|
13
|
+
if (mode === "insensitive" || mode === "sensitive" && provider !== "postgresql") throw new _hot_updater_plugin_core.DatabasePluginInputError("invalid-operation");
|
|
14
|
+
return mode === "sensitive" ? "default" : void 0;
|
|
15
|
+
};
|
|
16
|
+
const assertLiteralPattern = (value, provider) => {
|
|
17
|
+
if ((provider === "mongodb" ? MONGODB_PATTERN_METACHARACTERS : SQL_PATTERN_METACHARACTERS).test(value)) throw new _hot_updater_plugin_core.DatabasePluginInputError("invalid-operation");
|
|
18
|
+
};
|
|
19
|
+
const predicate = (where, provider) => {
|
|
20
|
+
const mode = prismaMode("mode" in where ? where.mode : void 0, provider);
|
|
21
|
+
switch (where.operator) {
|
|
22
|
+
case void 0:
|
|
23
|
+
case "eq": return { [where.field]: mode ? {
|
|
24
|
+
equals: where.value,
|
|
25
|
+
mode
|
|
26
|
+
} : where.value };
|
|
27
|
+
case "ne": return { [where.field]: {
|
|
28
|
+
not: where.value,
|
|
29
|
+
...mode ? { mode } : {}
|
|
30
|
+
} };
|
|
31
|
+
case "gt":
|
|
32
|
+
case "gte":
|
|
33
|
+
case "lt":
|
|
34
|
+
case "lte": return { [where.field]: { [where.operator]: where.value } };
|
|
35
|
+
case "in": return { [where.field]: { in: where.value } };
|
|
36
|
+
case "not_in": return { [where.field]: { notIn: where.value } };
|
|
37
|
+
case "contains":
|
|
38
|
+
case "starts_with":
|
|
39
|
+
case "ends_with":
|
|
40
|
+
assertLiteralPattern(where.value, provider);
|
|
41
|
+
return { [where.field]: stringFilter(where.operator, where.value, mode) };
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
const createPrismaWhere = (where, provider) => {
|
|
45
|
+
const items = where ?? [];
|
|
46
|
+
const first = items[0];
|
|
47
|
+
if (first === void 0) return {};
|
|
48
|
+
let result = predicate(first, provider);
|
|
49
|
+
for (const item of items.slice(1)) result = { [item.connector === "OR" ? "OR" : "AND"]: [result, predicate(item, provider)] };
|
|
50
|
+
return result;
|
|
51
|
+
};
|
|
52
|
+
const createPrismaOrderBy = (orderBy) => {
|
|
53
|
+
if (orderBy === void 0) return void 0;
|
|
54
|
+
return (Array.isArray(orderBy) ? orderBy : [orderBy]).map((clause) => ({ [clause.field]: clause.direction }));
|
|
55
|
+
};
|
|
56
|
+
//#endregion
|
|
57
|
+
exports.createPrismaOrderBy = createPrismaOrderBy;
|
|
58
|
+
exports.createPrismaWhere = createPrismaWhere;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { DatabasePluginInputError } from "@hot-updater/plugin-core";
|
|
2
|
+
//#region src/adapters/prismaQuery.ts
|
|
3
|
+
const stringFilter = (operator, value, mode) => {
|
|
4
|
+
return {
|
|
5
|
+
[operator === "starts_with" ? "startsWith" : operator === "ends_with" ? "endsWith" : "contains"]: value,
|
|
6
|
+
...mode ? { mode } : {}
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
const SQL_PATTERN_METACHARACTERS = /[%_\\]/u;
|
|
10
|
+
const MONGODB_PATTERN_METACHARACTERS = /[.*+?^${}()|[\]\\]/u;
|
|
11
|
+
const prismaMode = (mode, provider) => {
|
|
12
|
+
if (mode === "insensitive" || mode === "sensitive" && provider !== "postgresql") throw new DatabasePluginInputError("invalid-operation");
|
|
13
|
+
return mode === "sensitive" ? "default" : void 0;
|
|
14
|
+
};
|
|
15
|
+
const assertLiteralPattern = (value, provider) => {
|
|
16
|
+
if ((provider === "mongodb" ? MONGODB_PATTERN_METACHARACTERS : SQL_PATTERN_METACHARACTERS).test(value)) throw new DatabasePluginInputError("invalid-operation");
|
|
17
|
+
};
|
|
18
|
+
const predicate = (where, provider) => {
|
|
19
|
+
const mode = prismaMode("mode" in where ? where.mode : void 0, provider);
|
|
20
|
+
switch (where.operator) {
|
|
21
|
+
case void 0:
|
|
22
|
+
case "eq": return { [where.field]: mode ? {
|
|
23
|
+
equals: where.value,
|
|
24
|
+
mode
|
|
25
|
+
} : where.value };
|
|
26
|
+
case "ne": return { [where.field]: {
|
|
27
|
+
not: where.value,
|
|
28
|
+
...mode ? { mode } : {}
|
|
29
|
+
} };
|
|
30
|
+
case "gt":
|
|
31
|
+
case "gte":
|
|
32
|
+
case "lt":
|
|
33
|
+
case "lte": return { [where.field]: { [where.operator]: where.value } };
|
|
34
|
+
case "in": return { [where.field]: { in: where.value } };
|
|
35
|
+
case "not_in": return { [where.field]: { notIn: where.value } };
|
|
36
|
+
case "contains":
|
|
37
|
+
case "starts_with":
|
|
38
|
+
case "ends_with":
|
|
39
|
+
assertLiteralPattern(where.value, provider);
|
|
40
|
+
return { [where.field]: stringFilter(where.operator, where.value, mode) };
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const createPrismaWhere = (where, provider) => {
|
|
44
|
+
const items = where ?? [];
|
|
45
|
+
const first = items[0];
|
|
46
|
+
if (first === void 0) return {};
|
|
47
|
+
let result = predicate(first, provider);
|
|
48
|
+
for (const item of items.slice(1)) result = { [item.connector === "OR" ? "OR" : "AND"]: [result, predicate(item, provider)] };
|
|
49
|
+
return result;
|
|
50
|
+
};
|
|
51
|
+
const createPrismaOrderBy = (orderBy) => {
|
|
52
|
+
if (orderBy === void 0) return void 0;
|
|
53
|
+
return (Array.isArray(orderBy) ? orderBy : [orderBy]).map((clause) => ({ [clause.field]: clause.direction }));
|
|
54
|
+
};
|
|
55
|
+
//#endregion
|
|
56
|
+
export { createPrismaOrderBy, createPrismaWhere };
|