@hot-updater/supabase 1.0.0-rc.35 → 1.0.0-rc.37
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/edge.d.cts +1 -1
- package/dist/edge.d.mts +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/{supabaseDatabase-8UJoPfkM.d.cts → supabaseDatabase-D7HZjWap.d.cts} +72 -2
- package/dist/{supabaseDatabase-8UJoPfkM.d.mts → supabaseDatabase-D7HZjWap.d.mts} +72 -2
- package/package.json +8 -8
- package/supabase/migrations/20260818000000_hot-updater_1.0.0.sql +11 -1
package/dist/edge.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as plugins, n as supabaseDatabase, t as SupabaseDatabaseConfig } from "./supabaseDatabase-
|
|
1
|
+
import { i as plugins, n as supabaseDatabase, t as SupabaseDatabaseConfig } from "./supabaseDatabase-D7HZjWap.cjs";
|
|
2
2
|
import { StorageAdapterWith } from "@hot-updater/plugin-core";
|
|
3
3
|
//#region src/supabaseEdgeFunctionStorage.d.ts
|
|
4
4
|
interface SupabaseEdgeFunctionStorageConfig {
|
package/dist/edge.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as plugins, n as supabaseDatabase, t as SupabaseDatabaseConfig } from "./supabaseDatabase-
|
|
1
|
+
import { i as plugins, n as supabaseDatabase, t as SupabaseDatabaseConfig } from "./supabaseDatabase-D7HZjWap.mjs";
|
|
2
2
|
import { StorageAdapterWith } from "@hot-updater/plugin-core";
|
|
3
3
|
//#region src/supabaseEdgeFunctionStorage.d.ts
|
|
4
4
|
interface SupabaseEdgeFunctionStorageConfig {
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as plugins, r as SupabaseServiceRoleConfig, t as SupabaseDatabaseConfig } from "./supabaseDatabase-
|
|
1
|
+
import { i as plugins, r as SupabaseServiceRoleConfig, t as SupabaseDatabaseConfig } from "./supabaseDatabase-D7HZjWap.cjs";
|
|
2
2
|
import { StorageAdapterWith, ToolingDatabase } from "@hot-updater/plugin-core";
|
|
3
3
|
//#region src/supabaseMigration.d.ts
|
|
4
4
|
/**
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as plugins, r as SupabaseServiceRoleConfig, t as SupabaseDatabaseConfig } from "./supabaseDatabase-
|
|
1
|
+
import { i as plugins, r as SupabaseServiceRoleConfig, t as SupabaseDatabaseConfig } from "./supabaseDatabase-D7HZjWap.mjs";
|
|
2
2
|
import { StorageAdapterWith, ToolingDatabase } from "@hot-updater/plugin-core";
|
|
3
3
|
//#region src/supabaseMigration.d.ts
|
|
4
4
|
/**
|
|
@@ -27,12 +27,33 @@ type DatabaseHttpResponse = DatabaseJsonObject & {
|
|
|
27
27
|
readonly body_truncated: boolean;
|
|
28
28
|
readonly received_at_ms: number;
|
|
29
29
|
};
|
|
30
|
+
/** What a kept UNCHANGED row changed against its installation's head. */
|
|
31
|
+
type BundleEventChangeKind = "first_seen" | "bundle" | "release" | "app_version" | "channel" | "native_build";
|
|
32
|
+
/**
|
|
33
|
+
* An UNCHANGED report the server keeps: what it changed against its
|
|
34
|
+
* installation's head, and the running values the head held before it. A
|
|
35
|
+
* report from an installation without a head is `first_seen` alone, with no
|
|
36
|
+
* previous values: the installation is new to this server, not necessarily
|
|
37
|
+
* to its device.
|
|
38
|
+
*/
|
|
39
|
+
type BundleEventChange = DatabaseJsonObject & {
|
|
40
|
+
readonly kinds: BundleEventChangeKind[];
|
|
41
|
+
readonly previous: (DatabaseJsonObject & {
|
|
42
|
+
readonly bundle_id: string;
|
|
43
|
+
readonly release_id: string | null;
|
|
44
|
+
readonly app_version: string;
|
|
45
|
+
readonly channel: string;
|
|
46
|
+
readonly min_bundle_id?: string;
|
|
47
|
+
}) | null;
|
|
48
|
+
};
|
|
30
49
|
/** Ancillary report data; queryable identity and lifecycle fields stay on the row. */
|
|
31
50
|
type DatabaseBundleEventMetadata = DatabaseJsonObject & {
|
|
32
51
|
readonly cohort: string;
|
|
33
52
|
readonly update_strategy: "fingerprint" | "appVersion" | null;
|
|
34
53
|
readonly fingerprint_hash: string | null;
|
|
35
54
|
readonly sdk_version: string | null;
|
|
55
|
+
/** The native build's built-in bundle ID, when the SDK reports it. */
|
|
56
|
+
readonly min_bundle_id?: string;
|
|
36
57
|
/** `UPDATE_FAILED`: what failed. */
|
|
37
58
|
readonly failure?: BundleEventFailure;
|
|
38
59
|
readonly http_response?: DatabaseHttpResponse;
|
|
@@ -40,6 +61,19 @@ type DatabaseBundleEventMetadata = DatabaseJsonObject & {
|
|
|
40
61
|
readonly delivery?: "patch" | "manifest" | "archive" | "unknown";
|
|
41
62
|
/** `UPDATE_DOWNLOADED`: a patch failed and the full files came instead. */
|
|
42
63
|
readonly patch_fallback?: boolean;
|
|
64
|
+
/** A kept `UNCHANGED` row: what it changed, which the server sets. */
|
|
65
|
+
readonly change?: BundleEventChange;
|
|
66
|
+
/**
|
|
67
|
+
* A download or apply that arrived after its installation already ran its
|
|
68
|
+
* target, as when a reload cut the first runtime's report short: the
|
|
69
|
+
* server keeps it in history, but it moves and counts nothing.
|
|
70
|
+
*/
|
|
71
|
+
readonly late?: true;
|
|
72
|
+
/**
|
|
73
|
+
* A launch or crash of a bundle whose download report never arrived: the
|
|
74
|
+
* server counted that download with it.
|
|
75
|
+
*/
|
|
76
|
+
readonly implied_download?: true;
|
|
43
77
|
};
|
|
44
78
|
type BundleEventRowBase = {
|
|
45
79
|
readonly id: string;
|
|
@@ -82,13 +116,14 @@ interface InsightsScope {
|
|
|
82
116
|
}
|
|
83
117
|
/**
|
|
84
118
|
* Raw event predicates; recovery is attributed to the source bundle. An
|
|
85
|
-
* UNCHANGED
|
|
119
|
+
* UNCHANGED filter matches the kept rows that moved an installation to the
|
|
120
|
+
* bundle without an apply report.
|
|
86
121
|
*/
|
|
87
122
|
type InsightsBundleEventFilter = InsightsScope & ({
|
|
88
123
|
readonly type: "RECOVERED";
|
|
89
124
|
readonly fromBundleId: string;
|
|
90
125
|
} | {
|
|
91
|
-
readonly type: "UPDATE_DOWNLOADED" | "UPDATE_APPLIED" | "UPDATE_FAILED";
|
|
126
|
+
readonly type: "UPDATE_DOWNLOADED" | "UPDATE_APPLIED" | "UPDATE_FAILED" | "UNCHANGED";
|
|
92
127
|
readonly toBundleId: string;
|
|
93
128
|
});
|
|
94
129
|
type InsightsEventFilter = {
|
|
@@ -208,7 +243,10 @@ interface InsightsGetAppUsageResult {
|
|
|
208
243
|
readonly bundleDistribution: readonly {
|
|
209
244
|
readonly appVersion: string;
|
|
210
245
|
readonly platform: "ios" | "android";
|
|
246
|
+
/** The release the installations run; null for none. */
|
|
211
247
|
readonly releaseId: string | null;
|
|
248
|
+
/** The native build's built-in bundle, when they run it. */
|
|
249
|
+
readonly builtinBundleId: string | null;
|
|
212
250
|
readonly installations: number;
|
|
213
251
|
}[];
|
|
214
252
|
readonly measuredAtMs: number;
|
|
@@ -539,6 +577,38 @@ declare const plugins: readonly [import("@hot-updater/plugin-core").HotUpdaterPl
|
|
|
539
577
|
readonly sort: readonly ["bucket_start_ms"];
|
|
540
578
|
};
|
|
541
579
|
}, never, readonly ["channel", "platform", "app_version", "release_id", "bucket_start_ms"]>;
|
|
580
|
+
readonly insights_builtin_distribution: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
581
|
+
readonly channel: {
|
|
582
|
+
readonly type: "string";
|
|
583
|
+
};
|
|
584
|
+
readonly platform: {
|
|
585
|
+
readonly type: "string";
|
|
586
|
+
readonly maxLength: 16;
|
|
587
|
+
};
|
|
588
|
+
readonly app_version: {
|
|
589
|
+
readonly type: "string";
|
|
590
|
+
};
|
|
591
|
+
readonly release_id: {
|
|
592
|
+
readonly type: "string";
|
|
593
|
+
readonly maxLength: 36;
|
|
594
|
+
};
|
|
595
|
+
readonly builtin_bundle_id: {
|
|
596
|
+
readonly type: "string";
|
|
597
|
+
readonly maxLength: 36;
|
|
598
|
+
};
|
|
599
|
+
readonly bucket_start_ms: {
|
|
600
|
+
readonly type: "integer";
|
|
601
|
+
};
|
|
602
|
+
}, "latest_installations", {
|
|
603
|
+
readonly byScope: {
|
|
604
|
+
readonly eq: readonly ["channel", "platform"];
|
|
605
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
606
|
+
};
|
|
607
|
+
readonly byVersion: {
|
|
608
|
+
readonly eq: readonly ["channel", "platform", "app_version"];
|
|
609
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
610
|
+
};
|
|
611
|
+
}, never, readonly ["channel", "platform", "app_version", "release_id", "builtin_bundle_id", "bucket_start_ms"]>;
|
|
542
612
|
readonly insights_latest_by_bundle: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
543
613
|
readonly platform: {
|
|
544
614
|
readonly type: "string";
|
|
@@ -27,12 +27,33 @@ type DatabaseHttpResponse = DatabaseJsonObject & {
|
|
|
27
27
|
readonly body_truncated: boolean;
|
|
28
28
|
readonly received_at_ms: number;
|
|
29
29
|
};
|
|
30
|
+
/** What a kept UNCHANGED row changed against its installation's head. */
|
|
31
|
+
type BundleEventChangeKind = "first_seen" | "bundle" | "release" | "app_version" | "channel" | "native_build";
|
|
32
|
+
/**
|
|
33
|
+
* An UNCHANGED report the server keeps: what it changed against its
|
|
34
|
+
* installation's head, and the running values the head held before it. A
|
|
35
|
+
* report from an installation without a head is `first_seen` alone, with no
|
|
36
|
+
* previous values: the installation is new to this server, not necessarily
|
|
37
|
+
* to its device.
|
|
38
|
+
*/
|
|
39
|
+
type BundleEventChange = DatabaseJsonObject & {
|
|
40
|
+
readonly kinds: BundleEventChangeKind[];
|
|
41
|
+
readonly previous: (DatabaseJsonObject & {
|
|
42
|
+
readonly bundle_id: string;
|
|
43
|
+
readonly release_id: string | null;
|
|
44
|
+
readonly app_version: string;
|
|
45
|
+
readonly channel: string;
|
|
46
|
+
readonly min_bundle_id?: string;
|
|
47
|
+
}) | null;
|
|
48
|
+
};
|
|
30
49
|
/** Ancillary report data; queryable identity and lifecycle fields stay on the row. */
|
|
31
50
|
type DatabaseBundleEventMetadata = DatabaseJsonObject & {
|
|
32
51
|
readonly cohort: string;
|
|
33
52
|
readonly update_strategy: "fingerprint" | "appVersion" | null;
|
|
34
53
|
readonly fingerprint_hash: string | null;
|
|
35
54
|
readonly sdk_version: string | null;
|
|
55
|
+
/** The native build's built-in bundle ID, when the SDK reports it. */
|
|
56
|
+
readonly min_bundle_id?: string;
|
|
36
57
|
/** `UPDATE_FAILED`: what failed. */
|
|
37
58
|
readonly failure?: BundleEventFailure;
|
|
38
59
|
readonly http_response?: DatabaseHttpResponse;
|
|
@@ -40,6 +61,19 @@ type DatabaseBundleEventMetadata = DatabaseJsonObject & {
|
|
|
40
61
|
readonly delivery?: "patch" | "manifest" | "archive" | "unknown";
|
|
41
62
|
/** `UPDATE_DOWNLOADED`: a patch failed and the full files came instead. */
|
|
42
63
|
readonly patch_fallback?: boolean;
|
|
64
|
+
/** A kept `UNCHANGED` row: what it changed, which the server sets. */
|
|
65
|
+
readonly change?: BundleEventChange;
|
|
66
|
+
/**
|
|
67
|
+
* A download or apply that arrived after its installation already ran its
|
|
68
|
+
* target, as when a reload cut the first runtime's report short: the
|
|
69
|
+
* server keeps it in history, but it moves and counts nothing.
|
|
70
|
+
*/
|
|
71
|
+
readonly late?: true;
|
|
72
|
+
/**
|
|
73
|
+
* A launch or crash of a bundle whose download report never arrived: the
|
|
74
|
+
* server counted that download with it.
|
|
75
|
+
*/
|
|
76
|
+
readonly implied_download?: true;
|
|
43
77
|
};
|
|
44
78
|
type BundleEventRowBase = {
|
|
45
79
|
readonly id: string;
|
|
@@ -82,13 +116,14 @@ interface InsightsScope {
|
|
|
82
116
|
}
|
|
83
117
|
/**
|
|
84
118
|
* Raw event predicates; recovery is attributed to the source bundle. An
|
|
85
|
-
* UNCHANGED
|
|
119
|
+
* UNCHANGED filter matches the kept rows that moved an installation to the
|
|
120
|
+
* bundle without an apply report.
|
|
86
121
|
*/
|
|
87
122
|
type InsightsBundleEventFilter = InsightsScope & ({
|
|
88
123
|
readonly type: "RECOVERED";
|
|
89
124
|
readonly fromBundleId: string;
|
|
90
125
|
} | {
|
|
91
|
-
readonly type: "UPDATE_DOWNLOADED" | "UPDATE_APPLIED" | "UPDATE_FAILED";
|
|
126
|
+
readonly type: "UPDATE_DOWNLOADED" | "UPDATE_APPLIED" | "UPDATE_FAILED" | "UNCHANGED";
|
|
92
127
|
readonly toBundleId: string;
|
|
93
128
|
});
|
|
94
129
|
type InsightsEventFilter = {
|
|
@@ -208,7 +243,10 @@ interface InsightsGetAppUsageResult {
|
|
|
208
243
|
readonly bundleDistribution: readonly {
|
|
209
244
|
readonly appVersion: string;
|
|
210
245
|
readonly platform: "ios" | "android";
|
|
246
|
+
/** The release the installations run; null for none. */
|
|
211
247
|
readonly releaseId: string | null;
|
|
248
|
+
/** The native build's built-in bundle, when they run it. */
|
|
249
|
+
readonly builtinBundleId: string | null;
|
|
212
250
|
readonly installations: number;
|
|
213
251
|
}[];
|
|
214
252
|
readonly measuredAtMs: number;
|
|
@@ -539,6 +577,38 @@ declare const plugins: readonly [import("@hot-updater/plugin-core").HotUpdaterPl
|
|
|
539
577
|
readonly sort: readonly ["bucket_start_ms"];
|
|
540
578
|
};
|
|
541
579
|
}, never, readonly ["channel", "platform", "app_version", "release_id", "bucket_start_ms"]>;
|
|
580
|
+
readonly insights_builtin_distribution: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
581
|
+
readonly channel: {
|
|
582
|
+
readonly type: "string";
|
|
583
|
+
};
|
|
584
|
+
readonly platform: {
|
|
585
|
+
readonly type: "string";
|
|
586
|
+
readonly maxLength: 16;
|
|
587
|
+
};
|
|
588
|
+
readonly app_version: {
|
|
589
|
+
readonly type: "string";
|
|
590
|
+
};
|
|
591
|
+
readonly release_id: {
|
|
592
|
+
readonly type: "string";
|
|
593
|
+
readonly maxLength: 36;
|
|
594
|
+
};
|
|
595
|
+
readonly builtin_bundle_id: {
|
|
596
|
+
readonly type: "string";
|
|
597
|
+
readonly maxLength: 36;
|
|
598
|
+
};
|
|
599
|
+
readonly bucket_start_ms: {
|
|
600
|
+
readonly type: "integer";
|
|
601
|
+
};
|
|
602
|
+
}, "latest_installations", {
|
|
603
|
+
readonly byScope: {
|
|
604
|
+
readonly eq: readonly ["channel", "platform"];
|
|
605
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
606
|
+
};
|
|
607
|
+
readonly byVersion: {
|
|
608
|
+
readonly eq: readonly ["channel", "platform", "app_version"];
|
|
609
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
610
|
+
};
|
|
611
|
+
}, never, readonly ["channel", "platform", "app_version", "release_id", "builtin_bundle_id", "bucket_start_ms"]>;
|
|
542
612
|
readonly insights_latest_by_bundle: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
543
613
|
readonly platform: {
|
|
544
614
|
readonly type: "string";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hot-updater/supabase",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.0-rc.
|
|
4
|
+
"version": "1.0.0-rc.37",
|
|
5
5
|
"description": "React Native OTA solution for self-hosted",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
7
7
|
"module": "dist/index.mjs",
|
|
@@ -51,10 +51,10 @@
|
|
|
51
51
|
"@supabase/supabase-js": "2.76.1",
|
|
52
52
|
"hono": "4.12.34",
|
|
53
53
|
"uuidv7": "^1.0.2",
|
|
54
|
-
"@hot-updater/protocol": "1.0.0-rc.
|
|
55
|
-
"@hot-updater/
|
|
56
|
-
"@hot-updater/
|
|
57
|
-
"@hot-updater/
|
|
54
|
+
"@hot-updater/protocol": "1.0.0-rc.37",
|
|
55
|
+
"@hot-updater/plugin-core": "1.0.0-rc.37",
|
|
56
|
+
"@hot-updater/cli-tools": "1.0.0-rc.37",
|
|
57
|
+
"@hot-updater/server": "1.0.0-rc.37"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@electric-sql/pglite": "0.4.1",
|
|
@@ -64,9 +64,9 @@
|
|
|
64
64
|
"execa": "9.5.2",
|
|
65
65
|
"@types/node": "^20",
|
|
66
66
|
"mime": "^4.0.4",
|
|
67
|
-
"@hot-updater/
|
|
68
|
-
"@hot-updater/
|
|
69
|
-
"@hot-updater/postgres": "1.0.0-rc.
|
|
67
|
+
"@hot-updater/test-utils": "1.0.0-rc.37",
|
|
68
|
+
"@hot-updater/mock": "1.0.0-rc.37",
|
|
69
|
+
"@hot-updater/postgres": "1.0.0-rc.37"
|
|
70
70
|
},
|
|
71
71
|
"scripts": {
|
|
72
72
|
"build": "tsdown",
|
|
@@ -78,6 +78,14 @@ CREATE INDEX IF NOT EXISTS "hot_updater_v1_insights_distribution_byVersion" ON "
|
|
|
78
78
|
|
|
79
79
|
CREATE INDEX IF NOT EXISTS "hot_updater_v1_insights_distribution__retention" ON "hot_updater_v1_insights_distribution" ("bucket_start_ms", "channel", "platform", "app_version", "release_id", "_shard");
|
|
80
80
|
|
|
81
|
+
CREATE TABLE IF NOT EXISTS "hot_updater_v1_insights_builtin_distribution" ("channel" text COLLATE "C" NOT NULL, "platform" varchar(16) COLLATE "C" NOT NULL, "app_version" text COLLATE "C" NOT NULL, "release_id" varchar(36) COLLATE "C" NOT NULL, "builtin_bundle_id" varchar(36) COLLATE "C" NOT NULL, "bucket_start_ms" bigint NOT NULL, "_shard" bigint NOT NULL, "latest_installations" bigint NOT NULL, "_v" bigint NOT NULL DEFAULT 0, PRIMARY KEY ("channel", "platform", "app_version", "release_id", "builtin_bundle_id", "bucket_start_ms", "_shard"));
|
|
82
|
+
|
|
83
|
+
CREATE INDEX IF NOT EXISTS "hot_updater_v1_insights_builtin_distribution_byScope" ON "hot_updater_v1_insights_builtin_distribution" ("channel", "platform", "bucket_start_ms", "app_version", "release_id", "builtin_bundle_id", "_shard");
|
|
84
|
+
|
|
85
|
+
CREATE INDEX IF NOT EXISTS "hot_updater_v1_insights_builtin_distribution_byVersion" ON "hot_updater_v1_insights_builtin_distribution" ("channel", "platform", "app_version", "bucket_start_ms", "release_id", "builtin_bundle_id", "_shard");
|
|
86
|
+
|
|
87
|
+
CREATE INDEX IF NOT EXISTS "hot_updater_v1_insights_builtin_distribution__retention" ON "hot_updater_v1_insights_builtin_distribution" ("bucket_start_ms", "channel", "platform", "app_version", "release_id", "builtin_bundle_id", "_shard");
|
|
88
|
+
|
|
81
89
|
CREATE TABLE IF NOT EXISTS "hot_updater_v1_insights_latest_by_bundle" ("platform" varchar(16) COLLATE "C" NOT NULL, "channel" text COLLATE "C" NOT NULL, "bundle_field" varchar(16) COLLATE "C" NOT NULL, "bundle_id" varchar(36) COLLATE "C" NOT NULL, "type" varchar(32) COLLATE "C" NOT NULL, "bucket_start_ms" bigint NOT NULL, "_shard" bigint NOT NULL, "installations" bigint NOT NULL, "_v" bigint NOT NULL DEFAULT 0, PRIMARY KEY ("platform", "channel", "bundle_field", "bundle_id", "type", "bucket_start_ms", "_shard"));
|
|
82
90
|
|
|
83
91
|
CREATE INDEX IF NOT EXISTS "hot_updater_v1_insights_latest_by_bundle__retention" ON "hot_updater_v1_insights_latest_by_bundle" ("bucket_start_ms", "platform", "channel", "bundle_field", "bundle_id", "type", "_shard");
|
|
@@ -130,6 +138,8 @@ ALTER TABLE "hot_updater_v1_insights_sketches_lifetime" ENABLE ROW LEVEL SECURIT
|
|
|
130
138
|
|
|
131
139
|
ALTER TABLE "hot_updater_v1_insights_distribution" ENABLE ROW LEVEL SECURITY;
|
|
132
140
|
|
|
141
|
+
ALTER TABLE "hot_updater_v1_insights_builtin_distribution" ENABLE ROW LEVEL SECURITY;
|
|
142
|
+
|
|
133
143
|
ALTER TABLE "hot_updater_v1_insights_latest_by_bundle" ENABLE ROW LEVEL SECURITY;
|
|
134
144
|
|
|
135
145
|
ALTER TABLE "hot_updater_v1_insights_outcomes" ENABLE ROW LEVEL SECURITY;
|
|
@@ -161,7 +171,7 @@ BEGIN
|
|
|
161
171
|
FOR item IN SELECT value FROM jsonb_array_elements(p_statements) LOOP
|
|
162
172
|
statement := item->>'sql';
|
|
163
173
|
FOR target IN SELECT (regexp_matches(statement, '(?:FROM|INTO|UPDATE|JOIN) "([^"]+)"', 'g'))[1] LOOP
|
|
164
|
-
IF NOT target = ANY (ARRAY['hot_updater_v1_bundles', 'hot_updater_v1_bundle_patches', 'hot_updater_v1_releases', 'hot_updater_v1_release_catalogs', 'hot_updater_v1_channels', 'hot_updater_v1_bundle_totals', 'hot_updater_v1_bundle_events', 'hot_updater_v1_bundle_events__byBundle', 'hot_updater_v1_bundle_event_heads', 'hot_updater_v1_insights_overview', 'hot_updater_v1_insights_sketches', 'hot_updater_v1_insights_overview_daily', 'hot_updater_v1_insights_sketches_daily', 'hot_updater_v1_insights_overview_lifetime', 'hot_updater_v1_insights_sketches_lifetime', 'hot_updater_v1_insights_distribution', 'hot_updater_v1_insights_latest_by_bundle', 'hot_updater_v1_insights_outcomes', 'hot_updater_v1_insights_failures', 'hot_updater_v1_api_keys', 'hot_updater_v1_private_hot_updater_settings', 'hot_updater_v1__hu_write']) THEN
|
|
174
|
+
IF NOT target = ANY (ARRAY['hot_updater_v1_bundles', 'hot_updater_v1_bundle_patches', 'hot_updater_v1_releases', 'hot_updater_v1_release_catalogs', 'hot_updater_v1_channels', 'hot_updater_v1_bundle_totals', 'hot_updater_v1_bundle_events', 'hot_updater_v1_bundle_events__byBundle', 'hot_updater_v1_bundle_event_heads', 'hot_updater_v1_insights_overview', 'hot_updater_v1_insights_sketches', 'hot_updater_v1_insights_overview_daily', 'hot_updater_v1_insights_sketches_daily', 'hot_updater_v1_insights_overview_lifetime', 'hot_updater_v1_insights_sketches_lifetime', 'hot_updater_v1_insights_distribution', 'hot_updater_v1_insights_builtin_distribution', 'hot_updater_v1_insights_latest_by_bundle', 'hot_updater_v1_insights_outcomes', 'hot_updater_v1_insights_failures', 'hot_updater_v1_api_keys', 'hot_updater_v1_private_hot_updater_settings', 'hot_updater_v1__hu_write']) THEN
|
|
165
175
|
RAISE EXCEPTION 'hot_updater_v1_apply: % is not a Hot Updater table', target USING ERRCODE = '42501';
|
|
166
176
|
END IF;
|
|
167
177
|
END LOOP;
|