khotan-data 0.1.1 → 0.3.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 +60 -19
- package/dist/cli.js +183 -46
- package/dist/factory.cjs +86 -9
- package/dist/factory.cjs.map +1 -1
- package/dist/factory.d.cts +46 -1
- package/dist/factory.d.ts +46 -1
- package/dist/factory.js +86 -10
- package/dist/factory.js.map +1 -1
- package/dist/templates/api-state.tsx +249 -0
- package/dist/templates/catch.example.ts +25 -17
- package/dist/templates/catch.ts +20 -15
- package/dist/templates/debug-index-page.tsx +56 -36
- package/dist/templates/hub.tsx +105 -36
- package/dist/templates/inflow.example.ts +46 -38
- package/dist/templates/inflow.ts +37 -31
- package/dist/templates/khotan-config.ts +28 -0
- package/dist/templates/mapping-browser.tsx +56 -44
- package/dist/templates/outflow.example.ts +39 -31
- package/dist/templates/outflow.ts +28 -23
- package/dist/templates/pass.example.ts +38 -30
- package/dist/templates/pass.ts +29 -24
- package/dist/templates/plug-debugger.tsx +15 -7
- package/dist/templates/relay.example.ts +52 -44
- package/dist/templates/relay.ts +38 -33
- package/dist/templates/runs-table.tsx +133 -130
- package/dist/templates/skill-dashboard.md +2 -1
- package/dist/templates/skill-setup.md +113 -2
- package/dist/templates/skill-webhook.md +45 -23
- package/dist/templates/topology-canvas.tsx +19 -30
- package/dist/templates/var-panel.tsx +33 -10
- package/dist/templates/webhook-events-table.tsx +105 -102
- package/dist/templates/wire-panel.tsx +30 -8
- package/package.json +1 -1
package/dist/factory.d.cts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { PgDatabase } from 'drizzle-orm/pg-core';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Derives the CLI auth token: HMAC-SHA256 over the timestamp, keyed by the
|
|
5
|
+
* KHOTAN_SECRET. One-way, so the raw secret (the encryption key) never travels
|
|
6
|
+
* over the wire — even a token captured from a dev log can't be reversed into
|
|
7
|
+
* the secret. Exported so the CLI can compute the same value.
|
|
8
|
+
*/
|
|
9
|
+
declare function deriveCliToken(secret: string, timestamp: string): Promise<string>;
|
|
3
10
|
type ResourceConnectField = string | [string, ...string[]];
|
|
4
11
|
interface ResourcePlugParticipation {
|
|
5
12
|
uniqueIdentifier: string;
|
|
@@ -551,12 +558,50 @@ interface KhotanAdapter {
|
|
|
551
558
|
lastRunStatus: KhotanTerminalRunStatus;
|
|
552
559
|
}): Promise<void>;
|
|
553
560
|
}
|
|
561
|
+
/**
|
|
562
|
+
* Authorize an incoming request to the khotan management API.
|
|
563
|
+
*
|
|
564
|
+
* Return `true` to allow the request, `false` to reject it with `401`.
|
|
565
|
+
* The function receives the raw `Request`, so it composes directly with
|
|
566
|
+
* session libraries such as better-auth:
|
|
567
|
+
*
|
|
568
|
+
* ```ts
|
|
569
|
+
* authorize: async (request) => {
|
|
570
|
+
* const session = await auth.api.getSession({ headers: request.headers });
|
|
571
|
+
* return session?.user?.role === "admin";
|
|
572
|
+
* }
|
|
573
|
+
* ```
|
|
574
|
+
*
|
|
575
|
+
* Throwing is treated the same as returning `false`. A rejected request gets a
|
|
576
|
+
* `401` whose JSON body includes `code: "authorize_rejected"` and a `hint`
|
|
577
|
+
* describing the auth model (useful for programmatic callers).
|
|
578
|
+
*
|
|
579
|
+
* NOTE: `KHOTAN_SECRET` is an encryption key, NOT an HTTP credential. Sending it
|
|
580
|
+
* as a `Bearer` token does not authenticate a request — only `authorize` (and
|
|
581
|
+
* the dev-only `KhotanCLI` HMAC token used by the local CLI) can. To trigger a
|
|
582
|
+
* flow from outside the app, either call `khotanData.flow(name).start()` from
|
|
583
|
+
* server code, or send a credential your `authorize` hook accepts.
|
|
584
|
+
*
|
|
585
|
+
* The following routes are intentionally exempt and are NOT passed to
|
|
586
|
+
* `authorize` (they have their own protection):
|
|
587
|
+
* - Inbound webhooks (`POST .../webhook/:plug`) — verified per-plug via `onVerify`.
|
|
588
|
+
* - The cron dispatcher (`.../cron`) — protected by `CRON_SECRET`.
|
|
589
|
+
* - Debug routes (`.../debug...`) — gated by `KHOTAN_DEBUG` and disabled in production.
|
|
590
|
+
*/
|
|
591
|
+
type KhotanAuthorize = (request: Request) => boolean | Promise<boolean>;
|
|
554
592
|
interface KhotanConfig {
|
|
555
593
|
adapter: KhotanAdapter;
|
|
556
594
|
plugs: PlugRegistration[];
|
|
557
595
|
resources?: ResourceRegistration[];
|
|
558
596
|
caches?: CacheRegistration[];
|
|
559
597
|
secret?: string;
|
|
598
|
+
/**
|
|
599
|
+
* Gate every management route (plugs, variables, flows, runs, wires,
|
|
600
|
+
* mappings, caches, resources, webhook handlers/events) behind a custom
|
|
601
|
+
* authorization check. Strongly recommended for any deployed app — without
|
|
602
|
+
* it the management API is publicly accessible. See {@link KhotanAuthorize}.
|
|
603
|
+
*/
|
|
604
|
+
authorize?: KhotanAuthorize;
|
|
560
605
|
}
|
|
561
606
|
type KhotanHandler = (request: Request) => Promise<Response>;
|
|
562
607
|
interface WireInstance {
|
|
@@ -659,4 +704,4 @@ interface NextJsRouteHandlers {
|
|
|
659
704
|
}
|
|
660
705
|
declare function toNextJsHandler(factoryHandler: KhotanHandler): NextJsRouteHandlers;
|
|
661
706
|
|
|
662
|
-
export { type BindablePlug, type BoundPlug, type CacheEntryRecord, type CacheInstance, type CacheRegistration, type CacheScope, type CatchRegistration, type CatchWorkflowContext, type FlowInstance, type FlowRegistration, type FlowRunContext, type FlowRunResult, type FlowSelectorOptions, type FlowStartOptions, type FlowType, type FlowWorkflowContext, type KhotanAdapter, type KhotanConfig, type KhotanHandler, type KhotanInstance, type KhotanRunStatus, type KhotanRunUpdate, type KhotanTerminalRunStatus, type PassRegistration, type PassWorkflowContext, type PlugRegistration, type ResourceConnectField, type ResourceMappingRegistration, type ResourcePlugParticipation, type ResourceRegistration, type VarField, type WebhookRegistration, type WireInstance, type WireRegistration, type WireSubscribeContext, type WireUnsubscribeContext, type WireVerifyContext, __setWorkflowGetRunForTests, __setWorkflowGetWritableForTests, __setWorkflowStartForTests, bindWorkflowPlug, drizzleAdapter, khotan, khotanCache, khotanMappings, sendUpdate, toNextJsHandler };
|
|
707
|
+
export { type BindablePlug, type BoundPlug, type CacheEntryRecord, type CacheInstance, type CacheRegistration, type CacheScope, type CatchRegistration, type CatchWorkflowContext, type FlowInstance, type FlowRegistration, type FlowRunContext, type FlowRunResult, type FlowSelectorOptions, type FlowStartOptions, type FlowType, type FlowWorkflowContext, type KhotanAdapter, type KhotanAuthorize, type KhotanConfig, type KhotanHandler, type KhotanInstance, type KhotanRunStatus, type KhotanRunUpdate, type KhotanTerminalRunStatus, type PassRegistration, type PassWorkflowContext, type PlugRegistration, type ResourceConnectField, type ResourceMappingRegistration, type ResourcePlugParticipation, type ResourceRegistration, type VarField, type WebhookRegistration, type WireInstance, type WireRegistration, type WireSubscribeContext, type WireUnsubscribeContext, type WireVerifyContext, __setWorkflowGetRunForTests, __setWorkflowGetWritableForTests, __setWorkflowStartForTests, bindWorkflowPlug, deriveCliToken, drizzleAdapter, khotan, khotanCache, khotanMappings, sendUpdate, toNextJsHandler };
|
package/dist/factory.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { PgDatabase } from 'drizzle-orm/pg-core';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Derives the CLI auth token: HMAC-SHA256 over the timestamp, keyed by the
|
|
5
|
+
* KHOTAN_SECRET. One-way, so the raw secret (the encryption key) never travels
|
|
6
|
+
* over the wire — even a token captured from a dev log can't be reversed into
|
|
7
|
+
* the secret. Exported so the CLI can compute the same value.
|
|
8
|
+
*/
|
|
9
|
+
declare function deriveCliToken(secret: string, timestamp: string): Promise<string>;
|
|
3
10
|
type ResourceConnectField = string | [string, ...string[]];
|
|
4
11
|
interface ResourcePlugParticipation {
|
|
5
12
|
uniqueIdentifier: string;
|
|
@@ -551,12 +558,50 @@ interface KhotanAdapter {
|
|
|
551
558
|
lastRunStatus: KhotanTerminalRunStatus;
|
|
552
559
|
}): Promise<void>;
|
|
553
560
|
}
|
|
561
|
+
/**
|
|
562
|
+
* Authorize an incoming request to the khotan management API.
|
|
563
|
+
*
|
|
564
|
+
* Return `true` to allow the request, `false` to reject it with `401`.
|
|
565
|
+
* The function receives the raw `Request`, so it composes directly with
|
|
566
|
+
* session libraries such as better-auth:
|
|
567
|
+
*
|
|
568
|
+
* ```ts
|
|
569
|
+
* authorize: async (request) => {
|
|
570
|
+
* const session = await auth.api.getSession({ headers: request.headers });
|
|
571
|
+
* return session?.user?.role === "admin";
|
|
572
|
+
* }
|
|
573
|
+
* ```
|
|
574
|
+
*
|
|
575
|
+
* Throwing is treated the same as returning `false`. A rejected request gets a
|
|
576
|
+
* `401` whose JSON body includes `code: "authorize_rejected"` and a `hint`
|
|
577
|
+
* describing the auth model (useful for programmatic callers).
|
|
578
|
+
*
|
|
579
|
+
* NOTE: `KHOTAN_SECRET` is an encryption key, NOT an HTTP credential. Sending it
|
|
580
|
+
* as a `Bearer` token does not authenticate a request — only `authorize` (and
|
|
581
|
+
* the dev-only `KhotanCLI` HMAC token used by the local CLI) can. To trigger a
|
|
582
|
+
* flow from outside the app, either call `khotanData.flow(name).start()` from
|
|
583
|
+
* server code, or send a credential your `authorize` hook accepts.
|
|
584
|
+
*
|
|
585
|
+
* The following routes are intentionally exempt and are NOT passed to
|
|
586
|
+
* `authorize` (they have their own protection):
|
|
587
|
+
* - Inbound webhooks (`POST .../webhook/:plug`) — verified per-plug via `onVerify`.
|
|
588
|
+
* - The cron dispatcher (`.../cron`) — protected by `CRON_SECRET`.
|
|
589
|
+
* - Debug routes (`.../debug...`) — gated by `KHOTAN_DEBUG` and disabled in production.
|
|
590
|
+
*/
|
|
591
|
+
type KhotanAuthorize = (request: Request) => boolean | Promise<boolean>;
|
|
554
592
|
interface KhotanConfig {
|
|
555
593
|
adapter: KhotanAdapter;
|
|
556
594
|
plugs: PlugRegistration[];
|
|
557
595
|
resources?: ResourceRegistration[];
|
|
558
596
|
caches?: CacheRegistration[];
|
|
559
597
|
secret?: string;
|
|
598
|
+
/**
|
|
599
|
+
* Gate every management route (plugs, variables, flows, runs, wires,
|
|
600
|
+
* mappings, caches, resources, webhook handlers/events) behind a custom
|
|
601
|
+
* authorization check. Strongly recommended for any deployed app — without
|
|
602
|
+
* it the management API is publicly accessible. See {@link KhotanAuthorize}.
|
|
603
|
+
*/
|
|
604
|
+
authorize?: KhotanAuthorize;
|
|
560
605
|
}
|
|
561
606
|
type KhotanHandler = (request: Request) => Promise<Response>;
|
|
562
607
|
interface WireInstance {
|
|
@@ -659,4 +704,4 @@ interface NextJsRouteHandlers {
|
|
|
659
704
|
}
|
|
660
705
|
declare function toNextJsHandler(factoryHandler: KhotanHandler): NextJsRouteHandlers;
|
|
661
706
|
|
|
662
|
-
export { type BindablePlug, type BoundPlug, type CacheEntryRecord, type CacheInstance, type CacheRegistration, type CacheScope, type CatchRegistration, type CatchWorkflowContext, type FlowInstance, type FlowRegistration, type FlowRunContext, type FlowRunResult, type FlowSelectorOptions, type FlowStartOptions, type FlowType, type FlowWorkflowContext, type KhotanAdapter, type KhotanConfig, type KhotanHandler, type KhotanInstance, type KhotanRunStatus, type KhotanRunUpdate, type KhotanTerminalRunStatus, type PassRegistration, type PassWorkflowContext, type PlugRegistration, type ResourceConnectField, type ResourceMappingRegistration, type ResourcePlugParticipation, type ResourceRegistration, type VarField, type WebhookRegistration, type WireInstance, type WireRegistration, type WireSubscribeContext, type WireUnsubscribeContext, type WireVerifyContext, __setWorkflowGetRunForTests, __setWorkflowGetWritableForTests, __setWorkflowStartForTests, bindWorkflowPlug, drizzleAdapter, khotan, khotanCache, khotanMappings, sendUpdate, toNextJsHandler };
|
|
707
|
+
export { type BindablePlug, type BoundPlug, type CacheEntryRecord, type CacheInstance, type CacheRegistration, type CacheScope, type CatchRegistration, type CatchWorkflowContext, type FlowInstance, type FlowRegistration, type FlowRunContext, type FlowRunResult, type FlowSelectorOptions, type FlowStartOptions, type FlowType, type FlowWorkflowContext, type KhotanAdapter, type KhotanAuthorize, type KhotanConfig, type KhotanHandler, type KhotanInstance, type KhotanRunStatus, type KhotanRunUpdate, type KhotanTerminalRunStatus, type PassRegistration, type PassWorkflowContext, type PlugRegistration, type ResourceConnectField, type ResourceMappingRegistration, type ResourcePlugParticipation, type ResourceRegistration, type VarField, type WebhookRegistration, type WireInstance, type WireRegistration, type WireSubscribeContext, type WireUnsubscribeContext, type WireVerifyContext, __setWorkflowGetRunForTests, __setWorkflowGetWritableForTests, __setWorkflowStartForTests, bindWorkflowPlug, deriveCliToken, drizzleAdapter, khotan, khotanCache, khotanMappings, sendUpdate, toNextJsHandler };
|
package/dist/factory.js
CHANGED
|
@@ -259,6 +259,47 @@ function hexToBytes(hex) {
|
|
|
259
259
|
function bytesToHex(bytes) {
|
|
260
260
|
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
261
261
|
}
|
|
262
|
+
var CLI_TOKEN_SCHEME = "KhotanCLI";
|
|
263
|
+
var CLI_TOKEN_WINDOW_MS = 6e4;
|
|
264
|
+
async function deriveCliToken(secret, timestamp2) {
|
|
265
|
+
const key = await crypto.subtle.importKey(
|
|
266
|
+
"raw",
|
|
267
|
+
new TextEncoder().encode(secret),
|
|
268
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
269
|
+
false,
|
|
270
|
+
["sign"]
|
|
271
|
+
);
|
|
272
|
+
const sig = await crypto.subtle.sign(
|
|
273
|
+
"HMAC",
|
|
274
|
+
key,
|
|
275
|
+
new TextEncoder().encode(`khotan-cli:${timestamp2}`)
|
|
276
|
+
);
|
|
277
|
+
return bytesToHex(new Uint8Array(sig));
|
|
278
|
+
}
|
|
279
|
+
function timingSafeEqualHex(a, b) {
|
|
280
|
+
if (a.length !== b.length) return false;
|
|
281
|
+
let diff = 0;
|
|
282
|
+
for (let i = 0; i < a.length; i++) {
|
|
283
|
+
diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
|
|
284
|
+
}
|
|
285
|
+
return diff === 0;
|
|
286
|
+
}
|
|
287
|
+
async function isCliRequestAuthorized(request, secret) {
|
|
288
|
+
if (process.env["NODE_ENV"] === "production") return false;
|
|
289
|
+
if (!secret) return false;
|
|
290
|
+
const header = request.headers.get("authorization");
|
|
291
|
+
if (!header?.startsWith(`${CLI_TOKEN_SCHEME} `)) return false;
|
|
292
|
+
const token = header.slice(CLI_TOKEN_SCHEME.length + 1).trim();
|
|
293
|
+
const dotIdx = token.indexOf(".");
|
|
294
|
+
if (dotIdx === -1) return false;
|
|
295
|
+
const timestamp2 = token.slice(0, dotIdx);
|
|
296
|
+
const provided = token.slice(dotIdx + 1);
|
|
297
|
+
const ts = Number.parseInt(timestamp2, 10);
|
|
298
|
+
if (!Number.isFinite(ts)) return false;
|
|
299
|
+
if (Math.abs(Date.now() - ts) > CLI_TOKEN_WINDOW_MS) return false;
|
|
300
|
+
const expected = await deriveCliToken(secret, timestamp2);
|
|
301
|
+
return timingSafeEqualHex(provided, expected);
|
|
302
|
+
}
|
|
262
303
|
function bindPlugWithVars(plug, vars, setVars) {
|
|
263
304
|
const opts = (extra) => ({
|
|
264
305
|
...extra,
|
|
@@ -1104,9 +1145,14 @@ function coerceDate(value) {
|
|
|
1104
1145
|
}
|
|
1105
1146
|
function isCronRequestAuthorized(request) {
|
|
1106
1147
|
const secret = process.env["CRON_SECRET"]?.trim();
|
|
1107
|
-
if (!secret)
|
|
1148
|
+
if (!secret) {
|
|
1149
|
+
return process.env["NODE_ENV"] !== "production";
|
|
1150
|
+
}
|
|
1108
1151
|
return request.headers.get("authorization") === `Bearer ${secret}`;
|
|
1109
1152
|
}
|
|
1153
|
+
function isDebugEnabled() {
|
|
1154
|
+
return Boolean(process?.env?.["KHOTAN_DEBUG"]) && process?.env?.["NODE_ENV"] !== "production";
|
|
1155
|
+
}
|
|
1110
1156
|
function isWorkflowCancelledError(error) {
|
|
1111
1157
|
if (!error || typeof error !== "object") return false;
|
|
1112
1158
|
const record = error;
|
|
@@ -1400,8 +1446,18 @@ function canonicalizeConnectValue(resource, connectValue) {
|
|
|
1400
1446
|
);
|
|
1401
1447
|
}
|
|
1402
1448
|
function khotan(config) {
|
|
1403
|
-
const { adapter, plugs, resources = [], caches = [] } = config;
|
|
1449
|
+
const { adapter, plugs, resources = [], caches = [], authorize } = config;
|
|
1404
1450
|
const instanceId = crypto.randomUUID();
|
|
1451
|
+
if (!authorize) {
|
|
1452
|
+
console.warn(
|
|
1453
|
+
"[khotan] No `authorize` hook configured: the management API (/api/khotan/*) is publicly accessible. Pass `authorize` to gate it behind your auth layer (e.g. better-auth). This is required for any deployed environment."
|
|
1454
|
+
);
|
|
1455
|
+
}
|
|
1456
|
+
if (!(config.secret ?? process.env["KHOTAN_SECRET"])) {
|
|
1457
|
+
console.warn(
|
|
1458
|
+
"[khotan] No `secret`/`KHOTAN_SECRET` configured: plug credentials and wire metadata will not be encrypted at rest. Set KHOTAN_SECRET to a high-entropy value."
|
|
1459
|
+
);
|
|
1460
|
+
}
|
|
1405
1461
|
const plugNames = /* @__PURE__ */ new Set();
|
|
1406
1462
|
for (const plug of plugs) {
|
|
1407
1463
|
if (plugNames.has(plug.name)) {
|
|
@@ -2228,7 +2284,31 @@ function khotan(config) {
|
|
|
2228
2284
|
const webhookEventsIdx = segments.indexOf("webhook-events");
|
|
2229
2285
|
const variablesIdx = segments.indexOf("variables");
|
|
2230
2286
|
const cronIdx = segments.indexOf("cron");
|
|
2287
|
+
const webhookIdx = segments.indexOf("webhook");
|
|
2231
2288
|
const debugIdx = segments.indexOf("debug");
|
|
2289
|
+
const isInboundWebhook = webhookIdx !== -1 && webhookIdx === segments.length - 2;
|
|
2290
|
+
const isCronRoute = cronIdx !== -1 && cronIdx === segments.length - 1;
|
|
2291
|
+
const isDebugRoute = debugIdx !== -1;
|
|
2292
|
+
if (authorize && !isInboundWebhook && !isCronRoute && !isDebugRoute) {
|
|
2293
|
+
let allowed = await isCliRequestAuthorized(request, secret);
|
|
2294
|
+
if (!allowed) {
|
|
2295
|
+
try {
|
|
2296
|
+
allowed = await authorize(request);
|
|
2297
|
+
} catch {
|
|
2298
|
+
allowed = false;
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
if (!allowed) {
|
|
2302
|
+
return Response.json(
|
|
2303
|
+
{
|
|
2304
|
+
error: "Unauthorized",
|
|
2305
|
+
code: "authorize_rejected",
|
|
2306
|
+
hint: "Management routes (/api/khotan/*) require your `authorize` hook to pass. KHOTAN_SECRET is an encryption key, not an HTTP credential \u2014 sending it as a Bearer token will not authenticate the request. To trigger a flow: call khotanData.flow(name).start() from server code (no HTTP/auth needed), or send a credential your authorize hook accepts (e.g. a session cookie or your own token). The khotan CLI authenticates automatically via a dev-only token derived from KHOTAN_SECRET."
|
|
2307
|
+
},
|
|
2308
|
+
{ status: 401 }
|
|
2309
|
+
);
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
2232
2312
|
const limit = Math.min(
|
|
2233
2313
|
Math.max(
|
|
2234
2314
|
Number.parseInt(url.searchParams.get("limit") ?? "20", 10) || 20,
|
|
@@ -2270,15 +2350,13 @@ function khotan(config) {
|
|
|
2270
2350
|
return Response.json(result);
|
|
2271
2351
|
}
|
|
2272
2352
|
if (debugIdx !== -1 && debugIdx === segments.length - 1) {
|
|
2273
|
-
|
|
2274
|
-
if (!debugActive) {
|
|
2353
|
+
if (!isDebugEnabled()) {
|
|
2275
2354
|
return Response.json({ error: "Not found" }, { status: 404 });
|
|
2276
2355
|
}
|
|
2277
2356
|
return Response.json({ enabled: true });
|
|
2278
2357
|
}
|
|
2279
2358
|
if (debugIdx !== -1 && debugIdx === segments.length - 2) {
|
|
2280
|
-
|
|
2281
|
-
if (!debugActive) {
|
|
2359
|
+
if (!isDebugEnabled()) {
|
|
2282
2360
|
return Response.json({ error: "Not found" }, { status: 404 });
|
|
2283
2361
|
}
|
|
2284
2362
|
const plugName = segments[debugIdx + 1];
|
|
@@ -2580,7 +2658,6 @@ function khotan(config) {
|
|
|
2580
2658
|
const result = await dispatchScheduledFlows({ runType });
|
|
2581
2659
|
return Response.json(result);
|
|
2582
2660
|
}
|
|
2583
|
-
const webhookIdx = segments.indexOf("webhook");
|
|
2584
2661
|
if (webhookIdx !== -1 && webhookIdx === segments.length - 2) {
|
|
2585
2662
|
const plugName = segments[webhookIdx + 1];
|
|
2586
2663
|
const plugReg = plugs.find((p) => p.name === plugName);
|
|
@@ -2797,8 +2874,7 @@ function khotan(config) {
|
|
|
2797
2874
|
return Response.json({ received: true }, { status: 202 });
|
|
2798
2875
|
}
|
|
2799
2876
|
if (debugIdx !== -1 && debugIdx === segments.length - 2) {
|
|
2800
|
-
|
|
2801
|
-
if (!debugActive) {
|
|
2877
|
+
if (!isDebugEnabled()) {
|
|
2802
2878
|
return Response.json({ error: "Not found" }, { status: 404 });
|
|
2803
2879
|
}
|
|
2804
2880
|
const plugName = segments[debugIdx + 1];
|
|
@@ -3287,6 +3363,6 @@ function toNextJsHandler(factoryHandler) {
|
|
|
3287
3363
|
};
|
|
3288
3364
|
}
|
|
3289
3365
|
|
|
3290
|
-
export { __setWorkflowGetRunForTests, __setWorkflowGetWritableForTests, __setWorkflowStartForTests, bindWorkflowPlug, drizzleAdapter, khotan, khotanCache, khotanMappings, sendUpdate, toNextJsHandler };
|
|
3366
|
+
export { __setWorkflowGetRunForTests, __setWorkflowGetWritableForTests, __setWorkflowStartForTests, bindWorkflowPlug, deriveCliToken, drizzleAdapter, khotan, khotanCache, khotanMappings, sendUpdate, toNextJsHandler };
|
|
3291
3367
|
//# sourceMappingURL=factory.js.map
|
|
3292
3368
|
//# sourceMappingURL=factory.js.map
|