@pgflow/core 0.13.2 → 0.13.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @pgflow/core
2
2
 
3
+ ## 0.13.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 4391432: Add PGFLOW_AUTH_SECRET support to bypass JWT format mismatch in ensure_workers authentication
8
+ - @pgflow/dsl@0.13.3
9
+
3
10
  ## 0.13.2
4
11
 
5
12
  ### Patch Changes
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pgflow/core",
3
- "version": "0.13.2",
3
+ "version": "0.13.3",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -0,0 +1,107 @@
1
+ -- Modify "ensure_workers" function
2
+ CREATE OR REPLACE FUNCTION "pgflow"."ensure_workers" () RETURNS TABLE ("function_name" text, "invoked" boolean, "request_id" bigint) LANGUAGE sql AS $$
3
+ with
4
+ -- Detect environment
5
+ env as (
6
+ select pgflow.is_local() as is_local
7
+ ),
8
+
9
+ -- Get credentials: Local mode uses hardcoded URL, production uses vault secrets
10
+ -- Empty strings are treated as NULL using nullif()
11
+ -- pgflow_auth_secret takes priority over supabase_service_role_key for production auth
12
+ credentials as (
13
+ select
14
+ case
15
+ when (select is_local from env) then null
16
+ else coalesce(
17
+ nullif((select decrypted_secret from vault.decrypted_secrets where name = 'pgflow_auth_secret'), ''),
18
+ nullif((select decrypted_secret from vault.decrypted_secrets where name = 'supabase_service_role_key'), '')
19
+ )
20
+ end as service_role_key,
21
+ case
22
+ when (select is_local from env) then 'http://kong:8000/functions/v1'
23
+ else (select 'https://' || nullif(decrypted_secret, '') || '.supabase.co/functions/v1' from vault.decrypted_secrets where name = 'supabase_project_id')
24
+ end as base_url
25
+ ),
26
+
27
+ -- Find functions that pass the debounce check
28
+ debounce_passed as (
29
+ select wf.function_name, wf.debounce
30
+ from pgflow.worker_functions as wf
31
+ where wf.enabled = true
32
+ and (
33
+ wf.last_invoked_at is null
34
+ or wf.last_invoked_at < now() - wf.debounce
35
+ )
36
+ ),
37
+
38
+ -- Find functions that have at least one alive worker
39
+ functions_with_alive_workers as (
40
+ select distinct w.function_name
41
+ from pgflow.workers as w
42
+ inner join debounce_passed as dp on w.function_name = dp.function_name
43
+ where w.stopped_at is null
44
+ and w.deprecated_at is null
45
+ and w.last_heartbeat_at > now() - dp.debounce
46
+ ),
47
+
48
+ -- Determine which functions should be invoked
49
+ -- Local mode: all enabled functions (bypass debounce AND alive workers check)
50
+ -- Production mode: only functions that pass debounce AND have no alive workers
51
+ functions_to_invoke as (
52
+ select wf.function_name
53
+ from pgflow.worker_functions as wf
54
+ where wf.enabled = true
55
+ and (
56
+ pgflow.is_local() = true -- Local: all enabled functions
57
+ or (
58
+ -- Production: debounce + no alive workers
59
+ wf.function_name in (select dp.function_name from debounce_passed as dp)
60
+ and wf.function_name not in (select faw.function_name from functions_with_alive_workers as faw)
61
+ )
62
+ )
63
+ ),
64
+
65
+ -- Make HTTP requests and capture request_ids
66
+ http_requests as (
67
+ select
68
+ fti.function_name,
69
+ net.http_post(
70
+ url => c.base_url || '/' || fti.function_name,
71
+ headers => case
72
+ when e.is_local then '{}'::jsonb
73
+ else jsonb_build_object(
74
+ 'Content-Type', 'application/json',
75
+ 'Authorization', 'Bearer ' || c.service_role_key
76
+ )
77
+ end,
78
+ body => '{}'::jsonb
79
+ ) as request_id
80
+ from functions_to_invoke as fti
81
+ cross join credentials as c
82
+ cross join env as e
83
+ where c.base_url is not null
84
+ and (e.is_local or c.service_role_key is not null)
85
+ ),
86
+
87
+ -- Update last_invoked_at for invoked functions
88
+ updated as (
89
+ update pgflow.worker_functions as wf
90
+ set last_invoked_at = clock_timestamp()
91
+ from http_requests as hr
92
+ where wf.function_name = hr.function_name
93
+ returning wf.function_name
94
+ )
95
+
96
+ select u.function_name, true as invoked, hr.request_id
97
+ from updated as u
98
+ inner join http_requests as hr on u.function_name = hr.function_name
99
+ $$;
100
+ -- Set comment to function: "ensure_workers"
101
+ COMMENT ON FUNCTION "pgflow"."ensure_workers" IS 'Ensures worker functions are running by pinging them via HTTP when needed.
102
+ In local mode: pings ALL enabled functions (ignores debounce AND alive workers check).
103
+ In production mode: only pings functions that pass debounce AND have no alive workers.
104
+ Debounce: skips functions pinged within their debounce interval (production only).
105
+ Credentials: Uses Vault secrets (pgflow_auth_secret with fallback to supabase_service_role_key, supabase_project_id) or local fallbacks.
106
+ URL is built from project_id: https://{project_id}.supabase.co/functions/v1
107
+ Returns request_id from pg_net for each HTTP request made.';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pgflow/core",
3
- "version": "0.13.2",
3
+ "version": "0.13.3",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "postgres": "^3.4.5",
31
- "@pgflow/dsl": "0.13.2"
31
+ "@pgflow/dsl": "0.13.3"
32
32
  },
33
33
  "publishConfig": {
34
34
  "access": "public"