@hot-updater/plugin-core 1.0.0-rc.0 → 1.0.0-rc.2
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/_virtual/_rolldown/runtime.cjs +1 -1
- package/dist/assetStorageLayout.cjs +4 -2
- package/dist/assetStorageLayout.d.cts +5 -24
- package/dist/assetStorageLayout.d.mts +5 -24
- package/dist/assetStorageLayout.mjs +4 -2
- package/dist/calculatePagination.d.cts +0 -1
- package/dist/calculatePagination.d.mts +0 -1
- package/dist/compressionFormat.cjs +12 -5
- package/dist/compressionFormat.d.cts +1 -1
- package/dist/compressionFormat.d.mts +1 -1
- package/dist/compressionFormat.mjs +11 -4
- package/dist/contentAddressedAssets.d.cts +1 -4
- package/dist/contentAddressedAssets.d.mts +1 -4
- package/dist/createDatabasePlugin.cjs +162 -41
- package/dist/createDatabasePlugin.d.cts +3 -1
- package/dist/createDatabasePlugin.d.mts +3 -1
- package/dist/createDatabasePlugin.mjs +162 -42
- package/dist/createStoragePlugin.d.cts +0 -1
- package/dist/createStoragePlugin.d.mts +0 -1
- package/dist/databaseClient.cjs +6 -1
- package/dist/databaseClient.d.cts +1 -2
- package/dist/databaseClient.d.mts +1 -2
- package/dist/databaseClient.mjs +6 -2
- package/dist/databaseClientReads.cjs +3 -1
- package/dist/databaseClientReads.mjs +3 -2
- package/dist/databaseClientUpdates.cjs +2 -1
- package/dist/databaseClientUpdates.d.cts +1 -1
- package/dist/databaseClientUpdates.d.mts +1 -1
- package/dist/databaseClientUpdates.mjs +2 -0
- package/dist/databaseJsonValue.cjs +2 -0
- package/dist/databaseJsonValue.d.cts +1 -0
- package/dist/databaseJsonValue.d.mts +1 -0
- package/dist/databaseJsonValue.mjs +1 -1
- package/dist/databaseMetadata.cjs +0 -1
- package/dist/databasePluginCrud.cjs +3 -1
- package/dist/databasePluginCrud.d.cts +4 -1
- package/dist/databasePluginCrud.d.mts +4 -1
- package/dist/databasePluginCrud.mjs +4 -3
- package/dist/databasePluginCrudValidation.d.cts +6 -1
- package/dist/databasePluginCrudValidation.d.mts +6 -1
- package/dist/databasePluginCrudValidationErrors.cjs +1 -0
- package/dist/databasePluginCrudValidationErrors.mjs +1 -0
- package/dist/databasePluginCrudValidationFields.cjs +43 -13
- package/dist/databasePluginCrudValidationFields.d.cts +1 -1
- package/dist/databasePluginCrudValidationFields.d.mts +1 -1
- package/dist/databasePluginCrudValidationFields.mjs +41 -13
- package/dist/databasePluginCrudValidationMutations.cjs +20 -1
- package/dist/databasePluginCrudValidationMutations.d.cts +1 -1
- package/dist/databasePluginCrudValidationMutations.d.mts +1 -1
- package/dist/databasePluginCrudValidationMutations.mjs +20 -2
- package/dist/databasePluginCrudValidationQueries.d.cts +2 -1
- package/dist/databasePluginCrudValidationQueries.d.mts +2 -1
- package/dist/databasePluginCrudValidationRows.d.cts +1 -1
- package/dist/databasePluginCrudValidationRows.d.mts +1 -1
- package/dist/databaseRows.cjs +0 -1
- package/dist/databaseRows.d.cts +2 -6
- package/dist/databaseRows.d.mts +2 -6
- package/dist/index.cjs +4 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.mts +4 -3
- package/dist/index.mjs +2 -1
- package/dist/insightsContract.cjs +157 -0
- package/dist/insightsContract.d.cts +11 -0
- package/dist/insightsContract.d.mts +11 -0
- package/dist/insightsContract.mjs +153 -0
- package/dist/internal.d.cts +5 -4
- package/dist/internal.d.mts +5 -4
- package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/comparison-DenM3wCn.cjs +136 -0
- package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/comparison-DenM3wCn.mjs +116 -0
- package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/range-DvX-Y6iv.cjs +167 -0
- package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/range-DvX-Y6iv.mjs +165 -0
- package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/set-CC5YeoYX.cjs +42 -0
- package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/set-CC5YeoYX.mjs +39 -0
- package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/version-CQ98ZBpL.cjs +39 -0
- package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/version-CQ98ZBpL.mjs +37 -0
- package/dist/paginateBundles.d.cts +1 -8
- package/dist/paginateBundles.d.mts +1 -8
- package/dist/parseStorageUri.d.cts +1 -5
- package/dist/parseStorageUri.d.mts +1 -5
- package/dist/queryBundles.d.cts +0 -1
- package/dist/queryBundles.d.mts +0 -1
- package/dist/releaseCatalogCompiler.cjs +15 -12
- package/dist/releaseCatalogCompiler.d.cts +0 -1
- package/dist/releaseCatalogCompiler.d.mts +0 -1
- package/dist/releaseCatalogCompiler.mjs +11 -7
- package/dist/releaseCatalogMutation.cjs +1 -1
- package/dist/releaseCatalogMutation.d.cts +1 -1
- package/dist/releaseCatalogMutation.d.mts +1 -1
- package/dist/releaseCatalogMutation.mjs +1 -0
- package/dist/releaseManagement.cjs +3 -2
- package/dist/releaseManagement.d.cts +1 -1
- package/dist/releaseManagement.d.mts +1 -1
- package/dist/releaseManagement.mjs +3 -1
- package/dist/remoteBundleSigning.cjs +5 -7
- package/dist/remoteBundleSigning.d.cts +2 -15
- package/dist/remoteBundleSigning.d.mts +2 -15
- package/dist/remoteBundleSigning.mjs +5 -7
- package/dist/requestBundleCache.d.cts +1 -2
- package/dist/requestBundleCache.d.mts +1 -2
- package/dist/semverSatisfies.cjs +4 -3
- package/dist/semverSatisfies.mjs +2 -1
- package/dist/storageDownloadPath.cjs +2 -1
- package/dist/storageDownloadPath.d.cts +1 -3
- package/dist/storageDownloadPath.d.mts +1 -3
- package/dist/storageDownloadPath.mjs +2 -1
- package/dist/types/database.d.cts +4 -3
- package/dist/types/database.d.mts +4 -3
- package/dist/types/databaseFields.cjs +13 -0
- package/dist/types/databaseFields.d.cts +1 -0
- package/dist/types/databaseFields.d.mts +1 -0
- package/dist/types/databaseFields.mjs +13 -0
- package/dist/types/databaseOperations.d.cts +26 -15
- package/dist/types/databaseOperations.d.mts +26 -15
- package/dist/types/databasePlugin.d.cts +72 -14
- package/dist/types/databasePlugin.d.mts +72 -14
- package/dist/types/databaseQuery.d.cts +2 -3
- package/dist/types/databaseQuery.d.mts +2 -3
- package/dist/types/databaseRows.d.cts +3 -2
- package/dist/types/databaseRows.d.mts +3 -2
- package/dist/types/index.d.cts +15 -11
- package/dist/types/index.d.mts +15 -11
- package/dist/types/internal.d.cts +5 -4
- package/dist/types/internal.d.mts +5 -4
- package/dist/types/public.d.cts +4 -3
- package/dist/types/public.d.mts +4 -3
- package/dist/types/utils.d.cts +1 -1
- package/dist/types/utils.d.mts +1 -1
- package/dist/uuidv7.cjs +7 -2
- package/dist/uuidv7.d.cts +0 -1
- package/dist/uuidv7.d.mts +0 -1
- package/dist/uuidv7.mjs +1 -1
- package/package.json +3 -3
- package/dist/node_modules/.pnpm/verkit@0.3.2/node_modules/verkit/dist/index.cjs +0 -345
- package/dist/node_modules/.pnpm/verkit@0.3.2/node_modules/verkit/dist/index.mjs +0 -341
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
const require_databasePluginCrudValidationErrors = require("./databasePluginCrudValidationErrors.cjs");
|
|
2
|
+
const require_databasePluginCrudValidationFields = require("./databasePluginCrudValidationFields.cjs");
|
|
3
|
+
const require_databasePluginCrudValidationRows = require("./databasePluginCrudValidationRows.cjs");
|
|
4
|
+
let _hot_updater_core = require("@hot-updater/core");
|
|
5
|
+
//#region src/insightsContract.ts
|
|
6
|
+
const encoder = new TextEncoder();
|
|
7
|
+
/** Exact UTF-8 byte ordering, without case folding or Unicode normalization. */
|
|
8
|
+
const compareInsightsText = (left, right) => {
|
|
9
|
+
const a = encoder.encode(left);
|
|
10
|
+
const b = encoder.encode(right);
|
|
11
|
+
for (let index = 0; index < Math.min(a.length, b.length); index += 1) if (a[index] !== b[index]) return a[index] - b[index];
|
|
12
|
+
return a.length - b.length;
|
|
13
|
+
};
|
|
14
|
+
const isWellFormedText = (value) => {
|
|
15
|
+
for (const character of value) {
|
|
16
|
+
const point = character.codePointAt(0);
|
|
17
|
+
if (point >= 55296 && point <= 57343) return false;
|
|
18
|
+
}
|
|
19
|
+
return true;
|
|
20
|
+
};
|
|
21
|
+
const isIdentity = (value) => typeof value === "string" && value.length > 0 && value.length <= 255 && isWellFormedText(value);
|
|
22
|
+
const isText = (value) => typeof value === "string" && value.length > 0 && isWellFormedText(value);
|
|
23
|
+
const isTimestamp = (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
24
|
+
const isLimit = (value) => isTimestamp(value) && value >= 1 && value <= 101;
|
|
25
|
+
const hasOnlyKeys = (value, keys) => Object.keys(value).every((key) => keys.includes(key));
|
|
26
|
+
const hasScope = (value) => (value.platform === "ios" || value.platform === "android") && isText(value.channel);
|
|
27
|
+
const isBundleFilter = (value, withKind = false) => {
|
|
28
|
+
if (!require_databasePluginCrudValidationFields.isRecord(value) || !hasScope(value)) return false;
|
|
29
|
+
const keys = [
|
|
30
|
+
"platform",
|
|
31
|
+
"channel",
|
|
32
|
+
"type",
|
|
33
|
+
...withKind ? ["kind"] : []
|
|
34
|
+
];
|
|
35
|
+
return value.type === "RECOVERED" ? isText(value.fromBundleId) && hasOnlyKeys(value, [...keys, "fromBundleId"]) : (value.type === "UPDATE_APPLIED" || value.type === "RELEASE_ADOPTED") && isText(value.toBundleId) && hasOnlyKeys(value, [...keys, "toBundleId"]);
|
|
36
|
+
};
|
|
37
|
+
const isEventFilter = (value) => {
|
|
38
|
+
if (!require_databasePluginCrudValidationFields.isRecord(value)) return false;
|
|
39
|
+
if (value.kind === "all") return hasOnlyKeys(value, ["kind"]);
|
|
40
|
+
if (value.kind === "installationMovement") return isIdentity(value.installId) && hasOnlyKeys(value, ["kind", "installId"]);
|
|
41
|
+
return value.kind === "bundle" && isBundleFilter(value, true);
|
|
42
|
+
};
|
|
43
|
+
const validateRow = (model, row, result = false) => {
|
|
44
|
+
try {
|
|
45
|
+
require_databasePluginCrudValidationRows.validateCreateData(model, row);
|
|
46
|
+
if (!require_databasePluginCrudValidationFields.isRecord(row) || typeof row.id !== "string" || !(0, _hot_updater_core.isUUIDv7)(row.id) || Object.values(row).some((value) => typeof value === "string" && !isWellFormedText(value))) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
|
|
47
|
+
} catch (error) {
|
|
48
|
+
if (result) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-result");
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
/** Prepare the full latest-state candidate; the provider owns winning writes. */
|
|
53
|
+
const toInsightsInstallationRow = (event) => {
|
|
54
|
+
validateRow("bundle_events", event);
|
|
55
|
+
return {
|
|
56
|
+
id: event.id,
|
|
57
|
+
install_id: event.install_id,
|
|
58
|
+
user_id: event.user_id,
|
|
59
|
+
username: event.username,
|
|
60
|
+
to_bundle_id: event.to_bundle_id,
|
|
61
|
+
type: event.type,
|
|
62
|
+
platform: event.platform,
|
|
63
|
+
app_version: event.app_version,
|
|
64
|
+
channel: event.channel,
|
|
65
|
+
cohort: event.cohort,
|
|
66
|
+
received_at_ms: event.received_at_ms
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
/** Release adoption and unchanged lifecycle reports are not bundle movements. */
|
|
70
|
+
const isInsightsMovementEvent = (event) => event.type === "UPDATE_APPLIED" || event.type === "RECOVERED";
|
|
71
|
+
const matchesInsightsEventFilter = (event, filter) => {
|
|
72
|
+
if (filter.kind === "all") return true;
|
|
73
|
+
if (filter.kind === "installationMovement") return event.install_id === filter.installId && isInsightsMovementEvent(event);
|
|
74
|
+
return event.type === filter.type && event.platform === filter.platform && event.channel === filter.channel && (filter.type === "RECOVERED" ? event.from_bundle_id === filter.fromBundleId : event.to_bundle_id === filter.toBundleId);
|
|
75
|
+
};
|
|
76
|
+
const invalidQuery = () => {
|
|
77
|
+
throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-query");
|
|
78
|
+
};
|
|
79
|
+
const invalidResult = () => {
|
|
80
|
+
throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-result");
|
|
81
|
+
};
|
|
82
|
+
const validateCount = (count) => isTimestamp(count) ? count : invalidResult();
|
|
83
|
+
/** Validate custom and bundled providers at the same public boundary. */
|
|
84
|
+
const createValidatedInsightsModel = (model) => ({
|
|
85
|
+
async record(input) {
|
|
86
|
+
if (!require_databasePluginCrudValidationFields.isRecord(input) || !hasOnlyKeys(input, ["event", "installation"])) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
|
|
87
|
+
const expected = toInsightsInstallationRow(input.event);
|
|
88
|
+
validateRow("bundle_installations", input.installation);
|
|
89
|
+
if (Object.entries(expected).some(([field, value]) => Reflect.get(input.installation, field) !== value)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
|
|
90
|
+
await model.record(input);
|
|
91
|
+
},
|
|
92
|
+
async listEvents(input) {
|
|
93
|
+
if (!require_databasePluginCrudValidationFields.isRecord(input) || !hasOnlyKeys(input, [
|
|
94
|
+
"filter",
|
|
95
|
+
"sinceMs",
|
|
96
|
+
"beforeReceivedAtMs",
|
|
97
|
+
"after",
|
|
98
|
+
"limit"
|
|
99
|
+
]) || !isEventFilter(input.filter) || !isLimit(input.limit) || !isTimestamp(input.beforeReceivedAtMs) || input.sinceMs !== void 0 && !isTimestamp(input.sinceMs)) invalidQuery();
|
|
100
|
+
const sinceMs = input.sinceMs ?? 0;
|
|
101
|
+
if (sinceMs > input.beforeReceivedAtMs || input.after !== void 0 && (!require_databasePluginCrudValidationFields.isRecord(input.after) || !hasOnlyKeys(input.after, ["receivedAtMs", "id"]) || !isTimestamp(input.after.receivedAtMs) || typeof input.after.id !== "string" || !(0, _hot_updater_core.isUUIDv7)(input.after.id) || input.after.receivedAtMs < sinceMs || input.after.receivedAtMs >= input.beforeReceivedAtMs)) invalidQuery();
|
|
102
|
+
const rows = await model.listEvents(input);
|
|
103
|
+
if (!Array.isArray(rows) || rows.length > input.limit) invalidResult();
|
|
104
|
+
let previous = input.after;
|
|
105
|
+
for (const row of rows) {
|
|
106
|
+
validateRow("bundle_events", row, true);
|
|
107
|
+
if (row.received_at_ms < sinceMs || row.received_at_ms >= input.beforeReceivedAtMs || !matchesInsightsEventFilter(row, input.filter) || previous !== void 0 && (row.received_at_ms > previous.receivedAtMs || row.received_at_ms === previous.receivedAtMs && row.id >= previous.id)) invalidResult();
|
|
108
|
+
previous = {
|
|
109
|
+
receivedAtMs: row.received_at_ms,
|
|
110
|
+
id: row.id
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return rows;
|
|
114
|
+
},
|
|
115
|
+
async findInstallations(input) {
|
|
116
|
+
if (!require_databasePluginCrudValidationFields.isRecord(input)) invalidQuery();
|
|
117
|
+
if ("installId" in input) {
|
|
118
|
+
if (!hasOnlyKeys(input, ["installId"]) || !isIdentity(input.installId)) invalidQuery();
|
|
119
|
+
} else if (!hasOnlyKeys(input, [
|
|
120
|
+
"userId",
|
|
121
|
+
"afterInstallId",
|
|
122
|
+
"limit"
|
|
123
|
+
]) || !isIdentity(input.userId) || !isLimit(input.limit) || input.afterInstallId !== void 0 && !isIdentity(input.afterInstallId)) invalidQuery();
|
|
124
|
+
const rows = await model.findInstallations(input);
|
|
125
|
+
if (!Array.isArray(rows) || rows.length > ("installId" in input ? 1 : input.limit)) invalidResult();
|
|
126
|
+
let previous = "installId" in input ? void 0 : input.afterInstallId;
|
|
127
|
+
for (const row of rows) {
|
|
128
|
+
validateRow("bundle_installations", row, true);
|
|
129
|
+
if ("installId" in input ? row.install_id !== input.installId : row.user_id !== input.userId || previous !== void 0 && compareInsightsText(row.install_id, previous) <= 0) invalidResult();
|
|
130
|
+
previous = row.install_id;
|
|
131
|
+
}
|
|
132
|
+
return rows;
|
|
133
|
+
},
|
|
134
|
+
async countInstallations(input) {
|
|
135
|
+
if (!require_databasePluginCrudValidationFields.isRecord(input) || !hasOnlyKeys(input, [
|
|
136
|
+
"platform",
|
|
137
|
+
"channel",
|
|
138
|
+
"sinceMs",
|
|
139
|
+
"bundleId"
|
|
140
|
+
]) || !hasScope(input) || !isTimestamp(input.sinceMs) || input.bundleId !== void 0 && !isText(input.bundleId)) invalidQuery();
|
|
141
|
+
return validateCount(await model.countInstallations(input));
|
|
142
|
+
},
|
|
143
|
+
async countEvents(input) {
|
|
144
|
+
if (!require_databasePluginCrudValidationFields.isRecord(input) || !hasOnlyKeys(input, [
|
|
145
|
+
"filter",
|
|
146
|
+
"sinceMs",
|
|
147
|
+
"beforeReceivedAtMs"
|
|
148
|
+
]) || !isBundleFilter(input.filter) || !isTimestamp(input.sinceMs) || !isTimestamp(input.beforeReceivedAtMs) || input.sinceMs > input.beforeReceivedAtMs) invalidQuery();
|
|
149
|
+
return validateCount(await model.countEvents(input));
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
//#endregion
|
|
153
|
+
exports.compareInsightsText = compareInsightsText;
|
|
154
|
+
exports.createValidatedInsightsModel = createValidatedInsightsModel;
|
|
155
|
+
exports.isInsightsMovementEvent = isInsightsMovementEvent;
|
|
156
|
+
exports.matchesInsightsEventFilter = matchesInsightsEventFilter;
|
|
157
|
+
exports.toInsightsInstallationRow = toInsightsInstallationRow;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BundleEventRow, InsightsInstallationRow } from "./types/databaseRows.cjs";
|
|
2
|
+
import "./types/index.cjs";
|
|
3
|
+
//#region src/insightsContract.d.ts
|
|
4
|
+
/** Exact UTF-8 byte ordering, without case folding or Unicode normalization. */
|
|
5
|
+
declare const compareInsightsText: (left: string, right: string) => number;
|
|
6
|
+
/** Prepare the full latest-state candidate; the provider owns winning writes. */
|
|
7
|
+
declare const toInsightsInstallationRow: (event: BundleEventRow) => InsightsInstallationRow;
|
|
8
|
+
/** Release adoption and unchanged lifecycle reports are not bundle movements. */
|
|
9
|
+
declare const isInsightsMovementEvent: (event: Pick<BundleEventRow, "type">) => boolean;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { compareInsightsText, isInsightsMovementEvent, toInsightsInstallationRow };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BundleEventRow, InsightsInstallationRow } from "./types/databaseRows.mjs";
|
|
2
|
+
import "./types/index.mjs";
|
|
3
|
+
//#region src/insightsContract.d.ts
|
|
4
|
+
/** Exact UTF-8 byte ordering, without case folding or Unicode normalization. */
|
|
5
|
+
declare const compareInsightsText: (left: string, right: string) => number;
|
|
6
|
+
/** Prepare the full latest-state candidate; the provider owns winning writes. */
|
|
7
|
+
declare const toInsightsInstallationRow: (event: BundleEventRow) => InsightsInstallationRow;
|
|
8
|
+
/** Release adoption and unchanged lifecycle reports are not bundle movements. */
|
|
9
|
+
declare const isInsightsMovementEvent: (event: Pick<BundleEventRow, "type">) => boolean;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { compareInsightsText, isInsightsMovementEvent, toInsightsInstallationRow };
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { DatabasePluginInputError } from "./databasePluginCrudValidationErrors.mjs";
|
|
2
|
+
import { isUUIDv7 } from "./uuidv7.mjs";
|
|
3
|
+
import { isRecord } from "./databasePluginCrudValidationFields.mjs";
|
|
4
|
+
import { validateCreateData } from "./databasePluginCrudValidationRows.mjs";
|
|
5
|
+
//#region src/insightsContract.ts
|
|
6
|
+
const encoder = new TextEncoder();
|
|
7
|
+
/** Exact UTF-8 byte ordering, without case folding or Unicode normalization. */
|
|
8
|
+
const compareInsightsText = (left, right) => {
|
|
9
|
+
const a = encoder.encode(left);
|
|
10
|
+
const b = encoder.encode(right);
|
|
11
|
+
for (let index = 0; index < Math.min(a.length, b.length); index += 1) if (a[index] !== b[index]) return a[index] - b[index];
|
|
12
|
+
return a.length - b.length;
|
|
13
|
+
};
|
|
14
|
+
const isWellFormedText = (value) => {
|
|
15
|
+
for (const character of value) {
|
|
16
|
+
const point = character.codePointAt(0);
|
|
17
|
+
if (point >= 55296 && point <= 57343) return false;
|
|
18
|
+
}
|
|
19
|
+
return true;
|
|
20
|
+
};
|
|
21
|
+
const isIdentity = (value) => typeof value === "string" && value.length > 0 && value.length <= 255 && isWellFormedText(value);
|
|
22
|
+
const isText = (value) => typeof value === "string" && value.length > 0 && isWellFormedText(value);
|
|
23
|
+
const isTimestamp = (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
24
|
+
const isLimit = (value) => isTimestamp(value) && value >= 1 && value <= 101;
|
|
25
|
+
const hasOnlyKeys = (value, keys) => Object.keys(value).every((key) => keys.includes(key));
|
|
26
|
+
const hasScope = (value) => (value.platform === "ios" || value.platform === "android") && isText(value.channel);
|
|
27
|
+
const isBundleFilter = (value, withKind = false) => {
|
|
28
|
+
if (!isRecord(value) || !hasScope(value)) return false;
|
|
29
|
+
const keys = [
|
|
30
|
+
"platform",
|
|
31
|
+
"channel",
|
|
32
|
+
"type",
|
|
33
|
+
...withKind ? ["kind"] : []
|
|
34
|
+
];
|
|
35
|
+
return value.type === "RECOVERED" ? isText(value.fromBundleId) && hasOnlyKeys(value, [...keys, "fromBundleId"]) : (value.type === "UPDATE_APPLIED" || value.type === "RELEASE_ADOPTED") && isText(value.toBundleId) && hasOnlyKeys(value, [...keys, "toBundleId"]);
|
|
36
|
+
};
|
|
37
|
+
const isEventFilter = (value) => {
|
|
38
|
+
if (!isRecord(value)) return false;
|
|
39
|
+
if (value.kind === "all") return hasOnlyKeys(value, ["kind"]);
|
|
40
|
+
if (value.kind === "installationMovement") return isIdentity(value.installId) && hasOnlyKeys(value, ["kind", "installId"]);
|
|
41
|
+
return value.kind === "bundle" && isBundleFilter(value, true);
|
|
42
|
+
};
|
|
43
|
+
const validateRow = (model, row, result = false) => {
|
|
44
|
+
try {
|
|
45
|
+
validateCreateData(model, row);
|
|
46
|
+
if (!isRecord(row) || typeof row.id !== "string" || !isUUIDv7(row.id) || Object.values(row).some((value) => typeof value === "string" && !isWellFormedText(value))) throw new DatabasePluginInputError("invalid-data");
|
|
47
|
+
} catch (error) {
|
|
48
|
+
if (result) throw new DatabasePluginInputError("invalid-result");
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
/** Prepare the full latest-state candidate; the provider owns winning writes. */
|
|
53
|
+
const toInsightsInstallationRow = (event) => {
|
|
54
|
+
validateRow("bundle_events", event);
|
|
55
|
+
return {
|
|
56
|
+
id: event.id,
|
|
57
|
+
install_id: event.install_id,
|
|
58
|
+
user_id: event.user_id,
|
|
59
|
+
username: event.username,
|
|
60
|
+
to_bundle_id: event.to_bundle_id,
|
|
61
|
+
type: event.type,
|
|
62
|
+
platform: event.platform,
|
|
63
|
+
app_version: event.app_version,
|
|
64
|
+
channel: event.channel,
|
|
65
|
+
cohort: event.cohort,
|
|
66
|
+
received_at_ms: event.received_at_ms
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
/** Release adoption and unchanged lifecycle reports are not bundle movements. */
|
|
70
|
+
const isInsightsMovementEvent = (event) => event.type === "UPDATE_APPLIED" || event.type === "RECOVERED";
|
|
71
|
+
const matchesInsightsEventFilter = (event, filter) => {
|
|
72
|
+
if (filter.kind === "all") return true;
|
|
73
|
+
if (filter.kind === "installationMovement") return event.install_id === filter.installId && isInsightsMovementEvent(event);
|
|
74
|
+
return event.type === filter.type && event.platform === filter.platform && event.channel === filter.channel && (filter.type === "RECOVERED" ? event.from_bundle_id === filter.fromBundleId : event.to_bundle_id === filter.toBundleId);
|
|
75
|
+
};
|
|
76
|
+
const invalidQuery = () => {
|
|
77
|
+
throw new DatabasePluginInputError("invalid-query");
|
|
78
|
+
};
|
|
79
|
+
const invalidResult = () => {
|
|
80
|
+
throw new DatabasePluginInputError("invalid-result");
|
|
81
|
+
};
|
|
82
|
+
const validateCount = (count) => isTimestamp(count) ? count : invalidResult();
|
|
83
|
+
/** Validate custom and bundled providers at the same public boundary. */
|
|
84
|
+
const createValidatedInsightsModel = (model) => ({
|
|
85
|
+
async record(input) {
|
|
86
|
+
if (!isRecord(input) || !hasOnlyKeys(input, ["event", "installation"])) throw new DatabasePluginInputError("invalid-data");
|
|
87
|
+
const expected = toInsightsInstallationRow(input.event);
|
|
88
|
+
validateRow("bundle_installations", input.installation);
|
|
89
|
+
if (Object.entries(expected).some(([field, value]) => Reflect.get(input.installation, field) !== value)) throw new DatabasePluginInputError("invalid-data");
|
|
90
|
+
await model.record(input);
|
|
91
|
+
},
|
|
92
|
+
async listEvents(input) {
|
|
93
|
+
if (!isRecord(input) || !hasOnlyKeys(input, [
|
|
94
|
+
"filter",
|
|
95
|
+
"sinceMs",
|
|
96
|
+
"beforeReceivedAtMs",
|
|
97
|
+
"after",
|
|
98
|
+
"limit"
|
|
99
|
+
]) || !isEventFilter(input.filter) || !isLimit(input.limit) || !isTimestamp(input.beforeReceivedAtMs) || input.sinceMs !== void 0 && !isTimestamp(input.sinceMs)) invalidQuery();
|
|
100
|
+
const sinceMs = input.sinceMs ?? 0;
|
|
101
|
+
if (sinceMs > input.beforeReceivedAtMs || input.after !== void 0 && (!isRecord(input.after) || !hasOnlyKeys(input.after, ["receivedAtMs", "id"]) || !isTimestamp(input.after.receivedAtMs) || typeof input.after.id !== "string" || !isUUIDv7(input.after.id) || input.after.receivedAtMs < sinceMs || input.after.receivedAtMs >= input.beforeReceivedAtMs)) invalidQuery();
|
|
102
|
+
const rows = await model.listEvents(input);
|
|
103
|
+
if (!Array.isArray(rows) || rows.length > input.limit) invalidResult();
|
|
104
|
+
let previous = input.after;
|
|
105
|
+
for (const row of rows) {
|
|
106
|
+
validateRow("bundle_events", row, true);
|
|
107
|
+
if (row.received_at_ms < sinceMs || row.received_at_ms >= input.beforeReceivedAtMs || !matchesInsightsEventFilter(row, input.filter) || previous !== void 0 && (row.received_at_ms > previous.receivedAtMs || row.received_at_ms === previous.receivedAtMs && row.id >= previous.id)) invalidResult();
|
|
108
|
+
previous = {
|
|
109
|
+
receivedAtMs: row.received_at_ms,
|
|
110
|
+
id: row.id
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return rows;
|
|
114
|
+
},
|
|
115
|
+
async findInstallations(input) {
|
|
116
|
+
if (!isRecord(input)) invalidQuery();
|
|
117
|
+
if ("installId" in input) {
|
|
118
|
+
if (!hasOnlyKeys(input, ["installId"]) || !isIdentity(input.installId)) invalidQuery();
|
|
119
|
+
} else if (!hasOnlyKeys(input, [
|
|
120
|
+
"userId",
|
|
121
|
+
"afterInstallId",
|
|
122
|
+
"limit"
|
|
123
|
+
]) || !isIdentity(input.userId) || !isLimit(input.limit) || input.afterInstallId !== void 0 && !isIdentity(input.afterInstallId)) invalidQuery();
|
|
124
|
+
const rows = await model.findInstallations(input);
|
|
125
|
+
if (!Array.isArray(rows) || rows.length > ("installId" in input ? 1 : input.limit)) invalidResult();
|
|
126
|
+
let previous = "installId" in input ? void 0 : input.afterInstallId;
|
|
127
|
+
for (const row of rows) {
|
|
128
|
+
validateRow("bundle_installations", row, true);
|
|
129
|
+
if ("installId" in input ? row.install_id !== input.installId : row.user_id !== input.userId || previous !== void 0 && compareInsightsText(row.install_id, previous) <= 0) invalidResult();
|
|
130
|
+
previous = row.install_id;
|
|
131
|
+
}
|
|
132
|
+
return rows;
|
|
133
|
+
},
|
|
134
|
+
async countInstallations(input) {
|
|
135
|
+
if (!isRecord(input) || !hasOnlyKeys(input, [
|
|
136
|
+
"platform",
|
|
137
|
+
"channel",
|
|
138
|
+
"sinceMs",
|
|
139
|
+
"bundleId"
|
|
140
|
+
]) || !hasScope(input) || !isTimestamp(input.sinceMs) || input.bundleId !== void 0 && !isText(input.bundleId)) invalidQuery();
|
|
141
|
+
return validateCount(await model.countInstallations(input));
|
|
142
|
+
},
|
|
143
|
+
async countEvents(input) {
|
|
144
|
+
if (!isRecord(input) || !hasOnlyKeys(input, [
|
|
145
|
+
"filter",
|
|
146
|
+
"sinceMs",
|
|
147
|
+
"beforeReceivedAtMs"
|
|
148
|
+
]) || !isBundleFilter(input.filter) || !isTimestamp(input.sinceMs) || !isTimestamp(input.beforeReceivedAtMs) || input.sinceMs > input.beforeReceivedAtMs) invalidQuery();
|
|
149
|
+
return validateCount(await model.countEvents(input));
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
//#endregion
|
|
153
|
+
export { compareInsightsText, createValidatedInsightsModel, isInsightsMovementEvent, matchesInsightsEventFilter, toInsightsInstallationRow };
|
package/dist/internal.d.cts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { ApiKeyRow, BundleEventRow, BundleEventRowBase, BundlePatchRow, BundleRow, ChannelRow, DatabaseBundleMetadata, DatabaseField, DatabaseJsonObject, DatabaseJsonValue, DatabaseModel, DatabaseModelMap, DatabaseRow, ReleaseCatalogRow, ReleaseRow } from "./types/databaseRows.cjs";
|
|
2
|
-
import {
|
|
1
|
+
import { ApiKeyRow, BundleEventRow, BundleEventRowBase, BundlePatchRow, BundleRow, ChannelRow, DatabaseBundleMetadata, DatabaseField, DatabaseJsonObject, DatabaseJsonValue, DatabaseModel, DatabaseModelMap, DatabaseRow, InsightsInstallationRow, ReleaseCatalogRow, ReleaseRow } from "./types/databaseRows.cjs";
|
|
2
|
+
import { ApiKeyModel, BundleModel, BundleModelQuery, BundlePatchModel, BundleRepository, BundleRepositoryChange, BundleRepositoryCommit, ChannelDeleteInput, ChannelDeleteResult, ChannelInsertInput, ChannelInsertResult, ChannelModel, DatabaseChange, DatabaseCommit, DatabaseCommitExpectation, DatabaseCommitResult, DatabaseModels, DatabasePlugin, InsightsBundleEventFilter, InsightsCountEventsInput, InsightsCountInstallationsInput, InsightsEventCursor, InsightsEventFilter, InsightsFindInstallationsInput, InsightsListEventsInput, InsightsModel, InsightsRecordInput, InsightsScope, ReleaseCatalogModel, ReleaseModel } from "./types/databasePlugin.cjs";
|
|
3
3
|
import { DatabaseDistinctFields, DatabaseDistinctOn, DatabaseOrderBy, DatabaseSelect, DatabaseSortBy, DatabaseSortClause, DatabaseSortNulls, DatabaseStringComparisonMode, DatabaseWhere, DatabaseWhereConnector, DatabaseWhereOperator, SelectedDatabaseRow } from "./types/databaseQuery.cjs";
|
|
4
|
-
import { ApiKeyRowUpdate, BundleRowUpdate, CountBundlesDatabaseImplementationInput, CountBundlesDatabaseInput, CountDatabaseImplementationInput, CountDatabaseInput, CountDatabaseModel, CreateDatabaseImplementationInput, CreateDatabaseInput, CreateDatabaseModel, DatabaseCapability, DatabaseDeleteModel, DatabaseFindOneModel, DatabaseImplementationResult, DatabaseModelCapabilities, DatabaseModelsWithCapability, DatabasePluginCrud, DatabasePluginImplementation, DatabaseRowUpdate, DeleteDatabaseImplementationInput, DeleteDatabaseInput, DeleteDatabaseModel, FindManyDatabaseImplementationInput, FindManyDatabaseInput, FindManyDatabaseModel, FindManyDatabasePluginInput, FindOneDatabaseImplementationInput, FindOneDatabaseInput, FindOneDatabaseModel, ReleaseCatalogRowUpdate, ReleaseRowUpdate, SelectedDatabaseInputRow, TransactionDatabasePluginImplementation, UpdateBundleDatabaseImplementationInput, UpdateBundleDatabaseInput, UpdateDatabaseImplementationInput, UpdateDatabaseInput, UpdateDatabaseModel } from "./types/databaseOperations.cjs";
|
|
4
|
+
import { ApiKeyRowUpdate, BundleRowUpdate, CountBundlesDatabaseImplementationInput, CountBundlesDatabaseInput, CountDatabaseImplementationInput, CountDatabaseInput, CountDatabaseModel, CreateDatabaseImplementationInput, CreateDatabaseInput, CreateDatabaseModel, DatabaseCapability, DatabaseDeleteModel, DatabaseFindOneModel, DatabaseImplementationResult, DatabaseModelCapabilities, DatabaseModelsWithCapability, DatabasePluginCrud, DatabasePluginImplementation, DatabaseRowUpdate, DeleteDatabaseImplementationInput, DeleteDatabaseInput, DeleteDatabaseModel, FindManyDatabaseImplementationInput, FindManyDatabaseInput, FindManyDatabaseModel, FindManyDatabasePluginInput, FindOneDatabaseImplementationInput, FindOneDatabaseInput, FindOneDatabaseModel, InsightsInstallationRowUpdate, ReleaseCatalogRowUpdate, ReleaseRowUpdate, SelectedDatabaseInputRow, TransactionDatabasePluginImplementation, UpdateBundleDatabaseImplementationInput, UpdateBundleDatabaseInput, UpdateDatabaseImplementationInput, UpdateDatabaseInput, UpdateDatabaseModel } from "./types/databaseOperations.cjs";
|
|
5
5
|
import { BuiltIns, HasMultipleCallSignatures, Primitive, RequiredDeep } from "./types/utils.cjs";
|
|
6
6
|
import { ApplePlatform, BasePluginArgs, BuildPlugin, BuildPluginConfig, Bundle, BundleSigningPlugin, ConfigInput, DatabaseBundleCursor, DatabaseBundleIdFilter, DatabaseBundleQueryOptions, DatabaseBundleQueryOrder, DatabaseBundleQueryWhere, FingerprintExtraSources, IosBuildDestination, LocalSigningConfig, NativeBuildAndroidScheme, NativeBuildArgs, NativeBuildIosScheme, NativeBuildOptions, Paginated, PaginatedResult, PaginationInfo, Platform, PlatformConfig, SigningConfig, StorageDeleteInput, StorageDeleteResult, StorageExistsInput, StorageExistsResult, StorageGetDownloadUrlInput, StorageGetDownloadUrlResult, StorageGetInput, StorageGetResult, StorageObject, StoragePlugin, StoragePutInput, StoragePutResult, supportedIosPlatforms } from "./types/index.cjs";
|
|
7
7
|
import { databaseFields } from "./types/databaseFields.cjs";
|
|
8
|
+
import "./types/internal.cjs";
|
|
8
9
|
import { DatabasePluginAdapter, DatabaseRowReferencedError, createDatabasePluginAdapter } from "./createDatabasePlugin.cjs";
|
|
9
|
-
export {
|
|
10
|
+
export { type ApiKeyModel, type ApiKeyRow, type ApiKeyRowUpdate, type ApplePlatform, type BasePluginArgs, type BuildPlugin, type BuildPluginConfig, type BuiltIns, type Bundle, type BundleEventRow, type BundleEventRowBase, type BundleModel, type BundleModelQuery, type BundlePatchModel, type BundlePatchRow, type BundleRepository, type BundleRepositoryChange, type BundleRepositoryCommit, type BundleRow, type BundleRowUpdate, type BundleSigningPlugin, type ChannelDeleteInput, type ChannelDeleteResult, type ChannelInsertInput, type ChannelInsertResult, type ChannelModel, type ChannelRow, type ConfigInput, type CountBundlesDatabaseImplementationInput, type CountBundlesDatabaseInput, type CountDatabaseImplementationInput, type CountDatabaseInput, type CountDatabaseModel, type CreateDatabaseImplementationInput, type CreateDatabaseInput, type CreateDatabaseModel, type DatabaseBundleCursor, type DatabaseBundleIdFilter, type DatabaseBundleMetadata, type DatabaseBundleQueryOptions, type DatabaseBundleQueryOrder, type DatabaseBundleQueryWhere, type DatabaseCapability, type DatabaseChange, type DatabaseCommit, type DatabaseCommitExpectation, type DatabaseCommitResult, type DatabaseDeleteModel, type DatabaseDistinctFields, type DatabaseDistinctOn, type DatabaseField, type DatabaseFindOneModel, type DatabaseImplementationResult, type DatabaseJsonObject, type DatabaseJsonValue, type DatabaseModel, type DatabaseModelCapabilities, type DatabaseModelMap, type DatabaseModels, type DatabaseModelsWithCapability, type DatabaseOrderBy, type DatabasePlugin, type DatabasePluginAdapter, type DatabasePluginCrud, type DatabasePluginImplementation, type DatabaseRow, DatabaseRowReferencedError, type DatabaseRowUpdate, type DatabaseSelect, type DatabaseSortBy, type DatabaseSortClause, type DatabaseSortNulls, type DatabaseStringComparisonMode, type DatabaseWhere, type DatabaseWhereConnector, type DatabaseWhereOperator, type DeleteDatabaseImplementationInput, type DeleteDatabaseInput, type DeleteDatabaseModel, type FindManyDatabaseImplementationInput, type FindManyDatabaseInput, type FindManyDatabaseModel, type FindManyDatabasePluginInput, type FindOneDatabaseImplementationInput, type FindOneDatabaseInput, type FindOneDatabaseModel, type FingerprintExtraSources, type HasMultipleCallSignatures, type InsightsBundleEventFilter, type InsightsCountEventsInput, type InsightsCountInstallationsInput, type InsightsEventCursor, type InsightsEventFilter, type InsightsFindInstallationsInput, type InsightsInstallationRow, type InsightsInstallationRowUpdate, type InsightsListEventsInput, type InsightsModel, type InsightsRecordInput, type InsightsScope, type IosBuildDestination, type LocalSigningConfig, type NativeBuildAndroidScheme, type NativeBuildArgs, type NativeBuildIosScheme, type NativeBuildOptions, type Paginated, type PaginatedResult, type PaginationInfo, type Platform, type PlatformConfig, type Primitive, type ReleaseCatalogModel, type ReleaseCatalogRow, type ReleaseCatalogRowUpdate, type ReleaseModel, type ReleaseRow, type ReleaseRowUpdate, type RequiredDeep, type SelectedDatabaseInputRow, type SelectedDatabaseRow, type SigningConfig, type StorageDeleteInput, type StorageDeleteResult, type StorageExistsInput, type StorageExistsResult, type StorageGetDownloadUrlInput, type StorageGetDownloadUrlResult, type StorageGetInput, type StorageGetResult, type StorageObject, type StoragePlugin, type StoragePutInput, type StoragePutResult, type TransactionDatabasePluginImplementation, type UpdateBundleDatabaseImplementationInput, type UpdateBundleDatabaseInput, type UpdateDatabaseImplementationInput, type UpdateDatabaseInput, type UpdateDatabaseModel, createDatabasePluginAdapter, databaseFields, type supportedIosPlatforms };
|
package/dist/internal.d.mts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { ApiKeyRow, BundleEventRow, BundleEventRowBase, BundlePatchRow, BundleRow, ChannelRow, DatabaseBundleMetadata, DatabaseField, DatabaseJsonObject, DatabaseJsonValue, DatabaseModel, DatabaseModelMap, DatabaseRow, ReleaseCatalogRow, ReleaseRow } from "./types/databaseRows.mjs";
|
|
2
|
-
import {
|
|
1
|
+
import { ApiKeyRow, BundleEventRow, BundleEventRowBase, BundlePatchRow, BundleRow, ChannelRow, DatabaseBundleMetadata, DatabaseField, DatabaseJsonObject, DatabaseJsonValue, DatabaseModel, DatabaseModelMap, DatabaseRow, InsightsInstallationRow, ReleaseCatalogRow, ReleaseRow } from "./types/databaseRows.mjs";
|
|
2
|
+
import { ApiKeyModel, BundleModel, BundleModelQuery, BundlePatchModel, BundleRepository, BundleRepositoryChange, BundleRepositoryCommit, ChannelDeleteInput, ChannelDeleteResult, ChannelInsertInput, ChannelInsertResult, ChannelModel, DatabaseChange, DatabaseCommit, DatabaseCommitExpectation, DatabaseCommitResult, DatabaseModels, DatabasePlugin, InsightsBundleEventFilter, InsightsCountEventsInput, InsightsCountInstallationsInput, InsightsEventCursor, InsightsEventFilter, InsightsFindInstallationsInput, InsightsListEventsInput, InsightsModel, InsightsRecordInput, InsightsScope, ReleaseCatalogModel, ReleaseModel } from "./types/databasePlugin.mjs";
|
|
3
3
|
import { DatabaseDistinctFields, DatabaseDistinctOn, DatabaseOrderBy, DatabaseSelect, DatabaseSortBy, DatabaseSortClause, DatabaseSortNulls, DatabaseStringComparisonMode, DatabaseWhere, DatabaseWhereConnector, DatabaseWhereOperator, SelectedDatabaseRow } from "./types/databaseQuery.mjs";
|
|
4
|
-
import { ApiKeyRowUpdate, BundleRowUpdate, CountBundlesDatabaseImplementationInput, CountBundlesDatabaseInput, CountDatabaseImplementationInput, CountDatabaseInput, CountDatabaseModel, CreateDatabaseImplementationInput, CreateDatabaseInput, CreateDatabaseModel, DatabaseCapability, DatabaseDeleteModel, DatabaseFindOneModel, DatabaseImplementationResult, DatabaseModelCapabilities, DatabaseModelsWithCapability, DatabasePluginCrud, DatabasePluginImplementation, DatabaseRowUpdate, DeleteDatabaseImplementationInput, DeleteDatabaseInput, DeleteDatabaseModel, FindManyDatabaseImplementationInput, FindManyDatabaseInput, FindManyDatabaseModel, FindManyDatabasePluginInput, FindOneDatabaseImplementationInput, FindOneDatabaseInput, FindOneDatabaseModel, ReleaseCatalogRowUpdate, ReleaseRowUpdate, SelectedDatabaseInputRow, TransactionDatabasePluginImplementation, UpdateBundleDatabaseImplementationInput, UpdateBundleDatabaseInput, UpdateDatabaseImplementationInput, UpdateDatabaseInput, UpdateDatabaseModel } from "./types/databaseOperations.mjs";
|
|
4
|
+
import { ApiKeyRowUpdate, BundleRowUpdate, CountBundlesDatabaseImplementationInput, CountBundlesDatabaseInput, CountDatabaseImplementationInput, CountDatabaseInput, CountDatabaseModel, CreateDatabaseImplementationInput, CreateDatabaseInput, CreateDatabaseModel, DatabaseCapability, DatabaseDeleteModel, DatabaseFindOneModel, DatabaseImplementationResult, DatabaseModelCapabilities, DatabaseModelsWithCapability, DatabasePluginCrud, DatabasePluginImplementation, DatabaseRowUpdate, DeleteDatabaseImplementationInput, DeleteDatabaseInput, DeleteDatabaseModel, FindManyDatabaseImplementationInput, FindManyDatabaseInput, FindManyDatabaseModel, FindManyDatabasePluginInput, FindOneDatabaseImplementationInput, FindOneDatabaseInput, FindOneDatabaseModel, InsightsInstallationRowUpdate, ReleaseCatalogRowUpdate, ReleaseRowUpdate, SelectedDatabaseInputRow, TransactionDatabasePluginImplementation, UpdateBundleDatabaseImplementationInput, UpdateBundleDatabaseInput, UpdateDatabaseImplementationInput, UpdateDatabaseInput, UpdateDatabaseModel } from "./types/databaseOperations.mjs";
|
|
5
5
|
import { BuiltIns, HasMultipleCallSignatures, Primitive, RequiredDeep } from "./types/utils.mjs";
|
|
6
6
|
import { ApplePlatform, BasePluginArgs, BuildPlugin, BuildPluginConfig, Bundle, BundleSigningPlugin, ConfigInput, DatabaseBundleCursor, DatabaseBundleIdFilter, DatabaseBundleQueryOptions, DatabaseBundleQueryOrder, DatabaseBundleQueryWhere, FingerprintExtraSources, IosBuildDestination, LocalSigningConfig, NativeBuildAndroidScheme, NativeBuildArgs, NativeBuildIosScheme, NativeBuildOptions, Paginated, PaginatedResult, PaginationInfo, Platform, PlatformConfig, SigningConfig, StorageDeleteInput, StorageDeleteResult, StorageExistsInput, StorageExistsResult, StorageGetDownloadUrlInput, StorageGetDownloadUrlResult, StorageGetInput, StorageGetResult, StorageObject, StoragePlugin, StoragePutInput, StoragePutResult, supportedIosPlatforms } from "./types/index.mjs";
|
|
7
7
|
import { databaseFields } from "./types/databaseFields.mjs";
|
|
8
|
+
import "./types/internal.mjs";
|
|
8
9
|
import { DatabasePluginAdapter, DatabaseRowReferencedError, createDatabasePluginAdapter } from "./createDatabasePlugin.mjs";
|
|
9
|
-
export {
|
|
10
|
+
export { type ApiKeyModel, type ApiKeyRow, type ApiKeyRowUpdate, type ApplePlatform, type BasePluginArgs, type BuildPlugin, type BuildPluginConfig, type BuiltIns, type Bundle, type BundleEventRow, type BundleEventRowBase, type BundleModel, type BundleModelQuery, type BundlePatchModel, type BundlePatchRow, type BundleRepository, type BundleRepositoryChange, type BundleRepositoryCommit, type BundleRow, type BundleRowUpdate, type BundleSigningPlugin, type ChannelDeleteInput, type ChannelDeleteResult, type ChannelInsertInput, type ChannelInsertResult, type ChannelModel, type ChannelRow, type ConfigInput, type CountBundlesDatabaseImplementationInput, type CountBundlesDatabaseInput, type CountDatabaseImplementationInput, type CountDatabaseInput, type CountDatabaseModel, type CreateDatabaseImplementationInput, type CreateDatabaseInput, type CreateDatabaseModel, type DatabaseBundleCursor, type DatabaseBundleIdFilter, type DatabaseBundleMetadata, type DatabaseBundleQueryOptions, type DatabaseBundleQueryOrder, type DatabaseBundleQueryWhere, type DatabaseCapability, type DatabaseChange, type DatabaseCommit, type DatabaseCommitExpectation, type DatabaseCommitResult, type DatabaseDeleteModel, type DatabaseDistinctFields, type DatabaseDistinctOn, type DatabaseField, type DatabaseFindOneModel, type DatabaseImplementationResult, type DatabaseJsonObject, type DatabaseJsonValue, type DatabaseModel, type DatabaseModelCapabilities, type DatabaseModelMap, type DatabaseModels, type DatabaseModelsWithCapability, type DatabaseOrderBy, type DatabasePlugin, type DatabasePluginAdapter, type DatabasePluginCrud, type DatabasePluginImplementation, type DatabaseRow, DatabaseRowReferencedError, type DatabaseRowUpdate, type DatabaseSelect, type DatabaseSortBy, type DatabaseSortClause, type DatabaseSortNulls, type DatabaseStringComparisonMode, type DatabaseWhere, type DatabaseWhereConnector, type DatabaseWhereOperator, type DeleteDatabaseImplementationInput, type DeleteDatabaseInput, type DeleteDatabaseModel, type FindManyDatabaseImplementationInput, type FindManyDatabaseInput, type FindManyDatabaseModel, type FindManyDatabasePluginInput, type FindOneDatabaseImplementationInput, type FindOneDatabaseInput, type FindOneDatabaseModel, type FingerprintExtraSources, type HasMultipleCallSignatures, type InsightsBundleEventFilter, type InsightsCountEventsInput, type InsightsCountInstallationsInput, type InsightsEventCursor, type InsightsEventFilter, type InsightsFindInstallationsInput, type InsightsInstallationRow, type InsightsInstallationRowUpdate, type InsightsListEventsInput, type InsightsModel, type InsightsRecordInput, type InsightsScope, type IosBuildDestination, type LocalSigningConfig, type NativeBuildAndroidScheme, type NativeBuildArgs, type NativeBuildIosScheme, type NativeBuildOptions, type Paginated, type PaginatedResult, type PaginationInfo, type Platform, type PlatformConfig, type Primitive, type ReleaseCatalogModel, type ReleaseCatalogRow, type ReleaseCatalogRowUpdate, type ReleaseModel, type ReleaseRow, type ReleaseRowUpdate, type RequiredDeep, type SelectedDatabaseInputRow, type SelectedDatabaseRow, type SigningConfig, type StorageDeleteInput, type StorageDeleteResult, type StorageExistsInput, type StorageExistsResult, type StorageGetDownloadUrlInput, type StorageGetDownloadUrlResult, type StorageGetInput, type StorageGetResult, type StorageObject, type StoragePlugin, type StoragePutInput, type StoragePutResult, type TransactionDatabasePluginImplementation, type UpdateBundleDatabaseImplementationInput, type UpdateBundleDatabaseInput, type UpdateDatabaseImplementationInput, type UpdateDatabaseInput, type UpdateDatabaseModel, createDatabasePluginAdapter, databaseFields, type supportedIosPlatforms };
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
//#region ../../node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/comparison-DenM3wCn.js
|
|
2
|
+
const LETTER_DASH_NUMBER = "[a-zA-Z0-9-]";
|
|
3
|
+
const NUMERIC_IDENTIFIER = String.raw`0|[1-9]\d*`;
|
|
4
|
+
const NUMERIC_IDENTIFIER_LOOSE = String.raw`\d+`;
|
|
5
|
+
const NON_NUMERIC_IDENTIFIER = String.raw`\d*[a-zA-Z-]${LETTER_DASH_NUMBER}*`;
|
|
6
|
+
const MAIN_VERSION = String.raw`(${NUMERIC_IDENTIFIER})\.(${NUMERIC_IDENTIFIER})\.(${NUMERIC_IDENTIFIER})`;
|
|
7
|
+
const MAIN_VERSION_LOOSE = String.raw`(${NUMERIC_IDENTIFIER_LOOSE})\.(${NUMERIC_IDENTIFIER_LOOSE})\.(${NUMERIC_IDENTIFIER_LOOSE})`;
|
|
8
|
+
const PRERELEASE_IDENTIFIER = `(?:${NON_NUMERIC_IDENTIFIER}|${NUMERIC_IDENTIFIER})`;
|
|
9
|
+
const PRERELEASE_IDENTIFIER_LOOSE = `(?:${NON_NUMERIC_IDENTIFIER}|${NUMERIC_IDENTIFIER_LOOSE})`;
|
|
10
|
+
const PRERELEASE = String.raw`(?:-(${PRERELEASE_IDENTIFIER}(?:\.${PRERELEASE_IDENTIFIER})*))`;
|
|
11
|
+
const PRERELEASE_LOOSE = String.raw`(?:-?(${PRERELEASE_IDENTIFIER_LOOSE}(?:\.${PRERELEASE_IDENTIFIER_LOOSE})*))`;
|
|
12
|
+
const BUILD_IDENTIFIER = `${LETTER_DASH_NUMBER}+`;
|
|
13
|
+
const BUILD = String.raw`(?:\+(${BUILD_IDENTIFIER}(?:\.${BUILD_IDENTIFIER})*))`;
|
|
14
|
+
const FULL_PLAIN = `v?${MAIN_VERSION}${PRERELEASE}?${BUILD}?`;
|
|
15
|
+
const LOOSE_PLAIN = String.raw`[v=\s]*${MAIN_VERSION_LOOSE}${PRERELEASE_LOOSE}?${BUILD}?`;
|
|
16
|
+
const GREATER_LESS_THAN = "((?:<|>)?=?)";
|
|
17
|
+
const XRANGE_IDENTIFIER = String.raw`${NUMERIC_IDENTIFIER}|x|X|\*`;
|
|
18
|
+
const XRANGE_IDENTIFIER_LOOSE = String.raw`${NUMERIC_IDENTIFIER_LOOSE}|x|X|\*`;
|
|
19
|
+
const XRANGE_PLAIN = String.raw`[v=\s]*(${XRANGE_IDENTIFIER})(?:\.(${XRANGE_IDENTIFIER})(?:\.(${XRANGE_IDENTIFIER})(?:${PRERELEASE})?${BUILD}?)?)?`;
|
|
20
|
+
const XRANGE_PLAIN_LOOSE = String.raw`[v=\s]*(${XRANGE_IDENTIFIER_LOOSE})(?:\.(${XRANGE_IDENTIFIER_LOOSE})(?:\.(${XRANGE_IDENTIFIER_LOOSE})(?:${PRERELEASE_LOOSE})?${BUILD}?)?)?`;
|
|
21
|
+
const LONE_TILDE = "(?:~>?)";
|
|
22
|
+
const LONE_CARET = String.raw`(?:\^)`;
|
|
23
|
+
const COERCE_PLAIN = String.raw`(^|[^\d])(\d{1,${16}})(?:\.(\d{1,${16}}))?(?:\.(\d{1,${16}}))?`;
|
|
24
|
+
const COERCE = String.raw`${COERCE_PLAIN}(?:$|[^\d])`;
|
|
25
|
+
const COERCE_FULL = String.raw`${COERCE_PLAIN}(?:${PRERELEASE})?(?:${BUILD})?(?:$|[^\d])`;
|
|
26
|
+
function makeSafeRegexSource(source) {
|
|
27
|
+
const replacements = [
|
|
28
|
+
[String.raw`\s`, 1],
|
|
29
|
+
[String.raw`\d`, 256],
|
|
30
|
+
[LETTER_DASH_NUMBER, 250]
|
|
31
|
+
];
|
|
32
|
+
for (const [token, maximum] of replacements) source = source.split(`${token}*`).join(`${token}{0,${maximum}}`).split(`${token}+`).join(`${token}{1,${maximum}}`);
|
|
33
|
+
return source;
|
|
34
|
+
}
|
|
35
|
+
function safeRegex(source, flags) {
|
|
36
|
+
return new RegExp(makeSafeRegexSource(source), flags);
|
|
37
|
+
}
|
|
38
|
+
const FULL = safeRegex(`^${FULL_PLAIN}$`);
|
|
39
|
+
const LOOSE = safeRegex(`^${LOOSE_PLAIN}$`);
|
|
40
|
+
const NUMERIC$1 = /^\d+$/;
|
|
41
|
+
function formatComparableVersion(version) {
|
|
42
|
+
const base = `${version.major}.${version.minor}.${version.patch}`;
|
|
43
|
+
return version.prerelease?.length ? `${base}-${version.prerelease.join(".")}` : base;
|
|
44
|
+
}
|
|
45
|
+
function formatFullVersion(version) {
|
|
46
|
+
const comparable = formatComparableVersion(version);
|
|
47
|
+
return version.build?.length ? `${comparable}+${version.build.join(".")}` : comparable;
|
|
48
|
+
}
|
|
49
|
+
function parse(version, options = {}) {
|
|
50
|
+
if (typeof version !== "string") return version;
|
|
51
|
+
if (version.length > 256) throw new TypeError(`Version exceeds the maximum length of 256 characters`);
|
|
52
|
+
const match = version.trim().match(options.loose ? LOOSE : FULL);
|
|
53
|
+
if (!match) throw new TypeError(`Invalid version syntax: ${version}`);
|
|
54
|
+
const major = Number(match[1]);
|
|
55
|
+
const minor = Number(match[2]);
|
|
56
|
+
const patch = Number(match[3]);
|
|
57
|
+
if (major > Number.MAX_SAFE_INTEGER || major < 0) throw new TypeError(`Invalid major version: ${match[1]}`);
|
|
58
|
+
if (minor > Number.MAX_SAFE_INTEGER || minor < 0) throw new TypeError(`Invalid minor version: ${match[2]}`);
|
|
59
|
+
if (patch > Number.MAX_SAFE_INTEGER || patch < 0) throw new TypeError(`Invalid patch version: ${match[3]}`);
|
|
60
|
+
const prerelease = match[4] ? match[4].split(".").map((identifier) => {
|
|
61
|
+
if (NUMERIC$1.test(identifier)) {
|
|
62
|
+
const numeric = Number(identifier);
|
|
63
|
+
if (numeric >= 0 && numeric < Number.MAX_SAFE_INTEGER) return numeric;
|
|
64
|
+
}
|
|
65
|
+
return identifier;
|
|
66
|
+
}) : void 0;
|
|
67
|
+
return {
|
|
68
|
+
build: match[5]?.split("."),
|
|
69
|
+
major,
|
|
70
|
+
minor,
|
|
71
|
+
patch,
|
|
72
|
+
prerelease
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function tryParse(version, options = {}) {
|
|
76
|
+
try {
|
|
77
|
+
return parse(version, options);
|
|
78
|
+
} catch {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const NUMERIC = /^\d+$/;
|
|
83
|
+
function compareIdentifiers(left, right) {
|
|
84
|
+
if (typeof left === "number" && typeof right === "number") return left === right ? 0 : left < right ? -1 : 1;
|
|
85
|
+
const leftNumeric = NUMERIC.test(String(left));
|
|
86
|
+
const rightNumeric = NUMERIC.test(String(right));
|
|
87
|
+
const normalizedLeft = leftNumeric ? Number(left) : left;
|
|
88
|
+
const normalizedRight = rightNumeric ? Number(right) : right;
|
|
89
|
+
return normalizedLeft === normalizedRight ? 0 : leftNumeric && !rightNumeric ? -1 : rightNumeric && !leftNumeric ? 1 : normalizedLeft < normalizedRight ? -1 : 1;
|
|
90
|
+
}
|
|
91
|
+
function compareMainParsed(left, right) {
|
|
92
|
+
return left.major === right.major ? left.minor === right.minor ? left.patch === right.patch ? 0 : left.patch < right.patch ? -1 : 1 : left.minor < right.minor ? -1 : 1 : left.major < right.major ? -1 : 1;
|
|
93
|
+
}
|
|
94
|
+
function comparePrereleaseParsed(left, right) {
|
|
95
|
+
const leftPrerelease = left.prerelease;
|
|
96
|
+
const rightPrerelease = right.prerelease;
|
|
97
|
+
if (leftPrerelease?.length && !rightPrerelease?.length) return -1;
|
|
98
|
+
if (!leftPrerelease?.length && rightPrerelease?.length) return 1;
|
|
99
|
+
if (!leftPrerelease?.length && !rightPrerelease?.length) return 0;
|
|
100
|
+
for (let index = 0;; index++) {
|
|
101
|
+
const leftIdentifier = leftPrerelease?.[index];
|
|
102
|
+
const rightIdentifier = rightPrerelease?.[index];
|
|
103
|
+
if (leftIdentifier === void 0 && rightIdentifier === void 0) return 0;
|
|
104
|
+
if (rightIdentifier === void 0) return 1;
|
|
105
|
+
if (leftIdentifier === void 0) return -1;
|
|
106
|
+
if (leftIdentifier !== rightIdentifier) return compareIdentifiers(leftIdentifier, rightIdentifier);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function compareParsed(left, right) {
|
|
110
|
+
return compareMainParsed(left, right) || comparePrereleaseParsed(left, right);
|
|
111
|
+
}
|
|
112
|
+
function compare(left, right, options = {}) {
|
|
113
|
+
return compareParsed(parse(left, options), parse(right, options));
|
|
114
|
+
}
|
|
115
|
+
//#endregion
|
|
116
|
+
exports.A = LOOSE_PLAIN;
|
|
117
|
+
exports.C = BUILD;
|
|
118
|
+
exports.D = GREATER_LESS_THAN;
|
|
119
|
+
exports.E = FULL_PLAIN;
|
|
120
|
+
exports.F = safeRegex;
|
|
121
|
+
exports.M = PRERELEASE_LOOSE;
|
|
122
|
+
exports.N = XRANGE_PLAIN;
|
|
123
|
+
exports.O = LONE_CARET;
|
|
124
|
+
exports.P = XRANGE_PLAIN_LOOSE;
|
|
125
|
+
exports.S = tryParse;
|
|
126
|
+
exports.T = COERCE_FULL;
|
|
127
|
+
exports._ = compareIdentifiers;
|
|
128
|
+
exports.a = compareParsed;
|
|
129
|
+
exports.b = formatFullVersion;
|
|
130
|
+
exports.i = compareMainParsed;
|
|
131
|
+
exports.j = PRERELEASE;
|
|
132
|
+
exports.k = LONE_TILDE;
|
|
133
|
+
exports.t = compare;
|
|
134
|
+
exports.w = COERCE;
|
|
135
|
+
exports.x = parse;
|
|
136
|
+
exports.y = formatComparableVersion;
|