@_nazmiforreal/flutter-ota 0.1.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/README.md +38 -0
- package/bin/flutter-patcher-linux +0 -0
- package/bin/flutter-patcher.js +59 -0
- package/migrations/supabase/20250103114225_init.sql +228 -0
- package/migrations/supabase/20250314000000_hot-updater_0.13.0.sql +134 -0
- package/migrations/supabase/20250516000000_hot-updater_0.18.0.sql +194 -0
- package/migrations/supabase/20251014000000_hot-updater_0.21.0.sql +184 -0
- package/migrations/supabase/20260401000000_hot-updater_0.29.0.sql +503 -0
- package/migrations/supabase/20260414000000_hot-updater_0.30.0.sql +50 -0
- package/migrations/supabase/20260422000000_hot-updater_0.31.0.sql +20 -0
- package/migrations/supabase/20260520014100_hot-updater_rls.sql +48 -0
- package/package.json +25 -0
- package/scripts/postinstall.js +53 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
-- HotUpdater.is_cohort_eligible
|
|
2
|
+
CREATE OR REPLACE FUNCTION is_cohort_eligible(
|
|
3
|
+
bundle_id UUID,
|
|
4
|
+
cohort TEXT,
|
|
5
|
+
rollout_cohort_count INTEGER,
|
|
6
|
+
target_cohorts TEXT[]
|
|
7
|
+
)
|
|
8
|
+
RETURNS BOOLEAN
|
|
9
|
+
LANGUAGE plpgsql
|
|
10
|
+
IMMUTABLE
|
|
11
|
+
AS $$
|
|
12
|
+
DECLARE
|
|
13
|
+
normalized_cohort TEXT := normalize_cohort_value(cohort);
|
|
14
|
+
normalized_rollout_count INTEGER := COALESCE(rollout_cohort_count, 1000);
|
|
15
|
+
normalized_target_cohorts TEXT[];
|
|
16
|
+
BEGIN
|
|
17
|
+
IF target_cohorts IS NOT NULL THEN
|
|
18
|
+
normalized_target_cohorts := ARRAY(
|
|
19
|
+
SELECT normalize_cohort_value(value)
|
|
20
|
+
FROM unnest(target_cohorts) AS value
|
|
21
|
+
);
|
|
22
|
+
END IF;
|
|
23
|
+
|
|
24
|
+
IF normalized_target_cohorts IS NOT NULL
|
|
25
|
+
AND array_length(normalized_target_cohorts, 1) > 0
|
|
26
|
+
AND normalized_cohort IS NOT NULL
|
|
27
|
+
AND normalized_cohort = ANY(normalized_target_cohorts) THEN
|
|
28
|
+
RETURN TRUE;
|
|
29
|
+
END IF;
|
|
30
|
+
|
|
31
|
+
IF normalized_rollout_count <= 0 THEN
|
|
32
|
+
RETURN FALSE;
|
|
33
|
+
END IF;
|
|
34
|
+
|
|
35
|
+
IF normalized_cohort IS NULL THEN
|
|
36
|
+
RETURN normalized_rollout_count >= 1000;
|
|
37
|
+
END IF;
|
|
38
|
+
|
|
39
|
+
IF NOT is_numeric_cohort(normalized_cohort) THEN
|
|
40
|
+
RETURN FALSE;
|
|
41
|
+
END IF;
|
|
42
|
+
|
|
43
|
+
IF normalized_rollout_count >= 1000 THEN
|
|
44
|
+
RETURN TRUE;
|
|
45
|
+
END IF;
|
|
46
|
+
|
|
47
|
+
RETURN get_numeric_cohort_rollout_position(bundle_id, normalized_cohort)
|
|
48
|
+
< normalized_rollout_count;
|
|
49
|
+
END;
|
|
50
|
+
$$;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
-- HotUpdater.bundle_artifact_columns
|
|
2
|
+
|
|
3
|
+
ALTER TABLE bundles ADD COLUMN IF NOT EXISTS manifest_storage_uri text;
|
|
4
|
+
ALTER TABLE bundles ADD COLUMN IF NOT EXISTS manifest_file_hash text;
|
|
5
|
+
ALTER TABLE bundles ADD COLUMN IF NOT EXISTS asset_base_storage_uri text;
|
|
6
|
+
|
|
7
|
+
CREATE TABLE IF NOT EXISTS bundle_patches (
|
|
8
|
+
id text PRIMARY KEY,
|
|
9
|
+
bundle_id uuid NOT NULL REFERENCES bundles(id) ON DELETE CASCADE,
|
|
10
|
+
base_bundle_id uuid NOT NULL REFERENCES bundles(id) ON DELETE CASCADE,
|
|
11
|
+
base_file_hash text NOT NULL,
|
|
12
|
+
patch_file_hash text NOT NULL,
|
|
13
|
+
patch_storage_uri text NOT NULL,
|
|
14
|
+
order_index integer NOT NULL DEFAULT 0
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
CREATE INDEX IF NOT EXISTS bundle_patches_bundle_id_idx
|
|
18
|
+
ON bundle_patches(bundle_id);
|
|
19
|
+
CREATE INDEX IF NOT EXISTS bundle_patches_base_bundle_id_idx
|
|
20
|
+
ON bundle_patches(base_bundle_id);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
-- HotUpdater.supabase_rls
|
|
2
|
+
|
|
3
|
+
ALTER TABLE public.bundles ENABLE ROW LEVEL SECURITY;
|
|
4
|
+
ALTER TABLE public.bundle_patches ENABLE ROW LEVEL SECURITY;
|
|
5
|
+
|
|
6
|
+
ALTER FUNCTION public.get_target_app_version_list(public.platforms, uuid)
|
|
7
|
+
SET search_path = public, pg_catalog;
|
|
8
|
+
ALTER FUNCTION public.get_channels()
|
|
9
|
+
SET search_path = public, pg_catalog;
|
|
10
|
+
ALTER FUNCTION public.positive_mod(integer, integer)
|
|
11
|
+
SET search_path = public, pg_catalog;
|
|
12
|
+
ALTER FUNCTION public.hash_rollout_value(text)
|
|
13
|
+
SET search_path = public, pg_catalog;
|
|
14
|
+
ALTER FUNCTION public.normalize_cohort_value(text)
|
|
15
|
+
SET search_path = public, pg_catalog;
|
|
16
|
+
ALTER FUNCTION public.gcd_int(integer, integer)
|
|
17
|
+
SET search_path = public, pg_catalog;
|
|
18
|
+
ALTER FUNCTION public.get_rollout_multiplier(uuid)
|
|
19
|
+
SET search_path = public, pg_catalog;
|
|
20
|
+
ALTER FUNCTION public.get_rollout_offset(uuid)
|
|
21
|
+
SET search_path = public, pg_catalog;
|
|
22
|
+
ALTER FUNCTION public.get_modular_inverse(integer, integer)
|
|
23
|
+
SET search_path = public, pg_catalog;
|
|
24
|
+
ALTER FUNCTION public.is_numeric_cohort(text)
|
|
25
|
+
SET search_path = public, pg_catalog;
|
|
26
|
+
ALTER FUNCTION public.get_numeric_cohort_rollout_position(uuid, text)
|
|
27
|
+
SET search_path = public, pg_catalog;
|
|
28
|
+
ALTER FUNCTION public.is_cohort_eligible(uuid, text, integer, text[])
|
|
29
|
+
SET search_path = public, pg_catalog;
|
|
30
|
+
ALTER FUNCTION public.get_update_info_by_fingerprint_hash(
|
|
31
|
+
public.platforms,
|
|
32
|
+
uuid,
|
|
33
|
+
uuid,
|
|
34
|
+
text,
|
|
35
|
+
text,
|
|
36
|
+
text
|
|
37
|
+
)
|
|
38
|
+
SET search_path = public, pg_catalog;
|
|
39
|
+
ALTER FUNCTION public.get_update_info_by_app_version(
|
|
40
|
+
public.platforms,
|
|
41
|
+
text,
|
|
42
|
+
uuid,
|
|
43
|
+
uuid,
|
|
44
|
+
text,
|
|
45
|
+
text[],
|
|
46
|
+
text
|
|
47
|
+
)
|
|
48
|
+
SET search_path = public, pg_catalog;
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@_nazmiforreal/flutter-ota",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Command-line interface for flutter_patcher — an OTA code-push tool for Flutter, hot-updater compatible.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"flutter-patcher": "./bin/flutter-patcher.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"postinstall": "node scripts/postinstall.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"bin",
|
|
13
|
+
"scripts",
|
|
14
|
+
"migrations",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=16"
|
|
19
|
+
},
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "https://github.com/HYPER12755/flutter_patcher"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// Post-install: ensure a runnable flutter-patcher binary exists next to the
|
|
5
|
+
// launcher. If a prebuilt platform binary ships in `bin/`, use it. Otherwise
|
|
6
|
+
// build one from source with `dart compile exe` when the Dart SDK is present.
|
|
7
|
+
|
|
8
|
+
const { spawnSync } = require('child_process');
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
|
|
12
|
+
const platform =
|
|
13
|
+
process.platform === 'win32'
|
|
14
|
+
? 'windows'
|
|
15
|
+
: process.platform === 'darwin'
|
|
16
|
+
? 'macos'
|
|
17
|
+
: 'linux';
|
|
18
|
+
const ext = process.platform === 'win32' ? '.exe' : '';
|
|
19
|
+
const pkgDir = path.join(__dirname, '..');
|
|
20
|
+
const binDir = path.join(pkgDir, 'bin');
|
|
21
|
+
const target = path.join(binDir, `flutter-patcher-${platform}${ext}`);
|
|
22
|
+
|
|
23
|
+
if (fs.existsSync(target)) {
|
|
24
|
+
console.log('flutter-patcher: prebuilt binary present, skipping build.');
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const dartCheck = spawnSync('dart', ['--version'], { stdio: 'ignore' });
|
|
29
|
+
if (dartCheck.status !== 0) {
|
|
30
|
+
console.warn(
|
|
31
|
+
'flutter-patcher: Dart SDK not found; skipping build. Provide a prebuilt ' +
|
|
32
|
+
'binary in bin/ or install the Dart SDK (https://dart.dev).',
|
|
33
|
+
);
|
|
34
|
+
process.exit(0);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// packages/cli-tools/bin/flutter_patcher.dart relative to the repo root.
|
|
38
|
+
const repoRoot = path.join(pkgDir, '..', '..', '..');
|
|
39
|
+
const dartEntry = path.join(
|
|
40
|
+
repoRoot,
|
|
41
|
+
'packages',
|
|
42
|
+
'cli-tools',
|
|
43
|
+
'bin',
|
|
44
|
+
'flutter_patcher.dart',
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
console.log('flutter-patcher: building binary with `dart compile exe`...');
|
|
48
|
+
const res = spawnSync(
|
|
49
|
+
'dart',
|
|
50
|
+
['compile', 'exe', dartEntry, '-o', target],
|
|
51
|
+
{ stdio: 'inherit' },
|
|
52
|
+
);
|
|
53
|
+
process.exit(res.status == null ? 1 : res.status);
|