@hot-updater/plugin-core 0.36.7 → 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/dist/assetStorageLayout.cjs +36 -18
  2. package/dist/assetStorageLayout.d.cts +21 -6
  3. package/dist/assetStorageLayout.d.mts +21 -6
  4. package/dist/assetStorageLayout.mjs +36 -18
  5. package/dist/bundleStorageLayout.cjs +2 -3
  6. package/dist/bundleStorageLayout.mjs +2 -3
  7. package/dist/contentAddressedAssets.cjs +5 -0
  8. package/dist/contentAddressedAssets.d.cts +2 -1
  9. package/dist/contentAddressedAssets.d.mts +2 -1
  10. package/dist/contentAddressedAssets.mjs +5 -1
  11. package/dist/createDatabasePlugin.cjs +775 -284
  12. package/dist/createDatabasePlugin.d.cts +20 -64
  13. package/dist/createDatabasePlugin.d.mts +20 -64
  14. package/dist/createDatabasePlugin.mjs +773 -284
  15. package/dist/createStorageKeyBuilder.cjs +9 -2
  16. package/dist/createStorageKeyBuilder.mjs +9 -2
  17. package/dist/createStoragePlugin.cjs +6 -145
  18. package/dist/createStoragePlugin.d.cts +7 -52
  19. package/dist/createStoragePlugin.d.mts +7 -52
  20. package/dist/createStoragePlugin.mjs +5 -143
  21. package/dist/databaseClient.cjs +112 -0
  22. package/dist/databaseClient.d.cts +33 -0
  23. package/dist/databaseClient.d.mts +33 -0
  24. package/dist/databaseClient.mjs +110 -0
  25. package/dist/databaseClientReads.cjs +113 -0
  26. package/dist/databaseClientReads.mjs +112 -0
  27. package/dist/databaseClientUpdates.cjs +39 -0
  28. package/dist/databaseClientUpdates.d.cts +11 -0
  29. package/dist/databaseClientUpdates.d.mts +11 -0
  30. package/dist/databaseClientUpdates.mjs +36 -0
  31. package/dist/databaseJsonValue.cjs +37 -0
  32. package/dist/databaseJsonValue.d.cts +5 -0
  33. package/dist/databaseJsonValue.d.mts +5 -0
  34. package/dist/databaseJsonValue.mjs +37 -0
  35. package/dist/databaseMetadata.cjs +13 -0
  36. package/dist/databaseMetadata.mjs +12 -0
  37. package/dist/databasePluginCrud.cjs +86 -0
  38. package/dist/databasePluginCrud.d.cts +1 -0
  39. package/dist/databasePluginCrud.d.mts +1 -0
  40. package/dist/databasePluginCrud.mjs +86 -0
  41. package/dist/databasePluginCrudValidation.d.cts +1 -0
  42. package/dist/databasePluginCrudValidation.d.mts +1 -0
  43. package/dist/databasePluginCrudValidationErrors.cjs +10 -0
  44. package/dist/databasePluginCrudValidationErrors.d.cts +9 -0
  45. package/dist/databasePluginCrudValidationErrors.d.mts +9 -0
  46. package/dist/databasePluginCrudValidationErrors.mjs +10 -0
  47. package/dist/databasePluginCrudValidationFields.cjs +291 -0
  48. package/dist/databasePluginCrudValidationFields.d.cts +1 -0
  49. package/dist/databasePluginCrudValidationFields.d.mts +1 -0
  50. package/dist/databasePluginCrudValidationFields.mjs +281 -0
  51. package/dist/databasePluginCrudValidationMutations.cjs +88 -0
  52. package/dist/databasePluginCrudValidationMutations.d.cts +1 -0
  53. package/dist/databasePluginCrudValidationMutations.d.mts +1 -0
  54. package/dist/databasePluginCrudValidationMutations.mjs +82 -0
  55. package/dist/databasePluginCrudValidationQueries.cjs +103 -0
  56. package/dist/databasePluginCrudValidationQueries.d.cts +1 -0
  57. package/dist/databasePluginCrudValidationQueries.d.mts +1 -0
  58. package/dist/databasePluginCrudValidationQueries.mjs +97 -0
  59. package/dist/databasePluginCrudValidationRows.cjs +55 -0
  60. package/dist/databasePluginCrudValidationRows.d.cts +1 -0
  61. package/dist/databasePluginCrudValidationRows.d.mts +1 -0
  62. package/dist/databasePluginCrudValidationRows.mjs +53 -0
  63. package/dist/databasePluginTransaction.cjs +7 -0
  64. package/dist/databasePluginTransaction.mjs +7 -0
  65. package/dist/databaseRows.cjs +149 -0
  66. package/dist/databaseRows.d.cts +34 -0
  67. package/dist/databaseRows.d.mts +34 -0
  68. package/dist/databaseRows.mjs +141 -0
  69. package/dist/index.cjs +76 -24
  70. package/dist/index.d.cts +22 -12
  71. package/dist/index.d.mts +22 -12
  72. package/dist/index.mjs +21 -14
  73. package/dist/internal.cjs +6 -0
  74. package/dist/internal.d.cts +9 -0
  75. package/dist/internal.d.mts +9 -0
  76. package/dist/internal.mjs +3 -0
  77. package/dist/node_modules/.pnpm/verkit@0.3.2/node_modules/verkit/dist/index.cjs +345 -0
  78. package/dist/node_modules/.pnpm/verkit@0.3.2/node_modules/verkit/dist/index.mjs +341 -0
  79. package/dist/paginateBundles.d.cts +6 -4
  80. package/dist/paginateBundles.d.mts +6 -4
  81. package/dist/parseStorageUri.cjs +46 -30
  82. package/dist/parseStorageUri.d.cts +20 -17
  83. package/dist/parseStorageUri.d.mts +20 -17
  84. package/dist/parseStorageUri.mjs +46 -30
  85. package/dist/queryBundles.cjs +1 -7
  86. package/dist/queryBundles.d.cts +3 -1
  87. package/dist/queryBundles.d.mts +3 -1
  88. package/dist/queryBundles.mjs +1 -7
  89. package/dist/releaseCatalogCompiler.cjs +391 -0
  90. package/dist/releaseCatalogCompiler.d.cts +55 -0
  91. package/dist/releaseCatalogCompiler.d.mts +55 -0
  92. package/dist/releaseCatalogCompiler.mjs +386 -0
  93. package/dist/releaseCatalogMutation.cjs +303 -0
  94. package/dist/releaseCatalogMutation.d.cts +86 -0
  95. package/dist/releaseCatalogMutation.d.mts +86 -0
  96. package/dist/releaseCatalogMutation.mjs +297 -0
  97. package/dist/releaseManagement.cjs +231 -0
  98. package/dist/releaseManagement.d.cts +48 -0
  99. package/dist/releaseManagement.d.mts +48 -0
  100. package/dist/releaseManagement.mjs +224 -0
  101. package/dist/remoteBundleSigning.cjs +294 -0
  102. package/dist/remoteBundleSigning.d.cts +41 -0
  103. package/dist/remoteBundleSigning.d.mts +41 -0
  104. package/dist/remoteBundleSigning.mjs +289 -0
  105. package/dist/requestBundleCache.cjs +22 -0
  106. package/dist/requestBundleCache.d.cts +9 -0
  107. package/dist/requestBundleCache.d.mts +9 -0
  108. package/dist/requestBundleCache.mjs +22 -0
  109. package/dist/semverSatisfies.cjs +3 -4
  110. package/dist/semverSatisfies.mjs +1 -1
  111. package/dist/storageDownloadPath.cjs +48 -0
  112. package/dist/storageDownloadPath.d.cts +15 -0
  113. package/dist/storageDownloadPath.d.mts +15 -0
  114. package/dist/storageDownloadPath.mjs +46 -0
  115. package/dist/types/database.d.cts +4 -0
  116. package/dist/types/database.d.mts +4 -0
  117. package/dist/types/databaseFields.cjs +92 -0
  118. package/dist/types/databaseFields.d.cts +12 -0
  119. package/dist/types/databaseFields.d.mts +12 -0
  120. package/dist/types/databaseFields.mjs +92 -0
  121. package/dist/types/databaseOperations.d.cts +173 -0
  122. package/dist/types/databaseOperations.d.mts +173 -0
  123. package/dist/types/databasePlugin.d.cts +240 -0
  124. package/dist/types/databasePlugin.d.mts +240 -0
  125. package/dist/types/databaseQuery.d.cts +47 -0
  126. package/dist/types/databaseQuery.d.mts +47 -0
  127. package/dist/types/databaseRows.d.cts +120 -0
  128. package/dist/types/databaseRows.d.mts +120 -0
  129. package/dist/types/index.d.cts +119 -161
  130. package/dist/types/index.d.mts +119 -161
  131. package/dist/types/internal.d.cts +7 -0
  132. package/dist/types/internal.d.mts +7 -0
  133. package/dist/types/public.d.cts +3 -0
  134. package/dist/types/public.d.mts +3 -0
  135. package/dist/uuidv7.cjs +9 -0
  136. package/dist/uuidv7.d.cts +4 -1
  137. package/dist/uuidv7.d.mts +4 -1
  138. package/dist/uuidv7.mjs +8 -1
  139. package/package.json +10 -5
  140. package/dist/bundleUnitOfWork.cjs +0 -158
  141. package/dist/bundleUnitOfWork.mjs +0 -158
  142. package/dist/bundleUnitOfWorkStore.cjs +0 -15
  143. package/dist/bundleUnitOfWorkStore.mjs +0 -15
  144. package/dist/createBlobDatabasePlugin.cjs +0 -382
  145. package/dist/createBlobDatabasePlugin.d.cts +0 -29
  146. package/dist/createBlobDatabasePlugin.d.mts +0 -29
  147. package/dist/createBlobDatabasePlugin.mjs +0 -381
  148. package/dist/legacyAssetStorageLayout.cjs +0 -12
  149. package/dist/legacyAssetStorageLayout.mjs +0 -12
  150. package/dist/requestUpdateBundleState.cjs +0 -26
  151. package/dist/requestUpdateBundleState.d.cts +0 -12
  152. package/dist/requestUpdateBundleState.d.mts +0 -12
  153. package/dist/requestUpdateBundleState.mjs +0 -24
  154. package/dist/resolveUpdateInfoFromBundles.cjs +0 -14
  155. package/dist/resolveUpdateInfoFromBundles.d.cts +0 -16
  156. package/dist/resolveUpdateInfoFromBundles.d.mts +0 -16
  157. package/dist/resolveUpdateInfoFromBundles.mjs +0 -13
  158. package/dist/storageProfile.cjs +0 -15
  159. package/dist/storageProfile.d.cts +0 -9
  160. package/dist/storageProfile.d.mts +0 -9
  161. package/dist/storageProfile.mjs +0 -12
