Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/portable-edge-worker-npm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@pgflow/core": minor
"@pgflow/dsl": minor
"@pgflow/client": minor
"@pgflow/edge-worker": minor
"pgflow": minor
---

Publish `@pgflow/edge-worker` to npm and add Node/Bun process runtime support.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
"scripts": {
"build": "nx run-many --target=build --all",
"version": "pnpm changeset version && ./scripts/update-jsr-json-version.sh",
"validate:publish:npm": "pnpm nx run-many -t build --exclude=demo,website,example-flows && git status && pnpm publish --dry-run --provenance --recursive --filter=!./pkgs/edge-worker",
"smoke:edge-worker:dist": "pnpm nx build edge-worker && node ./scripts/smoke-edge-worker-dist.mjs",
"validate:publish:npm": "pnpm nx run-many -t build --exclude=demo,website,example-flows && pnpm smoke:edge-worker:dist && git status && pnpm publish --dry-run --provenance --recursive",
"validate:publish:jsr": "cd ./pkgs/edge-worker && jsr publish --dry-run --allow-slow-types",
"validate:publish": "pnpm run validate:publish:npm && pnpm run validate:publish:jsr",
"publish:npm": "pnpm nx run-many -t build --exclude=demo,website,example-flows && pnpm publish --provenance --recursive --filter=!./pkgs/edge-worker",
"publish:npm": "pnpm nx run-many -t build --exclude=demo,website,example-flows && pnpm publish --provenance --recursive",
"publish:jsr": "cd ./pkgs/edge-worker && jsr publish --allow-slow-types",
"changeset:tag": "pnpm changeset tag && git push --follow-tags",
"release": "git status && pnpm run validate:publish && pnpm run publish:npm && pnpm run publish:jsr && pnpm run changeset:tag"
Expand Down
6 changes: 2 additions & 4 deletions pkgs/edge-worker/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@
"executor": "nx:noop"
},
"build": {
"executor": "nx:noop",
"dependsOn": ["^build"]
},
"_build_disabled": {
"executor": "@nx/js:tsc",
"outputs": ["{options.outputPath}"],
"dependsOn": ["^build"],
"options": {
"outputPath": "pkgs/edge-worker/dist",
"main": "pkgs/edge-worker/src/index.ts",
Expand Down
4 changes: 2 additions & 2 deletions pkgs/edge-worker/src/control-plane/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* ```typescript
* // Using namespace import (recommended)
* import { ControlPlane } from '@pgflow/edge-worker';
* import * as flows from '../../flows/index.ts';
* import * as flows from '../../flows/index.js';
*
* ControlPlane.serve(flows);
* ```
Expand All @@ -17,7 +17,7 @@
* ```typescript
* // Using array (legacy)
* import { ControlPlane } from '@pgflow/edge-worker';
* import { MyFlow } from '../../flows/my_flow.ts';
* import { MyFlow } from '../../flows/my_flow.js';
*
* ControlPlane.serve([MyFlow]);
* ```
Expand Down
2 changes: 1 addition & 1 deletion pkgs/edge-worker/src/platform/processDeps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type CryptoLike = {

export function getProcessDeps(): ProcessDeps {
const processLike = (globalThis as { process?: ProcessLike }).process;
const cryptoLike = globalThis.crypto as CryptoLike | undefined;
const cryptoLike = (globalThis as { crypto?: CryptoLike }).crypto;

if (!processLike?.env || !processLike.on || !processLike.exit || !cryptoLike?.randomUUID) {
throw new Error('Process runtime is not available');
Expand Down
2 changes: 1 addition & 1 deletion pkgs/edge-worker/src/platform/resolveConnection.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isLocalSupabaseEnv } from '../shared/localDetection.ts';
import { isLocalSupabaseEnv } from '../shared/localDetection.js';
import postgres from 'postgres';

/**
Expand Down
24 changes: 16 additions & 8 deletions pkgs/edge-worker/src/shared/authValidation.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
import { timingSafeEqual } from '@std/crypto/timing-safe-equal';
import { isLocalSupabaseEnv } from './localDetection.ts';
import { isLocalSupabaseEnv } from './localDetection.js';

function timingSafeEqualBytes(a: Uint8Array, b: Uint8Array): boolean {
if (a.length !== b.length) {
return false;
}

let diff = 0;

for (let index = 0; index < a.length; index += 1) {
diff |= a[index] ^ b[index];
}

return diff === 0;
}

export interface AuthValidationResult {
valid: boolean;
Expand Down Expand Up @@ -38,12 +51,7 @@ export function validateServiceRoleAuth(
const authBytes = encoder.encode(authHeader);
const expectedBytes = encoder.encode(expected);

// Length check first (timingSafeEqual requires same length)
if (authBytes.length !== expectedBytes.length) {
return { valid: false, error: 'Invalid Authorization header' };
}

if (!timingSafeEqual(authBytes, expectedBytes)) {
if (!timingSafeEqualBytes(authBytes, expectedBytes)) {
return { valid: false, error: 'Invalid Authorization header' };
}

Expand Down
1 change: 1 addition & 0 deletions pkgs/edge-worker/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"rootDir": "src",
"outDir": "dist",
"tsBuildInfoFile": "dist/tsconfig.lib.tsbuildinfo",
"lib": ["es2022", "dom", "dom.iterable"],
"typeRoots": ["./node_modules/@types", "."],
"types": [
"node",
Expand Down
25 changes: 25 additions & 0 deletions scripts/smoke-edge-worker-dist.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as edgeWorker from '../pkgs/edge-worker/dist/index.js';
import * as internal from '../pkgs/edge-worker/dist/_internal.js';
import * as testing from '../pkgs/edge-worker/dist/testing.js';

const requiredExports = [
['EdgeWorker', edgeWorker.EdgeWorker],
['createQueueWorker', edgeWorker.createQueueWorker],
['createFlowWorker', edgeWorker.createFlowWorker],
['ProcessPlatformAdapter', edgeWorker.ProcessPlatformAdapter],
['SupabasePlatformAdapter', edgeWorker.SupabasePlatformAdapter],
];

for (const [name, value] of requiredExports) {
if (value === undefined) {
throw new Error(`Missing edge-worker export: ${name}`);
}
}

if (Object.keys(internal).length === 0) {
throw new Error('Expected _internal export surface to load');
}

if (Object.keys(testing).length === 0) {
throw new Error('Expected testing export surface to load');
}
Loading