@hot-updater/plugin-core 0.36.7 → 1.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assetStorageLayout.cjs +36 -18
- package/dist/assetStorageLayout.d.cts +21 -6
- package/dist/assetStorageLayout.d.mts +21 -6
- package/dist/assetStorageLayout.mjs +36 -18
- package/dist/bundleStorageLayout.cjs +2 -3
- package/dist/bundleStorageLayout.mjs +2 -3
- package/dist/contentAddressedAssets.cjs +5 -0
- package/dist/contentAddressedAssets.d.cts +2 -1
- package/dist/contentAddressedAssets.d.mts +2 -1
- package/dist/contentAddressedAssets.mjs +5 -1
- package/dist/createDatabasePlugin.cjs +775 -284
- package/dist/createDatabasePlugin.d.cts +20 -64
- package/dist/createDatabasePlugin.d.mts +20 -64
- package/dist/createDatabasePlugin.mjs +773 -284
- package/dist/createStorageKeyBuilder.cjs +9 -2
- package/dist/createStorageKeyBuilder.mjs +9 -2
- package/dist/createStoragePlugin.cjs +6 -145
- package/dist/createStoragePlugin.d.cts +7 -52
- package/dist/createStoragePlugin.d.mts +7 -52
- package/dist/createStoragePlugin.mjs +5 -143
- package/dist/databaseClient.cjs +112 -0
- package/dist/databaseClient.d.cts +33 -0
- package/dist/databaseClient.d.mts +33 -0
- package/dist/databaseClient.mjs +110 -0
- package/dist/databaseClientReads.cjs +113 -0
- package/dist/databaseClientReads.mjs +112 -0
- package/dist/databaseClientUpdates.cjs +39 -0
- package/dist/databaseClientUpdates.d.cts +11 -0
- package/dist/databaseClientUpdates.d.mts +11 -0
- package/dist/databaseClientUpdates.mjs +36 -0
- package/dist/databaseJsonValue.cjs +37 -0
- package/dist/databaseJsonValue.d.cts +5 -0
- package/dist/databaseJsonValue.d.mts +5 -0
- package/dist/databaseJsonValue.mjs +37 -0
- package/dist/databaseMetadata.cjs +13 -0
- package/dist/databaseMetadata.mjs +12 -0
- package/dist/databasePluginCrud.cjs +86 -0
- package/dist/databasePluginCrud.d.cts +1 -0
- package/dist/databasePluginCrud.d.mts +1 -0
- package/dist/databasePluginCrud.mjs +86 -0
- package/dist/databasePluginCrudValidation.d.cts +1 -0
- package/dist/databasePluginCrudValidation.d.mts +1 -0
- package/dist/databasePluginCrudValidationErrors.cjs +10 -0
- package/dist/databasePluginCrudValidationErrors.d.cts +9 -0
- package/dist/databasePluginCrudValidationErrors.d.mts +9 -0
- package/dist/databasePluginCrudValidationErrors.mjs +10 -0
- package/dist/databasePluginCrudValidationFields.cjs +291 -0
- package/dist/databasePluginCrudValidationFields.d.cts +1 -0
- package/dist/databasePluginCrudValidationFields.d.mts +1 -0
- package/dist/databasePluginCrudValidationFields.mjs +281 -0
- package/dist/databasePluginCrudValidationMutations.cjs +88 -0
- package/dist/databasePluginCrudValidationMutations.d.cts +1 -0
- package/dist/databasePluginCrudValidationMutations.d.mts +1 -0
- package/dist/databasePluginCrudValidationMutations.mjs +82 -0
- package/dist/databasePluginCrudValidationQueries.cjs +103 -0
- package/dist/databasePluginCrudValidationQueries.d.cts +1 -0
- package/dist/databasePluginCrudValidationQueries.d.mts +1 -0
- package/dist/databasePluginCrudValidationQueries.mjs +97 -0
- package/dist/databasePluginCrudValidationRows.cjs +55 -0
- package/dist/databasePluginCrudValidationRows.d.cts +1 -0
- package/dist/databasePluginCrudValidationRows.d.mts +1 -0
- package/dist/databasePluginCrudValidationRows.mjs +53 -0
- package/dist/databasePluginTransaction.cjs +7 -0
- package/dist/databasePluginTransaction.mjs +7 -0
- package/dist/databaseRows.cjs +149 -0
- package/dist/databaseRows.d.cts +34 -0
- package/dist/databaseRows.d.mts +34 -0
- package/dist/databaseRows.mjs +141 -0
- package/dist/index.cjs +76 -24
- package/dist/index.d.cts +22 -12
- package/dist/index.d.mts +22 -12
- package/dist/index.mjs +21 -14
- package/dist/internal.cjs +6 -0
- package/dist/internal.d.cts +9 -0
- package/dist/internal.d.mts +9 -0
- package/dist/internal.mjs +3 -0
- package/dist/node_modules/.pnpm/verkit@0.3.2/node_modules/verkit/dist/index.cjs +345 -0
- package/dist/node_modules/.pnpm/verkit@0.3.2/node_modules/verkit/dist/index.mjs +341 -0
- package/dist/paginateBundles.d.cts +6 -4
- package/dist/paginateBundles.d.mts +6 -4
- package/dist/parseStorageUri.cjs +46 -30
- package/dist/parseStorageUri.d.cts +20 -17
- package/dist/parseStorageUri.d.mts +20 -17
- package/dist/parseStorageUri.mjs +46 -30
- package/dist/queryBundles.cjs +1 -7
- package/dist/queryBundles.d.cts +3 -1
- package/dist/queryBundles.d.mts +3 -1
- package/dist/queryBundles.mjs +1 -7
- package/dist/releaseCatalogCompiler.cjs +391 -0
- package/dist/releaseCatalogCompiler.d.cts +55 -0
- package/dist/releaseCatalogCompiler.d.mts +55 -0
- package/dist/releaseCatalogCompiler.mjs +386 -0
- package/dist/releaseCatalogMutation.cjs +303 -0
- package/dist/releaseCatalogMutation.d.cts +86 -0
- package/dist/releaseCatalogMutation.d.mts +86 -0
- package/dist/releaseCatalogMutation.mjs +297 -0
- package/dist/releaseManagement.cjs +231 -0
- package/dist/releaseManagement.d.cts +48 -0
- package/dist/releaseManagement.d.mts +48 -0
- package/dist/releaseManagement.mjs +224 -0
- package/dist/remoteBundleSigning.cjs +296 -0
- package/dist/remoteBundleSigning.d.cts +43 -0
- package/dist/remoteBundleSigning.d.mts +43 -0
- package/dist/remoteBundleSigning.mjs +291 -0
- package/dist/requestBundleCache.cjs +22 -0
- package/dist/requestBundleCache.d.cts +9 -0
- package/dist/requestBundleCache.d.mts +9 -0
- package/dist/requestBundleCache.mjs +22 -0
- package/dist/semverSatisfies.cjs +3 -4
- package/dist/semverSatisfies.mjs +1 -1
- package/dist/storageDownloadPath.cjs +48 -0
- package/dist/storageDownloadPath.d.cts +15 -0
- package/dist/storageDownloadPath.d.mts +15 -0
- package/dist/storageDownloadPath.mjs +46 -0
- package/dist/types/database.d.cts +4 -0
- package/dist/types/database.d.mts +4 -0
- package/dist/types/databaseFields.cjs +92 -0
- package/dist/types/databaseFields.d.cts +12 -0
- package/dist/types/databaseFields.d.mts +12 -0
- package/dist/types/databaseFields.mjs +92 -0
- package/dist/types/databaseOperations.d.cts +173 -0
- package/dist/types/databaseOperations.d.mts +173 -0
- package/dist/types/databasePlugin.d.cts +240 -0
- package/dist/types/databasePlugin.d.mts +240 -0
- package/dist/types/databaseQuery.d.cts +47 -0
- package/dist/types/databaseQuery.d.mts +47 -0
- package/dist/types/databaseRows.d.cts +120 -0
- package/dist/types/databaseRows.d.mts +120 -0
- package/dist/types/index.d.cts +120 -162
- package/dist/types/index.d.mts +120 -162
- package/dist/types/internal.d.cts +7 -0
- package/dist/types/internal.d.mts +7 -0
- package/dist/types/public.d.cts +3 -0
- package/dist/types/public.d.mts +3 -0
- package/dist/uuidv7.cjs +9 -0
- package/dist/uuidv7.d.cts +4 -1
- package/dist/uuidv7.d.mts +4 -1
- package/dist/uuidv7.mjs +8 -1
- package/package.json +10 -5
- package/dist/bundleUnitOfWork.cjs +0 -158
- package/dist/bundleUnitOfWork.mjs +0 -158
- package/dist/bundleUnitOfWorkStore.cjs +0 -15
- package/dist/bundleUnitOfWorkStore.mjs +0 -15
- package/dist/createBlobDatabasePlugin.cjs +0 -382
- package/dist/createBlobDatabasePlugin.d.cts +0 -29
- package/dist/createBlobDatabasePlugin.d.mts +0 -29
- package/dist/createBlobDatabasePlugin.mjs +0 -381
- package/dist/legacyAssetStorageLayout.cjs +0 -12
- package/dist/legacyAssetStorageLayout.mjs +0 -12
- package/dist/requestUpdateBundleState.cjs +0 -26
- package/dist/requestUpdateBundleState.d.cts +0 -12
- package/dist/requestUpdateBundleState.d.mts +0 -12
- package/dist/requestUpdateBundleState.mjs +0 -24
- package/dist/resolveUpdateInfoFromBundles.cjs +0 -14
- package/dist/resolveUpdateInfoFromBundles.d.cts +0 -16
- package/dist/resolveUpdateInfoFromBundles.d.mts +0 -16
- package/dist/resolveUpdateInfoFromBundles.mjs +0 -13
- package/dist/storageProfile.cjs +0 -15
- package/dist/storageProfile.d.cts +0 -9
- package/dist/storageProfile.d.mts +0 -9
- package/dist/storageProfile.mjs +0 -12
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
//#region src/createStorageKeyBuilder.ts
|
|
2
|
-
const
|
|
3
|
-
|
|
2
|
+
const normalizeStorageKeyParts = (values) => {
|
|
3
|
+
if (values.some((value) => value.includes("\\"))) throw new Error("Storage keys must use '/' as the hierarchy separator.");
|
|
4
|
+
const segments = values.flatMap((value) => value.split("/").filter(Boolean));
|
|
5
|
+
if (segments.some((segment) => segment === "." || segment === "..")) throw new Error("Storage key segments must not be '.' or '..'.");
|
|
6
|
+
return segments;
|
|
7
|
+
};
|
|
8
|
+
const createStorageKeyBuilder = (basePath) => {
|
|
9
|
+
const baseSegments = normalizeStorageKeyParts([basePath ?? ""]);
|
|
10
|
+
return (...args) => [...baseSegments, ...normalizeStorageKeyParts(args)].join("/");
|
|
4
11
|
};
|
|
5
12
|
//#endregion
|
|
6
13
|
exports.createStorageKeyBuilder = createStorageKeyBuilder;
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
//#region src/createStorageKeyBuilder.ts
|
|
2
|
-
const
|
|
3
|
-
|
|
2
|
+
const normalizeStorageKeyParts = (values) => {
|
|
3
|
+
if (values.some((value) => value.includes("\\"))) throw new Error("Storage keys must use '/' as the hierarchy separator.");
|
|
4
|
+
const segments = values.flatMap((value) => value.split("/").filter(Boolean));
|
|
5
|
+
if (segments.some((segment) => segment === "." || segment === "..")) throw new Error("Storage key segments must not be '.' or '..'.");
|
|
6
|
+
return segments;
|
|
7
|
+
};
|
|
8
|
+
const createStorageKeyBuilder = (basePath) => {
|
|
9
|
+
const baseSegments = normalizeStorageKeyParts([basePath ?? ""]);
|
|
10
|
+
return (...args) => [...baseSegments, ...normalizeStorageKeyParts(args)].join("/");
|
|
4
11
|
};
|
|
5
12
|
//#endregion
|
|
6
13
|
export { createStorageKeyBuilder };
|
|
@@ -1,147 +1,8 @@
|
|
|
1
1
|
//#region src/createStoragePlugin.ts
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
await hooks?.onStorageUploaded?.();
|
|
7
|
-
return result;
|
|
8
|
-
}
|
|
9
|
-
});
|
|
10
|
-
const createProfiledStoragePlugin = ({ createProfiles, name, profileShape, supportedProtocol }, hooks) => {
|
|
11
|
-
let cachedProfiles = null;
|
|
12
|
-
let cachedNodeProfile;
|
|
13
|
-
let cachedRuntimeProfile;
|
|
14
|
-
const getProfiles = () => {
|
|
15
|
-
cachedProfiles ??= createProfiles();
|
|
16
|
-
return cachedProfiles;
|
|
17
|
-
};
|
|
18
|
-
const getNodeProfile = () => {
|
|
19
|
-
const node = getProfiles().node;
|
|
20
|
-
if (!node) return;
|
|
21
|
-
cachedNodeProfile ??= wrapNodeProfile(node, hooks);
|
|
22
|
-
return cachedNodeProfile;
|
|
23
|
-
};
|
|
24
|
-
const requireNodeProfile = () => {
|
|
25
|
-
const node = getNodeProfile();
|
|
26
|
-
if (!node) throw new Error(`${name} does not implement the node storage profile for protocol "${supportedProtocol}".`);
|
|
27
|
-
return node;
|
|
28
|
-
};
|
|
29
|
-
const getRuntimeProfile = () => {
|
|
30
|
-
const runtime = getProfiles().runtime;
|
|
31
|
-
if (!runtime) return;
|
|
32
|
-
cachedRuntimeProfile ??= runtime;
|
|
33
|
-
return cachedRuntimeProfile;
|
|
34
|
-
};
|
|
35
|
-
const requireRuntimeProfile = () => {
|
|
36
|
-
const runtime = getRuntimeProfile();
|
|
37
|
-
if (!runtime) throw new Error(`${name} does not implement the runtime storage profile for protocol "${supportedProtocol}".`);
|
|
38
|
-
return runtime;
|
|
39
|
-
};
|
|
40
|
-
const profiles = {};
|
|
41
|
-
if (profileShape?.node) {
|
|
42
|
-
const nodeProfile = {
|
|
43
|
-
async delete(storageUri) {
|
|
44
|
-
return requireNodeProfile().delete(storageUri);
|
|
45
|
-
},
|
|
46
|
-
async downloadFile(storageUri, filePath) {
|
|
47
|
-
return requireNodeProfile().downloadFile(storageUri, filePath);
|
|
48
|
-
},
|
|
49
|
-
async exists(storageUri) {
|
|
50
|
-
return requireNodeProfile().exists(storageUri);
|
|
51
|
-
},
|
|
52
|
-
async upload(key, filePath) {
|
|
53
|
-
return requireNodeProfile().upload(key, filePath);
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
Object.defineProperties(nodeProfile, {
|
|
57
|
-
deleteObjects: {
|
|
58
|
-
enumerable: true,
|
|
59
|
-
get: () => {
|
|
60
|
-
const deleteObjects = requireNodeProfile().deleteObjects;
|
|
61
|
-
return deleteObjects ? (keys) => deleteObjects(keys) : void 0;
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
listObjects: {
|
|
65
|
-
enumerable: true,
|
|
66
|
-
get: () => {
|
|
67
|
-
const listObjects = requireNodeProfile().listObjects;
|
|
68
|
-
return listObjects ? (prefix) => listObjects(prefix) : void 0;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
profiles.node = nodeProfile;
|
|
73
|
-
} else if (profileShape?.node !== false) Object.defineProperty(profiles, "node", {
|
|
74
|
-
enumerable: true,
|
|
75
|
-
get: getNodeProfile
|
|
76
|
-
});
|
|
77
|
-
if (profileShape?.runtime) profiles.runtime = {
|
|
78
|
-
async getDownloadUrl(storageUri, context) {
|
|
79
|
-
return requireRuntimeProfile().getDownloadUrl(storageUri, context);
|
|
80
|
-
},
|
|
81
|
-
async readText(storageUri, context) {
|
|
82
|
-
return requireRuntimeProfile().readText(storageUri, context);
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
else if (profileShape?.runtime !== false) Object.defineProperty(profiles, "runtime", {
|
|
86
|
-
enumerable: true,
|
|
87
|
-
get: getRuntimeProfile
|
|
88
|
-
});
|
|
89
|
-
return {
|
|
90
|
-
name,
|
|
91
|
-
supportedProtocol,
|
|
92
|
-
profiles
|
|
93
|
-
};
|
|
94
|
-
};
|
|
95
|
-
/**
|
|
96
|
-
* Creates a deploy/CLI/console storage plugin.
|
|
97
|
-
*/
|
|
98
|
-
const createNodeStoragePlugin = (options) => {
|
|
99
|
-
return (config, hooks) => {
|
|
100
|
-
return () => createProfiledStoragePlugin({
|
|
101
|
-
createProfiles: () => ({ node: options.factory(config) }),
|
|
102
|
-
name: options.name,
|
|
103
|
-
profileShape: {
|
|
104
|
-
node: true,
|
|
105
|
-
runtime: false
|
|
106
|
-
},
|
|
107
|
-
supportedProtocol: options.supportedProtocol
|
|
108
|
-
}, hooks);
|
|
109
|
-
};
|
|
110
|
-
};
|
|
111
|
-
/**
|
|
112
|
-
* Creates an update-check runtime storage plugin.
|
|
113
|
-
*/
|
|
114
|
-
const createRuntimeStoragePlugin = (options) => {
|
|
115
|
-
return (config, hooks) => {
|
|
116
|
-
return () => createProfiledStoragePlugin({
|
|
117
|
-
createProfiles: () => ({ runtime: options.factory(config) }),
|
|
118
|
-
name: options.name,
|
|
119
|
-
profileShape: {
|
|
120
|
-
node: false,
|
|
121
|
-
runtime: true
|
|
122
|
-
},
|
|
123
|
-
supportedProtocol: options.supportedProtocol
|
|
124
|
-
}, hooks);
|
|
125
|
-
};
|
|
126
|
-
};
|
|
127
|
-
/**
|
|
128
|
-
* Creates a storage plugin that can be used by both Node tooling and update
|
|
129
|
-
* check runtimes.
|
|
130
|
-
*/
|
|
131
|
-
const createUniversalStoragePlugin = (options) => {
|
|
132
|
-
return (config, hooks) => {
|
|
133
|
-
return () => createProfiledStoragePlugin({
|
|
134
|
-
createProfiles: () => options.factory(config),
|
|
135
|
-
name: options.name,
|
|
136
|
-
profileShape: {
|
|
137
|
-
node: true,
|
|
138
|
-
runtime: true
|
|
139
|
-
},
|
|
140
|
-
supportedProtocol: options.supportedProtocol
|
|
141
|
-
}, hooks);
|
|
142
|
-
};
|
|
143
|
-
};
|
|
2
|
+
const createStoragePlugin = (options) => ({ ...options });
|
|
3
|
+
function assertStorageOperations(plugin, operations) {
|
|
4
|
+
for (const operation of operations) if (typeof plugin[operation] !== "function") throw new Error(`Storage plugin "${plugin.name}" does not implement ${operation}.`);
|
|
5
|
+
}
|
|
144
6
|
//#endregion
|
|
145
|
-
exports.
|
|
146
|
-
exports.
|
|
147
|
-
exports.createUniversalStoragePlugin = createUniversalStoragePlugin;
|
|
7
|
+
exports.assertStorageOperations = assertStorageOperations;
|
|
8
|
+
exports.createStoragePlugin = createStoragePlugin;
|
|
@@ -1,55 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { StoragePlugin } from "./types/index.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/createStoragePlugin.d.ts
|
|
4
|
-
type
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
name: string;
|
|
10
|
-
/**
|
|
11
|
-
* The protocol that this storage plugin supports (e.g., "s3", "r2", "gs").
|
|
12
|
-
*
|
|
13
|
-
* This value is stored in the database and is used by the server to
|
|
14
|
-
* understand how to fetch assets.
|
|
15
|
-
*/
|
|
16
|
-
supportedProtocol: string;
|
|
17
|
-
/**
|
|
18
|
-
* Function that creates the storage plugin profiles.
|
|
19
|
-
*/
|
|
20
|
-
factory: StorageProfileFactory<TConfig, TProfiles>;
|
|
21
|
-
}
|
|
22
|
-
type CreateNodeStoragePluginOptions<TConfig> = Omit<BaseStoragePluginOptions<TConfig, unknown, {
|
|
23
|
-
node: NodeStorageProfile;
|
|
24
|
-
}>, "factory"> & {
|
|
25
|
-
factory: StorageProfileFactory<TConfig, NodeStorageProfile>;
|
|
26
|
-
};
|
|
27
|
-
type CreateRuntimeStoragePluginOptions<TConfig, TContext = unknown> = Omit<BaseStoragePluginOptions<TConfig, TContext, {
|
|
28
|
-
runtime: RuntimeStorageProfile<TContext>;
|
|
29
|
-
}>, "factory"> & {
|
|
30
|
-
factory: StorageProfileFactory<TConfig, RuntimeStorageProfile<TContext>>;
|
|
31
|
-
};
|
|
32
|
-
type CreateUniversalStoragePluginOptions<TConfig, TContext = unknown> = Omit<BaseStoragePluginOptions<TConfig, TContext, {
|
|
33
|
-
node: NodeStorageProfile;
|
|
34
|
-
runtime: RuntimeStorageProfile<TContext>;
|
|
35
|
-
}>, "factory"> & {
|
|
36
|
-
factory: StorageProfileFactory<TConfig, {
|
|
37
|
-
node: NodeStorageProfile;
|
|
38
|
-
runtime: RuntimeStorageProfile<TContext>;
|
|
39
|
-
}>;
|
|
40
|
-
};
|
|
41
|
-
/**
|
|
42
|
-
* Creates a deploy/CLI/console storage plugin.
|
|
43
|
-
*/
|
|
44
|
-
declare const createNodeStoragePlugin: <TConfig>(options: CreateNodeStoragePluginOptions<TConfig>) => (config: TConfig, hooks?: StoragePluginHooks) => () => NodeStoragePlugin;
|
|
45
|
-
/**
|
|
46
|
-
* Creates an update-check runtime storage plugin.
|
|
47
|
-
*/
|
|
48
|
-
declare const createRuntimeStoragePlugin: <TConfig, TContext = unknown>(options: CreateRuntimeStoragePluginOptions<TConfig, TContext>) => (config: TConfig, hooks?: StoragePluginHooks) => () => RuntimeStoragePlugin<TContext>;
|
|
49
|
-
/**
|
|
50
|
-
* Creates a storage plugin that can be used by both Node tooling and update
|
|
51
|
-
* check runtimes.
|
|
52
|
-
*/
|
|
53
|
-
declare const createUniversalStoragePlugin: <TConfig, TContext = unknown>(options: CreateUniversalStoragePluginOptions<TConfig, TContext>) => (config: TConfig, hooks?: StoragePluginHooks) => () => UniversalStoragePlugin<TContext>;
|
|
4
|
+
type CreateStoragePluginOptions = StoragePlugin;
|
|
5
|
+
type StorageOperation = Exclude<keyof StoragePlugin, "name" | "protocol">;
|
|
6
|
+
type StoragePluginWith<TOperation extends StorageOperation> = StoragePlugin & Required<Pick<StoragePlugin, TOperation>>;
|
|
7
|
+
declare const createStoragePlugin: <const TOptions extends CreateStoragePluginOptions>(options: TOptions) => TOptions;
|
|
8
|
+
declare function assertStorageOperations<const TOperations extends readonly StorageOperation[]>(plugin: StoragePlugin, operations: TOperations): asserts plugin is StoragePluginWith<TOperations[number]>;
|
|
54
9
|
//#endregion
|
|
55
|
-
export {
|
|
10
|
+
export { CreateStoragePluginOptions, StorageOperation, StoragePluginWith, assertStorageOperations, createStoragePlugin };
|
|
@@ -1,55 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { StoragePlugin } from "./types/index.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/createStoragePlugin.d.ts
|
|
4
|
-
type
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
name: string;
|
|
10
|
-
/**
|
|
11
|
-
* The protocol that this storage plugin supports (e.g., "s3", "r2", "gs").
|
|
12
|
-
*
|
|
13
|
-
* This value is stored in the database and is used by the server to
|
|
14
|
-
* understand how to fetch assets.
|
|
15
|
-
*/
|
|
16
|
-
supportedProtocol: string;
|
|
17
|
-
/**
|
|
18
|
-
* Function that creates the storage plugin profiles.
|
|
19
|
-
*/
|
|
20
|
-
factory: StorageProfileFactory<TConfig, TProfiles>;
|
|
21
|
-
}
|
|
22
|
-
type CreateNodeStoragePluginOptions<TConfig> = Omit<BaseStoragePluginOptions<TConfig, unknown, {
|
|
23
|
-
node: NodeStorageProfile;
|
|
24
|
-
}>, "factory"> & {
|
|
25
|
-
factory: StorageProfileFactory<TConfig, NodeStorageProfile>;
|
|
26
|
-
};
|
|
27
|
-
type CreateRuntimeStoragePluginOptions<TConfig, TContext = unknown> = Omit<BaseStoragePluginOptions<TConfig, TContext, {
|
|
28
|
-
runtime: RuntimeStorageProfile<TContext>;
|
|
29
|
-
}>, "factory"> & {
|
|
30
|
-
factory: StorageProfileFactory<TConfig, RuntimeStorageProfile<TContext>>;
|
|
31
|
-
};
|
|
32
|
-
type CreateUniversalStoragePluginOptions<TConfig, TContext = unknown> = Omit<BaseStoragePluginOptions<TConfig, TContext, {
|
|
33
|
-
node: NodeStorageProfile;
|
|
34
|
-
runtime: RuntimeStorageProfile<TContext>;
|
|
35
|
-
}>, "factory"> & {
|
|
36
|
-
factory: StorageProfileFactory<TConfig, {
|
|
37
|
-
node: NodeStorageProfile;
|
|
38
|
-
runtime: RuntimeStorageProfile<TContext>;
|
|
39
|
-
}>;
|
|
40
|
-
};
|
|
41
|
-
/**
|
|
42
|
-
* Creates a deploy/CLI/console storage plugin.
|
|
43
|
-
*/
|
|
44
|
-
declare const createNodeStoragePlugin: <TConfig>(options: CreateNodeStoragePluginOptions<TConfig>) => (config: TConfig, hooks?: StoragePluginHooks) => () => NodeStoragePlugin;
|
|
45
|
-
/**
|
|
46
|
-
* Creates an update-check runtime storage plugin.
|
|
47
|
-
*/
|
|
48
|
-
declare const createRuntimeStoragePlugin: <TConfig, TContext = unknown>(options: CreateRuntimeStoragePluginOptions<TConfig, TContext>) => (config: TConfig, hooks?: StoragePluginHooks) => () => RuntimeStoragePlugin<TContext>;
|
|
49
|
-
/**
|
|
50
|
-
* Creates a storage plugin that can be used by both Node tooling and update
|
|
51
|
-
* check runtimes.
|
|
52
|
-
*/
|
|
53
|
-
declare const createUniversalStoragePlugin: <TConfig, TContext = unknown>(options: CreateUniversalStoragePluginOptions<TConfig, TContext>) => (config: TConfig, hooks?: StoragePluginHooks) => () => UniversalStoragePlugin<TContext>;
|
|
4
|
+
type CreateStoragePluginOptions = StoragePlugin;
|
|
5
|
+
type StorageOperation = Exclude<keyof StoragePlugin, "name" | "protocol">;
|
|
6
|
+
type StoragePluginWith<TOperation extends StorageOperation> = StoragePlugin & Required<Pick<StoragePlugin, TOperation>>;
|
|
7
|
+
declare const createStoragePlugin: <const TOptions extends CreateStoragePluginOptions>(options: TOptions) => TOptions;
|
|
8
|
+
declare function assertStorageOperations<const TOperations extends readonly StorageOperation[]>(plugin: StoragePlugin, operations: TOperations): asserts plugin is StoragePluginWith<TOperations[number]>;
|
|
54
9
|
//#endregion
|
|
55
|
-
export {
|
|
10
|
+
export { CreateStoragePluginOptions, StorageOperation, StoragePluginWith, assertStorageOperations, createStoragePlugin };
|
|
@@ -1,145 +1,7 @@
|
|
|
1
1
|
//#region src/createStoragePlugin.ts
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
await hooks?.onStorageUploaded?.();
|
|
7
|
-
return result;
|
|
8
|
-
}
|
|
9
|
-
});
|
|
10
|
-
const createProfiledStoragePlugin = ({ createProfiles, name, profileShape, supportedProtocol }, hooks) => {
|
|
11
|
-
let cachedProfiles = null;
|
|
12
|
-
let cachedNodeProfile;
|
|
13
|
-
let cachedRuntimeProfile;
|
|
14
|
-
const getProfiles = () => {
|
|
15
|
-
cachedProfiles ??= createProfiles();
|
|
16
|
-
return cachedProfiles;
|
|
17
|
-
};
|
|
18
|
-
const getNodeProfile = () => {
|
|
19
|
-
const node = getProfiles().node;
|
|
20
|
-
if (!node) return;
|
|
21
|
-
cachedNodeProfile ??= wrapNodeProfile(node, hooks);
|
|
22
|
-
return cachedNodeProfile;
|
|
23
|
-
};
|
|
24
|
-
const requireNodeProfile = () => {
|
|
25
|
-
const node = getNodeProfile();
|
|
26
|
-
if (!node) throw new Error(`${name} does not implement the node storage profile for protocol "${supportedProtocol}".`);
|
|
27
|
-
return node;
|
|
28
|
-
};
|
|
29
|
-
const getRuntimeProfile = () => {
|
|
30
|
-
const runtime = getProfiles().runtime;
|
|
31
|
-
if (!runtime) return;
|
|
32
|
-
cachedRuntimeProfile ??= runtime;
|
|
33
|
-
return cachedRuntimeProfile;
|
|
34
|
-
};
|
|
35
|
-
const requireRuntimeProfile = () => {
|
|
36
|
-
const runtime = getRuntimeProfile();
|
|
37
|
-
if (!runtime) throw new Error(`${name} does not implement the runtime storage profile for protocol "${supportedProtocol}".`);
|
|
38
|
-
return runtime;
|
|
39
|
-
};
|
|
40
|
-
const profiles = {};
|
|
41
|
-
if (profileShape?.node) {
|
|
42
|
-
const nodeProfile = {
|
|
43
|
-
async delete(storageUri) {
|
|
44
|
-
return requireNodeProfile().delete(storageUri);
|
|
45
|
-
},
|
|
46
|
-
async downloadFile(storageUri, filePath) {
|
|
47
|
-
return requireNodeProfile().downloadFile(storageUri, filePath);
|
|
48
|
-
},
|
|
49
|
-
async exists(storageUri) {
|
|
50
|
-
return requireNodeProfile().exists(storageUri);
|
|
51
|
-
},
|
|
52
|
-
async upload(key, filePath) {
|
|
53
|
-
return requireNodeProfile().upload(key, filePath);
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
Object.defineProperties(nodeProfile, {
|
|
57
|
-
deleteObjects: {
|
|
58
|
-
enumerable: true,
|
|
59
|
-
get: () => {
|
|
60
|
-
const deleteObjects = requireNodeProfile().deleteObjects;
|
|
61
|
-
return deleteObjects ? (keys) => deleteObjects(keys) : void 0;
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
listObjects: {
|
|
65
|
-
enumerable: true,
|
|
66
|
-
get: () => {
|
|
67
|
-
const listObjects = requireNodeProfile().listObjects;
|
|
68
|
-
return listObjects ? (prefix) => listObjects(prefix) : void 0;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
profiles.node = nodeProfile;
|
|
73
|
-
} else if (profileShape?.node !== false) Object.defineProperty(profiles, "node", {
|
|
74
|
-
enumerable: true,
|
|
75
|
-
get: getNodeProfile
|
|
76
|
-
});
|
|
77
|
-
if (profileShape?.runtime) profiles.runtime = {
|
|
78
|
-
async getDownloadUrl(storageUri, context) {
|
|
79
|
-
return requireRuntimeProfile().getDownloadUrl(storageUri, context);
|
|
80
|
-
},
|
|
81
|
-
async readText(storageUri, context) {
|
|
82
|
-
return requireRuntimeProfile().readText(storageUri, context);
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
else if (profileShape?.runtime !== false) Object.defineProperty(profiles, "runtime", {
|
|
86
|
-
enumerable: true,
|
|
87
|
-
get: getRuntimeProfile
|
|
88
|
-
});
|
|
89
|
-
return {
|
|
90
|
-
name,
|
|
91
|
-
supportedProtocol,
|
|
92
|
-
profiles
|
|
93
|
-
};
|
|
94
|
-
};
|
|
95
|
-
/**
|
|
96
|
-
* Creates a deploy/CLI/console storage plugin.
|
|
97
|
-
*/
|
|
98
|
-
const createNodeStoragePlugin = (options) => {
|
|
99
|
-
return (config, hooks) => {
|
|
100
|
-
return () => createProfiledStoragePlugin({
|
|
101
|
-
createProfiles: () => ({ node: options.factory(config) }),
|
|
102
|
-
name: options.name,
|
|
103
|
-
profileShape: {
|
|
104
|
-
node: true,
|
|
105
|
-
runtime: false
|
|
106
|
-
},
|
|
107
|
-
supportedProtocol: options.supportedProtocol
|
|
108
|
-
}, hooks);
|
|
109
|
-
};
|
|
110
|
-
};
|
|
111
|
-
/**
|
|
112
|
-
* Creates an update-check runtime storage plugin.
|
|
113
|
-
*/
|
|
114
|
-
const createRuntimeStoragePlugin = (options) => {
|
|
115
|
-
return (config, hooks) => {
|
|
116
|
-
return () => createProfiledStoragePlugin({
|
|
117
|
-
createProfiles: () => ({ runtime: options.factory(config) }),
|
|
118
|
-
name: options.name,
|
|
119
|
-
profileShape: {
|
|
120
|
-
node: false,
|
|
121
|
-
runtime: true
|
|
122
|
-
},
|
|
123
|
-
supportedProtocol: options.supportedProtocol
|
|
124
|
-
}, hooks);
|
|
125
|
-
};
|
|
126
|
-
};
|
|
127
|
-
/**
|
|
128
|
-
* Creates a storage plugin that can be used by both Node tooling and update
|
|
129
|
-
* check runtimes.
|
|
130
|
-
*/
|
|
131
|
-
const createUniversalStoragePlugin = (options) => {
|
|
132
|
-
return (config, hooks) => {
|
|
133
|
-
return () => createProfiledStoragePlugin({
|
|
134
|
-
createProfiles: () => options.factory(config),
|
|
135
|
-
name: options.name,
|
|
136
|
-
profileShape: {
|
|
137
|
-
node: true,
|
|
138
|
-
runtime: true
|
|
139
|
-
},
|
|
140
|
-
supportedProtocol: options.supportedProtocol
|
|
141
|
-
}, hooks);
|
|
142
|
-
};
|
|
143
|
-
};
|
|
2
|
+
const createStoragePlugin = (options) => ({ ...options });
|
|
3
|
+
function assertStorageOperations(plugin, operations) {
|
|
4
|
+
for (const operation of operations) if (typeof plugin[operation] !== "function") throw new Error(`Storage plugin "${plugin.name}" does not implement ${operation}.`);
|
|
5
|
+
}
|
|
144
6
|
//#endregion
|
|
145
|
-
export {
|
|
7
|
+
export { assertStorageOperations, createStoragePlugin };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
const require_createDatabasePlugin = require("./createDatabasePlugin.cjs");
|
|
2
|
+
const require_databaseRows = require("./databaseRows.cjs");
|
|
3
|
+
const require_databaseClientReads = require("./databaseClientReads.cjs");
|
|
4
|
+
const require_databaseClientUpdates = require("./databaseClientUpdates.cjs");
|
|
5
|
+
//#region src/databaseClient.ts
|
|
6
|
+
var DatabaseBundleNotFoundError = class extends Error {
|
|
7
|
+
name = "DatabaseBundleNotFoundError";
|
|
8
|
+
constructor(bundleId) {
|
|
9
|
+
super(`Bundle "${bundleId}" was not found.`);
|
|
10
|
+
this.bundleId = bundleId;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
var DatabasePatchInsertUnsupportedError = class extends Error {
|
|
14
|
+
name = "DatabasePatchInsertUnsupportedError";
|
|
15
|
+
constructor(bundleId, pluginName) {
|
|
16
|
+
super(`Database plugin "${pluginName}" cannot atomically insert patches for bundle "${bundleId}".`);
|
|
17
|
+
this.bundleId = bundleId;
|
|
18
|
+
this.pluginName = pluginName;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const insertChanges = (bundle) => [{
|
|
22
|
+
model: "bundles",
|
|
23
|
+
operation: "insert",
|
|
24
|
+
row: require_databaseRows.bundleToRow(bundle)
|
|
25
|
+
}, ...require_databaseRows.bundleToPatchRows(bundle).map((row) => ({
|
|
26
|
+
model: "bundlePatches",
|
|
27
|
+
operation: "insert",
|
|
28
|
+
row
|
|
29
|
+
}))];
|
|
30
|
+
const updateChanges = (bundleId, update) => {
|
|
31
|
+
const rowUpdate = require_databaseClientUpdates.bundleUpdateToRow(update);
|
|
32
|
+
return [{
|
|
33
|
+
model: "bundles",
|
|
34
|
+
operation: "update",
|
|
35
|
+
where: { id: bundleId },
|
|
36
|
+
update: rowUpdate
|
|
37
|
+
}, ...Object.hasOwn(update, "patches") ? [{
|
|
38
|
+
model: "bundlePatches",
|
|
39
|
+
operation: "delete",
|
|
40
|
+
where: { bundleId }
|
|
41
|
+
}, ...require_databaseClientUpdates.bundleUpdateToPatchRows(bundleId, update).map((row) => ({
|
|
42
|
+
model: "bundlePatches",
|
|
43
|
+
operation: "insert",
|
|
44
|
+
row
|
|
45
|
+
}))] : []];
|
|
46
|
+
};
|
|
47
|
+
const deleteChanges = (bundleId) => [{
|
|
48
|
+
model: "bundles",
|
|
49
|
+
operation: "delete",
|
|
50
|
+
where: { id: bundleId }
|
|
51
|
+
}];
|
|
52
|
+
const createDatabaseClient = (plugin) => {
|
|
53
|
+
const getBundleById = async (id) => {
|
|
54
|
+
const row = await plugin.models.bundles.findById(id);
|
|
55
|
+
if (!row) return null;
|
|
56
|
+
return (await require_databaseClientReads.hydrateRows(plugin, [row]))[0] ?? null;
|
|
57
|
+
};
|
|
58
|
+
const insertChannel = (input) => plugin.models.channels.insert(input);
|
|
59
|
+
const createMutationClient = (commit) => ({
|
|
60
|
+
getBundleById,
|
|
61
|
+
getBundles: (options) => require_databaseClientReads.responsePage(plugin, options),
|
|
62
|
+
async getChannels() {
|
|
63
|
+
return (await plugin.models.channels.list({})).channels;
|
|
64
|
+
},
|
|
65
|
+
insertChannel,
|
|
66
|
+
async insertBundle(bundle) {
|
|
67
|
+
try {
|
|
68
|
+
await commit(insertChanges(bundle));
|
|
69
|
+
} catch (error) {
|
|
70
|
+
if (error instanceof require_createDatabasePlugin.DatabaseAtomicCommitUnsupportedError && require_databaseRows.bundleToPatchRows(bundle).length > 0) throw new DatabasePatchInsertUnsupportedError(bundle.id, plugin.name);
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
async updateBundleById(bundleId, update) {
|
|
75
|
+
try {
|
|
76
|
+
if (!(await commit(updateChanges(bundleId, update))).committed) throw new DatabaseBundleNotFoundError(bundleId);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
if (error instanceof require_createDatabasePlugin.DatabaseAtomicCommitUnsupportedError && Object.hasOwn(update, "patches")) throw new require_databaseClientUpdates.DatabasePatchUpdateUnsupportedError(bundleId, plugin.name);
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
async deleteBundleById(bundleId) {
|
|
83
|
+
const result = await commit(deleteChanges(bundleId));
|
|
84
|
+
if (!result.committed && result.conflict.reason === "referenced") throw new require_createDatabasePlugin.DatabaseRowReferencedError();
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
const runMutation = async (operation) => {
|
|
88
|
+
const changes = [];
|
|
89
|
+
const result = await operation(createMutationClient(async (input) => {
|
|
90
|
+
changes.push(...input);
|
|
91
|
+
return { committed: true };
|
|
92
|
+
}));
|
|
93
|
+
if (changes.length === 0) return result;
|
|
94
|
+
const commitResult = await plugin.commit({ changes });
|
|
95
|
+
if (!commitResult.committed) {
|
|
96
|
+
const change = changes[commitResult.conflict.changeIndex];
|
|
97
|
+
if (commitResult.conflict.reason === "referenced" && change?.model === "bundles" && change.operation === "delete") throw new require_createDatabasePlugin.DatabaseRowReferencedError();
|
|
98
|
+
if (change?.model === "bundles" && change.operation === "update") throw new DatabaseBundleNotFoundError(change.where.id);
|
|
99
|
+
throw new Error(`Database plugin "${plugin.name}" rejected a commit.`);
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
};
|
|
103
|
+
return {
|
|
104
|
+
...createMutationClient((changes) => plugin.commit({ changes })),
|
|
105
|
+
deleteChannel: (input) => plugin.models.channels.delete(input),
|
|
106
|
+
mutate: runMutation
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
//#endregion
|
|
110
|
+
exports.DatabaseBundleNotFoundError = DatabaseBundleNotFoundError;
|
|
111
|
+
exports.DatabasePatchInsertUnsupportedError = DatabasePatchInsertUnsupportedError;
|
|
112
|
+
exports.createDatabaseClient = createDatabaseClient;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ChannelRow } from "./types/databaseRows.cjs";
|
|
2
|
+
import { BundleRepository, ChannelDeleteInput, ChannelDeleteResult, ChannelInsertInput, ChannelInsertResult } from "./types/databasePlugin.cjs";
|
|
3
|
+
import { DatabaseBundleQueryOptions, PaginatedResult } from "./types/index.cjs";
|
|
4
|
+
import { DatabasePatchUpdateUnsupportedError } from "./databaseClientUpdates.cjs";
|
|
5
|
+
import { Bundle } from "@hot-updater/core";
|
|
6
|
+
|
|
7
|
+
//#region src/databaseClient.d.ts
|
|
8
|
+
interface DatabaseClient {
|
|
9
|
+
getBundleById(id: string): Promise<Bundle | null>;
|
|
10
|
+
getChannels(): Promise<readonly ChannelRow[]>;
|
|
11
|
+
insertChannel(input: ChannelInsertInput): Promise<ChannelInsertResult>;
|
|
12
|
+
deleteChannel(input: ChannelDeleteInput): Promise<ChannelDeleteResult>;
|
|
13
|
+
getBundles(options: DatabaseBundleQueryOptions): Promise<PaginatedResult>;
|
|
14
|
+
insertBundle(bundle: Bundle): Promise<void>;
|
|
15
|
+
updateBundleById(bundleId: string, update: Partial<Bundle>): Promise<void>;
|
|
16
|
+
deleteBundleById(bundleId: string): Promise<void>;
|
|
17
|
+
mutate<TResult>(operation: (client: DatabaseMutationClient) => Promise<TResult>): Promise<TResult>;
|
|
18
|
+
}
|
|
19
|
+
type DatabaseMutationClient = Omit<DatabaseClient, "deleteChannel" | "mutate">;
|
|
20
|
+
declare class DatabaseBundleNotFoundError extends Error {
|
|
21
|
+
readonly bundleId: string;
|
|
22
|
+
readonly name = "DatabaseBundleNotFoundError";
|
|
23
|
+
constructor(bundleId: string);
|
|
24
|
+
}
|
|
25
|
+
declare class DatabasePatchInsertUnsupportedError extends Error {
|
|
26
|
+
readonly bundleId: string;
|
|
27
|
+
readonly pluginName: string;
|
|
28
|
+
readonly name = "DatabasePatchInsertUnsupportedError";
|
|
29
|
+
constructor(bundleId: string, pluginName: string);
|
|
30
|
+
}
|
|
31
|
+
declare const createDatabaseClient: (plugin: BundleRepository) => DatabaseClient;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { DatabaseBundleNotFoundError, DatabaseClient, DatabaseMutationClient, DatabasePatchInsertUnsupportedError, createDatabaseClient };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ChannelRow } from "./types/databaseRows.mjs";
|
|
2
|
+
import { BundleRepository, ChannelDeleteInput, ChannelDeleteResult, ChannelInsertInput, ChannelInsertResult } from "./types/databasePlugin.mjs";
|
|
3
|
+
import { DatabaseBundleQueryOptions, PaginatedResult } from "./types/index.mjs";
|
|
4
|
+
import { DatabasePatchUpdateUnsupportedError } from "./databaseClientUpdates.mjs";
|
|
5
|
+
import { Bundle } from "@hot-updater/core";
|
|
6
|
+
|
|
7
|
+
//#region src/databaseClient.d.ts
|
|
8
|
+
interface DatabaseClient {
|
|
9
|
+
getBundleById(id: string): Promise<Bundle | null>;
|
|
10
|
+
getChannels(): Promise<readonly ChannelRow[]>;
|
|
11
|
+
insertChannel(input: ChannelInsertInput): Promise<ChannelInsertResult>;
|
|
12
|
+
deleteChannel(input: ChannelDeleteInput): Promise<ChannelDeleteResult>;
|
|
13
|
+
getBundles(options: DatabaseBundleQueryOptions): Promise<PaginatedResult>;
|
|
14
|
+
insertBundle(bundle: Bundle): Promise<void>;
|
|
15
|
+
updateBundleById(bundleId: string, update: Partial<Bundle>): Promise<void>;
|
|
16
|
+
deleteBundleById(bundleId: string): Promise<void>;
|
|
17
|
+
mutate<TResult>(operation: (client: DatabaseMutationClient) => Promise<TResult>): Promise<TResult>;
|
|
18
|
+
}
|
|
19
|
+
type DatabaseMutationClient = Omit<DatabaseClient, "deleteChannel" | "mutate">;
|
|
20
|
+
declare class DatabaseBundleNotFoundError extends Error {
|
|
21
|
+
readonly bundleId: string;
|
|
22
|
+
readonly name = "DatabaseBundleNotFoundError";
|
|
23
|
+
constructor(bundleId: string);
|
|
24
|
+
}
|
|
25
|
+
declare class DatabasePatchInsertUnsupportedError extends Error {
|
|
26
|
+
readonly bundleId: string;
|
|
27
|
+
readonly pluginName: string;
|
|
28
|
+
readonly name = "DatabasePatchInsertUnsupportedError";
|
|
29
|
+
constructor(bundleId: string, pluginName: string);
|
|
30
|
+
}
|
|
31
|
+
declare const createDatabaseClient: (plugin: BundleRepository) => DatabaseClient;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { DatabaseBundleNotFoundError, DatabaseClient, DatabaseMutationClient, DatabasePatchInsertUnsupportedError, createDatabaseClient };
|