@@ -0,0 +1,281 @@
1
+ import { DatabasePluginInputError } from "./databasePluginCrudValidationErrors.mjs";
2
+ import { isDatabaseMetadataObject } from "./databaseJsonValue.mjs";
3
+ import { databaseFields } from "./types/databaseFields.mjs";
4
+ import { isUUIDv7 } from "./uuidv7.mjs";
5
+ //#region src/databasePluginCrudValidationFields.ts
6
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
7
+ const isChannelText = (value) => {
8
+ if (typeof value !== "string" || value.length === 0) return false;
9
+ let codePointCount = 0;
10
+ for (const _codePoint of value) {
11
+ codePointCount += 1;
12
+ if (codePointCount > 255) return false;
13
+ }
14
+ return true;
15
+ };
16
+ const modelValidators = {
17
+ bundles: {
18
+ id: (value) => typeof value === "string",
19
+ platform: (value) => value === "ios" || value === "android",
20
+ should_force_update: (value) => typeof value === "boolean",
21
+ enabled: (value) => typeof value === "boolean",
22
+ file_hash: (value) => typeof value === "string",
23
+ git_commit_hash: (value) => value === null || typeof value === "string",
24
+ message: (value) => value === null || typeof value === "string",
25
+ channel: isChannelText,
26
+ channel_id: isChannelText,
27
+ storage_uri: (value) => typeof value === "string",
28
+ archive_byte_size: (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0,
29
+ target_app_version: (value) => value === null || typeof value === "string",
30
+ fingerprint_hash: (value) => value === null || typeof value === "string",
31
+ metadata: isDatabaseMetadataObject,
32
+ rollout_cohort_count: (value) => typeof value === "number" && Number.isInteger(value) && value >= 0 && value <= 1e3,
33
+ target_cohorts: (value) => value === null || Array.isArray(value) && value.every((item) => typeof item === "string"),
34
+ manifest_storage_uri: (value) => value === null || typeof value === "string",
35
+ manifest_file_hash: (value) => value === null || typeof value === "string",
36
+ asset_base_storage_uri: (value) => value === null || typeof value === "string"
37
+ },
38
+ bundle_patches: {
39
+ id: (value) => typeof value === "string",
40
+ bundle_id: (value) => typeof value === "string",
41
+ base_bundle_id: (value) => typeof value === "string",
42
+ base_file_hash: (value) => typeof value === "string",
43
+ patch_file_hash: (value) => typeof value === "string",
44
+ patch_storage_uri: (value) => typeof value === "string",
45
+ byte_size: (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0,
46
+ order_index: (value) => typeof value === "number" && Number.isInteger(value) && value >= 0
47
+ },
48
+ releases: {
49
+ id: isUUIDv7,
50
+ revision: (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 1,
51
+ scope_key: (value) => typeof value === "string" && value.length > 0,
52
+ channel_id: isChannelText,
53
+ platform: (value) => value === "ios" || value === "android",
54
+ kind: (value) => value === "BUNDLE" || value === "EMBEDDED",
55
+ bundle_id: (value) => value === null || typeof value === "string",
56
+ strategy: (value) => value === "APP_VERSION" || value === "FINGERPRINT",
57
+ target_app_version: (value) => value === null || typeof value === "string",
58
+ fingerprint_hash: (value) => value === null || typeof value === "string",
59
+ enabled: (value) => typeof value === "boolean",
60
+ should_force_update: (value) => typeof value === "boolean",
61
+ message: (value) => value === null || typeof value === "string",
62
+ rollout_cohort_count: (value) => typeof value === "number" && Number.isInteger(value) && value >= 0 && value <= 1e3,
63
+ target_cohorts: (value) => Array.isArray(value) && value.every((item) => typeof item === "string"),
64
+ operation: (value) => value === "DEPLOY" || value === "PROMOTE" || value === "ROLLBACK",
65
+ source_release_id: (value) => value === null || isUUIDv7(value),
66
+ created_at_ms: (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0,
67
+ updated_at_ms: (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0
68
+ },
69
+ release_catalogs: {
70
+ scope_key: (value) => typeof value === "string" && value.length > 0,
71
+ catalog_id: (value) => typeof value === "string" && value.length > 0,
72
+ strategy: (value) => value === "APP_VERSION" || value === "FINGERPRINT",
73
+ channel_id: isChannelText,
74
+ channel_key: (value) => typeof value === "string" && value.length > 0,
75
+ platform: (value) => value === "ios" || value === "android",
76
+ fingerprint_hash: (value) => value === null || typeof value === "string",
77
+ generation: (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 1,
78
+ payload: (value) => typeof value === "string",
79
+ catalog_hash: (value) => typeof value === "string" && value.length > 0,
80
+ byte_size: (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0,
81
+ is_tombstone: (value) => typeof value === "boolean",
82
+ updated_at_ms: (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0
83
+ },
84
+ channels: {
85
+ id: isChannelText,
86
+ name: isChannelText
87
+ },
88
+ bundle_events: {
89
+ id: (value) => typeof value === "string",
90
+ type: (value) => value === "UPDATE_APPLIED" || value === "RECOVERED" || value === "RELEASE_ADOPTED" || value === "UNCHANGED",
91
+ install_id: (value) => typeof value === "string",
92
+ user_id: (value) => value === null || typeof value === "string",
93
+ username: (value) => value === null || typeof value === "string",
94
+ from_bundle_id: (value) => value === null || typeof value === "string",
95
+ from_release_id: (value) => value === null || typeof value === "string",
96
+ to_release_id: (value) => value === null || typeof value === "string",
97
+ to_bundle_id: (value) => typeof value === "string",
98
+ platform: (value) => value === "ios" || value === "android",
99
+ app_version: (value) => typeof value === "string",
100
+ channel: (value) => typeof value === "string",
101
+ cohort: (value) => typeof value === "string",
102
+ update_strategy: (value) => value === null || value === "fingerprint" || value === "appVersion",
103
+ fingerprint_hash: (value) => value === null || typeof value === "string",
104
+ sdk_version: (value) => value === null || typeof value === "string",
105
+ received_at_ms: (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0
106
+ },
107
+ api_keys: {
108
+ id: (value) => typeof value === "string",
109
+ hash: (value) => typeof value === "string",
110
+ name: (value) => typeof value === "string",
111
+ prefix: (value) => typeof value === "string",
112
+ role: (value) => value === "client",
113
+ created_at_ms: (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0,
114
+ revoked_at_ms: (value) => value === null || typeof value === "number" && Number.isSafeInteger(value) && value >= 0
115
+ }
116
+ };
117
+ const stringFields = new Set([
118
+ "id",
119
+ "platform",
120
+ "file_hash",
121
+ "git_commit_hash",
122
+ "message",
123
+ "channel",
124
+ "channel_id",
125
+ "storage_uri",
126
+ "target_app_version",
127
+ "fingerprint_hash",
128
+ "bundle_id",
129
+ "base_bundle_id",
130
+ "base_file_hash",
131
+ "patch_file_hash",
132
+ "patch_storage_uri",
133
+ "scope_key",
134
+ "catalog_id",
135
+ "channel_key",
136
+ "kind",
137
+ "bundle_id",
138
+ "strategy",
139
+ "operation",
140
+ "source_release_id",
141
+ "payload",
142
+ "catalog_hash",
143
+ "type",
144
+ "install_id",
145
+ "user_id",
146
+ "username",
147
+ "from_bundle_id",
148
+ "to_bundle_id",
149
+ "app_version",
150
+ "cohort",
151
+ "update_strategy",
152
+ "sdk_version",
153
+ "hash",
154
+ "name",
155
+ "prefix",
156
+ "role"
157
+ ]);
158
+ const numberFields = new Set([
159
+ "archive_byte_size",
160
+ "byte_size",
161
+ "rollout_cohort_count",
162
+ "order_index",
163
+ "revision",
164
+ "generation",
165
+ "byte_size",
166
+ "updated_at_ms",
167
+ "received_at_ms",
168
+ "created_at_ms",
169
+ "revoked_at_ms"
170
+ ]);
171
+ const booleanFields = new Set([
172
+ "should_force_update",
173
+ "enabled",
174
+ "is_tombstone"
175
+ ]);
176
+ const sortableFields = {
177
+ bundles: new Set([
178
+ "id",
179
+ "platform",
180
+ "file_hash",
181
+ "git_commit_hash",
182
+ "message",
183
+ "channel",
184
+ "channel_id",
185
+ "storage_uri",
186
+ "archive_byte_size",
187
+ "target_app_version",
188
+ "fingerprint_hash",
189
+ "rollout_cohort_count",
190
+ "manifest_storage_uri",
191
+ "manifest_file_hash",
192
+ "asset_base_storage_uri"
193
+ ]),
194
+ bundle_patches: new Set([
195
+ "id",
196
+ "bundle_id",
197
+ "base_bundle_id",
198
+ "base_file_hash",
199
+ "patch_file_hash",
200
+ "patch_storage_uri",
201
+ "byte_size",
202
+ "order_index"
203
+ ]),
204
+ releases: new Set([
205
+ "id",
206
+ "revision",
207
+ "scope_key",
208
+ "channel_id",
209
+ "platform",
210
+ "kind",
211
+ "bundle_id",
212
+ "strategy",
213
+ "target_app_version",
214
+ "fingerprint_hash",
215
+ "enabled",
216
+ "should_force_update",
217
+ "message",
218
+ "rollout_cohort_count",
219
+ "operation",
220
+ "source_release_id",
221
+ "created_at_ms",
222
+ "updated_at_ms"
223
+ ]),
224
+ release_catalogs: new Set([
225
+ "scope_key",
226
+ "catalog_id",
227
+ "strategy",
228
+ "channel_id",
229
+ "channel_key",
230
+ "platform",
231
+ "fingerprint_hash",
232
+ "generation",
233
+ "catalog_hash",
234
+ "byte_size",
235
+ "is_tombstone",
236
+ "updated_at_ms"
237
+ ]),
238
+ channels: new Set(["id", "name"]),
239
+ bundle_events: new Set([
240
+ "id",
241
+ "type",
242
+ "install_id",
243
+ "user_id",
244
+ "username",
245
+ "from_bundle_id",
246
+ "from_release_id",
247
+ "to_release_id",
248
+ "to_bundle_id",
249
+ "platform",
250
+ "app_version",
251
+ "channel",
252
+ "cohort",
253
+ "update_strategy",
254
+ "fingerprint_hash",
255
+ "sdk_version",
256
+ "received_at_ms"
257
+ ]),
258
+ api_keys: new Set([
259
+ "id",
260
+ "hash",
261
+ "name",
262
+ "prefix",
263
+ "role",
264
+ "created_at_ms",
265
+ "revoked_at_ms"
266
+ ])
267
+ };
268
+ const validateModel = (model) => {
269
+ if (typeof model !== "string" || !Object.hasOwn(databaseFields, model)) throw new DatabasePluginInputError("invalid-model");
270
+ };
271
+ const validateField = (model, field) => {
272
+ if (!databaseFields[model].includes(field)) throw new DatabasePluginInputError("invalid-field");
273
+ };
274
+ const validateFields = (model, fields) => {
275
+ for (const field of fields) validateField(model, field);
276
+ };
277
+ const isStringField = (field) => stringFields.has(field);
278
+ const isNumberField = (field) => numberFields.has(field);
279
+ const isBooleanField = (field) => booleanFields.has(field);
280
+ //#endregion
281
+ export { isBooleanField, isChannelText, isNumberField, isRecord, isStringField, modelValidators, sortableFields, validateField, validateFields, validateModel };
@@ -0,0 +1,88 @@
1
+ const require_databasePluginCrudValidationErrors = require("./databasePluginCrudValidationErrors.cjs");
2
+ const require_databasePluginCrudValidationFields = require("./databasePluginCrudValidationFields.cjs");
3
+ const require_databasePluginCrudValidationRows = require("./databasePluginCrudValidationRows.cjs");
4
+ //#region src/databasePluginCrudValidationMutations.ts
5
+ const validateMutationWhere = (where) => {
6
+ if (where.length === 0) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("empty-mutation-where");
7
+ };
8
+ const validateUpdateWhere = (model, where) => {
9
+ const selector = where[0];
10
+ const primaryField = model === "release_catalogs" ? "scope_key" : "id";
11
+ if (where.length !== 1 || !require_databasePluginCrudValidationFields.isRecord(selector) || selector.field !== primaryField || selector.operator !== void 0 && selector.operator !== "eq" || typeof selector.value !== "string" || selector.connector !== void 0 || selector.mode !== void 0) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-update-selector");
12
+ };
13
+ const validateBundleUpdateData = (update) => {
14
+ if (!require_databasePluginCrudValidationFields.isRecord(update)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
15
+ for (const [field, value] of Object.entries(update)) {
16
+ if (field === "id") throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
17
+ require_databasePluginCrudValidationFields.validateField("bundles", field);
18
+ const validator = require_databasePluginCrudValidationFields.modelValidators.bundles[field];
19
+ if (!validator || !validator(value)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
20
+ }
21
+ };
22
+ const validateApiKeyUpdateData = (update) => {
23
+ if (!require_databasePluginCrudValidationFields.isRecord(update) || Reflect.ownKeys(update).length !== 1 || !Object.hasOwn(update, "revoked_at_ms") || !require_databasePluginCrudValidationFields.modelValidators.api_keys.revoked_at_ms(Reflect.get(update, "revoked_at_ms"))) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
24
+ };
25
+ const RELEASE_MUTABLE_FIELDS = new Set([
26
+ "revision",
27
+ "scope_key",
28
+ "target_app_version",
29
+ "fingerprint_hash",
30
+ "enabled",
31
+ "should_force_update",
32
+ "message",
33
+ "rollout_cohort_count",
34
+ "target_cohorts",
35
+ "updated_at_ms"
36
+ ]);
37
+ const validateReleaseUpdateData = (update) => {
38
+ if (!require_databasePluginCrudValidationFields.isRecord(update) || Reflect.ownKeys(update).length === 0) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
39
+ for (const [field, value] of Object.entries(update)) {
40
+ if (!RELEASE_MUTABLE_FIELDS.has(field)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
41
+ const validator = require_databasePluginCrudValidationFields.modelValidators.releases[field];
42
+ if (!validator || !validator(value)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
43
+ }
44
+ };
45
+ const validateReleaseCatalogUpdateData = (update) => {
46
+ if (!require_databasePluginCrudValidationFields.isRecord(update)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
47
+ const expectedFields = Object.keys(require_databasePluginCrudValidationFields.modelValidators.release_catalogs).filter((field) => field !== "scope_key");
48
+ if (Reflect.ownKeys(update).length !== expectedFields.length || expectedFields.some((field) => !Object.hasOwn(update, field))) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
49
+ for (const [field, value] of Object.entries(update)) {
50
+ const validator = require_databasePluginCrudValidationFields.modelValidators.release_catalogs[field];
51
+ if (!validator || !validator(value)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
52
+ }
53
+ };
54
+ const validateReleaseTargetUpdate = async (implementation, input) => {
55
+ if (!Object.hasOwn(input.update, "target_app_version") && !Object.hasOwn(input.update, "fingerprint_hash")) return;
56
+ const id = input.where[0]?.value;
57
+ if (typeof id !== "string") return;
58
+ const current = await implementation.findOne({
59
+ model: "releases",
60
+ where: [{
61
+ field: "id",
62
+ value: id
63
+ }],
64
+ select: [
65
+ "strategy",
66
+ "target_app_version",
67
+ "fingerprint_hash"
68
+ ]
69
+ });
70
+ if (current === null) return;
71
+ require_databasePluginCrudValidationRows.validateResult("releases", current, [
72
+ "strategy",
73
+ "target_app_version",
74
+ "fingerprint_hash"
75
+ ]);
76
+ const strategy = Reflect.get(current, "strategy");
77
+ const targetAppVersion = Object.hasOwn(input.update, "target_app_version") ? input.update.target_app_version : Reflect.get(current, "target_app_version");
78
+ const fingerprintHash = Object.hasOwn(input.update, "fingerprint_hash") ? input.update.fingerprint_hash : Reflect.get(current, "fingerprint_hash");
79
+ if (!(strategy === "APP_VERSION" && typeof targetAppVersion === "string" && fingerprintHash === null || strategy === "FINGERPRINT" && targetAppVersion === null && typeof fingerprintHash === "string")) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-data");
80
+ };
81
+ //#endregion
82
+ exports.validateApiKeyUpdateData = validateApiKeyUpdateData;
83
+ exports.validateBundleUpdateData = validateBundleUpdateData;
84
+ exports.validateMutationWhere = validateMutationWhere;
85
+ exports.validateReleaseCatalogUpdateData = validateReleaseCatalogUpdateData;
86
+ exports.validateReleaseTargetUpdate = validateReleaseTargetUpdate;
87
+ exports.validateReleaseUpdateData = validateReleaseUpdateData;
88
+ exports.validateUpdateWhere = validateUpdateWhere;
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,82 @@
1
+ import { DatabasePluginInputError } from "./databasePluginCrudValidationErrors.mjs";
2
+ import { isRecord, modelValidators, validateField } from "./databasePluginCrudValidationFields.mjs";
3
+ import { validateResult } from "./databasePluginCrudValidationRows.mjs";
4
+ //#region src/databasePluginCrudValidationMutations.ts
5
+ const validateMutationWhere = (where) => {
6
+ if (where.length === 0) throw new DatabasePluginInputError("empty-mutation-where");
7
+ };
8
+ const validateUpdateWhere = (model, where) => {
9
+ const selector = where[0];
10
+ const primaryField = model === "release_catalogs" ? "scope_key" : "id";
11
+ if (where.length !== 1 || !isRecord(selector) || selector.field !== primaryField || selector.operator !== void 0 && selector.operator !== "eq" || typeof selector.value !== "string" || selector.connector !== void 0 || selector.mode !== void 0) throw new DatabasePluginInputError("invalid-update-selector");
12
+ };
13
+ const validateBundleUpdateData = (update) => {
14
+ if (!isRecord(update)) throw new DatabasePluginInputError("invalid-data");
15
+ for (const [field, value] of Object.entries(update)) {
16
+ if (field === "id") throw new DatabasePluginInputError("invalid-data");
17
+ validateField("bundles", field);
18
+ const validator = modelValidators.bundles[field];
19
+ if (!validator || !validator(value)) throw new DatabasePluginInputError("invalid-data");
20
+ }
21
+ };
22
+ const validateApiKeyUpdateData = (update) => {
23
+ if (!isRecord(update) || Reflect.ownKeys(update).length !== 1 || !Object.hasOwn(update, "revoked_at_ms") || !modelValidators.api_keys.revoked_at_ms(Reflect.get(update, "revoked_at_ms"))) throw new DatabasePluginInputError("invalid-data");
24
+ };
25
+ const RELEASE_MUTABLE_FIELDS = new Set([
26
+ "revision",
27
+ "scope_key",
28
+ "target_app_version",
29
+ "fingerprint_hash",
30
+ "enabled",
31
+ "should_force_update",
32
+ "message",
33
+ "rollout_cohort_count",
34
+ "target_cohorts",
35
+ "updated_at_ms"
36
+ ]);
37
+ const validateReleaseUpdateData = (update) => {
38
+ if (!isRecord(update) || Reflect.ownKeys(update).length === 0) throw new DatabasePluginInputError("invalid-data");
39
+ for (const [field, value] of Object.entries(update)) {
40
+ if (!RELEASE_MUTABLE_FIELDS.has(field)) throw new DatabasePluginInputError("invalid-data");
41
+ const validator = modelValidators.releases[field];
42
+ if (!validator || !validator(value)) throw new DatabasePluginInputError("invalid-data");
43
+ }
44
+ };
45
+ const validateReleaseCatalogUpdateData = (update) => {
46
+ if (!isRecord(update)) throw new DatabasePluginInputError("invalid-data");
47
+ const expectedFields = Object.keys(modelValidators.release_catalogs).filter((field) => field !== "scope_key");
48
+ if (Reflect.ownKeys(update).length !== expectedFields.length || expectedFields.some((field) => !Object.hasOwn(update, field))) throw new DatabasePluginInputError("invalid-data");
49
+ for (const [field, value] of Object.entries(update)) {
50
+ const validator = modelValidators.release_catalogs[field];
51
+ if (!validator || !validator(value)) throw new DatabasePluginInputError("invalid-data");
52
+ }
53
+ };
54
+ const validateReleaseTargetUpdate = async (implementation, input) => {
55
+ if (!Object.hasOwn(input.update, "target_app_version") && !Object.hasOwn(input.update, "fingerprint_hash")) return;
56
+ const id = input.where[0]?.value;
57
+ if (typeof id !== "string") return;
58
+ const current = await implementation.findOne({
59
+ model: "releases",
60
+ where: [{
61
+ field: "id",
62
+ value: id
63
+ }],
64
+ select: [
65
+ "strategy",
66
+ "target_app_version",
67
+ "fingerprint_hash"
68
+ ]
69
+ });
70
+ if (current === null) return;
71
+ validateResult("releases", current, [
72
+ "strategy",
73
+ "target_app_version",
74
+ "fingerprint_hash"
75
+ ]);
76
+ const strategy = Reflect.get(current, "strategy");
77
+ const targetAppVersion = Object.hasOwn(input.update, "target_app_version") ? input.update.target_app_version : Reflect.get(current, "target_app_version");
78
+ const fingerprintHash = Object.hasOwn(input.update, "fingerprint_hash") ? input.update.fingerprint_hash : Reflect.get(current, "fingerprint_hash");
79
+ if (!(strategy === "APP_VERSION" && typeof targetAppVersion === "string" && fingerprintHash === null || strategy === "FINGERPRINT" && targetAppVersion === null && typeof fingerprintHash === "string")) throw new DatabasePluginInputError("invalid-data");
80
+ };
81
+ //#endregion
82
+ export { validateApiKeyUpdateData, validateBundleUpdateData, validateMutationWhere, validateReleaseCatalogUpdateData, validateReleaseTargetUpdate, validateReleaseUpdateData, validateUpdateWhere };
@@ -0,0 +1,103 @@
1
+ const require_databasePluginCrudValidationErrors = require("./databasePluginCrudValidationErrors.cjs");
2
+ const require_databasePluginCrudValidationFields = require("./databasePluginCrudValidationFields.cjs");
3
+ //#region src/databasePluginCrudValidationQueries.ts
4
+ const validateSelect = (model, select) => {
5
+ if (select === void 0) return;
6
+ if (!Array.isArray(select) || select.length === 0) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("empty-select");
7
+ if (!select.every((field) => typeof field === "string")) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-query");
8
+ require_databasePluginCrudValidationFields.validateFields(model, select);
9
+ };
10
+ const validateWhereValue = (model, condition) => {
11
+ const field = condition.field;
12
+ if (typeof field !== "string") throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-query");
13
+ require_databasePluginCrudValidationFields.validateField(model, field);
14
+ const operator = condition.operator ?? "eq";
15
+ const value = condition.value;
16
+ const mode = condition.mode;
17
+ if (mode !== void 0 && mode !== "sensitive" && mode !== "insensitive") throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-query");
18
+ switch (operator) {
19
+ case "eq":
20
+ case "ne":
21
+ if (!(require_databasePluginCrudValidationFields.isStringField(field) || require_databasePluginCrudValidationFields.isNumberField(field) || require_databasePluginCrudValidationFields.isBooleanField(field)) || !require_databasePluginCrudValidationFields.modelValidators[model][field]?.(value) || mode !== void 0 && (!require_databasePluginCrudValidationFields.isStringField(field) || typeof value !== "string")) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-query");
22
+ return;
23
+ case "gt":
24
+ case "gte":
25
+ case "lt":
26
+ case "lte":
27
+ if (mode !== void 0 || !(require_databasePluginCrudValidationFields.isStringField(field) || require_databasePluginCrudValidationFields.isNumberField(field)) || value === null || !require_databasePluginCrudValidationFields.modelValidators[model][field]?.(value)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-query");
28
+ return;
29
+ case "in":
30
+ case "not_in":
31
+ if (!Array.isArray(value) || mode !== void 0) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-query");
32
+ if (!(require_databasePluginCrudValidationFields.isStringField(field) || require_databasePluginCrudValidationFields.isNumberField(field) || require_databasePluginCrudValidationFields.isBooleanField(field))) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-query");
33
+ if (!value.every((item) => require_databasePluginCrudValidationFields.modelValidators[model][field]?.(item))) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-query");
34
+ return;
35
+ case "contains":
36
+ case "starts_with":
37
+ case "ends_with":
38
+ if (!require_databasePluginCrudValidationFields.isStringField(field) || typeof value !== "string" || !require_databasePluginCrudValidationFields.modelValidators[model][field]?.(value)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-query");
39
+ return;
40
+ default: throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-query");
41
+ }
42
+ };
43
+ const validateWhere = (model, where) => {
44
+ if (where === void 0) return;
45
+ if (!Array.isArray(where)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-query");
46
+ for (const item of where) {
47
+ if (!require_databasePluginCrudValidationFields.isRecord(item)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-query");
48
+ if (item.connector !== void 0 && item.connector !== "AND" && item.connector !== "OR") throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-query");
49
+ validateWhereValue(model, item);
50
+ }
51
+ };
52
+ const validateDistinctFields = (model, fields) => {
53
+ if (fields === void 0) return void 0;
54
+ if (!Array.isArray(fields) || fields.length === 0) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-distinct");
55
+ if (!fields.every((field) => typeof field === "string")) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-distinct");
56
+ require_databasePluginCrudValidationFields.validateFields(model, fields);
57
+ return fields;
58
+ };
59
+ const validateOrderBy = (model, orderBy) => {
60
+ if (orderBy === void 0) return void 0;
61
+ if (!Array.isArray(orderBy) || orderBy.length === 0) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-query");
62
+ const fields = /* @__PURE__ */ new Set();
63
+ return orderBy.map((clause) => {
64
+ if (!require_databasePluginCrudValidationFields.isRecord(clause) || typeof clause.field !== "string") throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-query");
65
+ require_databasePluginCrudValidationFields.validateField(model, clause.field);
66
+ if (!require_databasePluginCrudValidationFields.sortableFields[model].has(clause.field)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-query");
67
+ if (clause.direction !== "asc" && clause.direction !== "desc") throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-query");
68
+ if (clause.nulls !== void 0 && clause.nulls !== "first" && clause.nulls !== "last") throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-query");
69
+ if (fields.has(clause.field)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-operation");
70
+ fields.add(clause.field);
71
+ return clause;
72
+ });
73
+ };
74
+ const validateDistinctOn = (model, distinctOn, orderBy) => {
75
+ if (distinctOn === void 0) return;
76
+ if (!require_databasePluginCrudValidationFields.isRecord(distinctOn)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-distinct");
77
+ const fields = validateDistinctFields(model, distinctOn.fields);
78
+ if (fields === void 0 || orderBy === void 0) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-distinct");
79
+ for (const [index, field] of fields.entries()) if (orderBy[index]?.field !== field) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-distinct");
80
+ };
81
+ const validatePagination = (limit, offset) => {
82
+ const effectiveLimit = limit ?? 100;
83
+ const effectiveOffset = offset ?? 0;
84
+ if (limit !== void 0 && (!Number.isSafeInteger(limit) || limit < 0) || offset !== void 0 && (!Number.isSafeInteger(offset) || offset < 0) || !Number.isSafeInteger(effectiveOffset + effectiveLimit)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-pagination");
85
+ };
86
+ const validateBundlePagination = (options) => {
87
+ if (!Number.isSafeInteger(options.limit) || options.limit <= 0 || options.page !== void 0 && (!Number.isSafeInteger(options.page) || options.page <= 0) || options.page !== void 0 && options.cursor !== void 0) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-pagination");
88
+ const cursor = options.cursor;
89
+ if (cursor === void 0) return;
90
+ if (!require_databasePluginCrudValidationFields.isRecord(cursor)) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-pagination");
91
+ const hasAfter = Object.hasOwn(cursor, "after");
92
+ if (hasAfter === Object.hasOwn(cursor, "before")) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-pagination");
93
+ const value = hasAfter ? cursor.after : cursor.before;
94
+ if (typeof value !== "string" || value.length === 0) throw new require_databasePluginCrudValidationErrors.DatabasePluginInputError("invalid-pagination");
95
+ };
96
+ //#endregion
97
+ exports.validateBundlePagination = validateBundlePagination;
98
+ exports.validateDistinctFields = validateDistinctFields;
99
+ exports.validateDistinctOn = validateDistinctOn;
100
+ exports.validateOrderBy = validateOrderBy;
101
+ exports.validatePagination = validatePagination;
102
+ exports.validateSelect = validateSelect;
103
+ exports.validateWhere = validateWhere;
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1 @@
1
+ export { };