@hot-updater/plugin-core 0.36.7 → 1.0.0-rc.0
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/assetStorageLayout.cjs +36 -18
- package/dist/assetStorageLayout.d.cts +21 -6
- package/dist/assetStorageLayout.d.mts +21 -6
- package/dist/assetStorageLayout.mjs +36 -18
- package/dist/bundleStorageLayout.cjs +2 -3
- package/dist/bundleStorageLayout.mjs +2 -3
- package/dist/contentAddressedAssets.cjs +5 -0
- package/dist/contentAddressedAssets.d.cts +2 -1
- package/dist/contentAddressedAssets.d.mts +2 -1
- package/dist/contentAddressedAssets.mjs +5 -1
- package/dist/createDatabasePlugin.cjs +775 -284
- package/dist/createDatabasePlugin.d.cts +20 -64
- package/dist/createDatabasePlugin.d.mts +20 -64
- package/dist/createDatabasePlugin.mjs +773 -284
- package/dist/createStorageKeyBuilder.cjs +9 -2
- package/dist/createStorageKeyBuilder.mjs +9 -2
- package/dist/createStoragePlugin.cjs +6 -145
- package/dist/createStoragePlugin.d.cts +7 -52
- package/dist/createStoragePlugin.d.mts +7 -52
- package/dist/createStoragePlugin.mjs +5 -143
- package/dist/databaseClient.cjs +112 -0
- package/dist/databaseClient.d.cts +33 -0
- package/dist/databaseClient.d.mts +33 -0
- package/dist/databaseClient.mjs +110 -0
- package/dist/databaseClientReads.cjs +113 -0
- package/dist/databaseClientReads.mjs +112 -0
- package/dist/databaseClientUpdates.cjs +39 -0
- package/dist/databaseClientUpdates.d.cts +11 -0
- package/dist/databaseClientUpdates.d.mts +11 -0
- package/dist/databaseClientUpdates.mjs +36 -0
- package/dist/databaseJsonValue.cjs +37 -0
- package/dist/databaseJsonValue.d.cts +5 -0
- package/dist/databaseJsonValue.d.mts +5 -0
- package/dist/databaseJsonValue.mjs +37 -0
- package/dist/databaseMetadata.cjs +13 -0
- package/dist/databaseMetadata.mjs +12 -0
- package/dist/databasePluginCrud.cjs +86 -0
- package/dist/databasePluginCrud.d.cts +1 -0
- package/dist/databasePluginCrud.d.mts +1 -0
- package/dist/databasePluginCrud.mjs +86 -0
- package/dist/databasePluginCrudValidation.d.cts +1 -0
- package/dist/databasePluginCrudValidation.d.mts +1 -0
- package/dist/databasePluginCrudValidationErrors.cjs +10 -0
- package/dist/databasePluginCrudValidationErrors.d.cts +9 -0
- package/dist/databasePluginCrudValidationErrors.d.mts +9 -0
- package/dist/databasePluginCrudValidationErrors.mjs +10 -0
- package/dist/databasePluginCrudValidationFields.cjs +291 -0
- package/dist/databasePluginCrudValidationFields.d.cts +1 -0
- package/dist/databasePluginCrudValidationFields.d.mts +1 -0
- package/dist/databasePluginCrudValidationFields.mjs +281 -0
- package/dist/databasePluginCrudValidationMutations.cjs +88 -0
- package/dist/databasePluginCrudValidationMutations.d.cts +1 -0
- package/dist/databasePluginCrudValidationMutations.d.mts +1 -0
- package/dist/databasePluginCrudValidationMutations.mjs +82 -0
- package/dist/databasePluginCrudValidationQueries.cjs +103 -0
- package/dist/databasePluginCrudValidationQueries.d.cts +1 -0
- package/dist/databasePluginCrudValidationQueries.d.mts +1 -0
- package/dist/databasePluginCrudValidationQueries.mjs +97 -0
- package/dist/databasePluginCrudValidationRows.cjs +55 -0
- package/dist/databasePluginCrudValidationRows.d.cts +1 -0
- package/dist/databasePluginCrudValidationRows.d.mts +1 -0
- package/dist/databasePluginCrudValidationRows.mjs +53 -0
- package/dist/databasePluginTransaction.cjs +7 -0
- package/dist/databasePluginTransaction.mjs +7 -0
- package/dist/databaseRows.cjs +149 -0
- package/dist/databaseRows.d.cts +34 -0
- package/dist/databaseRows.d.mts +34 -0
- package/dist/databaseRows.mjs +141 -0
- package/dist/index.cjs +76 -24
- package/dist/index.d.cts +22 -12
- package/dist/index.d.mts +22 -12
- package/dist/index.mjs +21 -14
- package/dist/internal.cjs +6 -0
- package/dist/internal.d.cts +9 -0
- package/dist/internal.d.mts +9 -0
- package/dist/internal.mjs +3 -0
- package/dist/node_modules/.pnpm/verkit@0.3.2/node_modules/verkit/dist/index.cjs +345 -0
- package/dist/node_modules/.pnpm/verkit@0.3.2/node_modules/verkit/dist/index.mjs +341 -0
- package/dist/paginateBundles.d.cts +6 -4
- package/dist/paginateBundles.d.mts +6 -4
- package/dist/parseStorageUri.cjs +46 -30
- package/dist/parseStorageUri.d.cts +20 -17
- package/dist/parseStorageUri.d.mts +20 -17
- package/dist/parseStorageUri.mjs +46 -30
- package/dist/queryBundles.cjs +1 -7
- package/dist/queryBundles.d.cts +3 -1
- package/dist/queryBundles.d.mts +3 -1
- package/dist/queryBundles.mjs +1 -7
- package/dist/releaseCatalogCompiler.cjs +391 -0
- package/dist/releaseCatalogCompiler.d.cts +55 -0
- package/dist/releaseCatalogCompiler.d.mts +55 -0
- package/dist/releaseCatalogCompiler.mjs +386 -0
- package/dist/releaseCatalogMutation.cjs +303 -0
- package/dist/releaseCatalogMutation.d.cts +86 -0
- package/dist/releaseCatalogMutation.d.mts +86 -0
- package/dist/releaseCatalogMutation.mjs +297 -0
- package/dist/releaseManagement.cjs +231 -0
- package/dist/releaseManagement.d.cts +48 -0
- package/dist/releaseManagement.d.mts +48 -0
- package/dist/releaseManagement.mjs +224 -0
- package/dist/remoteBundleSigning.cjs +296 -0
- package/dist/remoteBundleSigning.d.cts +43 -0
- package/dist/remoteBundleSigning.d.mts +43 -0
- package/dist/remoteBundleSigning.mjs +291 -0
- package/dist/requestBundleCache.cjs +22 -0
- package/dist/requestBundleCache.d.cts +9 -0
- package/dist/requestBundleCache.d.mts +9 -0
- package/dist/requestBundleCache.mjs +22 -0
- package/dist/semverSatisfies.cjs +3 -4
- package/dist/semverSatisfies.mjs +1 -1
- package/dist/storageDownloadPath.cjs +48 -0
- package/dist/storageDownloadPath.d.cts +15 -0
- package/dist/storageDownloadPath.d.mts +15 -0
- package/dist/storageDownloadPath.mjs +46 -0
- package/dist/types/database.d.cts +4 -0
- package/dist/types/database.d.mts +4 -0
- package/dist/types/databaseFields.cjs +92 -0
- package/dist/types/databaseFields.d.cts +12 -0
- package/dist/types/databaseFields.d.mts +12 -0
- package/dist/types/databaseFields.mjs +92 -0
- package/dist/types/databaseOperations.d.cts +173 -0
- package/dist/types/databaseOperations.d.mts +173 -0
- package/dist/types/databasePlugin.d.cts +240 -0
- package/dist/types/databasePlugin.d.mts +240 -0
- package/dist/types/databaseQuery.d.cts +47 -0
- package/dist/types/databaseQuery.d.mts +47 -0
- package/dist/types/databaseRows.d.cts +120 -0
- package/dist/types/databaseRows.d.mts +120 -0
- package/dist/types/index.d.cts +120 -162
- package/dist/types/index.d.mts +120 -162
- package/dist/types/internal.d.cts +7 -0
- package/dist/types/internal.d.mts +7 -0
- package/dist/types/public.d.cts +3 -0
- package/dist/types/public.d.mts +3 -0
- package/dist/uuidv7.cjs +9 -0
- package/dist/uuidv7.d.cts +4 -1
- package/dist/uuidv7.d.mts +4 -1
- package/dist/uuidv7.mjs +8 -1
- package/package.json +10 -5
- package/dist/bundleUnitOfWork.cjs +0 -158
- package/dist/bundleUnitOfWork.mjs +0 -158
- package/dist/bundleUnitOfWorkStore.cjs +0 -15
- package/dist/bundleUnitOfWorkStore.mjs +0 -15
- package/dist/createBlobDatabasePlugin.cjs +0 -382
- package/dist/createBlobDatabasePlugin.d.cts +0 -29
- package/dist/createBlobDatabasePlugin.d.mts +0 -29
- package/dist/createBlobDatabasePlugin.mjs +0 -381
- package/dist/legacyAssetStorageLayout.cjs +0 -12
- package/dist/legacyAssetStorageLayout.mjs +0 -12
- package/dist/requestUpdateBundleState.cjs +0 -26
- package/dist/requestUpdateBundleState.d.cts +0 -12
- package/dist/requestUpdateBundleState.d.mts +0 -12
- package/dist/requestUpdateBundleState.mjs +0 -24
- package/dist/resolveUpdateInfoFromBundles.cjs +0 -14
- package/dist/resolveUpdateInfoFromBundles.d.cts +0 -16
- package/dist/resolveUpdateInfoFromBundles.d.mts +0 -16
- package/dist/resolveUpdateInfoFromBundles.mjs +0 -13
- package/dist/storageProfile.cjs +0 -15
- package/dist/storageProfile.d.cts +0 -9
- package/dist/storageProfile.d.mts +0 -9
- package/dist/storageProfile.mjs +0 -12
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { DatabasePluginInputError } from "./databasePluginCrudValidationErrors.mjs";
|
|
2
|
+
import { isBooleanField, isNumberField, isRecord, isStringField, modelValidators, sortableFields, validateField, validateFields } from "./databasePluginCrudValidationFields.mjs";
|
|
3
|
+
//#region src/databasePluginCrudValidationQueries.ts
|
|
4
|
+
const validateSelect = (model, select) => {
|
|
5
|
+
if (select === void 0) return;
|
|
6
|
+
if (!Array.isArray(select) || select.length === 0) throw new DatabasePluginInputError("empty-select");
|
|
7
|
+
if (!select.every((field) => typeof field === "string")) throw new DatabasePluginInputError("invalid-query");
|
|
8
|
+
validateFields(model, select);
|
|
9
|
+
};
|
|
10
|
+
const validateWhereValue = (model, condition) => {
|
|
11
|
+
const field = condition.field;
|
|
12
|
+
if (typeof field !== "string") throw new DatabasePluginInputError("invalid-query");
|
|
13
|
+
validateField(model, field);
|
|
14
|
+
const operator = condition.operator ?? "eq";
|
|
15
|
+
const value = condition.value;
|
|
16
|
+
const mode = condition.mode;
|
|
17
|
+
if (mode !== void 0 && mode !== "sensitive" && mode !== "insensitive") throw new DatabasePluginInputError("invalid-query");
|
|
18
|
+
switch (operator) {
|
|
19
|
+
case "eq":
|
|
20
|
+
case "ne":
|
|
21
|
+
if (!(isStringField(field) || isNumberField(field) || isBooleanField(field)) || !modelValidators[model][field]?.(value) || mode !== void 0 && (!isStringField(field) || typeof value !== "string")) throw new DatabasePluginInputError("invalid-query");
|
|
22
|
+
return;
|
|
23
|
+
case "gt":
|
|
24
|
+
case "gte":
|
|
25
|
+
case "lt":
|
|
26
|
+
case "lte":
|
|
27
|
+
if (mode !== void 0 || !(isStringField(field) || isNumberField(field)) || value === null || !modelValidators[model][field]?.(value)) throw new DatabasePluginInputError("invalid-query");
|
|
28
|
+
return;
|
|
29
|
+
case "in":
|
|
30
|
+
case "not_in":
|
|
31
|
+
if (!Array.isArray(value) || mode !== void 0) throw new DatabasePluginInputError("invalid-query");
|
|
32
|
+
if (!(isStringField(field) || isNumberField(field) || isBooleanField(field))) throw new DatabasePluginInputError("invalid-query");
|
|
33
|
+
if (!value.every((item) => modelValidators[model][field]?.(item))) throw new DatabasePluginInputError("invalid-query");
|
|
34
|
+
return;
|
|
35
|
+
case "contains":
|
|
36
|
+
case "starts_with":
|
|
37
|
+
case "ends_with":
|
|
38
|
+
if (!isStringField(field) || typeof value !== "string" || !modelValidators[model][field]?.(value)) throw new DatabasePluginInputError("invalid-query");
|
|
39
|
+
return;
|
|
40
|
+
default: throw new DatabasePluginInputError("invalid-query");
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const validateWhere = (model, where) => {
|
|
44
|
+
if (where === void 0) return;
|
|
45
|
+
if (!Array.isArray(where)) throw new DatabasePluginInputError("invalid-query");
|
|
46
|
+
for (const item of where) {
|
|
47
|
+
if (!isRecord(item)) throw new DatabasePluginInputError("invalid-query");
|
|
48
|
+
if (item.connector !== void 0 && item.connector !== "AND" && item.connector !== "OR") throw new DatabasePluginInputError("invalid-query");
|
|
49
|
+
validateWhereValue(model, item);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const validateDistinctFields = (model, fields) => {
|
|
53
|
+
if (fields === void 0) return void 0;
|
|
54
|
+
if (!Array.isArray(fields) || fields.length === 0) throw new DatabasePluginInputError("invalid-distinct");
|
|
55
|
+
if (!fields.every((field) => typeof field === "string")) throw new DatabasePluginInputError("invalid-distinct");
|
|
56
|
+
validateFields(model, fields);
|
|
57
|
+
return fields;
|
|
58
|
+
};
|
|
59
|
+
const validateOrderBy = (model, orderBy) => {
|
|
60
|
+
if (orderBy === void 0) return void 0;
|
|
61
|
+
if (!Array.isArray(orderBy) || orderBy.length === 0) throw new DatabasePluginInputError("invalid-query");
|
|
62
|
+
const fields = /* @__PURE__ */ new Set();
|
|
63
|
+
return orderBy.map((clause) => {
|
|
64
|
+
if (!isRecord(clause) || typeof clause.field !== "string") throw new DatabasePluginInputError("invalid-query");
|
|
65
|
+
validateField(model, clause.field);
|
|
66
|
+
if (!sortableFields[model].has(clause.field)) throw new DatabasePluginInputError("invalid-query");
|
|
67
|
+
if (clause.direction !== "asc" && clause.direction !== "desc") throw new DatabasePluginInputError("invalid-query");
|
|
68
|
+
if (clause.nulls !== void 0 && clause.nulls !== "first" && clause.nulls !== "last") throw new DatabasePluginInputError("invalid-query");
|
|
69
|
+
if (fields.has(clause.field)) throw new DatabasePluginInputError("invalid-operation");
|
|
70
|
+
fields.add(clause.field);
|
|
71
|
+
return clause;
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
const validateDistinctOn = (model, distinctOn, orderBy) => {
|
|
75
|
+
if (distinctOn === void 0) return;
|
|
76
|
+
if (!isRecord(distinctOn)) throw new DatabasePluginInputError("invalid-distinct");
|
|
77
|
+
const fields = validateDistinctFields(model, distinctOn.fields);
|
|
78
|
+
if (fields === void 0 || orderBy === void 0) throw new DatabasePluginInputError("invalid-distinct");
|
|
79
|
+
for (const [index, field] of fields.entries()) if (orderBy[index]?.field !== field) throw new DatabasePluginInputError("invalid-distinct");
|
|
80
|
+
};
|
|
81
|
+
const validatePagination = (limit, offset) => {
|
|
82
|
+
const effectiveLimit = limit ?? 100;
|
|
83
|
+
const effectiveOffset = offset ?? 0;
|
|
84
|
+
if (limit !== void 0 && (!Number.isSafeInteger(limit) || limit < 0) || offset !== void 0 && (!Number.isSafeInteger(offset) || offset < 0) || !Number.isSafeInteger(effectiveOffset + effectiveLimit)) throw new DatabasePluginInputError("invalid-pagination");
|
|
85
|
+
};
|
|
86
|
+
const validateBundlePagination = (options) => {
|
|
87
|
+
if (!Number.isSafeInteger(options.limit) || options.limit <= 0 || options.page !== void 0 && (!Number.isSafeInteger(options.page) || options.page <= 0) || options.page !== void 0 && options.cursor !== void 0) throw new DatabasePluginInputError("invalid-pagination");
|
|
88
|
+
const cursor = options.cursor;
|
|
89
|
+
if (cursor === void 0) return;
|
|
90
|
+
if (!isRecord(cursor)) throw new DatabasePluginInputError("invalid-pagination");
|
|
91
|
+
const hasAfter = Object.hasOwn(cursor, "after");
|
|
92
|
+
if (hasAfter === Object.hasOwn(cursor, "before")) throw new DatabasePluginInputError("invalid-pagination");
|
|
93
|
+
const value = hasAfter ? cursor.after : cursor.before;
|
|
94
|
+
if (typeof value !== "string" || value.length === 0) throw new DatabasePluginInputError("invalid-pagination");
|
|
95
|
+
};
|
|
96
|
+
//#endregion
|
|
97
|
+
export { validateBundlePagination, validateDistinctFields, validateDistinctOn, validateOrderBy, validatePagination, validateSelect, validateWhere };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const require_databasePluginCrudValidationErrors = require("./databasePluginCrudValidationErrors.cjs");
|
|
2
|
+
const require_databaseFields = require("./types/databaseFields.cjs");
|
|
3
|
+
const require_databasePluginCrudValidationFields = require("./databasePluginCrudValidationFields.cjs");
|
|
4
|
+
//#region src/databasePluginCrudValidationRows.ts
|
|
5
|
+
const hasValidReleaseInvariants = (data) => {
|
|
6
|
+
const kind = data.kind;
|
|
7
|
+
const bundleId = data.bundle_id;
|
|
8
|
+
const strategy = data.strategy;
|
|
9
|
+
const targetAppVersion = data.target_app_version;
|
|
10
|
+
const fingerprintHash = data.fingerprint_hash;
|
|
11
|
+
return (kind === "BUNDLE" && typeof bundleId === "string" || kind === "EMBEDDED" && bundleId === null) && (strategy === "APP_VERSION" && typeof targetAppVersion === "string" && fingerprintHash === null || strategy === "FINGERPRINT" && targetAppVersion === null && typeof fingerprintHash === "string");
|
|
12
|
+
};
|
|
13
|
+
const hasValidBundleEventInvariants = (data) => (data.type === "UPDATE_APPLIED" || data.type === "RECOVERED" || data.type === "RELEASE_ADOPTED") && typeof data.from_bundle_id === "string" && (data.update_strategy === "fingerprint" || data.update_strategy === "appVersion") || data.type === "UNCHANGED" && data.from_bundle_id === null && data.update_strategy === null;
|
|
14
|
+
const validateCreateData = (model, data) => {
|
|
15
|
+
if (!require_databasePluginCrudValidationFields.isRecord(data)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
|
|
16
|
+
require_databasePluginCrudValidationFields.validateFields(model, Object.keys(data));
|
|
17
|
+
for (const field of require_databaseFields.databaseFields[model]) {
|
|
18
|
+
const validator = require_databasePluginCrudValidationFields.modelValidators[model][field];
|
|
19
|
+
if (!Object.hasOwn(data, field) || !validator || !validator(Reflect.get(data, field))) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
|
|
20
|
+
}
|
|
21
|
+
if (model === "bundles" && data.target_app_version === null && data.fingerprint_hash === null) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
|
|
22
|
+
if (model === "releases" && !hasValidReleaseInvariants(data)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
|
|
23
|
+
if (model === "release_catalogs" && (data.strategy === "APP_VERSION" && data.fingerprint_hash !== null || data.strategy === "FINGERPRINT" && typeof data.fingerprint_hash !== "string")) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
|
|
24
|
+
if (model === "bundle_events" && !hasValidBundleEventInvariants(data)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
|
|
25
|
+
};
|
|
26
|
+
const selectRow = (row, input) => {
|
|
27
|
+
const { select } = input;
|
|
28
|
+
if (!select) return row;
|
|
29
|
+
return Object.fromEntries(select.map((field) => [field, Reflect.get(row, field)]));
|
|
30
|
+
};
|
|
31
|
+
const validateResult = (model, row, select) => {
|
|
32
|
+
if (!require_databasePluginCrudValidationFields.isRecord(row)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-result");
|
|
33
|
+
const fields = select ?? require_databaseFields.databaseFields[model];
|
|
34
|
+
for (const field of fields) {
|
|
35
|
+
const validator = require_databasePluginCrudValidationFields.modelValidators[model][field];
|
|
36
|
+
if (!Object.hasOwn(row, field) || !validator || !validator(Reflect.get(row, field))) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-result");
|
|
37
|
+
}
|
|
38
|
+
if (model === "bundles" && Object.hasOwn(row, "target_app_version") && Object.hasOwn(row, "fingerprint_hash") && Reflect.get(row, "target_app_version") === null && Reflect.get(row, "fingerprint_hash") === null) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-result");
|
|
39
|
+
if (model === "releases" && [
|
|
40
|
+
"kind",
|
|
41
|
+
"bundle_id",
|
|
42
|
+
"strategy",
|
|
43
|
+
"target_app_version",
|
|
44
|
+
"fingerprint_hash"
|
|
45
|
+
].every((field) => Object.hasOwn(row, field)) && !hasValidReleaseInvariants(row)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-result");
|
|
46
|
+
if (model === "bundle_events" && [
|
|
47
|
+
"type",
|
|
48
|
+
"from_bundle_id",
|
|
49
|
+
"update_strategy"
|
|
50
|
+
].every((field) => Object.hasOwn(row, field)) && !hasValidBundleEventInvariants(row)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-result");
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
exports.selectRow = selectRow;
|
|
54
|
+
exports.validateCreateData = validateCreateData;
|
|
55
|
+
exports.validateResult = validateResult;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { DatabasePluginInputError } from "./databasePluginCrudValidationErrors.mjs";
|
|
2
|
+
import { databaseFields } from "./types/databaseFields.mjs";
|
|
3
|
+
import { isRecord, modelValidators, validateFields } from "./databasePluginCrudValidationFields.mjs";
|
|
4
|
+
//#region src/databasePluginCrudValidationRows.ts
|
|
5
|
+
const hasValidReleaseInvariants = (data) => {
|
|
6
|
+
const kind = data.kind;
|
|
7
|
+
const bundleId = data.bundle_id;
|
|
8
|
+
const strategy = data.strategy;
|
|
9
|
+
const targetAppVersion = data.target_app_version;
|
|
10
|
+
const fingerprintHash = data.fingerprint_hash;
|
|
11
|
+
return (kind === "BUNDLE" && typeof bundleId === "string" || kind === "EMBEDDED" && bundleId === null) && (strategy === "APP_VERSION" && typeof targetAppVersion === "string" && fingerprintHash === null || strategy === "FINGERPRINT" && targetAppVersion === null && typeof fingerprintHash === "string");
|
|
12
|
+
};
|
|
13
|
+
const hasValidBundleEventInvariants = (data) => (data.type === "UPDATE_APPLIED" || data.type === "RECOVERED" || data.type === "RELEASE_ADOPTED") && typeof data.from_bundle_id === "string" && (data.update_strategy === "fingerprint" || data.update_strategy === "appVersion") || data.type === "UNCHANGED" && data.from_bundle_id === null && data.update_strategy === null;
|
|
14
|
+
const validateCreateData = (model, data) => {
|
|
15
|
+
if (!isRecord(data)) throw new DatabasePluginInputError("invalid-data");
|
|
16
|
+
validateFields(model, Object.keys(data));
|
|
17
|
+
for (const field of databaseFields[model]) {
|
|
18
|
+
const validator = modelValidators[model][field];
|
|
19
|
+
if (!Object.hasOwn(data, field) || !validator || !validator(Reflect.get(data, field))) throw new DatabasePluginInputError("invalid-data");
|
|
20
|
+
}
|
|
21
|
+
if (model === "bundles" && data.target_app_version === null && data.fingerprint_hash === null) throw new DatabasePluginInputError("invalid-data");
|
|
22
|
+
if (model === "releases" && !hasValidReleaseInvariants(data)) throw new DatabasePluginInputError("invalid-data");
|
|
23
|
+
if (model === "release_catalogs" && (data.strategy === "APP_VERSION" && data.fingerprint_hash !== null || data.strategy === "FINGERPRINT" && typeof data.fingerprint_hash !== "string")) throw new DatabasePluginInputError("invalid-data");
|
|
24
|
+
if (model === "bundle_events" && !hasValidBundleEventInvariants(data)) throw new DatabasePluginInputError("invalid-data");
|
|
25
|
+
};
|
|
26
|
+
const selectRow = (row, input) => {
|
|
27
|
+
const { select } = input;
|
|
28
|
+
if (!select) return row;
|
|
29
|
+
return Object.fromEntries(select.map((field) => [field, Reflect.get(row, field)]));
|
|
30
|
+
};
|
|
31
|
+
const validateResult = (model, row, select) => {
|
|
32
|
+
if (!isRecord(row)) throw new DatabasePluginInputError("invalid-result");
|
|
33
|
+
const fields = select ?? databaseFields[model];
|
|
34
|
+
for (const field of fields) {
|
|
35
|
+
const validator = modelValidators[model][field];
|
|
36
|
+
if (!Object.hasOwn(row, field) || !validator || !validator(Reflect.get(row, field))) throw new DatabasePluginInputError("invalid-result");
|
|
37
|
+
}
|
|
38
|
+
if (model === "bundles" && Object.hasOwn(row, "target_app_version") && Object.hasOwn(row, "fingerprint_hash") && Reflect.get(row, "target_app_version") === null && Reflect.get(row, "fingerprint_hash") === null) throw new DatabasePluginInputError("invalid-result");
|
|
39
|
+
if (model === "releases" && [
|
|
40
|
+
"kind",
|
|
41
|
+
"bundle_id",
|
|
42
|
+
"strategy",
|
|
43
|
+
"target_app_version",
|
|
44
|
+
"fingerprint_hash"
|
|
45
|
+
].every((field) => Object.hasOwn(row, field)) && !hasValidReleaseInvariants(row)) throw new DatabasePluginInputError("invalid-result");
|
|
46
|
+
if (model === "bundle_events" && [
|
|
47
|
+
"type",
|
|
48
|
+
"from_bundle_id",
|
|
49
|
+
"update_strategy"
|
|
50
|
+
].every((field) => Object.hasOwn(row, field)) && !hasValidBundleEventInvariants(row)) throw new DatabasePluginInputError("invalid-result");
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
export { selectRow, validateCreateData, validateResult };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const require_databasePluginCrud = require("./databasePluginCrud.cjs");
|
|
2
|
+
//#region src/databasePluginTransaction.ts
|
|
3
|
+
const createTransactionDatabasePlugin = (implementation) => {
|
|
4
|
+
return require_databasePluginCrud.createDatabasePluginCrud(implementation);
|
|
5
|
+
};
|
|
6
|
+
//#endregion
|
|
7
|
+
exports.createTransactionDatabasePlugin = createTransactionDatabasePlugin;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createDatabasePluginCrud } from "./databasePluginCrud.mjs";
|
|
2
|
+
//#region src/databasePluginTransaction.ts
|
|
3
|
+
const createTransactionDatabasePlugin = (implementation) => {
|
|
4
|
+
return createDatabasePluginCrud(implementation);
|
|
5
|
+
};
|
|
6
|
+
//#endregion
|
|
7
|
+
export { createTransactionDatabasePlugin };
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
require("./_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
const require_databaseMetadata = require("./databaseMetadata.cjs");
|
|
3
|
+
let _hot_updater_core = require("@hot-updater/core");
|
|
4
|
+
//#region src/databaseRows.ts
|
|
5
|
+
const releaseToRow = (release, scopeKey) => ({
|
|
6
|
+
id: release.id,
|
|
7
|
+
revision: release.revision,
|
|
8
|
+
scope_key: scopeKey,
|
|
9
|
+
channel_id: release.channelId,
|
|
10
|
+
platform: release.platform,
|
|
11
|
+
kind: release.kind,
|
|
12
|
+
bundle_id: release.bundleId,
|
|
13
|
+
strategy: release.strategy,
|
|
14
|
+
target_app_version: release.targetAppVersion,
|
|
15
|
+
fingerprint_hash: release.fingerprintHash,
|
|
16
|
+
enabled: release.enabled,
|
|
17
|
+
should_force_update: release.shouldForceUpdate,
|
|
18
|
+
message: release.message,
|
|
19
|
+
rollout_cohort_count: release.rolloutCohortCount,
|
|
20
|
+
target_cohorts: release.targetCohorts,
|
|
21
|
+
operation: release.operation,
|
|
22
|
+
source_release_id: release.sourceReleaseId,
|
|
23
|
+
created_at_ms: release.createdAtMs,
|
|
24
|
+
updated_at_ms: release.updatedAtMs
|
|
25
|
+
});
|
|
26
|
+
const releaseRowToRelease = (row) => ({
|
|
27
|
+
id: row.id,
|
|
28
|
+
revision: row.revision,
|
|
29
|
+
channelId: row.channel_id,
|
|
30
|
+
platform: row.platform,
|
|
31
|
+
kind: row.kind,
|
|
32
|
+
bundleId: row.bundle_id,
|
|
33
|
+
strategy: row.strategy,
|
|
34
|
+
targetAppVersion: row.target_app_version,
|
|
35
|
+
fingerprintHash: row.fingerprint_hash,
|
|
36
|
+
enabled: row.enabled,
|
|
37
|
+
shouldForceUpdate: row.should_force_update,
|
|
38
|
+
message: row.message,
|
|
39
|
+
rolloutCohortCount: row.rollout_cohort_count,
|
|
40
|
+
targetCohorts: row.target_cohorts,
|
|
41
|
+
operation: row.operation,
|
|
42
|
+
sourceReleaseId: row.source_release_id,
|
|
43
|
+
createdAtMs: row.created_at_ms,
|
|
44
|
+
updatedAtMs: row.updated_at_ms
|
|
45
|
+
});
|
|
46
|
+
const BundleRowHydrationErrorReason = {
|
|
47
|
+
duplicatePatchId: "duplicate_patch_id",
|
|
48
|
+
orphanPatchOwner: "orphan_patch_owner",
|
|
49
|
+
orphanPatchBase: "orphan_patch_base"
|
|
50
|
+
};
|
|
51
|
+
var BundleRowHydrationError = class extends Error {
|
|
52
|
+
name = "BundleRowHydrationError";
|
|
53
|
+
reason;
|
|
54
|
+
patchId;
|
|
55
|
+
bundleId;
|
|
56
|
+
constructor({ reason, patchId, bundleId }) {
|
|
57
|
+
super(`Cannot hydrate bundle rows: ${reason} for patch "${patchId}" and bundle "${bundleId}".`);
|
|
58
|
+
this.reason = reason;
|
|
59
|
+
this.patchId = patchId;
|
|
60
|
+
this.bundleId = bundleId;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const bundleToRow = (bundle) => {
|
|
64
|
+
const metadata = require_databaseMetadata.bundleMetadataToRow(bundle.metadata);
|
|
65
|
+
return {
|
|
66
|
+
id: bundle.id,
|
|
67
|
+
platform: bundle.platform,
|
|
68
|
+
file_hash: bundle.fileHash,
|
|
69
|
+
git_commit_hash: bundle.gitCommitHash,
|
|
70
|
+
storage_uri: bundle.storageUri,
|
|
71
|
+
archive_byte_size: bundle.archiveByteSize,
|
|
72
|
+
metadata,
|
|
73
|
+
manifest_storage_uri: (0, _hot_updater_core.getManifestStorageUri)(bundle),
|
|
74
|
+
manifest_file_hash: (0, _hot_updater_core.getManifestFileHash)(bundle),
|
|
75
|
+
asset_base_storage_uri: (0, _hot_updater_core.getAssetBaseStorageUri)(bundle)
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
const bundleToPatchRows = (bundle) => (0, _hot_updater_core.getBundlePatches)(bundle).map((patch, orderIndex) => ({
|
|
79
|
+
id: `${bundle.id}:${patch.baseBundleId}`,
|
|
80
|
+
bundle_id: bundle.id,
|
|
81
|
+
base_bundle_id: patch.baseBundleId,
|
|
82
|
+
base_file_hash: patch.baseFileHash,
|
|
83
|
+
patch_file_hash: patch.patchFileHash,
|
|
84
|
+
patch_storage_uri: patch.patchStorageUri,
|
|
85
|
+
byte_size: patch.byteSize,
|
|
86
|
+
order_index: orderIndex
|
|
87
|
+
}));
|
|
88
|
+
const comparePatchRows = (left, right) => left.order_index - right.order_index || left.id.localeCompare(right.id);
|
|
89
|
+
const patchRowToArtifact = (row) => ({
|
|
90
|
+
baseBundleId: row.base_bundle_id,
|
|
91
|
+
baseFileHash: row.base_file_hash,
|
|
92
|
+
byteSize: row.byte_size,
|
|
93
|
+
patchFileHash: row.patch_file_hash,
|
|
94
|
+
patchStorageUri: row.patch_storage_uri
|
|
95
|
+
});
|
|
96
|
+
const rowToBundle = (row, patchRows = []) => {
|
|
97
|
+
const patches = patchRows.slice().sort(comparePatchRows).map(patchRowToArtifact);
|
|
98
|
+
return {
|
|
99
|
+
id: row.id,
|
|
100
|
+
platform: row.platform,
|
|
101
|
+
fileHash: row.file_hash,
|
|
102
|
+
gitCommitHash: row.git_commit_hash,
|
|
103
|
+
storageUri: row.storage_uri,
|
|
104
|
+
archiveByteSize: row.archive_byte_size,
|
|
105
|
+
metadata: (0, _hot_updater_core.stripBundleArtifactMetadata)(row.metadata),
|
|
106
|
+
manifestStorageUri: row.manifest_storage_uri,
|
|
107
|
+
manifestFileHash: row.manifest_file_hash,
|
|
108
|
+
assetBaseStorageUri: row.asset_base_storage_uri,
|
|
109
|
+
patches
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
const rowsToBundles = (bundleRows, patchRows, referencedBundleRows) => {
|
|
113
|
+
const ownerIds = new Set(bundleRows.map(({ id }) => id));
|
|
114
|
+
const baseIds = new Set(ownerIds);
|
|
115
|
+
for (const row of referencedBundleRows) baseIds.add(row.id);
|
|
116
|
+
const patchIds = /* @__PURE__ */ new Set();
|
|
117
|
+
const patchesByOwner = /* @__PURE__ */ new Map();
|
|
118
|
+
for (const patch of patchRows) {
|
|
119
|
+
if (patchIds.has(patch.id)) throw new BundleRowHydrationError({
|
|
120
|
+
reason: BundleRowHydrationErrorReason.duplicatePatchId,
|
|
121
|
+
patchId: patch.id,
|
|
122
|
+
bundleId: patch.bundle_id
|
|
123
|
+
});
|
|
124
|
+
patchIds.add(patch.id);
|
|
125
|
+
if (!ownerIds.has(patch.bundle_id)) throw new BundleRowHydrationError({
|
|
126
|
+
reason: BundleRowHydrationErrorReason.orphanPatchOwner,
|
|
127
|
+
patchId: patch.id,
|
|
128
|
+
bundleId: patch.bundle_id
|
|
129
|
+
});
|
|
130
|
+
if (!baseIds.has(patch.base_bundle_id)) throw new BundleRowHydrationError({
|
|
131
|
+
reason: BundleRowHydrationErrorReason.orphanPatchBase,
|
|
132
|
+
patchId: patch.id,
|
|
133
|
+
bundleId: patch.base_bundle_id
|
|
134
|
+
});
|
|
135
|
+
const ownerPatches = patchesByOwner.get(patch.bundle_id) ?? [];
|
|
136
|
+
ownerPatches.push(patch);
|
|
137
|
+
patchesByOwner.set(patch.bundle_id, ownerPatches);
|
|
138
|
+
}
|
|
139
|
+
return bundleRows.map((row) => rowToBundle(row, patchesByOwner.get(row.id) ?? []));
|
|
140
|
+
};
|
|
141
|
+
//#endregion
|
|
142
|
+
exports.BundleRowHydrationError = BundleRowHydrationError;
|
|
143
|
+
exports.BundleRowHydrationErrorReason = BundleRowHydrationErrorReason;
|
|
144
|
+
exports.bundleToPatchRows = bundleToPatchRows;
|
|
145
|
+
exports.bundleToRow = bundleToRow;
|
|
146
|
+
exports.releaseRowToRelease = releaseRowToRelease;
|
|
147
|
+
exports.releaseToRow = releaseToRow;
|
|
148
|
+
exports.rowToBundle = rowToBundle;
|
|
149
|
+
exports.rowsToBundles = rowsToBundles;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { BundlePatchRow, BundleRow, ReleaseRow } from "./types/databaseRows.cjs";
|
|
2
|
+
import { Bundle, Release } from "@hot-updater/core";
|
|
3
|
+
|
|
4
|
+
//#region src/databaseRows.d.ts
|
|
5
|
+
declare const releaseToRow: (release: Release, scopeKey: string) => ReleaseRow;
|
|
6
|
+
declare const releaseRowToRelease: (row: ReleaseRow) => Release;
|
|
7
|
+
declare const BundleRowHydrationErrorReason: {
|
|
8
|
+
readonly duplicatePatchId: "duplicate_patch_id";
|
|
9
|
+
readonly orphanPatchOwner: "orphan_patch_owner";
|
|
10
|
+
readonly orphanPatchBase: "orphan_patch_base";
|
|
11
|
+
};
|
|
12
|
+
type BundleRowHydrationErrorReason = (typeof BundleRowHydrationErrorReason)[keyof typeof BundleRowHydrationErrorReason];
|
|
13
|
+
type BundleRowHydrationErrorInput = {
|
|
14
|
+
readonly reason: BundleRowHydrationErrorReason;
|
|
15
|
+
readonly patchId: string;
|
|
16
|
+
readonly bundleId: string;
|
|
17
|
+
};
|
|
18
|
+
declare class BundleRowHydrationError extends Error {
|
|
19
|
+
readonly name = "BundleRowHydrationError";
|
|
20
|
+
readonly reason: BundleRowHydrationErrorReason;
|
|
21
|
+
readonly patchId: string;
|
|
22
|
+
readonly bundleId: string;
|
|
23
|
+
constructor({
|
|
24
|
+
reason,
|
|
25
|
+
patchId,
|
|
26
|
+
bundleId
|
|
27
|
+
}: BundleRowHydrationErrorInput);
|
|
28
|
+
}
|
|
29
|
+
declare const bundleToRow: (bundle: Bundle) => BundleRow;
|
|
30
|
+
declare const bundleToPatchRows: (bundle: Bundle) => BundlePatchRow[];
|
|
31
|
+
declare const rowToBundle: (row: BundleRow, patchRows?: readonly BundlePatchRow[]) => Bundle;
|
|
32
|
+
declare const rowsToBundles: (bundleRows: readonly BundleRow[], patchRows: readonly BundlePatchRow[], referencedBundleRows: readonly BundleRow[]) => Bundle[];
|
|
33
|
+
//#endregion
|
|
34
|
+
export { BundleRowHydrationError, BundleRowHydrationErrorReason, bundleToPatchRows, bundleToRow, releaseRowToRelease, releaseToRow, rowToBundle, rowsToBundles };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { BundlePatchRow, BundleRow, ReleaseRow } from "./types/databaseRows.mjs";
|
|
2
|
+
import { Bundle, Release } from "@hot-updater/core";
|
|
3
|
+
|
|
4
|
+
//#region src/databaseRows.d.ts
|
|
5
|
+
declare const releaseToRow: (release: Release, scopeKey: string) => ReleaseRow;
|
|
6
|
+
declare const releaseRowToRelease: (row: ReleaseRow) => Release;
|
|
7
|
+
declare const BundleRowHydrationErrorReason: {
|
|
8
|
+
readonly duplicatePatchId: "duplicate_patch_id";
|
|
9
|
+
readonly orphanPatchOwner: "orphan_patch_owner";
|
|
10
|
+
readonly orphanPatchBase: "orphan_patch_base";
|
|
11
|
+
};
|
|
12
|
+
type BundleRowHydrationErrorReason = (typeof BundleRowHydrationErrorReason)[keyof typeof BundleRowHydrationErrorReason];
|
|
13
|
+
type BundleRowHydrationErrorInput = {
|
|
14
|
+
readonly reason: BundleRowHydrationErrorReason;
|
|
15
|
+
readonly patchId: string;
|
|
16
|
+
readonly bundleId: string;
|
|
17
|
+
};
|
|
18
|
+
declare class BundleRowHydrationError extends Error {
|
|
19
|
+
readonly name = "BundleRowHydrationError";
|
|
20
|
+
readonly reason: BundleRowHydrationErrorReason;
|
|
21
|
+
readonly patchId: string;
|
|
22
|
+
readonly bundleId: string;
|
|
23
|
+
constructor({
|
|
24
|
+
reason,
|
|
25
|
+
patchId,
|
|
26
|
+
bundleId
|
|
27
|
+
}: BundleRowHydrationErrorInput);
|
|
28
|
+
}
|
|
29
|
+
declare const bundleToRow: (bundle: Bundle) => BundleRow;
|
|
30
|
+
declare const bundleToPatchRows: (bundle: Bundle) => BundlePatchRow[];
|
|
31
|
+
declare const rowToBundle: (row: BundleRow, patchRows?: readonly BundlePatchRow[]) => Bundle;
|
|
32
|
+
declare const rowsToBundles: (bundleRows: readonly BundleRow[], patchRows: readonly BundlePatchRow[], referencedBundleRows: readonly BundleRow[]) => Bundle[];
|
|
33
|
+
//#endregion
|
|
34
|
+
export { BundleRowHydrationError, BundleRowHydrationErrorReason, bundleToPatchRows, bundleToRow, releaseRowToRelease, releaseToRow, rowToBundle, rowsToBundles };
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { bundleMetadataToRow } from "./databaseMetadata.mjs";
|
|
2
|
+
import { getAssetBaseStorageUri, getBundlePatches, getManifestFileHash, getManifestStorageUri, stripBundleArtifactMetadata } from "@hot-updater/core";
|
|
3
|
+
//#region src/databaseRows.ts
|
|
4
|
+
const releaseToRow = (release, scopeKey) => ({
|
|
5
|
+
id: release.id,
|
|
6
|
+
revision: release.revision,
|
|
7
|
+
scope_key: scopeKey,
|
|
8
|
+
channel_id: release.channelId,
|
|
9
|
+
platform: release.platform,
|
|
10
|
+
kind: release.kind,
|
|
11
|
+
bundle_id: release.bundleId,
|
|
12
|
+
strategy: release.strategy,
|
|
13
|
+
target_app_version: release.targetAppVersion,
|
|
14
|
+
fingerprint_hash: release.fingerprintHash,
|
|
15
|
+
enabled: release.enabled,
|
|
16
|
+
should_force_update: release.shouldForceUpdate,
|
|
17
|
+
message: release.message,
|
|
18
|
+
rollout_cohort_count: release.rolloutCohortCount,
|
|
19
|
+
target_cohorts: release.targetCohorts,
|
|
20
|
+
operation: release.operation,
|
|
21
|
+
source_release_id: release.sourceReleaseId,
|
|
22
|
+
created_at_ms: release.createdAtMs,
|
|
23
|
+
updated_at_ms: release.updatedAtMs
|
|
24
|
+
});
|
|
25
|
+
const releaseRowToRelease = (row) => ({
|
|
26
|
+
id: row.id,
|
|
27
|
+
revision: row.revision,
|
|
28
|
+
channelId: row.channel_id,
|
|
29
|
+
platform: row.platform,
|
|
30
|
+
kind: row.kind,
|
|
31
|
+
bundleId: row.bundle_id,
|
|
32
|
+
strategy: row.strategy,
|
|
33
|
+
targetAppVersion: row.target_app_version,
|
|
34
|
+
fingerprintHash: row.fingerprint_hash,
|
|
35
|
+
enabled: row.enabled,
|
|
36
|
+
shouldForceUpdate: row.should_force_update,
|
|
37
|
+
message: row.message,
|
|
38
|
+
rolloutCohortCount: row.rollout_cohort_count,
|
|
39
|
+
targetCohorts: row.target_cohorts,
|
|
40
|
+
operation: row.operation,
|
|
41
|
+
sourceReleaseId: row.source_release_id,
|
|
42
|
+
createdAtMs: row.created_at_ms,
|
|
43
|
+
updatedAtMs: row.updated_at_ms
|
|
44
|
+
});
|
|
45
|
+
const BundleRowHydrationErrorReason = {
|
|
46
|
+
duplicatePatchId: "duplicate_patch_id",
|
|
47
|
+
orphanPatchOwner: "orphan_patch_owner",
|
|
48
|
+
orphanPatchBase: "orphan_patch_base"
|
|
49
|
+
};
|
|
50
|
+
var BundleRowHydrationError = class extends Error {
|
|
51
|
+
name = "BundleRowHydrationError";
|
|
52
|
+
reason;
|
|
53
|
+
patchId;
|
|
54
|
+
bundleId;
|
|
55
|
+
constructor({ reason, patchId, bundleId }) {
|
|
56
|
+
super(`Cannot hydrate bundle rows: ${reason} for patch "${patchId}" and bundle "${bundleId}".`);
|
|
57
|
+
this.reason = reason;
|
|
58
|
+
this.patchId = patchId;
|
|
59
|
+
this.bundleId = bundleId;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const bundleToRow = (bundle) => {
|
|
63
|
+
const metadata = bundleMetadataToRow(bundle.metadata);
|
|
64
|
+
return {
|
|
65
|
+
id: bundle.id,
|
|
66
|
+
platform: bundle.platform,
|
|
67
|
+
file_hash: bundle.fileHash,
|
|
68
|
+
git_commit_hash: bundle.gitCommitHash,
|
|
69
|
+
storage_uri: bundle.storageUri,
|
|
70
|
+
archive_byte_size: bundle.archiveByteSize,
|
|
71
|
+
metadata,
|
|
72
|
+
manifest_storage_uri: getManifestStorageUri(bundle),
|
|
73
|
+
manifest_file_hash: getManifestFileHash(bundle),
|
|
74
|
+
asset_base_storage_uri: getAssetBaseStorageUri(bundle)
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
const bundleToPatchRows = (bundle) => getBundlePatches(bundle).map((patch, orderIndex) => ({
|
|
78
|
+
id: `${bundle.id}:${patch.baseBundleId}`,
|
|
79
|
+
bundle_id: bundle.id,
|
|
80
|
+
base_bundle_id: patch.baseBundleId,
|
|
81
|
+
base_file_hash: patch.baseFileHash,
|
|
82
|
+
patch_file_hash: patch.patchFileHash,
|
|
83
|
+
patch_storage_uri: patch.patchStorageUri,
|
|
84
|
+
byte_size: patch.byteSize,
|
|
85
|
+
order_index: orderIndex
|
|
86
|
+
}));
|
|
87
|
+
const comparePatchRows = (left, right) => left.order_index - right.order_index || left.id.localeCompare(right.id);
|
|
88
|
+
const patchRowToArtifact = (row) => ({
|
|
89
|
+
baseBundleId: row.base_bundle_id,
|
|
90
|
+
baseFileHash: row.base_file_hash,
|
|
91
|
+
byteSize: row.byte_size,
|
|
92
|
+
patchFileHash: row.patch_file_hash,
|
|
93
|
+
patchStorageUri: row.patch_storage_uri
|
|
94
|
+
});
|
|
95
|
+
const rowToBundle = (row, patchRows = []) => {
|
|
96
|
+
const patches = patchRows.slice().sort(comparePatchRows).map(patchRowToArtifact);
|
|
97
|
+
return {
|
|
98
|
+
id: row.id,
|
|
99
|
+
platform: row.platform,
|
|
100
|
+
fileHash: row.file_hash,
|
|
101
|
+
gitCommitHash: row.git_commit_hash,
|
|
102
|
+
storageUri: row.storage_uri,
|
|
103
|
+
archiveByteSize: row.archive_byte_size,
|
|
104
|
+
metadata: stripBundleArtifactMetadata(row.metadata),
|
|
105
|
+
manifestStorageUri: row.manifest_storage_uri,
|
|
106
|
+
manifestFileHash: row.manifest_file_hash,
|
|
107
|
+
assetBaseStorageUri: row.asset_base_storage_uri,
|
|
108
|
+
patches
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
const rowsToBundles = (bundleRows, patchRows, referencedBundleRows) => {
|
|
112
|
+
const ownerIds = new Set(bundleRows.map(({ id }) => id));
|
|
113
|
+
const baseIds = new Set(ownerIds);
|
|
114
|
+
for (const row of referencedBundleRows) baseIds.add(row.id);
|
|
115
|
+
const patchIds = /* @__PURE__ */ new Set();
|
|
116
|
+
const patchesByOwner = /* @__PURE__ */ new Map();
|
|
117
|
+
for (const patch of patchRows) {
|
|
118
|
+
if (patchIds.has(patch.id)) throw new BundleRowHydrationError({
|
|
119
|
+
reason: BundleRowHydrationErrorReason.duplicatePatchId,
|
|
120
|
+
patchId: patch.id,
|
|
121
|
+
bundleId: patch.bundle_id
|
|
122
|
+
});
|
|
123
|
+
patchIds.add(patch.id);
|
|
124
|
+
if (!ownerIds.has(patch.bundle_id)) throw new BundleRowHydrationError({
|
|
125
|
+
reason: BundleRowHydrationErrorReason.orphanPatchOwner,
|
|
126
|
+
patchId: patch.id,
|
|
127
|
+
bundleId: patch.bundle_id
|
|
128
|
+
});
|
|
129
|
+
if (!baseIds.has(patch.base_bundle_id)) throw new BundleRowHydrationError({
|
|
130
|
+
reason: BundleRowHydrationErrorReason.orphanPatchBase,
|
|
131
|
+
patchId: patch.id,
|
|
132
|
+
bundleId: patch.base_bundle_id
|
|
133
|
+
});
|
|
134
|
+
const ownerPatches = patchesByOwner.get(patch.bundle_id) ?? [];
|
|
135
|
+
ownerPatches.push(patch);
|
|
136
|
+
patchesByOwner.set(patch.bundle_id, ownerPatches);
|
|
137
|
+
}
|
|
138
|
+
return bundleRows.map((row) => rowToBundle(row, patchesByOwner.get(row.id) ?? []));
|
|
139
|
+
};
|
|
140
|
+
//#endregion
|
|
141
|
+
export { BundleRowHydrationError, BundleRowHydrationErrorReason, bundleToPatchRows, bundleToRow, releaseRowToRelease, releaseToRow, rowToBundle, rowsToBundles };
|