@omg-dev/server 0.4.29 → 0.4.31
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/index.mjs +27 -15
- package/dist/trigger-scan.mjs +2 -0
- package/package.json +10 -5
- package/src/agent-url.test.ts +36 -0
- package/src/agent-url.ts +11 -0
- package/src/billing.ts +4 -3
- package/src/storage.ts +4 -5
- package/src/triggers.ts +4 -3
- package/src/workflows.ts +2 -1
package/dist/index.mjs
CHANGED
|
@@ -763,7 +763,7 @@ async function sendResumeReplay(client, sub, fromSeq) {
|
|
|
763
763
|
replayed
|
|
764
764
|
});
|
|
765
765
|
}
|
|
766
|
-
const RESERVED = new Set([
|
|
766
|
+
const RESERVED = /* @__PURE__ */ new Set([
|
|
767
767
|
"id",
|
|
768
768
|
"created_at",
|
|
769
769
|
"updated_at",
|
|
@@ -802,7 +802,7 @@ const scopedTables = /* @__PURE__ */ new Set();
|
|
|
802
802
|
function markScoped(table) {
|
|
803
803
|
scopedTables.add(table);
|
|
804
804
|
}
|
|
805
|
-
const RESERVED_COLUMNS = new Set([
|
|
805
|
+
const RESERVED_COLUMNS = /* @__PURE__ */ new Set([
|
|
806
806
|
"id",
|
|
807
807
|
"_owner",
|
|
808
808
|
"created_at",
|
|
@@ -1363,6 +1363,18 @@ function buildAutoCrudRoutes(schema) {
|
|
|
1363
1363
|
return routes;
|
|
1364
1364
|
}
|
|
1365
1365
|
//#endregion
|
|
1366
|
+
//#region src/agent-url.ts
|
|
1367
|
+
const DEFAULT_AGENT_URL = "http://localhost:8080";
|
|
1368
|
+
/**
|
|
1369
|
+
* Base URL for the in-VM agent.
|
|
1370
|
+
*
|
|
1371
|
+
* Read lazily so local runtimes can inject the emulator URL before loading
|
|
1372
|
+
* user code without coupling the SDK to a particular process bootstrap.
|
|
1373
|
+
*/
|
|
1374
|
+
function agentBase() {
|
|
1375
|
+
return process.env.OMG_AGENT_URL || process.env.VIBES_AGENT_URL || DEFAULT_AGENT_URL;
|
|
1376
|
+
}
|
|
1377
|
+
//#endregion
|
|
1366
1378
|
//#region src/triggers.ts
|
|
1367
1379
|
/**
|
|
1368
1380
|
* Schedule a function to run on a cron expression (UTC, 5-field syntax).
|
|
@@ -1661,7 +1673,8 @@ function emitInProcess(topic, payload) {
|
|
|
1661
1673
|
async function emitToOrchestrator(topic, payload) {
|
|
1662
1674
|
const payloadStr = JSON.stringify(payload ?? null);
|
|
1663
1675
|
if (payloadStr.length > MAX_EMIT_BYTES) throw new Error(`emit("${topic}"): payload exceeds ${MAX_EMIT_BYTES} bytes`);
|
|
1664
|
-
const
|
|
1676
|
+
const url = `${agentBase()}/_emit`;
|
|
1677
|
+
const res = await fetch(url, {
|
|
1665
1678
|
method: "POST",
|
|
1666
1679
|
headers: { "Content-Type": "application/json" },
|
|
1667
1680
|
body: JSON.stringify({
|
|
@@ -1773,7 +1786,8 @@ function updateDevDelivery(id, patch) {
|
|
|
1773
1786
|
async function scheduleToOrchestrator(atMs, topic, payload) {
|
|
1774
1787
|
const payloadStr = JSON.stringify(payload ?? null);
|
|
1775
1788
|
if (payloadStr.length > MAX_EMIT_BYTES) throw new Error(`schedule("${topic}"): payload exceeds ${MAX_EMIT_BYTES} bytes`);
|
|
1776
|
-
const
|
|
1789
|
+
const url = `${agentBase()}/_schedule`;
|
|
1790
|
+
const res = await fetch(url, {
|
|
1777
1791
|
method: "POST",
|
|
1778
1792
|
headers: { "Content-Type": "application/json" },
|
|
1779
1793
|
body: JSON.stringify({
|
|
@@ -1794,7 +1808,7 @@ async function scheduleToOrchestrator(atMs, topic, payload) {
|
|
|
1794
1808
|
};
|
|
1795
1809
|
}
|
|
1796
1810
|
async function cancelOnOrchestrator(eventId) {
|
|
1797
|
-
const url =
|
|
1811
|
+
const url = `${agentBase()}/_schedule/${encodeURIComponent(eventId)}`;
|
|
1798
1812
|
const res = await fetch(url, { method: "DELETE" });
|
|
1799
1813
|
if (!res.ok) {
|
|
1800
1814
|
const text = await res.text().catch(() => "");
|
|
@@ -2150,7 +2164,7 @@ function handleWorkflowRequest(req) {
|
|
|
2150
2164
|
return restateFetchHandler(req);
|
|
2151
2165
|
}
|
|
2152
2166
|
async function startViaAgent(name, payloadStr, opts) {
|
|
2153
|
-
const res = await fetch(
|
|
2167
|
+
const res = await fetch(`${agentBase()}/_workflow/start`, {
|
|
2154
2168
|
method: "POST",
|
|
2155
2169
|
headers: { "Content-Type": "application/json" },
|
|
2156
2170
|
body: JSON.stringify({
|
|
@@ -2237,9 +2251,8 @@ const storage = {
|
|
|
2237
2251
|
onUpload,
|
|
2238
2252
|
onDelete
|
|
2239
2253
|
};
|
|
2240
|
-
const AGENT_BASE$1 = "http://localhost:8080";
|
|
2241
2254
|
async function prodPresign(action, key, scope, userId, contentType) {
|
|
2242
|
-
const res = await fetch(`${
|
|
2255
|
+
const res = await fetch(`${agentBase()}/_storage/presign`, {
|
|
2243
2256
|
method: "POST",
|
|
2244
2257
|
headers: { "Content-Type": "application/json" },
|
|
2245
2258
|
body: JSON.stringify({
|
|
@@ -2264,7 +2277,7 @@ async function prodPresign(action, key, scope, userId, contentType) {
|
|
|
2264
2277
|
};
|
|
2265
2278
|
}
|
|
2266
2279
|
async function prodList(scope, userId, prefix, limit) {
|
|
2267
|
-
const res = await fetch(`${
|
|
2280
|
+
const res = await fetch(`${agentBase()}/_storage/list`, {
|
|
2268
2281
|
method: "POST",
|
|
2269
2282
|
headers: { "Content-Type": "application/json" },
|
|
2270
2283
|
body: JSON.stringify({
|
|
@@ -2287,7 +2300,7 @@ async function prodList(scope, userId, prefix, limit) {
|
|
|
2287
2300
|
}));
|
|
2288
2301
|
}
|
|
2289
2302
|
async function prodDelete(key, scope, userId) {
|
|
2290
|
-
const res = await fetch(`${
|
|
2303
|
+
const res = await fetch(`${agentBase()}/_storage/delete`, {
|
|
2291
2304
|
method: "POST",
|
|
2292
2305
|
headers: { "Content-Type": "application/json" },
|
|
2293
2306
|
body: JSON.stringify({
|
|
@@ -2405,7 +2418,7 @@ const NOTIFICATIONS_TABLE = "vibesNotifications";
|
|
|
2405
2418
|
const PREFERENCES_TABLE = "vibesNotificationPreferences";
|
|
2406
2419
|
const SUBSCRIPTIONS_TABLE = "vibesPushSubscriptions";
|
|
2407
2420
|
const DELIVERIES_TABLE = "vibesNotificationDeliveries";
|
|
2408
|
-
const notificationSystemCollectionNames = new Set([
|
|
2421
|
+
const notificationSystemCollectionNames = /* @__PURE__ */ new Set([
|
|
2409
2422
|
NOTIFICATIONS_TABLE,
|
|
2410
2423
|
PREFERENCES_TABLE,
|
|
2411
2424
|
SUBSCRIPTIONS_TABLE,
|
|
@@ -2879,7 +2892,6 @@ self.addEventListener("notificationclick", (event) => {
|
|
|
2879
2892
|
}
|
|
2880
2893
|
//#endregion
|
|
2881
2894
|
//#region src/billing.ts
|
|
2882
|
-
const AGENT_BASE = "http://localhost:8080";
|
|
2883
2895
|
const MICROS_PER_UNIT = 1e6;
|
|
2884
2896
|
/**
|
|
2885
2897
|
* Dollars (or whole credit units) → integer micro-units, for the amount
|
|
@@ -2890,7 +2902,7 @@ function usd(amount) {
|
|
|
2890
2902
|
return Math.round(amount * MICROS_PER_UNIT);
|
|
2891
2903
|
}
|
|
2892
2904
|
async function agentPost(path, body, label) {
|
|
2893
|
-
const res = await fetch(`${
|
|
2905
|
+
const res = await fetch(`${agentBase()}${path}`, {
|
|
2894
2906
|
method: "POST",
|
|
2895
2907
|
headers: { "Content-Type": "application/json" },
|
|
2896
2908
|
body: JSON.stringify(body)
|
|
@@ -2902,7 +2914,7 @@ async function agentPost(path, body, label) {
|
|
|
2902
2914
|
return await res.json();
|
|
2903
2915
|
}
|
|
2904
2916
|
async function agentGet(path, label) {
|
|
2905
|
-
const res = await fetch(`${
|
|
2917
|
+
const res = await fetch(`${agentBase()}${path}`, {
|
|
2906
2918
|
method: "GET",
|
|
2907
2919
|
headers: { Accept: "application/json" }
|
|
2908
2920
|
});
|
|
@@ -3156,7 +3168,7 @@ async function createVibesServer(opts) {
|
|
|
3156
3168
|
];
|
|
3157
3169
|
function rebuildRoutes() {
|
|
3158
3170
|
const explicit = new Set(explicitRoutes.map((r) => `${r.method} ${r.path}`));
|
|
3159
|
-
const builtinKeys = new Set([...storageBuiltinRoutes.map((r) => `${r.method} ${r.path}`), ...notificationBuiltinRoutes.map((r) => `${r.method} ${r.path}`)]);
|
|
3171
|
+
const builtinKeys = /* @__PURE__ */ new Set([...storageBuiltinRoutes.map((r) => `${r.method} ${r.path}`), ...notificationBuiltinRoutes.map((r) => `${r.method} ${r.path}`)]);
|
|
3160
3172
|
const builtinStorage = storageBuiltinRoutes.filter((r) => !explicit.has(`${r.method} ${r.path}`));
|
|
3161
3173
|
const builtinNotifications = notificationBuiltinRoutes.filter((r) => !explicit.has(`${r.method} ${r.path}`));
|
|
3162
3174
|
if (hasCollections(currentSchema) && opts.autoCrud !== false) routes = [
|
package/dist/trigger-scan.mjs
CHANGED
|
@@ -24,6 +24,8 @@ function walk(dir, out) {
|
|
|
24
24
|
const EXPORT_TRIGGER_RE = /^export\s+const\s+(\w+)\s*(?::\s*[^=]+)?\s*=\s*(cron|on)\s*\(\s*(.+?)\s*,/gm;
|
|
25
25
|
const EXPORT_STORAGE_HOOK_RE = /^export\s+const\s+(\w+)\s*(?::\s*[^=]+)?\s*=\s*storage\.(onUpload|onDelete)\s*\(/gm;
|
|
26
26
|
var TriggerScanError = class extends Error {
|
|
27
|
+
file;
|
|
28
|
+
detail;
|
|
27
29
|
constructor(file, detail) {
|
|
28
30
|
super(`[vibes:triggers] ${file}: ${detail}`);
|
|
29
31
|
this.file = file;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@omg-dev/server",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.31",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -14,14 +14,19 @@
|
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@restatedev/restate-sdk": "1.14.5",
|
|
17
|
-
"@omg-dev/auth": "0.4.
|
|
18
|
-
"@omg-dev/schema": "0.4.
|
|
19
|
-
"@omg-dev/stream": "0.4.
|
|
17
|
+
"@omg-dev/auth": "0.4.31",
|
|
18
|
+
"@omg-dev/schema": "0.4.31",
|
|
19
|
+
"@omg-dev/stream": "0.4.31",
|
|
20
20
|
"web-push": "^3.6.7"
|
|
21
21
|
},
|
|
22
22
|
"scripts": {
|
|
23
23
|
"build": "vp pack src/index.ts src/trigger-scan.ts --no-dts",
|
|
24
|
-
"test": "vp test run"
|
|
24
|
+
"test": "vp test run",
|
|
25
|
+
"typecheck": "tsc6 --noEmit --allowImportingTsExtensions --types bun"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/bun": "^1.0.0",
|
|
29
|
+
"typescript": "npm:@typescript/typescript6@6.0.2"
|
|
25
30
|
},
|
|
26
31
|
"license": "MIT",
|
|
27
32
|
"repository": {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it } from "vitest"
|
|
2
|
+
import { agentBase } from "./agent-url.ts"
|
|
3
|
+
|
|
4
|
+
const originalOmgAgentUrl = process.env.OMG_AGENT_URL
|
|
5
|
+
const originalVibesAgentUrl = process.env.VIBES_AGENT_URL
|
|
6
|
+
|
|
7
|
+
afterEach(() => {
|
|
8
|
+
if (originalOmgAgentUrl === undefined) delete process.env.OMG_AGENT_URL
|
|
9
|
+
else process.env.OMG_AGENT_URL = originalOmgAgentUrl
|
|
10
|
+
|
|
11
|
+
if (originalVibesAgentUrl === undefined) delete process.env.VIBES_AGENT_URL
|
|
12
|
+
else process.env.VIBES_AGENT_URL = originalVibesAgentUrl
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
describe("agentBase", () => {
|
|
16
|
+
it("preserves the in-VM default when no override is set", () => {
|
|
17
|
+
delete process.env.OMG_AGENT_URL
|
|
18
|
+
delete process.env.VIBES_AGENT_URL
|
|
19
|
+
|
|
20
|
+
expect(agentBase()).toBe("http://localhost:8080")
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
it("uses VIBES_AGENT_URL as the compatibility override", () => {
|
|
24
|
+
delete process.env.OMG_AGENT_URL
|
|
25
|
+
process.env.VIBES_AGENT_URL = "http://127.0.0.1:4100"
|
|
26
|
+
|
|
27
|
+
expect(agentBase()).toBe("http://127.0.0.1:4100")
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it("prefers OMG_AGENT_URL when both overrides are set", () => {
|
|
31
|
+
process.env.OMG_AGENT_URL = "http://127.0.0.1:4200"
|
|
32
|
+
process.env.VIBES_AGENT_URL = "http://127.0.0.1:4100"
|
|
33
|
+
|
|
34
|
+
expect(agentBase()).toBe("http://127.0.0.1:4200")
|
|
35
|
+
})
|
|
36
|
+
})
|
package/src/agent-url.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const DEFAULT_AGENT_URL = "http://localhost:8080"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Base URL for the in-VM agent.
|
|
5
|
+
*
|
|
6
|
+
* Read lazily so local runtimes can inject the emulator URL before loading
|
|
7
|
+
* user code without coupling the SDK to a particular process bootstrap.
|
|
8
|
+
*/
|
|
9
|
+
export function agentBase(): string {
|
|
10
|
+
return process.env.OMG_AGENT_URL || process.env.VIBES_AGENT_URL || DEFAULT_AGENT_URL
|
|
11
|
+
}
|
package/src/billing.ts
CHANGED
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
// return Response.json(result)
|
|
35
35
|
// }
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
import { agentBase } from "./agent-url.ts"
|
|
38
|
+
|
|
38
39
|
const MICROS_PER_UNIT = 1_000_000
|
|
39
40
|
|
|
40
41
|
/**
|
|
@@ -140,7 +141,7 @@ export interface GrantOptions {
|
|
|
140
141
|
// out, throw on non-2xx with a truncated body for diagnosability.
|
|
141
142
|
|
|
142
143
|
async function agentPost<T>(path: string, body: unknown, label: string): Promise<T> {
|
|
143
|
-
const res = await fetch(`${
|
|
144
|
+
const res = await fetch(`${agentBase()}${path}`, {
|
|
144
145
|
method: "POST",
|
|
145
146
|
headers: { "Content-Type": "application/json" },
|
|
146
147
|
body: JSON.stringify(body),
|
|
@@ -153,7 +154,7 @@ async function agentPost<T>(path: string, body: unknown, label: string): Promise
|
|
|
153
154
|
}
|
|
154
155
|
|
|
155
156
|
async function agentGet<T>(path: string, label: string): Promise<T> {
|
|
156
|
-
const res = await fetch(`${
|
|
157
|
+
const res = await fetch(`${agentBase()}${path}`, {
|
|
157
158
|
method: "GET",
|
|
158
159
|
headers: { Accept: "application/json" },
|
|
159
160
|
})
|
package/src/storage.ts
CHANGED
|
@@ -31,6 +31,7 @@ import path from "node:path"
|
|
|
31
31
|
import fs from "node:fs"
|
|
32
32
|
import crypto from "node:crypto"
|
|
33
33
|
import { ctxStore, ctx } from "./ctx.ts"
|
|
34
|
+
import { agentBase } from "./agent-url.ts"
|
|
34
35
|
|
|
35
36
|
// ── Types ────────────────────────────────────────────────────────────────────
|
|
36
37
|
|
|
@@ -192,8 +193,6 @@ export const storage = {
|
|
|
192
193
|
|
|
193
194
|
// ── prod-mode: HTTP to the agent ─────────────────────────────────────────────
|
|
194
195
|
|
|
195
|
-
const AGENT_BASE = "http://localhost:8080"
|
|
196
|
-
|
|
197
196
|
async function prodPresign(
|
|
198
197
|
action: "put" | "get",
|
|
199
198
|
key: string,
|
|
@@ -201,7 +200,7 @@ async function prodPresign(
|
|
|
201
200
|
userId: string,
|
|
202
201
|
contentType?: string,
|
|
203
202
|
): Promise<PresignedUploadResult> {
|
|
204
|
-
const res = await fetch(`${
|
|
203
|
+
const res = await fetch(`${agentBase()}/_storage/presign`, {
|
|
205
204
|
method: "POST",
|
|
206
205
|
headers: { "Content-Type": "application/json" },
|
|
207
206
|
body: JSON.stringify({ action, key, scope, userId, contentType }),
|
|
@@ -221,7 +220,7 @@ async function prodPresign(
|
|
|
221
220
|
}
|
|
222
221
|
|
|
223
222
|
async function prodList(scope: StorageScope, userId: string, prefix: string, limit: number): Promise<StorageItem[]> {
|
|
224
|
-
const res = await fetch(`${
|
|
223
|
+
const res = await fetch(`${agentBase()}/_storage/list`, {
|
|
225
224
|
method: "POST",
|
|
226
225
|
headers: { "Content-Type": "application/json" },
|
|
227
226
|
body: JSON.stringify({ scope, userId, prefix, limit }),
|
|
@@ -247,7 +246,7 @@ async function prodList(scope: StorageScope, userId: string, prefix: string, lim
|
|
|
247
246
|
}
|
|
248
247
|
|
|
249
248
|
async function prodDelete(key: string, scope: StorageScope, userId: string): Promise<void> {
|
|
250
|
-
const res = await fetch(`${
|
|
249
|
+
const res = await fetch(`${agentBase()}/_storage/delete`, {
|
|
251
250
|
method: "POST",
|
|
252
251
|
headers: { "Content-Type": "application/json" },
|
|
253
252
|
body: JSON.stringify({ key, scope, userId }),
|
package/src/triggers.ts
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
import path from "node:path"
|
|
26
26
|
import fs from "node:fs"
|
|
27
27
|
import { ctxStore, type VibesCtx } from "./ctx.ts"
|
|
28
|
+
import { agentBase } from "./agent-url.ts"
|
|
28
29
|
|
|
29
30
|
// ── Public API ───────────────────────────────────────────────────────────────
|
|
30
31
|
|
|
@@ -480,7 +481,7 @@ async function emitToOrchestrator(topic: string, payload: unknown): Promise<{ su
|
|
|
480
481
|
if (payloadStr.length > MAX_EMIT_BYTES) {
|
|
481
482
|
throw new Error(`emit("${topic}"): payload exceeds ${MAX_EMIT_BYTES} bytes`)
|
|
482
483
|
}
|
|
483
|
-
const url =
|
|
484
|
+
const url = `${agentBase()}/_emit`
|
|
484
485
|
const res = await fetch(url, {
|
|
485
486
|
method: "POST",
|
|
486
487
|
headers: { "Content-Type": "application/json" },
|
|
@@ -637,7 +638,7 @@ async function scheduleToOrchestrator(
|
|
|
637
638
|
if (payloadStr.length > MAX_EMIT_BYTES) {
|
|
638
639
|
throw new Error(`schedule("${topic}"): payload exceeds ${MAX_EMIT_BYTES} bytes`)
|
|
639
640
|
}
|
|
640
|
-
const url =
|
|
641
|
+
const url = `${agentBase()}/_schedule`
|
|
641
642
|
const res = await fetch(url, {
|
|
642
643
|
method: "POST",
|
|
643
644
|
headers: { "Content-Type": "application/json" },
|
|
@@ -664,7 +665,7 @@ async function scheduleToOrchestrator(
|
|
|
664
665
|
}
|
|
665
666
|
|
|
666
667
|
async function cancelOnOrchestrator(eventId: string): Promise<{ cancelled: number }> {
|
|
667
|
-
const url =
|
|
668
|
+
const url = `${agentBase()}/_schedule/${encodeURIComponent(eventId)}`
|
|
668
669
|
const res = await fetch(url, { method: "DELETE" })
|
|
669
670
|
if (!res.ok) {
|
|
670
671
|
const text = await res.text().catch(() => "")
|
package/src/workflows.ts
CHANGED
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
import path from "node:path"
|
|
39
39
|
import fs from "node:fs"
|
|
40
40
|
import { ctxStore, type VibesCtx } from "./ctx.ts"
|
|
41
|
+
import { agentBase } from "./agent-url.ts"
|
|
41
42
|
|
|
42
43
|
// ── Public API ───────────────────────────────────────────────────────────────
|
|
43
44
|
|
|
@@ -417,7 +418,7 @@ async function startViaAgent(
|
|
|
417
418
|
payloadStr: string,
|
|
418
419
|
opts: StartWorkflowOptions,
|
|
419
420
|
): Promise<{ runId: string }> {
|
|
420
|
-
const res = await fetch(
|
|
421
|
+
const res = await fetch(`${agentBase()}/_workflow/start`, {
|
|
421
422
|
method: "POST",
|
|
422
423
|
headers: { "Content-Type": "application/json" },
|
|
423
424
|
body: JSON.stringify({
|