@hot-updater/postgres 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/index.cjs +238 -1096
- package/dist/index.d.cts +7 -24
- package/dist/index.d.mts +7 -24
- package/dist/index.mjs +240 -1120
- package/package.json +5 -12
- package/sql/bundles.sql +179 -45
- package/sql/get_target_app_version_list.sql +0 -21
- package/sql/get_update_info.spec.ts +0 -171
- package/sql/get_update_info_by_app_version.sql +0 -126
- package/sql/get_update_info_by_fingerprint_hash.sql +0 -125
- package/sql/hash_user_id.sql +0 -30
- package/sql/is_device_eligible.sql +0 -237
- package/sql/prepareSql.ts +0 -11
package/dist/index.cjs
CHANGED
|
@@ -6,7 +6,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
10
9
|
var __copyProps = (to, from, except, desc) => {
|
|
11
10
|
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
12
11
|
key = keys[i];
|
|
@@ -22,1135 +21,278 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
22
21
|
enumerable: true
|
|
23
22
|
}) : target, mod));
|
|
24
23
|
//#endregion
|
|
25
|
-
let _hot_updater_core = require("@hot-updater/core");
|
|
26
24
|
let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
25
|
+
let _hot_updater_plugin_core_internal = require("@hot-updater/plugin-core/internal");
|
|
27
26
|
let kysely = require("kysely");
|
|
28
27
|
let pg = require("pg");
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
const MAIN_VERSION = String.raw`(${NUMERIC_IDENTIFIER})\.(${NUMERIC_IDENTIFIER})\.(${NUMERIC_IDENTIFIER})`;
|
|
35
|
-
const MAIN_VERSION_LOOSE = String.raw`(${NUMERIC_IDENTIFIER_LOOSE})\.(${NUMERIC_IDENTIFIER_LOOSE})\.(${NUMERIC_IDENTIFIER_LOOSE})`;
|
|
36
|
-
const PRERELEASE_IDENTIFIER = `(?:${NON_NUMERIC_IDENTIFIER}|${NUMERIC_IDENTIFIER})`;
|
|
37
|
-
const PRERELEASE_IDENTIFIER_LOOSE = `(?:${NON_NUMERIC_IDENTIFIER}|${NUMERIC_IDENTIFIER_LOOSE})`;
|
|
38
|
-
const PRERELEASE = String.raw`(?:-(${PRERELEASE_IDENTIFIER}(?:\.${PRERELEASE_IDENTIFIER})*))`;
|
|
39
|
-
const PRERELEASE_LOOSE = String.raw`(?:-?(${PRERELEASE_IDENTIFIER_LOOSE}(?:\.${PRERELEASE_IDENTIFIER_LOOSE})*))`;
|
|
40
|
-
const BUILD_IDENTIFIER = `${LETTER_DASH_NUMBER}+`;
|
|
41
|
-
const BUILD = String.raw`(?:\+(${BUILD_IDENTIFIER}(?:\.${BUILD_IDENTIFIER})*))`;
|
|
42
|
-
const FULL_PLAIN = `v?${MAIN_VERSION}${PRERELEASE}?${BUILD}?`;
|
|
43
|
-
const LOOSE_PLAIN = String.raw`[v=\s]*${MAIN_VERSION_LOOSE}${PRERELEASE_LOOSE}?${BUILD}?`;
|
|
44
|
-
const GREATER_LESS_THAN = "((?:<|>)?=?)";
|
|
45
|
-
const XRANGE_IDENTIFIER = String.raw`${NUMERIC_IDENTIFIER}|x|X|\*`;
|
|
46
|
-
const XRANGE_IDENTIFIER_LOOSE = String.raw`${NUMERIC_IDENTIFIER_LOOSE}|x|X|\*`;
|
|
47
|
-
const XRANGE_PLAIN = String.raw`[v=\s]*(${XRANGE_IDENTIFIER})(?:\.(${XRANGE_IDENTIFIER})(?:\.(${XRANGE_IDENTIFIER})(?:${PRERELEASE})?${BUILD}?)?)?`;
|
|
48
|
-
const XRANGE_PLAIN_LOOSE = String.raw`[v=\s]*(${XRANGE_IDENTIFIER_LOOSE})(?:\.(${XRANGE_IDENTIFIER_LOOSE})(?:\.(${XRANGE_IDENTIFIER_LOOSE})(?:${PRERELEASE_LOOSE})?${BUILD}?)?)?`;
|
|
49
|
-
const LONE_TILDE = "(?:~>?)";
|
|
50
|
-
const LONE_CARET = String.raw`(?:\^)`;
|
|
51
|
-
const COERCE_PLAIN = String.raw`(^|[^\d])(\d{1,${16}})(?:\.(\d{1,${16}}))?(?:\.(\d{1,${16}}))?`;
|
|
52
|
-
const COERCE = String.raw`${COERCE_PLAIN}(?:$|[^\d])`;
|
|
53
|
-
const COERCE_FULL = String.raw`${COERCE_PLAIN}(?:${PRERELEASE})?(?:${BUILD})?(?:$|[^\d])`;
|
|
54
|
-
function makeSafeRegexSource(source) {
|
|
55
|
-
const replacements = [
|
|
56
|
-
[String.raw`\s`, 1],
|
|
57
|
-
[String.raw`\d`, 256],
|
|
58
|
-
[LETTER_DASH_NUMBER, 250]
|
|
59
|
-
];
|
|
60
|
-
for (const [token, maximum] of replacements) source = source.split(`${token}*`).join(`${token}{0,${maximum}}`).split(`${token}+`).join(`${token}{1,${maximum}}`);
|
|
61
|
-
return source;
|
|
62
|
-
}
|
|
63
|
-
function safeRegex(source, flags) {
|
|
64
|
-
return new RegExp(makeSafeRegexSource(source), flags);
|
|
65
|
-
}
|
|
66
|
-
const NUMERIC$1 = /^\d+$/;
|
|
67
|
-
function compareIdentifiers(left, right) {
|
|
68
|
-
if (typeof left === "number" && typeof right === "number") return left === right ? 0 : left < right ? -1 : 1;
|
|
69
|
-
const leftNumeric = NUMERIC$1.test(String(left));
|
|
70
|
-
const rightNumeric = NUMERIC$1.test(String(right));
|
|
71
|
-
const normalizedLeft = leftNumeric ? Number(left) : left;
|
|
72
|
-
const normalizedRight = rightNumeric ? Number(right) : right;
|
|
73
|
-
return normalizedLeft === normalizedRight ? 0 : leftNumeric && !rightNumeric ? -1 : rightNumeric && !leftNumeric ? 1 : normalizedLeft < normalizedRight ? -1 : 1;
|
|
74
|
-
}
|
|
75
|
-
const FULL = safeRegex(`^${FULL_PLAIN}$`);
|
|
76
|
-
const LOOSE = safeRegex(`^${LOOSE_PLAIN}$`);
|
|
77
|
-
safeRegex(`^${PRERELEASE}$`);
|
|
78
|
-
safeRegex(`^${PRERELEASE_LOOSE}$`);
|
|
79
|
-
const COERCE_EXACT = safeRegex(COERCE);
|
|
80
|
-
const COERCE_FULL_EXACT = safeRegex(COERCE_FULL);
|
|
81
|
-
const NUMERIC = /^\d+$/;
|
|
82
|
-
function formatComparableVersion(version) {
|
|
83
|
-
const base = `${version.major}.${version.minor}.${version.patch}`;
|
|
84
|
-
return version.prerelease?.length ? `${base}-${version.prerelease.join(".")}` : base;
|
|
85
|
-
}
|
|
86
|
-
function formatFullVersion(version) {
|
|
87
|
-
const comparable = formatComparableVersion(version);
|
|
88
|
-
return version.build?.length ? `${comparable}+${version.build.join(".")}` : comparable;
|
|
89
|
-
}
|
|
90
|
-
function parse(version, options = {}) {
|
|
91
|
-
if (typeof version !== "string") return version;
|
|
92
|
-
if (version.length > 256) throw new TypeError(`Version exceeds the maximum length of 256 characters`);
|
|
93
|
-
const match = version.trim().match(options.loose ? LOOSE : FULL);
|
|
94
|
-
if (!match) throw new TypeError(`Invalid version syntax: ${version}`);
|
|
95
|
-
const major = Number(match[1]);
|
|
96
|
-
const minor = Number(match[2]);
|
|
97
|
-
const patch = Number(match[3]);
|
|
98
|
-
if (major > Number.MAX_SAFE_INTEGER || major < 0) throw new TypeError(`Invalid major version: ${match[1]}`);
|
|
99
|
-
if (minor > Number.MAX_SAFE_INTEGER || minor < 0) throw new TypeError(`Invalid minor version: ${match[2]}`);
|
|
100
|
-
if (patch > Number.MAX_SAFE_INTEGER || patch < 0) throw new TypeError(`Invalid patch version: ${match[3]}`);
|
|
101
|
-
const prerelease = match[4] ? match[4].split(".").map((identifier) => {
|
|
102
|
-
if (NUMERIC.test(identifier)) {
|
|
103
|
-
const numeric = Number(identifier);
|
|
104
|
-
if (numeric >= 0 && numeric < Number.MAX_SAFE_INTEGER) return numeric;
|
|
105
|
-
}
|
|
106
|
-
return identifier;
|
|
107
|
-
}) : void 0;
|
|
108
|
-
return {
|
|
109
|
-
build: match[5]?.split("."),
|
|
110
|
-
major,
|
|
111
|
-
minor,
|
|
112
|
-
patch,
|
|
113
|
-
prerelease
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
function tryParse(version, options = {}) {
|
|
117
|
-
try {
|
|
118
|
-
return parse(version, options);
|
|
119
|
-
} catch {
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
function compareMainParsed(left, right) {
|
|
124
|
-
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;
|
|
125
|
-
}
|
|
126
|
-
function comparePrereleaseParsed(left, right) {
|
|
127
|
-
const leftPrerelease = left.prerelease;
|
|
128
|
-
const rightPrerelease = right.prerelease;
|
|
129
|
-
if (leftPrerelease?.length && !rightPrerelease?.length) return -1;
|
|
130
|
-
if (!leftPrerelease?.length && rightPrerelease?.length) return 1;
|
|
131
|
-
if (!leftPrerelease?.length && !rightPrerelease?.length) return 0;
|
|
132
|
-
for (let index = 0;; index++) {
|
|
133
|
-
const leftIdentifier = leftPrerelease?.[index];
|
|
134
|
-
const rightIdentifier = rightPrerelease?.[index];
|
|
135
|
-
if (leftIdentifier === void 0 && rightIdentifier === void 0) return 0;
|
|
136
|
-
if (rightIdentifier === void 0) return 1;
|
|
137
|
-
if (leftIdentifier === void 0) return -1;
|
|
138
|
-
if (leftIdentifier !== rightIdentifier) return compareIdentifiers(leftIdentifier, rightIdentifier);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
function compareParsed(left, right) {
|
|
142
|
-
return compareMainParsed(left, right) || comparePrereleaseParsed(left, right);
|
|
143
|
-
}
|
|
144
|
-
function coerceParsedVersion(value, options = {}) {
|
|
145
|
-
if (typeof value === "object") return value;
|
|
146
|
-
const input = typeof value === "number" ? String(value) : value;
|
|
147
|
-
if (typeof input !== "string") return null;
|
|
148
|
-
let match = null;
|
|
149
|
-
if (options.rtl) {
|
|
150
|
-
const expression = safeRegex(options.includePrerelease ? COERCE_FULL : COERCE, "g");
|
|
151
|
-
let next;
|
|
152
|
-
while ((next = expression.exec(input)) && (!match || match.index + match[0].length !== input.length)) {
|
|
153
|
-
if (!match || next.index + next[0].length !== match.index + match[0].length) match = next;
|
|
154
|
-
expression.lastIndex = next.index + next[1].length + next[2].length;
|
|
155
|
-
}
|
|
156
|
-
} else match = (options.includePrerelease ? COERCE_FULL_EXACT : COERCE_EXACT).exec(input);
|
|
157
|
-
if (!match) return null;
|
|
158
|
-
const major = match[2];
|
|
159
|
-
return tryParse(`${major}.${match[3] || "0"}.${match[4] || "0"}${options.includePrerelease && match[5] ? `-${match[5]}` : ""}${options.includePrerelease && match[6] ? `+${match[6]}` : ""}`, options);
|
|
160
|
-
}
|
|
161
|
-
const STRICT_COMPARATOR = safeRegex(String.raw`^${GREATER_LESS_THAN}\s*(${FULL_PLAIN})$|^$`);
|
|
162
|
-
const LOOSE_COMPARATOR$1 = safeRegex(String.raw`^${GREATER_LESS_THAN}\s*(${LOOSE_PLAIN})$|^$`);
|
|
163
|
-
function parseComparator(comparator, options = {}) {
|
|
164
|
-
const normalized = comparator.trim().replaceAll(/\s+/g, " ");
|
|
165
|
-
const match = normalized.match(options.loose ? LOOSE_COMPARATOR$1 : STRICT_COMPARATOR);
|
|
166
|
-
if (!match) throw new TypeError(`Invalid comparator: ${normalized}`);
|
|
167
|
-
const operator = match[1] === "=" ? "" : match[1] || "";
|
|
168
|
-
const version = match[2] ? parse(match[2], options) : null;
|
|
169
|
-
return {
|
|
170
|
-
operator,
|
|
171
|
-
options,
|
|
172
|
-
value: version ? `${operator}${formatComparableVersion(version)}` : "",
|
|
173
|
-
version
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
function testParsedComparator(comparator, version) {
|
|
177
|
-
if (!comparator.version) return true;
|
|
178
|
-
const comparison = compareParsed(version, comparator.version);
|
|
179
|
-
switch (comparator.operator) {
|
|
180
|
-
case "": return comparison === 0;
|
|
181
|
-
case ">": return comparison > 0;
|
|
182
|
-
case ">=": return comparison >= 0;
|
|
183
|
-
case "<": return comparison < 0;
|
|
184
|
-
case "<=": return comparison <= 0;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
function comparatorAllowsPrerelease(comparator, version) {
|
|
188
|
-
const allowed = comparator.version;
|
|
189
|
-
return allowed !== null && !!allowed.prerelease?.length && allowed.major === version.major && allowed.minor === version.minor && allowed.patch === version.patch;
|
|
190
|
-
}
|
|
191
|
-
function testComparatorSet(set, version, options) {
|
|
192
|
-
if (set.some((comparator) => !testParsedComparator(comparator, version))) return false;
|
|
193
|
-
return !version.prerelease?.length || !!options.includePrerelease || set.some((comparator) => comparatorAllowsPrerelease(comparator, version));
|
|
194
|
-
}
|
|
195
|
-
const BUILD_STRIP = new RegExp(BUILD, "g");
|
|
196
|
-
const BUILD_SAFE = safeRegex(BUILD);
|
|
197
|
-
const STRICT_HYPHEN = safeRegex(String.raw`^\s*(${XRANGE_PLAIN})\s+-\s+(${XRANGE_PLAIN})\s*$`);
|
|
198
|
-
const LOOSE_HYPHEN = safeRegex(String.raw`^\s*(${XRANGE_PLAIN_LOOSE})\s+-\s+(${XRANGE_PLAIN_LOOSE})\s*$`);
|
|
199
|
-
const COMPARATOR_TRIM = safeRegex(String.raw`(\s*)${GREATER_LESS_THAN}\s*(${LOOSE_PLAIN}|${XRANGE_PLAIN})`, "g");
|
|
200
|
-
const TILDE_TRIM = safeRegex(String.raw`(\s*)${LONE_TILDE}\s+`, "g");
|
|
201
|
-
const CARET_TRIM = safeRegex(String.raw`(\s*)${LONE_CARET}\s+`, "g");
|
|
202
|
-
const STRICT_TILDE = safeRegex(`^${LONE_TILDE}${XRANGE_PLAIN}$`);
|
|
203
|
-
const LOOSE_TILDE = safeRegex(`^${LONE_TILDE}${XRANGE_PLAIN_LOOSE}$`);
|
|
204
|
-
const STRICT_CARET = safeRegex(`^${LONE_CARET}${XRANGE_PLAIN}$`);
|
|
205
|
-
const LOOSE_CARET = safeRegex(`^${LONE_CARET}${XRANGE_PLAIN_LOOSE}$`);
|
|
206
|
-
const STRICT_XRANGE = safeRegex(String.raw`^${GREATER_LESS_THAN}\s*${XRANGE_PLAIN}$`);
|
|
207
|
-
const LOOSE_XRANGE = safeRegex(String.raw`^${GREATER_LESS_THAN}\s*${XRANGE_PLAIN_LOOSE}$`);
|
|
208
|
-
const STAR = safeRegex(String.raw`(<|>)?=?\s*\*`);
|
|
209
|
-
const GTE_ZERO = /^\s*>=\s*0\.0\.0\s*$/;
|
|
210
|
-
const GTE_ZERO_PRERELEASE = /^\s*>=\s*0\.0\.0-0\s*$/;
|
|
211
|
-
const LOOSE_COMPARATOR = safeRegex(String.raw`^${GREATER_LESS_THAN}\s*(${LOOSE_PLAIN})$|^$`);
|
|
212
|
-
function isWildcard(value) {
|
|
213
|
-
return !value || String(value).toLowerCase() === "x" || String(value) === "*";
|
|
214
|
-
}
|
|
215
|
-
function hasInvalidWildcardOrder(major, minor, patch) {
|
|
216
|
-
return isWildcard(major) && !isWildcard(minor) || isWildcard(minor) && Boolean(patch) && !isWildcard(patch);
|
|
217
|
-
}
|
|
218
|
-
function replaceTilde(comparator, options) {
|
|
219
|
-
const expression = options.loose ? LOOSE_TILDE : STRICT_TILDE;
|
|
220
|
-
const lowerPrerelease = options.includePrerelease ? "-0" : "";
|
|
221
|
-
return comparator.replace(expression, (_match, major, minor, patch, prerelease) => {
|
|
222
|
-
if (isWildcard(major)) return "";
|
|
223
|
-
if (isWildcard(minor)) return `>=${major}.0.0${lowerPrerelease} <${Number(major) + 1}.0.0-0`;
|
|
224
|
-
if (isWildcard(patch)) return `>=${major}.${minor}.0${lowerPrerelease} <${major}.${Number(minor) + 1}.0-0`;
|
|
225
|
-
return prerelease ? `>=${major}.${minor}.${patch}-${prerelease} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.${patch} <${major}.${Number(minor) + 1}.0-0`;
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
function replaceTildes(comparator, options) {
|
|
229
|
-
return comparator.trim().split(/\s+/).map((part) => replaceTilde(part, options)).join(" ");
|
|
230
|
-
}
|
|
231
|
-
function replaceCaret(comparator, options) {
|
|
232
|
-
const expression = options.loose ? LOOSE_CARET : STRICT_CARET;
|
|
233
|
-
const lowerPrerelease = options.includePrerelease ? "-0" : "";
|
|
234
|
-
return comparator.replace(expression, (_match, major, minor, patch, prerelease) => {
|
|
235
|
-
if (isWildcard(major)) return "";
|
|
236
|
-
if (isWildcard(minor)) return `>=${major}.0.0${lowerPrerelease} <${Number(major) + 1}.0.0-0`;
|
|
237
|
-
if (isWildcard(patch)) return major === "0" ? `>=${major}.${minor}.0${lowerPrerelease} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.0${lowerPrerelease} <${Number(major) + 1}.0.0-0`;
|
|
238
|
-
if (prerelease) return major === "0" ? minor === "0" ? `>=${major}.${minor}.${patch}-${prerelease} <${major}.${minor}.${Number(patch) + 1}-0` : `>=${major}.${minor}.${patch}-${prerelease} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.${patch}-${prerelease} <${Number(major) + 1}.0.0-0`;
|
|
239
|
-
return major === "0" ? minor === "0" ? `>=${major}.${minor}.${patch} <${major}.${minor}.${Number(patch) + 1}-0` : `>=${major}.${minor}.${patch} <${major}.${Number(minor) + 1}.0-0` : `>=${major}.${minor}.${patch} <${Number(major) + 1}.0.0-0`;
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
function replaceCarets(comparator, options) {
|
|
243
|
-
return comparator.trim().split(/\s+/).map((part) => replaceCaret(part, options)).join(" ");
|
|
244
|
-
}
|
|
245
|
-
function replaceXRange(comparator, options) {
|
|
246
|
-
const expression = options.loose ? LOOSE_XRANGE : STRICT_XRANGE;
|
|
247
|
-
return comparator.trim().replace(expression, (match, rawOperator, rawMajor, rawMinor, rawPatch) => {
|
|
248
|
-
let operator = rawOperator;
|
|
249
|
-
let major = rawMajor;
|
|
250
|
-
let minor = rawMinor;
|
|
251
|
-
let patch = rawPatch;
|
|
252
|
-
if (hasInvalidWildcardOrder(String(major), minor === void 0 ? void 0 : String(minor), patch === void 0 ? void 0 : String(patch))) return comparator;
|
|
253
|
-
const wildcardMajor = isWildcard(major);
|
|
254
|
-
const wildcardMinor = wildcardMajor || isWildcard(minor);
|
|
255
|
-
const wildcardPatch = wildcardMinor || isWildcard(patch);
|
|
256
|
-
if (operator === "=" && wildcardPatch) operator = "";
|
|
257
|
-
if (wildcardMajor) return operator === ">" || operator === "<" ? "<0.0.0-0" : "*";
|
|
258
|
-
let prerelease = options.includePrerelease ? "-0" : "";
|
|
259
|
-
if (operator && wildcardPatch) {
|
|
260
|
-
if (wildcardMinor) minor = 0;
|
|
261
|
-
patch = 0;
|
|
262
|
-
if (operator === ">") {
|
|
263
|
-
operator = ">=";
|
|
264
|
-
if (wildcardMinor) {
|
|
265
|
-
major = Number(major) + 1;
|
|
266
|
-
minor = 0;
|
|
267
|
-
} else minor = Number(minor) + 1;
|
|
268
|
-
} else if (operator === "<=") {
|
|
269
|
-
operator = "<";
|
|
270
|
-
if (wildcardMinor) major = Number(major) + 1;
|
|
271
|
-
else minor = Number(minor) + 1;
|
|
272
|
-
}
|
|
273
|
-
if (operator === "<") prerelease = "-0";
|
|
274
|
-
return `${operator}${major}.${minor}.${patch}${prerelease}`;
|
|
275
|
-
}
|
|
276
|
-
if (wildcardMinor) return `>=${major}.0.0${prerelease} <${Number(major) + 1}.0.0-0`;
|
|
277
|
-
if (wildcardPatch) return `>=${major}.${minor}.0${prerelease} <${major}.${Number(minor) + 1}.0-0`;
|
|
278
|
-
return match;
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
function replaceXRanges(comparator, options) {
|
|
282
|
-
return comparator.split(/\s+/).map((part) => replaceXRange(part, options)).join(" ");
|
|
283
|
-
}
|
|
284
|
-
function replaceHyphenRange(range, options) {
|
|
285
|
-
const expression = options.loose ? LOOSE_HYPHEN : STRICT_HYPHEN;
|
|
286
|
-
return range.replace(expression, (_match, rawFrom, fromMajor, fromMinor, fromPatch, fromPrerelease, _fromBuild, rawTo, toMajor, toMinor, toPatch, toPrerelease) => {
|
|
287
|
-
let from = rawFrom;
|
|
288
|
-
let to = rawTo;
|
|
289
|
-
if (isWildcard(fromMajor)) from = "";
|
|
290
|
-
else if (isWildcard(fromMinor)) from = `>=${fromMajor}.0.0${options.includePrerelease ? "-0" : ""}`;
|
|
291
|
-
else if (isWildcard(fromPatch)) from = `>=${fromMajor}.${fromMinor}.0${options.includePrerelease ? "-0" : ""}`;
|
|
292
|
-
else if (fromPrerelease) from = `>=${from}`;
|
|
293
|
-
else from = `>=${from}${options.includePrerelease ? "-0" : ""}`;
|
|
294
|
-
if (isWildcard(toMajor)) to = "";
|
|
295
|
-
else if (isWildcard(toMinor)) to = `<${Number(toMajor) + 1}.0.0-0`;
|
|
296
|
-
else if (isWildcard(toPatch)) to = `<${toMajor}.${Number(toMinor) + 1}.0-0`;
|
|
297
|
-
else if (toPrerelease) to = `<=${toMajor}.${toMinor}.${toPatch}-${toPrerelease}`;
|
|
298
|
-
else if (options.includePrerelease) to = `<${toMajor}.${toMinor}.${Number(toPatch) + 1}-0`;
|
|
299
|
-
else to = `<=${to}`;
|
|
300
|
-
return `${from} ${to}`.trim();
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
function expandComparator(comparator, options) {
|
|
304
|
-
return replaceXRanges(replaceTildes(replaceCarets(comparator.replace(BUILD_SAFE, ""), options), options), options).trim().replace(STAR, "");
|
|
305
|
-
}
|
|
306
|
-
function parseSimpleRange(input, options) {
|
|
307
|
-
let parts = replaceHyphenRange(input.replace(BUILD_STRIP, ""), options).replace(COMPARATOR_TRIM, "$1$2$3").replace(TILDE_TRIM, "$1~").replace(CARET_TRIM, "$1^").split(" ").map((part) => expandComparator(part, options)).join(" ").split(/\s+/).map((part) => part.trim().replace(options.includePrerelease ? GTE_ZERO_PRERELEASE : GTE_ZERO, ""));
|
|
308
|
-
if (options.loose) parts = parts.filter((part) => LOOSE_COMPARATOR.test(part));
|
|
309
|
-
const unique = /* @__PURE__ */ new Map();
|
|
310
|
-
for (const comparator of parts.map((part) => parseComparator(part, options))) {
|
|
311
|
-
if (comparator.value === "<0.0.0-0") return [comparator];
|
|
312
|
-
unique.set(comparator.value, comparator);
|
|
313
|
-
}
|
|
314
|
-
if (unique.size > 1) unique.delete("");
|
|
315
|
-
return [...unique.values()];
|
|
316
|
-
}
|
|
317
|
-
function parseRange(range, options = {}) {
|
|
318
|
-
if (typeof range !== "string") return range;
|
|
319
|
-
const parsedOptions = { ...options };
|
|
320
|
-
const raw = range.trim().replaceAll(/\s+/g, " ");
|
|
321
|
-
let sets = raw.split("||").map((part) => parseSimpleRange(part.trim(), parsedOptions)).filter((set) => set.length);
|
|
322
|
-
if (!sets.length) throw new TypeError(`Range contains no valid comparator sets: ${raw}`);
|
|
323
|
-
if (sets.length > 1) {
|
|
324
|
-
const first = sets[0];
|
|
325
|
-
sets = sets.filter((set) => set[0]?.value !== "<0.0.0-0");
|
|
326
|
-
if (!sets.length) sets = [first];
|
|
327
|
-
else if (sets.length > 1) {
|
|
328
|
-
const any = sets.find((set) => set.length === 1 && set[0]?.value === "");
|
|
329
|
-
if (any) sets = [any];
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
return {
|
|
333
|
-
normalized: sets.map((set) => set.map((comparator) => comparator.value).join(" ")).join("||"),
|
|
334
|
-
options: parsedOptions,
|
|
335
|
-
raw,
|
|
336
|
-
sets
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
function tryParseRange(range, options = {}) {
|
|
340
|
-
try {
|
|
341
|
-
return parseRange(range, options);
|
|
342
|
-
} catch {
|
|
343
|
-
return null;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
function testParsedRange(range, version) {
|
|
347
|
-
return range.sets.some((set) => testComparatorSet(set, version, range.options));
|
|
348
|
-
}
|
|
349
|
-
function testRangeVersion(range, version) {
|
|
350
|
-
const parsed = tryParse(version, range.options);
|
|
351
|
-
return parsed ? testParsedRange(range, parsed) : false;
|
|
352
|
-
}
|
|
353
|
-
function satisfies(version, range, options = {}) {
|
|
354
|
-
const parsed = tryParseRange(range, options);
|
|
355
|
-
return parsed ? testRangeVersion(parsed, version) : false;
|
|
356
|
-
}
|
|
357
|
-
function coerce(value, options = {}) {
|
|
358
|
-
const parsed = coerceParsedVersion(value, options);
|
|
359
|
-
return parsed ? formatFullVersion(parsed) : null;
|
|
360
|
-
}
|
|
361
|
-
const semverSatisfies = (targetAppVersion, currentVersion) => {
|
|
362
|
-
const currentCoerce = coerce(currentVersion);
|
|
363
|
-
if (!currentCoerce) return false;
|
|
364
|
-
return satisfies(currentCoerce, targetAppVersion);
|
|
365
|
-
};
|
|
366
|
-
/**
|
|
367
|
-
* Filters target app versions that are compatible with the current app version.
|
|
368
|
-
* Returns only versions that are compatible with the current version according to semver rules.
|
|
369
|
-
*
|
|
370
|
-
* @param targetAppVersionList - List of target app versions to filter
|
|
371
|
-
* @param currentVersion - Current app version
|
|
372
|
-
* @returns Array of target app versions compatible with the current version
|
|
373
|
-
*/
|
|
374
|
-
const filterCompatibleAppVersions = (targetAppVersionList, currentVersion) => {
|
|
375
|
-
return targetAppVersionList.filter((version) => semverSatisfies(version, currentVersion)).sort((a, b) => b.localeCompare(a));
|
|
28
|
+
pg = __toESM(pg);
|
|
29
|
+
//#region src/postgresQuery.ts
|
|
30
|
+
const applyOrder = (order, clause) => {
|
|
31
|
+
const directed = clause.direction === "asc" ? order.asc() : order.desc();
|
|
32
|
+
return clause.nulls === void 0 ? directed : clause.nulls === "first" ? directed.nullsFirst() : directed.nullsLast();
|
|
376
33
|
};
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
const isObject$1 = (value) => typeof value === "object" && value !== null;
|
|
385
|
-
const isObjectCustom = (value) => isObject$1(value) && !(value instanceof RegExp) && !(value instanceof Error) && !(value instanceof Date);
|
|
386
|
-
const mapObjectSkip = Symbol("mapObjectSkip");
|
|
387
|
-
const _mapObject = (object, mapper, options, isSeen = /* @__PURE__ */ new WeakMap()) => {
|
|
388
|
-
options = {
|
|
389
|
-
deep: false,
|
|
390
|
-
target: {},
|
|
391
|
-
...options
|
|
392
|
-
};
|
|
393
|
-
if (isSeen.has(object)) return isSeen.get(object);
|
|
394
|
-
isSeen.set(object, options.target);
|
|
395
|
-
const { target } = options;
|
|
396
|
-
delete options.target;
|
|
397
|
-
const mapArray = (array) => array.map((element) => isObjectCustom(element) ? _mapObject(element, mapper, options, isSeen) : element);
|
|
398
|
-
if (Array.isArray(object)) return mapArray(object);
|
|
399
|
-
for (const [key, value] of Object.entries(object)) {
|
|
400
|
-
const mapResult = mapper(key, value, object);
|
|
401
|
-
if (mapResult === mapObjectSkip) continue;
|
|
402
|
-
let [newKey, newValue, { shouldRecurse = true } = {}] = mapResult;
|
|
403
|
-
if (newKey === "__proto__") continue;
|
|
404
|
-
if (options.deep && shouldRecurse && isObjectCustom(newValue)) newValue = Array.isArray(newValue) ? mapArray(newValue) : _mapObject(newValue, mapper, options, isSeen);
|
|
405
|
-
target[newKey] = newValue;
|
|
406
|
-
}
|
|
407
|
-
return target;
|
|
408
|
-
};
|
|
409
|
-
function mapObject(object, mapper, options) {
|
|
410
|
-
if (!isObject$1(object)) throw new TypeError(`Expected an object, got \`${object}\` (${typeof object})`);
|
|
411
|
-
return _mapObject(object, mapper, options);
|
|
412
|
-
}
|
|
413
|
-
//#endregion
|
|
414
|
-
//#region ../../node_modules/.pnpm/camelcase@8.0.0/node_modules/camelcase/index.js
|
|
415
|
-
const UPPERCASE = /[\p{Lu}]/u;
|
|
416
|
-
const LOWERCASE = /[\p{Ll}]/u;
|
|
417
|
-
const LEADING_CAPITAL = /^[\p{Lu}](?![\p{Lu}])/gu;
|
|
418
|
-
const IDENTIFIER = /([\p{Alpha}\p{N}_]|$)/u;
|
|
419
|
-
const SEPARATORS = /[_.\- ]+/;
|
|
420
|
-
const LEADING_SEPARATORS = new RegExp("^" + SEPARATORS.source);
|
|
421
|
-
const SEPARATORS_AND_IDENTIFIER = new RegExp(SEPARATORS.source + IDENTIFIER.source, "gu");
|
|
422
|
-
const NUMBERS_AND_IDENTIFIER = new RegExp("\\d+" + IDENTIFIER.source, "gu");
|
|
423
|
-
const preserveCamelCase = (string, toLowerCase, toUpperCase, preserveConsecutiveUppercase) => {
|
|
424
|
-
let isLastCharLower = false;
|
|
425
|
-
let isLastCharUpper = false;
|
|
426
|
-
let isLastLastCharUpper = false;
|
|
427
|
-
let isLastLastCharPreserved = false;
|
|
428
|
-
for (let index = 0; index < string.length; index++) {
|
|
429
|
-
const character = string[index];
|
|
430
|
-
isLastLastCharPreserved = index > 2 ? string[index - 3] === "-" : true;
|
|
431
|
-
if (isLastCharLower && UPPERCASE.test(character)) {
|
|
432
|
-
string = string.slice(0, index) + "-" + string.slice(index);
|
|
433
|
-
isLastCharLower = false;
|
|
434
|
-
isLastLastCharUpper = isLastCharUpper;
|
|
435
|
-
isLastCharUpper = true;
|
|
436
|
-
index++;
|
|
437
|
-
} else if (isLastCharUpper && isLastLastCharUpper && LOWERCASE.test(character) && (!isLastLastCharPreserved || preserveConsecutiveUppercase)) {
|
|
438
|
-
string = string.slice(0, index - 1) + "-" + string.slice(index - 1);
|
|
439
|
-
isLastLastCharUpper = isLastCharUpper;
|
|
440
|
-
isLastCharUpper = false;
|
|
441
|
-
isLastCharLower = true;
|
|
442
|
-
} else {
|
|
443
|
-
isLastCharLower = toLowerCase(character) === character && toUpperCase(character) !== character;
|
|
444
|
-
isLastLastCharUpper = isLastCharUpper;
|
|
445
|
-
isLastCharUpper = toUpperCase(character) === character && toLowerCase(character) !== character;
|
|
34
|
+
const countPostgresRows = async (db, input, where) => {
|
|
35
|
+
switch (input.model) {
|
|
36
|
+
case "bundles": {
|
|
37
|
+
let rows = db.selectFrom("bundles");
|
|
38
|
+
if (where !== void 0) rows = rows.where(where);
|
|
39
|
+
const query = input.distinct === void 0 ? rows.select(({ fn }) => fn.countAll().as("count")) : db.selectFrom(rows.select(input.distinct).distinct().as("distinct_rows")).select(({ fn }) => fn.countAll().as("count"));
|
|
40
|
+
return Number((await query.executeTakeFirstOrThrow()).count);
|
|
446
41
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
const
|
|
451
|
-
|
|
452
|
-
return input.replaceAll(LEADING_CAPITAL, (match) => toLowerCase(match));
|
|
453
|
-
};
|
|
454
|
-
const postProcess = (input, toUpperCase) => {
|
|
455
|
-
SEPARATORS_AND_IDENTIFIER.lastIndex = 0;
|
|
456
|
-
NUMBERS_AND_IDENTIFIER.lastIndex = 0;
|
|
457
|
-
return input.replaceAll(NUMBERS_AND_IDENTIFIER, (match, pattern, offset) => ["_", "-"].includes(input.charAt(offset + match.length)) ? match : toUpperCase(match)).replaceAll(SEPARATORS_AND_IDENTIFIER, (_, identifier) => toUpperCase(identifier));
|
|
458
|
-
};
|
|
459
|
-
function camelCase(input, options) {
|
|
460
|
-
if (!(typeof input === "string" || Array.isArray(input))) throw new TypeError("Expected the input to be `string | string[]`");
|
|
461
|
-
options = {
|
|
462
|
-
pascalCase: false,
|
|
463
|
-
preserveConsecutiveUppercase: false,
|
|
464
|
-
...options
|
|
465
|
-
};
|
|
466
|
-
if (Array.isArray(input)) input = input.map((x) => x.trim()).filter((x) => x.length).join("-");
|
|
467
|
-
else input = input.trim();
|
|
468
|
-
if (input.length === 0) return "";
|
|
469
|
-
const toLowerCase = options.locale === false ? (string) => string.toLowerCase() : (string) => string.toLocaleLowerCase(options.locale);
|
|
470
|
-
const toUpperCase = options.locale === false ? (string) => string.toUpperCase() : (string) => string.toLocaleUpperCase(options.locale);
|
|
471
|
-
if (input.length === 1) {
|
|
472
|
-
if (SEPARATORS.test(input)) return "";
|
|
473
|
-
return options.pascalCase ? toUpperCase(input) : toLowerCase(input);
|
|
474
|
-
}
|
|
475
|
-
if (input !== toLowerCase(input)) input = preserveCamelCase(input, toLowerCase, toUpperCase, options.preserveConsecutiveUppercase);
|
|
476
|
-
input = input.replace(LEADING_SEPARATORS, "");
|
|
477
|
-
input = options.preserveConsecutiveUppercase ? preserveConsecutiveUppercase(input, toLowerCase) : toLowerCase(input);
|
|
478
|
-
if (options.pascalCase) input = toUpperCase(input.charAt(0)) + input.slice(1);
|
|
479
|
-
return postProcess(input, toUpperCase);
|
|
480
|
-
}
|
|
481
|
-
//#endregion
|
|
482
|
-
//#region ../../node_modules/.pnpm/quick-lru@6.1.2/node_modules/quick-lru/index.js
|
|
483
|
-
var QuickLRU = class extends Map {
|
|
484
|
-
constructor(options = {}) {
|
|
485
|
-
super();
|
|
486
|
-
if (!(options.maxSize && options.maxSize > 0)) throw new TypeError("`maxSize` must be a number greater than 0");
|
|
487
|
-
if (typeof options.maxAge === "number" && options.maxAge === 0) throw new TypeError("`maxAge` must be a number greater than 0");
|
|
488
|
-
this.maxSize = options.maxSize;
|
|
489
|
-
this.maxAge = options.maxAge || Number.POSITIVE_INFINITY;
|
|
490
|
-
this.onEviction = options.onEviction;
|
|
491
|
-
this.cache = /* @__PURE__ */ new Map();
|
|
492
|
-
this.oldCache = /* @__PURE__ */ new Map();
|
|
493
|
-
this._size = 0;
|
|
494
|
-
}
|
|
495
|
-
_emitEvictions(cache) {
|
|
496
|
-
if (typeof this.onEviction !== "function") return;
|
|
497
|
-
for (const [key, item] of cache) this.onEviction(key, item.value);
|
|
498
|
-
}
|
|
499
|
-
_deleteIfExpired(key, item) {
|
|
500
|
-
if (typeof item.expiry === "number" && item.expiry <= Date.now()) {
|
|
501
|
-
if (typeof this.onEviction === "function") this.onEviction(key, item.value);
|
|
502
|
-
return this.delete(key);
|
|
42
|
+
case "bundle_patches": {
|
|
43
|
+
let rows = db.selectFrom("bundle_patches");
|
|
44
|
+
if (where !== void 0) rows = rows.where(where);
|
|
45
|
+
const query = input.distinct === void 0 ? rows.select(({ fn }) => fn.countAll().as("count")) : db.selectFrom(rows.select(input.distinct).distinct().as("distinct_rows")).select(({ fn }) => fn.countAll().as("count"));
|
|
46
|
+
return Number((await query.executeTakeFirstOrThrow()).count);
|
|
503
47
|
}
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
_getItemValue(key, item) {
|
|
510
|
-
return item.expiry ? this._getOrDeleteIfExpired(key, item) : item.value;
|
|
511
|
-
}
|
|
512
|
-
_peek(key, cache) {
|
|
513
|
-
const item = cache.get(key);
|
|
514
|
-
return this._getItemValue(key, item);
|
|
515
|
-
}
|
|
516
|
-
_set(key, value) {
|
|
517
|
-
this.cache.set(key, value);
|
|
518
|
-
this._size++;
|
|
519
|
-
if (this._size >= this.maxSize) {
|
|
520
|
-
this._size = 0;
|
|
521
|
-
this._emitEvictions(this.oldCache);
|
|
522
|
-
this.oldCache = this.cache;
|
|
523
|
-
this.cache = /* @__PURE__ */ new Map();
|
|
48
|
+
case "releases": {
|
|
49
|
+
let rows = db.selectFrom("releases");
|
|
50
|
+
if (where !== void 0) rows = rows.where(where);
|
|
51
|
+
const query = rows.select(({ fn }) => fn.countAll().as("count"));
|
|
52
|
+
return Number((await query.executeTakeFirstOrThrow()).count);
|
|
524
53
|
}
|
|
525
54
|
}
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
for (const item of this.cache) {
|
|
538
|
-
const [key, value] = item;
|
|
539
|
-
if (this._deleteIfExpired(key, value) === false) yield item;
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
get(key) {
|
|
543
|
-
if (this.cache.has(key)) {
|
|
544
|
-
const item = this.cache.get(key);
|
|
545
|
-
return this._getItemValue(key, item);
|
|
55
|
+
};
|
|
56
|
+
const findManyPostgresRows = async (db, input, where) => {
|
|
57
|
+
switch (input.model) {
|
|
58
|
+
case "bundles": {
|
|
59
|
+
let query = db.selectFrom("bundles").selectAll();
|
|
60
|
+
if (where !== void 0) query = query.where(where);
|
|
61
|
+
if (input.distinctOn !== void 0) query = query.distinctOn(input.distinctOn.fields);
|
|
62
|
+
for (const clause of input.orderBy ?? []) query = query.orderBy(clause.field, (order) => applyOrder(order, clause));
|
|
63
|
+
return query.limit(input.limit).offset(input.offset).execute();
|
|
546
64
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
if (
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
}
|
|
65
|
+
case "release_catalogs": {
|
|
66
|
+
let query = db.selectFrom("release_catalogs").selectAll();
|
|
67
|
+
if (where !== void 0) query = query.where(where);
|
|
68
|
+
for (const clause of input.orderBy ?? []) query = query.orderBy(clause.field, (order) => applyOrder(order, clause));
|
|
69
|
+
return query.limit(input.limit).offset(input.offset).execute();
|
|
553
70
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
});
|
|
561
|
-
else this._set(key, {
|
|
562
|
-
value,
|
|
563
|
-
expiry
|
|
564
|
-
});
|
|
565
|
-
return this;
|
|
566
|
-
}
|
|
567
|
-
has(key) {
|
|
568
|
-
if (this.cache.has(key)) return !this._deleteIfExpired(key, this.cache.get(key));
|
|
569
|
-
if (this.oldCache.has(key)) return !this._deleteIfExpired(key, this.oldCache.get(key));
|
|
570
|
-
return false;
|
|
571
|
-
}
|
|
572
|
-
peek(key) {
|
|
573
|
-
if (this.cache.has(key)) return this._peek(key, this.cache);
|
|
574
|
-
if (this.oldCache.has(key)) return this._peek(key, this.oldCache);
|
|
575
|
-
}
|
|
576
|
-
delete(key) {
|
|
577
|
-
const deleted = this.cache.delete(key);
|
|
578
|
-
if (deleted) this._size--;
|
|
579
|
-
return this.oldCache.delete(key) || deleted;
|
|
580
|
-
}
|
|
581
|
-
clear() {
|
|
582
|
-
this.cache.clear();
|
|
583
|
-
this.oldCache.clear();
|
|
584
|
-
this._size = 0;
|
|
585
|
-
}
|
|
586
|
-
resize(newSize) {
|
|
587
|
-
if (!(newSize && newSize > 0)) throw new TypeError("`maxSize` must be a number greater than 0");
|
|
588
|
-
const items = [...this._entriesAscending()];
|
|
589
|
-
const removeCount = items.length - newSize;
|
|
590
|
-
if (removeCount < 0) {
|
|
591
|
-
this.cache = new Map(items);
|
|
592
|
-
this.oldCache = /* @__PURE__ */ new Map();
|
|
593
|
-
this._size = items.length;
|
|
594
|
-
} else {
|
|
595
|
-
if (removeCount > 0) this._emitEvictions(items.slice(0, removeCount));
|
|
596
|
-
this.oldCache = new Map(items.slice(removeCount));
|
|
597
|
-
this.cache = /* @__PURE__ */ new Map();
|
|
598
|
-
this._size = 0;
|
|
71
|
+
case "bundle_events": {
|
|
72
|
+
let query = db.selectFrom("bundle_events").selectAll();
|
|
73
|
+
if (where !== void 0) query = query.where(where);
|
|
74
|
+
if (input.distinctOn !== void 0) query = query.distinctOn(input.distinctOn.fields);
|
|
75
|
+
for (const clause of input.orderBy ?? []) query = query.orderBy(clause.field, (order) => applyOrder(order, clause));
|
|
76
|
+
return query.limit(input.limit).offset(input.offset).execute();
|
|
599
77
|
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
*values() {
|
|
606
|
-
for (const [, value] of this) yield value;
|
|
607
|
-
}
|
|
608
|
-
*[Symbol.iterator]() {
|
|
609
|
-
for (const item of this.cache) {
|
|
610
|
-
const [key, value] = item;
|
|
611
|
-
if (this._deleteIfExpired(key, value) === false) yield [key, value.value];
|
|
78
|
+
case "channels": {
|
|
79
|
+
let query = db.selectFrom("channels").selectAll();
|
|
80
|
+
if (where !== void 0) query = query.where(where);
|
|
81
|
+
for (const clause of input.orderBy ?? []) query = query.orderBy(clause.field, (order) => applyOrder(order, clause));
|
|
82
|
+
return query.limit(input.limit).offset(input.offset).execute();
|
|
612
83
|
}
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
if (
|
|
616
|
-
|
|
617
|
-
|
|
84
|
+
case "api_keys": {
|
|
85
|
+
let query = db.selectFrom("api_keys").selectAll();
|
|
86
|
+
if (where !== void 0) query = query.where(where);
|
|
87
|
+
if (input.distinctOn !== void 0) query = query.distinctOn(input.distinctOn.fields);
|
|
88
|
+
for (const clause of input.orderBy ?? []) query = query.orderBy(clause.field, (order) => applyOrder(order, clause));
|
|
89
|
+
return query.limit(input.limit).offset(input.offset).execute();
|
|
618
90
|
}
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
const [
|
|
624
|
-
|
|
91
|
+
case "bundle_patches": {
|
|
92
|
+
let query = db.selectFrom("bundle_patches").selectAll();
|
|
93
|
+
if (where !== void 0) query = query.where(where);
|
|
94
|
+
if (input.distinctOn !== void 0) query = query.distinctOn(input.distinctOn.fields);
|
|
95
|
+
for (const clause of input.orderBy ?? []) query = query.orderBy(clause.field, (order) => applyOrder(order, clause));
|
|
96
|
+
return query.limit(input.limit).offset(input.offset).execute();
|
|
625
97
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
}
|
|
98
|
+
case "releases": {
|
|
99
|
+
let query = db.selectFrom("releases").selectAll();
|
|
100
|
+
if (where !== void 0) query = query.where(where);
|
|
101
|
+
for (const clause of input.orderBy ?? []) query = query.orderBy(clause.field, (order) => applyOrder(order, clause));
|
|
102
|
+
return query.limit(input.limit).offset(input.offset).execute();
|
|
632
103
|
}
|
|
633
104
|
}
|
|
634
|
-
*entriesAscending() {
|
|
635
|
-
for (const [key, value] of this._entriesAscending()) yield [key, value.value];
|
|
636
|
-
}
|
|
637
|
-
get size() {
|
|
638
|
-
if (!this._size) return this.oldCache.size;
|
|
639
|
-
let oldCacheSize = 0;
|
|
640
|
-
for (const key of this.oldCache.keys()) if (!this.cache.has(key)) oldCacheSize++;
|
|
641
|
-
return Math.min(this._size + oldCacheSize, this.maxSize);
|
|
642
|
-
}
|
|
643
|
-
entries() {
|
|
644
|
-
return this.entriesAscending();
|
|
645
|
-
}
|
|
646
|
-
forEach(callbackFunction, thisArgument = this) {
|
|
647
|
-
for (const [key, value] of this.entriesAscending()) callbackFunction.call(thisArgument, value, key, this);
|
|
648
|
-
}
|
|
649
|
-
get [Symbol.toStringTag]() {
|
|
650
|
-
return JSON.stringify([...this.entriesAscending()]);
|
|
651
|
-
}
|
|
652
105
|
};
|
|
653
106
|
//#endregion
|
|
654
|
-
//#region
|
|
655
|
-
const
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
return element.test(key);
|
|
659
|
-
});
|
|
660
|
-
const cache = new QuickLRU({ maxSize: 1e5 });
|
|
661
|
-
const isObject = (value) => typeof value === "object" && value !== null && !(value instanceof RegExp) && !(value instanceof Error) && !(value instanceof Date);
|
|
662
|
-
const transform = (input, options = {}) => {
|
|
663
|
-
if (!isObject(input)) return input;
|
|
664
|
-
const { exclude, pascalCase = false, stopPaths, deep = false, preserveConsecutiveUppercase = false } = options;
|
|
665
|
-
const stopPathsSet = new Set(stopPaths);
|
|
666
|
-
const makeMapper = (parentPath) => (key, value) => {
|
|
667
|
-
if (deep && isObject(value)) {
|
|
668
|
-
const path = parentPath === void 0 ? key : `${parentPath}.${key}`;
|
|
669
|
-
if (!stopPathsSet.has(path)) value = mapObject(value, makeMapper(path));
|
|
670
|
-
}
|
|
671
|
-
if (!(exclude && has(exclude, key))) {
|
|
672
|
-
const cacheKey = pascalCase ? `${key}_` : key;
|
|
673
|
-
if (cache.has(cacheKey)) key = cache.get(cacheKey);
|
|
674
|
-
else {
|
|
675
|
-
const returnValue = camelCase(key, {
|
|
676
|
-
pascalCase,
|
|
677
|
-
locale: false,
|
|
678
|
-
preserveConsecutiveUppercase
|
|
679
|
-
});
|
|
680
|
-
if (key.length < 100) cache.set(cacheKey, returnValue);
|
|
681
|
-
key = returnValue;
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
return [key, value];
|
|
685
|
-
};
|
|
686
|
-
return mapObject(input, makeMapper(void 0));
|
|
107
|
+
//#region src/postgres.ts
|
|
108
|
+
const { Pool } = pg.default;
|
|
109
|
+
var InvalidPostgresPredicateError = class extends Error {
|
|
110
|
+
name = "InvalidPostgresPredicateError";
|
|
687
111
|
};
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
112
|
+
const isForeignKeyViolation = (error) => typeof error === "object" && error !== null && Reflect.get(error, "code") === "23503";
|
|
113
|
+
const escapeLikePattern = (value) => value.replaceAll("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_");
|
|
114
|
+
const stringPredicate = (condition, operator) => {
|
|
115
|
+
if (typeof condition.value !== "string") throw new InvalidPostgresPredicateError();
|
|
116
|
+
const column = kysely.sql.ref(condition.field);
|
|
117
|
+
const literal = escapeLikePattern(condition.value);
|
|
118
|
+
const pattern = operator === "contains" ? `%${literal}%` : operator === "starts_with" ? `${literal}%` : `%${literal}`;
|
|
119
|
+
return "mode" in condition && condition.mode === "insensitive" ? kysely.sql`lower(${column}) like lower(${pattern}) escape '\\'` : kysely.sql`${column} like ${pattern} escape '\\'`;
|
|
120
|
+
};
|
|
121
|
+
const predicate = (condition) => {
|
|
122
|
+
const column = kysely.sql.ref(condition.field);
|
|
123
|
+
const operator = condition.operator ?? "eq";
|
|
124
|
+
switch (operator) {
|
|
125
|
+
case "eq":
|
|
126
|
+
case "ne":
|
|
127
|
+
if (condition.value === null) return operator === "eq" ? kysely.sql`${column} is null` : kysely.sql`${column} is not null`;
|
|
128
|
+
if ("mode" in condition && condition.mode === "insensitive") return operator === "eq" ? kysely.sql`lower(${column}) = lower(${condition.value})` : kysely.sql`lower(${column}) <> lower(${condition.value})`;
|
|
129
|
+
return operator === "eq" ? kysely.sql`${column} = ${condition.value}` : kysely.sql`${column} <> ${condition.value}`;
|
|
130
|
+
case "gt": return kysely.sql`${column} > ${condition.value}`;
|
|
131
|
+
case "gte": return kysely.sql`${column} >= ${condition.value}`;
|
|
132
|
+
case "lt": return kysely.sql`${column} < ${condition.value}`;
|
|
133
|
+
case "lte": return kysely.sql`${column} <= ${condition.value}`;
|
|
134
|
+
case "in":
|
|
135
|
+
case "not_in":
|
|
136
|
+
if (!Array.isArray(condition.value)) throw new InvalidPostgresPredicateError();
|
|
137
|
+
if (condition.value.length === 0) return kysely.sql`${operator === "not_in"}`;
|
|
138
|
+
return operator === "in" ? kysely.sql`${column} in (${kysely.sql.join(condition.value)})` : kysely.sql`${column} not in (${kysely.sql.join(condition.value)})`;
|
|
139
|
+
case "contains":
|
|
140
|
+
case "starts_with":
|
|
141
|
+
case "ends_with": return stringPredicate(condition, operator);
|
|
715
142
|
}
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
name: "unclosedText",
|
|
741
|
-
message: "Unclosed text block."
|
|
742
|
-
},
|
|
743
|
-
{
|
|
744
|
-
name: "unclosedQI",
|
|
745
|
-
message: "Unclosed quoted identifier."
|
|
746
|
-
},
|
|
747
|
-
{
|
|
748
|
-
name: "multiLineQI",
|
|
749
|
-
message: "Multi-line quoted identifiers are not supported."
|
|
143
|
+
};
|
|
144
|
+
const buildWhere = (where) => {
|
|
145
|
+
const [first, ...rest] = where ?? [];
|
|
146
|
+
if (first === void 0) return;
|
|
147
|
+
let expression = predicate(first);
|
|
148
|
+
for (const condition of rest) {
|
|
149
|
+
const next = predicate(condition);
|
|
150
|
+
expression = condition.connector === "OR" ? kysely.sql`(${expression} or ${next})` : kysely.sql`(${expression} and ${next})`;
|
|
151
|
+
}
|
|
152
|
+
return expression;
|
|
153
|
+
};
|
|
154
|
+
const createPostgresImplementation = (db) => ({
|
|
155
|
+
async create(input) {
|
|
156
|
+
switch (input.model) {
|
|
157
|
+
case "bundles": return db.insertInto("bundles").values(input.data).returningAll().executeTakeFirstOrThrow();
|
|
158
|
+
case "bundle_patches": return db.insertInto("bundle_patches").values(input.data).returningAll().executeTakeFirstOrThrow();
|
|
159
|
+
case "bundle_events": return db.insertInto("bundle_events").values(input.data).returningAll().executeTakeFirstOrThrow();
|
|
160
|
+
case "releases": return db.insertInto("releases").values(input.data).returningAll().executeTakeFirstOrThrow();
|
|
161
|
+
case "release_catalogs": return db.insertInto("release_catalogs").values(input.data).returningAll().executeTakeFirstOrThrow();
|
|
162
|
+
case "channels": {
|
|
163
|
+
const query = db.insertInto("channels").values(input.data);
|
|
164
|
+
return await (input.onConflict === "ignore" ? query.onConflict((conflict) => conflict.column("name").doNothing()) : query).returningAll().executeTakeFirst() ?? await db.selectFrom("channels").selectAll().where("name", "=", input.data.name).executeTakeFirstOrThrow();
|
|
165
|
+
}
|
|
166
|
+
case "api_keys": return await (input.onConflict === "ignore" ? db.insertInto("api_keys").values(input.data).onConflict((conflict) => conflict.column("hash").doNothing()) : db.insertInto("api_keys").values(input.data)).returningAll().executeTakeFirst() ?? await db.selectFrom("api_keys").selectAll().where("hash", "=", input.data.hash).executeTakeFirstOrThrow();
|
|
750
167
|
}
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
this.error = err;
|
|
759
|
-
this.code = code;
|
|
760
|
-
this.position = position;
|
|
761
|
-
Error.captureStackTrace(this, this.constructor);
|
|
168
|
+
},
|
|
169
|
+
async update(input) {
|
|
170
|
+
const where = buildWhere(input.where);
|
|
171
|
+
if (input.model === "api_keys") {
|
|
172
|
+
let query = db.updateTable("api_keys").set(input.update);
|
|
173
|
+
if (where !== void 0) query = query.where(where);
|
|
174
|
+
return await query.returningAll().executeTakeFirst() ?? null;
|
|
762
175
|
}
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
var require_parser = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
786
|
-
const { parsingErrorCode, SQLParsingError } = require_error();
|
|
787
|
-
const { getIndexPos } = require_utils();
|
|
788
|
-
const compressors = ".,;:()[]=<>+-*/|!?@#";
|
|
789
|
-
function minify(sql, options) {
|
|
790
|
-
if (typeof sql !== "string") throw new TypeError("Input SQL must be a text string.");
|
|
791
|
-
if (!sql.length) return "";
|
|
792
|
-
sql = sql.replace(/\r\n/g, "\n");
|
|
793
|
-
options = options || {};
|
|
794
|
-
let idx = 0, result = "", space = false;
|
|
795
|
-
const len = sql.length;
|
|
796
|
-
do {
|
|
797
|
-
const s = sql[idx], s1 = sql[idx + 1];
|
|
798
|
-
if (isGap(s)) {
|
|
799
|
-
while (++idx < len && isGap(sql[idx]));
|
|
800
|
-
if (idx < len) space = true;
|
|
801
|
-
idx--;
|
|
802
|
-
continue;
|
|
176
|
+
if (input.model === "releases") {
|
|
177
|
+
let query = db.updateTable("releases").set(input.update);
|
|
178
|
+
if (where !== void 0) query = query.where(where);
|
|
179
|
+
return await query.returningAll().executeTakeFirst() ?? null;
|
|
180
|
+
}
|
|
181
|
+
if (input.model === "release_catalogs") {
|
|
182
|
+
let query = db.updateTable("release_catalogs").set(input.update);
|
|
183
|
+
if (where !== void 0) query = query.where(where);
|
|
184
|
+
return await query.returningAll().executeTakeFirst() ?? null;
|
|
185
|
+
}
|
|
186
|
+
let query = db.updateTable("bundles").set(input.update);
|
|
187
|
+
if (where !== void 0) query = query.where(where);
|
|
188
|
+
return await query.returningAll().executeTakeFirst() ?? null;
|
|
189
|
+
},
|
|
190
|
+
async delete(input) {
|
|
191
|
+
const where = buildWhere(input.where);
|
|
192
|
+
switch (input.model) {
|
|
193
|
+
case "bundles": {
|
|
194
|
+
let query = db.deleteFrom("bundles");
|
|
195
|
+
if (where !== void 0) query = query.where(where);
|
|
196
|
+
await query.execute();
|
|
197
|
+
return;
|
|
803
198
|
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
if (
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
continue;
|
|
199
|
+
case "bundle_patches": {
|
|
200
|
+
let query = db.deleteFrom("bundle_patches");
|
|
201
|
+
if (where !== void 0) query = query.where(where);
|
|
202
|
+
await query.execute();
|
|
203
|
+
return;
|
|
810
204
|
}
|
|
811
|
-
|
|
812
|
-
let
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
close++;
|
|
820
|
-
c++;
|
|
821
|
-
}
|
|
822
|
-
if (close <= open) {
|
|
823
|
-
idx = lastOpen;
|
|
824
|
-
throwError(parsingErrorCode.unclosedMLC);
|
|
825
|
-
}
|
|
826
|
-
if (sql[idx + 2] === "!" && !options.removeAll) {
|
|
827
|
-
if (options.compress) space = false;
|
|
828
|
-
addSpace();
|
|
829
|
-
result += sql.substring(idx, lastClose + 2).replace(/\n/g, "\r\n");
|
|
205
|
+
case "channels": {
|
|
206
|
+
let query = db.deleteFrom("channels");
|
|
207
|
+
if (where !== void 0) query = query.where(where);
|
|
208
|
+
try {
|
|
209
|
+
await query.execute();
|
|
210
|
+
} catch (error) {
|
|
211
|
+
if (isForeignKeyViolation(error)) throw new _hot_updater_plugin_core_internal.DatabaseRowReferencedError();
|
|
212
|
+
throw error;
|
|
830
213
|
}
|
|
831
|
-
idx = lastClose + 1;
|
|
832
|
-
skipGaps();
|
|
833
|
-
continue;
|
|
834
214
|
}
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
text = sql.substring(idx, closeIdx + 1);
|
|
840
|
-
if (text.indexOf("\n") > 0) throwError(parsingErrorCode.multiLineQI);
|
|
841
|
-
if (options.compress) space = false;
|
|
842
|
-
addSpace();
|
|
843
|
-
result += text;
|
|
844
|
-
idx = closeIdx;
|
|
845
|
-
skipGaps();
|
|
846
|
-
continue;
|
|
215
|
+
case "releases": {
|
|
216
|
+
let query = db.deleteFrom("releases");
|
|
217
|
+
if (where !== void 0) query = query.where(where);
|
|
218
|
+
await query.execute();
|
|
847
219
|
}
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
if ((step - closeIdx) % 2) {
|
|
859
|
-
closeIdx = step - 1;
|
|
860
|
-
break;
|
|
861
|
-
}
|
|
862
|
-
closeIdx = step === len ? -1 : step;
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
} while (closeIdx > 0);
|
|
866
|
-
if (closeIdx < 0) throwError(parsingErrorCode.unclosedText);
|
|
867
|
-
if (options.compress) space = false;
|
|
868
|
-
addSpace();
|
|
869
|
-
text = sql.substring(idx, closeIdx + 1);
|
|
870
|
-
const hasLB = text.indexOf("\n") > 0;
|
|
871
|
-
if (hasLB) text = text.split("\n").map((m) => {
|
|
872
|
-
return m.replace(/^\s+|\s+$/g, "");
|
|
873
|
-
}).join("\\n");
|
|
874
|
-
const hasTabs = text.indexOf(" ") > 0;
|
|
875
|
-
if (hasLB || hasTabs) {
|
|
876
|
-
const prev = idx ? sql[idx - 1] : "";
|
|
877
|
-
if (prev !== "E" && prev !== "e") {
|
|
878
|
-
const r = result ? result[result.length - 1] : "";
|
|
879
|
-
if (r && r !== " " && compressors.indexOf(r) < 0) result += " ";
|
|
880
|
-
result += "E";
|
|
881
|
-
}
|
|
882
|
-
if (hasTabs) text = text.replace(/\t/g, "\\t");
|
|
883
|
-
}
|
|
884
|
-
result += text;
|
|
885
|
-
idx = closeIdx;
|
|
886
|
-
skipGaps();
|
|
887
|
-
continue;
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
count: (input) => countPostgresRows(db, input, buildWhere(input.where)),
|
|
223
|
+
async findOne(input) {
|
|
224
|
+
const where = buildWhere(input.where);
|
|
225
|
+
switch (input.model) {
|
|
226
|
+
case "bundles": {
|
|
227
|
+
let query = db.selectFrom("bundles").selectAll();
|
|
228
|
+
if (where !== void 0) query = query.where(where);
|
|
229
|
+
return await query.executeTakeFirst() ?? null;
|
|
888
230
|
}
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
231
|
+
case "api_keys": {
|
|
232
|
+
let query = db.selectFrom("api_keys").selectAll();
|
|
233
|
+
if (where !== void 0) query = query.where(where);
|
|
234
|
+
return await query.executeTakeFirst() ?? null;
|
|
892
235
|
}
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
function skipGaps() {
|
|
898
|
-
if (options.compress) while (idx < len - 1 && isGap(sql[idx + 1]) && idx++);
|
|
899
|
-
}
|
|
900
|
-
function addSpace() {
|
|
901
|
-
if (space) {
|
|
902
|
-
if (result.length) result += " ";
|
|
903
|
-
space = false;
|
|
236
|
+
case "bundle_patches": {
|
|
237
|
+
let query = db.selectFrom("bundle_patches").selectAll();
|
|
238
|
+
if (where !== void 0) query = query.where(where);
|
|
239
|
+
return await query.executeTakeFirst() ?? null;
|
|
904
240
|
}
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
const error = require_error();
|
|
920
|
-
parser.SQLParsingError = error.SQLParsingError;
|
|
921
|
-
parser.parsingErrorCode = error.parsingErrorCode;
|
|
922
|
-
module.exports = parser;
|
|
923
|
-
})))(), 1);
|
|
924
|
-
const appVersionStrategy = async (pool, { platform, appVersion, bundleId, minBundleId = _hot_updater_core.NIL_UUID, channel = "production", cohort }) => {
|
|
925
|
-
const sqlGetTargetAppVersionList = (0, import_lib.default)(`
|
|
926
|
-
SELECT target_app_version
|
|
927
|
-
FROM get_target_app_version_list($1, $2);
|
|
928
|
-
`);
|
|
929
|
-
const { rows: appVersionList } = await pool.query(sqlGetTargetAppVersionList, [platform, minBundleId]);
|
|
930
|
-
const targetAppVersionList = filterCompatibleAppVersions(appVersionList?.map((group) => group.target_app_version) ?? [], appVersion);
|
|
931
|
-
const sqlGetUpdateInfo = (0, import_lib.default)(`
|
|
932
|
-
SELECT *
|
|
933
|
-
FROM get_update_info_by_app_version(
|
|
934
|
-
$1, -- platform
|
|
935
|
-
$2, -- appVersion
|
|
936
|
-
$3, -- bundleId
|
|
937
|
-
$4, -- minBundleId (nullable)
|
|
938
|
-
$5, -- channel
|
|
939
|
-
$6, -- targetAppVersionList (text array)
|
|
940
|
-
$7 -- cohort (nullable)
|
|
941
|
-
);
|
|
942
|
-
`);
|
|
943
|
-
const result = await pool.query(sqlGetUpdateInfo, [
|
|
944
|
-
platform,
|
|
945
|
-
appVersion,
|
|
946
|
-
bundleId,
|
|
947
|
-
minBundleId ?? _hot_updater_core.NIL_UUID,
|
|
948
|
-
channel,
|
|
949
|
-
targetAppVersionList,
|
|
950
|
-
cohort ?? null
|
|
951
|
-
]);
|
|
952
|
-
return result.rows[0] ? camelcaseKeys(result.rows[0]) : null;
|
|
953
|
-
};
|
|
954
|
-
const fingerprintStrategy = async (pool, { platform, fingerprintHash, bundleId, minBundleId = _hot_updater_core.NIL_UUID, channel = "production", cohort }) => {
|
|
955
|
-
const sqlGetUpdateInfo = (0, import_lib.default)(`
|
|
956
|
-
SELECT *
|
|
957
|
-
FROM get_update_info_by_fingerprint_hash(
|
|
958
|
-
$1, -- platform
|
|
959
|
-
$2, -- bundleId
|
|
960
|
-
$3, -- minBundleId (nullable)
|
|
961
|
-
$4, -- channel
|
|
962
|
-
$5, -- fingerprintHash
|
|
963
|
-
$6 -- cohort (nullable)
|
|
964
|
-
);
|
|
965
|
-
`);
|
|
966
|
-
const result = await pool.query(sqlGetUpdateInfo, [
|
|
967
|
-
platform,
|
|
968
|
-
bundleId,
|
|
969
|
-
minBundleId ?? _hot_updater_core.NIL_UUID,
|
|
970
|
-
channel,
|
|
971
|
-
fingerprintHash,
|
|
972
|
-
cohort ?? null
|
|
973
|
-
]);
|
|
974
|
-
return result.rows[0] ? camelcaseKeys(result.rows[0]) : null;
|
|
975
|
-
};
|
|
976
|
-
const getUpdateInfo = (pool, args) => {
|
|
977
|
-
if (args._updateStrategy === "appVersion") return appVersionStrategy(pool, args);
|
|
978
|
-
return fingerprintStrategy(pool, args);
|
|
979
|
-
};
|
|
980
|
-
//#endregion
|
|
981
|
-
//#region src/postgres.ts
|
|
982
|
-
const normalizeMetadata = (value) => {
|
|
983
|
-
if (!value) return;
|
|
984
|
-
if (typeof value === "string") try {
|
|
985
|
-
return normalizeMetadata(JSON.parse(value));
|
|
986
|
-
} catch {
|
|
987
|
-
return;
|
|
988
|
-
}
|
|
989
|
-
if (typeof value === "object" && !Array.isArray(value)) return value;
|
|
990
|
-
};
|
|
991
|
-
const buildBundlePatchId = (bundleId, baseBundleId) => `${bundleId}:${baseBundleId}`;
|
|
992
|
-
const mapPatchRowToPatch = (row) => ({
|
|
993
|
-
baseBundleId: row.base_bundle_id,
|
|
994
|
-
baseFileHash: row.base_file_hash,
|
|
995
|
-
patchFileHash: row.patch_file_hash,
|
|
996
|
-
patchStorageUri: row.patch_storage_uri
|
|
997
|
-
});
|
|
998
|
-
const mapRowToBundle = (data, patchRows = []) => {
|
|
999
|
-
const rawMetadata = normalizeMetadata(data.metadata);
|
|
1000
|
-
const patches = patchRows.slice().sort((left, right) => left.order_index - right.order_index || left.base_bundle_id.localeCompare(right.base_bundle_id)).map(mapPatchRowToPatch);
|
|
1001
|
-
const primaryPatch = patches[0] ?? null;
|
|
1002
|
-
return {
|
|
1003
|
-
enabled: data.enabled,
|
|
1004
|
-
shouldForceUpdate: data.should_force_update,
|
|
1005
|
-
fileHash: data.file_hash,
|
|
1006
|
-
gitCommitHash: data.git_commit_hash,
|
|
1007
|
-
id: data.id,
|
|
1008
|
-
message: data.message,
|
|
1009
|
-
platform: data.platform,
|
|
1010
|
-
targetAppVersion: data.target_app_version,
|
|
1011
|
-
channel: data.channel,
|
|
1012
|
-
storageUri: data.storage_uri,
|
|
1013
|
-
fingerprintHash: data.fingerprint_hash,
|
|
1014
|
-
metadata: (0, _hot_updater_core.stripBundleArtifactMetadata)(rawMetadata),
|
|
1015
|
-
manifestStorageUri: data.manifest_storage_uri ?? null,
|
|
1016
|
-
manifestFileHash: data.manifest_file_hash ?? null,
|
|
1017
|
-
assetBaseStorageUri: data.asset_base_storage_uri ?? null,
|
|
1018
|
-
patches,
|
|
1019
|
-
patchBaseBundleId: primaryPatch?.baseBundleId ?? null,
|
|
1020
|
-
patchBaseFileHash: primaryPatch?.baseFileHash ?? null,
|
|
1021
|
-
patchFileHash: primaryPatch?.patchFileHash ?? null,
|
|
1022
|
-
patchStorageUri: primaryPatch?.patchStorageUri ?? null,
|
|
1023
|
-
rolloutCohortCount: data.rollout_cohort_count,
|
|
1024
|
-
targetCohorts: data.target_cohorts
|
|
1025
|
-
};
|
|
1026
|
-
};
|
|
1027
|
-
const bundleToRowValues = (bundle) => ({
|
|
1028
|
-
id: bundle.id,
|
|
1029
|
-
enabled: bundle.enabled,
|
|
1030
|
-
should_force_update: bundle.shouldForceUpdate,
|
|
1031
|
-
file_hash: bundle.fileHash,
|
|
1032
|
-
git_commit_hash: bundle.gitCommitHash,
|
|
1033
|
-
message: bundle.message,
|
|
1034
|
-
platform: bundle.platform,
|
|
1035
|
-
target_app_version: bundle.targetAppVersion,
|
|
1036
|
-
channel: bundle.channel,
|
|
1037
|
-
storage_uri: bundle.storageUri,
|
|
1038
|
-
fingerprint_hash: bundle.fingerprintHash,
|
|
1039
|
-
metadata: (0, _hot_updater_core.stripBundleArtifactMetadata)(bundle.metadata) ?? {},
|
|
1040
|
-
manifest_storage_uri: (0, _hot_updater_core.getManifestStorageUri)(bundle),
|
|
1041
|
-
manifest_file_hash: (0, _hot_updater_core.getManifestFileHash)(bundle),
|
|
1042
|
-
asset_base_storage_uri: (0, _hot_updater_core.getAssetBaseStorageUri)(bundle),
|
|
1043
|
-
rollout_cohort_count: bundle.rolloutCohortCount ?? null,
|
|
1044
|
-
target_cohorts: bundle.targetCohorts ?? null
|
|
1045
|
-
});
|
|
1046
|
-
const bundleToPatchRows = (bundle) => (0, _hot_updater_core.getBundlePatches)(bundle).map((patch, index) => ({
|
|
1047
|
-
id: buildBundlePatchId(bundle.id, patch.baseBundleId),
|
|
1048
|
-
bundle_id: bundle.id,
|
|
1049
|
-
base_bundle_id: patch.baseBundleId,
|
|
1050
|
-
base_file_hash: patch.baseFileHash,
|
|
1051
|
-
patch_file_hash: patch.patchFileHash,
|
|
1052
|
-
patch_storage_uri: patch.patchStorageUri,
|
|
1053
|
-
order_index: index
|
|
1054
|
-
}));
|
|
1055
|
-
const postgres = (0, _hot_updater_plugin_core.createDatabasePlugin)({
|
|
1056
|
-
name: "postgres",
|
|
1057
|
-
factory: (config) => {
|
|
1058
|
-
const pool = new pg.Pool(config);
|
|
1059
|
-
const db = new kysely.Kysely({ dialect: new kysely.PostgresDialect({ pool }) });
|
|
1060
|
-
const fetchPatchMap = async (bundleIds) => {
|
|
1061
|
-
const patchMap = /* @__PURE__ */ new Map();
|
|
1062
|
-
if (bundleIds.length === 0) return patchMap;
|
|
1063
|
-
const rows = await db.selectFrom("bundle_patches").selectAll().where("bundle_id", "in", bundleIds).orderBy("order_index", "asc").execute();
|
|
1064
|
-
for (const row of rows) {
|
|
1065
|
-
const current = patchMap.get(row.bundle_id) ?? [];
|
|
1066
|
-
current.push(row);
|
|
1067
|
-
patchMap.set(row.bundle_id, current);
|
|
241
|
+
case "channels": {
|
|
242
|
+
let query = db.selectFrom("channels").selectAll();
|
|
243
|
+
if (where !== void 0) query = query.where(where);
|
|
244
|
+
return await query.executeTakeFirst() ?? null;
|
|
245
|
+
}
|
|
246
|
+
case "releases": {
|
|
247
|
+
let query = db.selectFrom("releases").selectAll();
|
|
248
|
+
if (where !== void 0) query = query.where(where);
|
|
249
|
+
return await query.executeTakeFirst() ?? null;
|
|
250
|
+
}
|
|
251
|
+
case "release_catalogs": {
|
|
252
|
+
let query = db.selectFrom("release_catalogs").selectAll();
|
|
253
|
+
if (where !== void 0) query = query.where(where);
|
|
254
|
+
return await query.executeTakeFirst() ?? null;
|
|
1068
255
|
}
|
|
1069
|
-
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
findMany: (input) => findManyPostgresRows(db, input, buildWhere(input.where)),
|
|
259
|
+
async insertChannel({ row }) {
|
|
260
|
+
const inserted = await db.insertInto("channels").values(row).onConflict((conflict) => conflict.column("name").doNothing()).returningAll().executeTakeFirst();
|
|
261
|
+
if (inserted !== void 0) return {
|
|
262
|
+
row: inserted,
|
|
263
|
+
inserted: true
|
|
1070
264
|
};
|
|
1071
265
|
return {
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
await pool.end();
|
|
1075
|
-
},
|
|
1076
|
-
async getUpdateInfo(args) {
|
|
1077
|
-
return getUpdateInfo(pool, args);
|
|
1078
|
-
},
|
|
1079
|
-
async getBundleById(bundleId) {
|
|
1080
|
-
const [data, patchMap] = await Promise.all([db.selectFrom("bundles").selectAll().where("id", "=", bundleId).executeTakeFirst(), fetchPatchMap([bundleId])]);
|
|
1081
|
-
if (!data) return null;
|
|
1082
|
-
return mapRowToBundle(data, patchMap.get(bundleId) ?? []);
|
|
1083
|
-
},
|
|
1084
|
-
async getBundles(options) {
|
|
1085
|
-
const { where, limit, orderBy } = options ?? {};
|
|
1086
|
-
const offset = (options && "offset" in options ? options.offset : void 0) ?? 0;
|
|
1087
|
-
let countQuery = db.selectFrom("bundles");
|
|
1088
|
-
if (where?.channel) countQuery = countQuery.where("channel", "=", where.channel);
|
|
1089
|
-
if (where?.platform) countQuery = countQuery.where("platform", "=", where.platform);
|
|
1090
|
-
if (where?.enabled !== void 0) countQuery = countQuery.where("enabled", "=", where.enabled);
|
|
1091
|
-
if (where?.fingerprintHash !== void 0) countQuery = where.fingerprintHash === null ? countQuery.where("fingerprint_hash", "is", null) : countQuery.where("fingerprint_hash", "=", where.fingerprintHash);
|
|
1092
|
-
if (where?.targetAppVersion !== void 0) countQuery = where.targetAppVersion === null ? countQuery.where("target_app_version", "is", null) : countQuery.where("target_app_version", "=", where.targetAppVersion);
|
|
1093
|
-
if (where?.targetAppVersionIn) countQuery = countQuery.where("target_app_version", "in", where.targetAppVersionIn);
|
|
1094
|
-
if (where?.targetAppVersionNotNull) countQuery = countQuery.where("target_app_version", "is not", null);
|
|
1095
|
-
if (where?.id?.eq) countQuery = countQuery.where("id", "=", where.id.eq);
|
|
1096
|
-
if (where?.id?.gt) countQuery = countQuery.where("id", ">", where.id.gt);
|
|
1097
|
-
if (where?.id?.gte) countQuery = countQuery.where("id", ">=", where.id.gte);
|
|
1098
|
-
if (where?.id?.lt) countQuery = countQuery.where("id", "<", where.id.lt);
|
|
1099
|
-
if (where?.id?.lte) countQuery = countQuery.where("id", "<=", where.id.lte);
|
|
1100
|
-
if (where?.id?.in) countQuery = countQuery.where("id", "in", where.id.in);
|
|
1101
|
-
const total = (await countQuery.select(db.fn.count("id").as("total")).executeTakeFirst())?.total || 0;
|
|
1102
|
-
let query = db.selectFrom("bundles").orderBy("id", orderBy?.direction === "asc" ? "asc" : "desc");
|
|
1103
|
-
if (where?.channel) query = query.where("channel", "=", where.channel);
|
|
1104
|
-
if (where?.platform) query = query.where("platform", "=", where.platform);
|
|
1105
|
-
if (where?.enabled !== void 0) query = query.where("enabled", "=", where.enabled);
|
|
1106
|
-
if (where?.fingerprintHash !== void 0) query = where.fingerprintHash === null ? query.where("fingerprint_hash", "is", null) : query.where("fingerprint_hash", "=", where.fingerprintHash);
|
|
1107
|
-
if (where?.targetAppVersion !== void 0) query = where.targetAppVersion === null ? query.where("target_app_version", "is", null) : query.where("target_app_version", "=", where.targetAppVersion);
|
|
1108
|
-
if (where?.targetAppVersionIn) query = query.where("target_app_version", "in", where.targetAppVersionIn);
|
|
1109
|
-
if (where?.targetAppVersionNotNull) query = query.where("target_app_version", "is not", null);
|
|
1110
|
-
if (where?.id?.eq) query = query.where("id", "=", where.id.eq);
|
|
1111
|
-
if (where?.id?.gt) query = query.where("id", ">", where.id.gt);
|
|
1112
|
-
if (where?.id?.gte) query = query.where("id", ">=", where.id.gte);
|
|
1113
|
-
if (where?.id?.lt) query = query.where("id", "<", where.id.lt);
|
|
1114
|
-
if (where?.id?.lte) query = query.where("id", "<=", where.id.lte);
|
|
1115
|
-
if (where?.id?.in) query = query.where("id", "in", where.id.in);
|
|
1116
|
-
if (limit) query = query.limit(limit);
|
|
1117
|
-
if (offset) query = query.offset(offset);
|
|
1118
|
-
const data = await query.selectAll().execute();
|
|
1119
|
-
const patchMap = await fetchPatchMap(data.map((bundle) => bundle.id));
|
|
1120
|
-
return {
|
|
1121
|
-
data: data.map((bundle) => mapRowToBundle(bundle, patchMap.get(bundle.id) ?? [])),
|
|
1122
|
-
pagination: (0, _hot_updater_plugin_core.calculatePagination)(total, {
|
|
1123
|
-
limit,
|
|
1124
|
-
offset
|
|
1125
|
-
})
|
|
1126
|
-
};
|
|
1127
|
-
},
|
|
1128
|
-
async getChannels() {
|
|
1129
|
-
return (await db.selectFrom("bundles").select("channel").groupBy("channel").execute()).map((bundle) => bundle.channel);
|
|
1130
|
-
},
|
|
1131
|
-
async commitBundle({ changedSets }) {
|
|
1132
|
-
if (changedSets.length === 0) return;
|
|
1133
|
-
await db.transaction().execute(async (tx) => {
|
|
1134
|
-
for (const op of changedSets) if (op.operation === "delete") {
|
|
1135
|
-
await tx.deleteFrom("bundle_patches").where("bundle_id", "=", op.data.id).execute();
|
|
1136
|
-
await tx.deleteFrom("bundle_patches").where("base_bundle_id", "=", op.data.id).execute();
|
|
1137
|
-
if ((await tx.deleteFrom("bundles").where("id", "=", op.data.id).executeTakeFirst()).numDeletedRows === 0n) throw new Error(`Bundle with id ${op.data.id} not found`);
|
|
1138
|
-
} else if (op.operation === "insert" || op.operation === "update") {
|
|
1139
|
-
const bundle = op.data;
|
|
1140
|
-
const values = bundleToRowValues(bundle);
|
|
1141
|
-
const patchRows = bundleToPatchRows(bundle);
|
|
1142
|
-
const { id: _id, ...updateValues } = values;
|
|
1143
|
-
await tx.insertInto("bundles").values(values).onConflict((oc) => oc.column("id").doUpdateSet(updateValues)).execute();
|
|
1144
|
-
await tx.deleteFrom("bundle_patches").where("bundle_id", "=", bundle.id).execute();
|
|
1145
|
-
if (patchRows.length > 0) await tx.insertInto("bundle_patches").values(patchRows).execute();
|
|
1146
|
-
}
|
|
1147
|
-
});
|
|
1148
|
-
}
|
|
266
|
+
row: await db.selectFrom("channels").selectAll().where("name", "=", row.name).executeTakeFirstOrThrow(),
|
|
267
|
+
inserted: false
|
|
1149
268
|
};
|
|
1150
|
-
}
|
|
269
|
+
},
|
|
270
|
+
async deleteChannel({ id }) {
|
|
271
|
+
try {
|
|
272
|
+
return await db.deleteFrom("channels").where("id", "=", id).returning("id").executeTakeFirst() === void 0 ? {
|
|
273
|
+
deleted: false,
|
|
274
|
+
reason: "not_found"
|
|
275
|
+
} : { deleted: true };
|
|
276
|
+
} catch (error) {
|
|
277
|
+
if (isForeignKeyViolation(error)) return {
|
|
278
|
+
deleted: false,
|
|
279
|
+
reason: "not_empty"
|
|
280
|
+
};
|
|
281
|
+
throw error;
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
transaction: (callback) => db.transaction().execute((transaction) => callback(createPostgresImplementation(transaction))),
|
|
285
|
+
dispose: () => db.destroy()
|
|
1151
286
|
});
|
|
287
|
+
const postgres = (config) => {
|
|
288
|
+
const { dialect, ...poolConfig } = config;
|
|
289
|
+
const adapter = (0, _hot_updater_plugin_core_internal.createDatabasePluginAdapter)("postgres", dialect !== void 0 ? createPostgresImplementation(new kysely.Kysely({ dialect })) : createPostgresImplementation(new kysely.Kysely({ dialect: new kysely.PostgresDialect({ pool: new Pool(poolConfig) }) })));
|
|
290
|
+
return (0, _hot_updater_plugin_core.createDatabasePlugin)({
|
|
291
|
+
name: "postgres",
|
|
292
|
+
models: adapter.models,
|
|
293
|
+
commit: adapter.commit,
|
|
294
|
+
dispose: adapter.dispose
|
|
295
|
+
});
|
|
296
|
+
};
|
|
1152
297
|
//#endregion
|
|
1153
|
-
exports.appVersionStrategy = appVersionStrategy;
|
|
1154
|
-
exports.fingerprintStrategy = fingerprintStrategy;
|
|
1155
|
-
exports.getUpdateInfo = getUpdateInfo;
|
|
1156
298
|
exports.postgres = postgres;
|