skedyul 1.2.23 → 1.2.25

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.js CHANGED
@@ -1066,13 +1066,13 @@ function mergeRuntimeEnv() {
1066
1066
 
1067
1067
  // src/server/utils/http.ts
1068
1068
  function readRawRequestBody(req) {
1069
- return new Promise((resolve2, reject) => {
1069
+ return new Promise((resolve3, reject) => {
1070
1070
  let body = "";
1071
1071
  req.on("data", (chunk) => {
1072
1072
  body += chunk.toString();
1073
1073
  });
1074
1074
  req.on("end", () => {
1075
- resolve2(body);
1075
+ resolve3(body);
1076
1076
  });
1077
1077
  req.on("error", reject);
1078
1078
  });
@@ -2363,6 +2363,7 @@ function createCallToolHandler(registry, state, onMaxRequests) {
2363
2363
  }
2364
2364
 
2365
2365
  // src/server/dedicated.ts
2366
+ var fs = __toESM(require("fs"));
2366
2367
  var import_http2 = __toESM(require("http"));
2367
2368
  var import_streamableHttp = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
2368
2369
 
@@ -2895,7 +2896,7 @@ async function handleOAuthCallback(parsedBody, hooks) {
2895
2896
  }
2896
2897
 
2897
2898
  // src/server/handlers/webhook-handler.ts
2898
- function parseWebhookRequest(parsedBody, method, url, path2, headers, query, rawBody, appIdHeader, appVersionIdHeader) {
2899
+ function parseWebhookRequest(parsedBody, method, url, path3, headers, query, rawBody, appIdHeader, appVersionIdHeader) {
2899
2900
  const isEnvelope = typeof parsedBody === "object" && parsedBody !== null && "env" in parsedBody && "request" in parsedBody && "context" in parsedBody;
2900
2901
  if (isEnvelope) {
2901
2902
  const envelope = parsedBody;
@@ -2949,7 +2950,7 @@ function parseWebhookRequest(parsedBody, method, url, path2, headers, query, raw
2949
2950
  const webhookRequest = {
2950
2951
  method,
2951
2952
  url,
2952
- path: path2,
2953
+ path: path3,
2953
2954
  headers,
2954
2955
  query,
2955
2956
  body: parsedBody,
@@ -3006,6 +3007,7 @@ function isMethodAllowed(webhookRegistry, handle, method) {
3006
3007
  }
3007
3008
 
3008
3009
  // src/server/dedicated.ts
3010
+ var CONFIG_FILE_PATH = ".skedyul/config.json";
3009
3011
  function createDedicatedServerInstance(config, tools, callTool, state, mcpServer) {
3010
3012
  const port = getListeningPort(config);
3011
3013
  const registry = config.tools;
@@ -3026,6 +3028,15 @@ function createDedicatedServerInstance(config, tools, callTool, state, mcpServer
3026
3028
  return;
3027
3029
  }
3028
3030
  if (pathname === "/config" && req.method === "GET") {
3031
+ try {
3032
+ if (fs.existsSync(CONFIG_FILE_PATH)) {
3033
+ const fileConfig = JSON.parse(fs.readFileSync(CONFIG_FILE_PATH, "utf-8"));
3034
+ sendJSON(res, 200, fileConfig);
3035
+ return;
3036
+ }
3037
+ } catch (err) {
3038
+ console.warn("[/config] Failed to read config file, falling back to runtime serialization:", err);
3039
+ }
3029
3040
  sendJSON(res, 200, serializeConfig(config));
3030
3041
  return;
3031
3042
  }
@@ -3325,10 +3336,10 @@ function createDedicatedServerInstance(config, tools, callTool, state, mcpServer
3325
3336
  return {
3326
3337
  async listen(listenPort) {
3327
3338
  const finalPort = listenPort ?? port;
3328
- return new Promise((resolve2, reject) => {
3339
+ return new Promise((resolve3, reject) => {
3329
3340
  httpServer.listen(finalPort, () => {
3330
3341
  printStartupLog(config, tools, finalPort);
3331
- resolve2();
3342
+ resolve3();
3332
3343
  });
3333
3344
  httpServer.once("error", reject);
3334
3345
  });
@@ -3338,6 +3349,8 @@ function createDedicatedServerInstance(config, tools, callTool, state, mcpServer
3338
3349
  }
3339
3350
 
3340
3351
  // src/server/serverless.ts
3352
+ var fs2 = __toESM(require("fs"));
3353
+ var CONFIG_FILE_PATH2 = ".skedyul/config.json";
3341
3354
  function createServerlessInstance(config, tools, callTool, state, mcpServer) {
3342
3355
  const headers = getDefaultHeaders(config.cors);
3343
3356
  const registry = config.tools;
@@ -3350,13 +3363,13 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer) {
3350
3363
  hasLoggedStartup = true;
3351
3364
  }
3352
3365
  try {
3353
- const path2 = event.path || event.rawPath || "/";
3366
+ const path3 = event.path || event.rawPath || "/";
3354
3367
  const method = event.httpMethod || event.requestContext?.http?.method || "POST";
3355
3368
  if (method === "OPTIONS") {
3356
3369
  return createResponse(200, { message: "OK" }, headers);
3357
3370
  }
3358
- if (path2.startsWith("/webhooks/") && webhookRegistry) {
3359
- const handle = path2.slice("/webhooks/".length);
3371
+ if (path3.startsWith("/webhooks/") && webhookRegistry) {
3372
+ const handle = path3.slice("/webhooks/".length);
3360
3373
  if (!webhookRegistry[handle]) {
3361
3374
  return createResponse(404, { error: `Webhook handler '${handle}' not found` }, headers);
3362
3375
  }
@@ -3379,12 +3392,12 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer) {
3379
3392
  const protocol = forwardedProto ?? "https";
3380
3393
  const host = event.headers?.host ?? event.headers?.Host ?? "localhost";
3381
3394
  const queryString = event.queryStringParameters ? "?" + new URLSearchParams(event.queryStringParameters).toString() : "";
3382
- const webhookUrl = `${protocol}://${host}${path2}${queryString}`;
3395
+ const webhookUrl = `${protocol}://${host}${path3}${queryString}`;
3383
3396
  const parseResult = parseWebhookRequest(
3384
3397
  parsedBody,
3385
3398
  method,
3386
3399
  webhookUrl,
3387
- path2,
3400
+ path3,
3388
3401
  event.headers,
3389
3402
  event.queryStringParameters ?? {},
3390
3403
  rawBody,
@@ -3405,7 +3418,7 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer) {
3405
3418
  body: result.body !== void 0 ? typeof result.body === "string" ? result.body : JSON.stringify(result.body) : ""
3406
3419
  };
3407
3420
  }
3408
- if (path2 === "/core" && method === "POST") {
3421
+ if (path3 === "/core" && method === "POST") {
3409
3422
  let coreBody;
3410
3423
  try {
3411
3424
  coreBody = event.body ? JSON.parse(event.body) : {};
@@ -3437,7 +3450,7 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer) {
3437
3450
  const result = await handleCoreMethod(coreMethod, coreBody.params);
3438
3451
  return createResponse(result.status, result.payload, headers);
3439
3452
  }
3440
- if (path2 === "/core/webhook" && method === "POST") {
3453
+ if (path3 === "/core/webhook" && method === "POST") {
3441
3454
  const rawWebhookBody = event.body ?? "";
3442
3455
  let webhookBody;
3443
3456
  try {
@@ -3452,14 +3465,14 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer) {
3452
3465
  const forwardedProto = event.headers?.["x-forwarded-proto"] ?? event.headers?.["X-Forwarded-Proto"];
3453
3466
  const protocol = forwardedProto ?? "https";
3454
3467
  const host = event.headers?.host ?? event.headers?.Host ?? "localhost";
3455
- const webhookUrl = `${protocol}://${host}${path2}`;
3468
+ const webhookUrl = `${protocol}://${host}${path3}`;
3456
3469
  const coreWebhookRequest = {
3457
3470
  method,
3458
3471
  headers: event.headers ?? {},
3459
3472
  body: webhookBody,
3460
3473
  query: event.queryStringParameters ?? {},
3461
3474
  url: webhookUrl,
3462
- path: path2,
3475
+ path: path3,
3463
3476
  rawBody: rawWebhookBody ? Buffer.from(rawWebhookBody, "utf-8") : void 0
3464
3477
  };
3465
3478
  const webhookResponse = await coreApiService.dispatchWebhook(
@@ -3471,7 +3484,7 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer) {
3471
3484
  headers
3472
3485
  );
3473
3486
  }
3474
- if (path2 === "/estimate" && method === "POST") {
3487
+ if (path3 === "/estimate" && method === "POST") {
3475
3488
  let estimateBody;
3476
3489
  try {
3477
3490
  estimateBody = event.body ? JSON.parse(event.body) : {};
@@ -3537,7 +3550,7 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer) {
3537
3550
  );
3538
3551
  }
3539
3552
  }
3540
- if (path2 === "/install" && method === "POST") {
3553
+ if (path3 === "/install" && method === "POST") {
3541
3554
  let installBody;
3542
3555
  try {
3543
3556
  installBody = event.body ? JSON.parse(event.body) : {};
@@ -3551,7 +3564,7 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer) {
3551
3564
  const result = await handleInstall(installBody, config.hooks);
3552
3565
  return createResponse(result.status, result.body, headers);
3553
3566
  }
3554
- if (path2 === "/uninstall" && method === "POST") {
3567
+ if (path3 === "/uninstall" && method === "POST") {
3555
3568
  let uninstallBody;
3556
3569
  try {
3557
3570
  uninstallBody = event.body ? JSON.parse(event.body) : {};
@@ -3565,7 +3578,7 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer) {
3565
3578
  const result = await handleUninstall(uninstallBody, config.hooks);
3566
3579
  return createResponse(result.status, result.body, headers);
3567
3580
  }
3568
- if (path2 === "/provision" && method === "POST") {
3581
+ if (path3 === "/provision" && method === "POST") {
3569
3582
  let provisionBody;
3570
3583
  try {
3571
3584
  provisionBody = event.body ? JSON.parse(event.body) : {};
@@ -3579,7 +3592,7 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer) {
3579
3592
  const result = await handleProvision(provisionBody, config.hooks);
3580
3593
  return createResponse(result.status, result.body, headers);
3581
3594
  }
3582
- if (path2 === "/oauth_callback" && method === "POST") {
3595
+ if (path3 === "/oauth_callback" && method === "POST") {
3583
3596
  let parsedBody;
3584
3597
  try {
3585
3598
  parsedBody = event.body ? JSON.parse(event.body) : {};
@@ -3594,13 +3607,21 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer) {
3594
3607
  const result = await handleOAuthCallback(parsedBody, config.hooks);
3595
3608
  return createResponse(result.status, result.body, headers);
3596
3609
  }
3597
- if (path2 === "/health" && method === "GET") {
3610
+ if (path3 === "/health" && method === "GET") {
3598
3611
  return createResponse(200, state.getHealthStatus(), headers);
3599
3612
  }
3600
- if (path2 === "/config" && method === "GET") {
3613
+ if (path3 === "/config" && method === "GET") {
3614
+ try {
3615
+ if (fs2.existsSync(CONFIG_FILE_PATH2)) {
3616
+ const fileConfig = JSON.parse(fs2.readFileSync(CONFIG_FILE_PATH2, "utf-8"));
3617
+ return createResponse(200, fileConfig, headers);
3618
+ }
3619
+ } catch (err) {
3620
+ console.warn("[/config] Failed to read config file, falling back to runtime serialization:", err);
3621
+ }
3601
3622
  return createResponse(200, serializeConfig(config), headers);
3602
3623
  }
3603
- if (path2 === "/mcp" && method === "POST") {
3624
+ if (path3 === "/mcp" && method === "POST") {
3604
3625
  let body;
3605
3626
  try {
3606
3627
  body = event.body ? JSON.parse(event.body) : {};
@@ -4008,12 +4029,14 @@ COPY src ./src
4008
4029
  # Note: tsup.config.ts is optional - skedyul build generates it if not present
4009
4030
  COPY *.ts ./
4010
4031
 
4011
- # Install dependencies (including dev deps for build), compile, smoke test, then prune
4032
+ # Install dependencies (including dev deps for build), compile, export config, smoke test, then prune
4012
4033
  # Note: Using --no-frozen-lockfile since lockfile may not exist
4013
4034
  # skedyul build reads computeLayer from skedyul.config.ts
4035
+ # skedyul config:export resolves all dynamic imports and writes .skedyul/config.json
4014
4036
  # Smoke test runs before pruning since skedyul CLI is a dev dependency
4015
4037
  RUN pnpm install --no-frozen-lockfile && \\
4016
4038
  pnpm run build && \\
4039
+ pnpm exec skedyul config:export && \\
4017
4040
  pnpm exec skedyul smoke-test && \\
4018
4041
  pnpm prune --prod && \\
4019
4042
  pnpm store prune && \\
@@ -4030,6 +4053,7 @@ WORKDIR /app
4030
4053
  COPY --from=builder /app/node_modules ./node_modules
4031
4054
  COPY --from=builder /app/dist ./dist
4032
4055
  COPY --from=builder /app/package.json ./package.json
4056
+ COPY --from=builder /app/.skedyul ./.skedyul
4033
4057
 
4034
4058
  # Allow overriding the baked-in MCP env at runtime
4035
4059
  ARG MCP_ENV_JSON="{}"
@@ -4052,6 +4076,7 @@ WORKDIR \${LAMBDA_TASK_ROOT}
4052
4076
  COPY --from=builder /app/node_modules ./node_modules
4053
4077
  COPY --from=builder /app/dist ./dist
4054
4078
  COPY --from=builder /app/package.json ./package.json
4079
+ COPY --from=builder /app/.skedyul ./.skedyul
4055
4080
 
4056
4081
  # Allow overriding the baked-in MCP env at runtime
4057
4082
  ARG MCP_ENV_JSON="{}"
@@ -4095,7 +4120,7 @@ function defineNavigation(navigation) {
4095
4120
  }
4096
4121
 
4097
4122
  // src/config/loader.ts
4098
- var fs = __toESM(require("fs"));
4123
+ var fs3 = __toESM(require("fs"));
4099
4124
  var path = __toESM(require("path"));
4100
4125
  var os = __toESM(require("os"));
4101
4126
  var CONFIG_FILE_NAMES = [
@@ -4105,7 +4130,7 @@ var CONFIG_FILE_NAMES = [
4105
4130
  "skedyul.config.cjs"
4106
4131
  ];
4107
4132
  async function transpileTypeScript(filePath) {
4108
- const content = fs.readFileSync(filePath, "utf-8");
4133
+ const content = fs3.readFileSync(filePath, "utf-8");
4109
4134
  const configDir = path.dirname(path.resolve(filePath));
4110
4135
  let transpiled = content.replace(/import\s+type\s+\{[^}]+\}\s+from\s+['"][^'"]+['"]\s*;?\n?/g, "").replace(/import\s+\{\s*defineConfig\s*\}\s+from\s+['"]skedyul['"]\s*;?\n?/g, "").replace(/:\s*SkedyulConfig/g, "").replace(/export\s+default\s+/, "module.exports = ").replace(/defineConfig\s*\(\s*\{/, "{").replace(/\}\s*\)\s*;?\s*$/, "}");
4111
4136
  transpiled = transpiled.replace(
@@ -4120,7 +4145,7 @@ async function transpileTypeScript(filePath) {
4120
4145
  }
4121
4146
  async function loadConfig(configPath) {
4122
4147
  const absolutePath = path.resolve(configPath);
4123
- if (!fs.existsSync(absolutePath)) {
4148
+ if (!fs3.existsSync(absolutePath)) {
4124
4149
  throw new Error(`Config file not found: ${absolutePath}`);
4125
4150
  }
4126
4151
  const isTypeScript = absolutePath.endsWith(".ts");
@@ -4130,7 +4155,7 @@ async function loadConfig(configPath) {
4130
4155
  const transpiled = await transpileTypeScript(absolutePath);
4131
4156
  const tempDir = os.tmpdir();
4132
4157
  const tempFile = path.join(tempDir, `skedyul-config-${Date.now()}.js`);
4133
- fs.writeFileSync(tempFile, transpiled);
4158
+ fs3.writeFileSync(tempFile, transpiled);
4134
4159
  moduleToLoad = tempFile;
4135
4160
  try {
4136
4161
  const module3 = require(moduleToLoad);
@@ -4144,7 +4169,7 @@ async function loadConfig(configPath) {
4144
4169
  return config2;
4145
4170
  } finally {
4146
4171
  try {
4147
- fs.unlinkSync(tempFile);
4172
+ fs3.unlinkSync(tempFile);
4148
4173
  } catch {
4149
4174
  }
4150
4175
  }
@@ -4175,6 +4200,9 @@ function validateConfig(config) {
4175
4200
  return { valid: errors.length === 0, errors };
4176
4201
  }
4177
4202
 
4203
+ // src/config/resolver.ts
4204
+ var path2 = __toESM(require("path"));
4205
+
4178
4206
  // src/config/utils.ts
4179
4207
  function getAllEnvKeys(config) {
4180
4208
  const provision = config.provision && "env" in config.provision ? config.provision : void 0;
package/dist/server.js CHANGED
@@ -485,6 +485,7 @@ function createCallToolHandler(registry, state, onMaxRequests) {
485
485
  }
486
486
 
487
487
  // src/server/dedicated.ts
488
+ var fs = __toESM(require("fs"));
488
489
  var import_http2 = __toESM(require("http"));
489
490
  var import_streamableHttp = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
490
491
 
@@ -1128,6 +1129,7 @@ function isMethodAllowed(webhookRegistry, handle, method) {
1128
1129
  }
1129
1130
 
1130
1131
  // src/server/dedicated.ts
1132
+ var CONFIG_FILE_PATH = ".skedyul/config.json";
1131
1133
  function createDedicatedServerInstance(config, tools, callTool, state, mcpServer) {
1132
1134
  const port = getListeningPort(config);
1133
1135
  const registry = config.tools;
@@ -1148,6 +1150,15 @@ function createDedicatedServerInstance(config, tools, callTool, state, mcpServer
1148
1150
  return;
1149
1151
  }
1150
1152
  if (pathname === "/config" && req.method === "GET") {
1153
+ try {
1154
+ if (fs.existsSync(CONFIG_FILE_PATH)) {
1155
+ const fileConfig = JSON.parse(fs.readFileSync(CONFIG_FILE_PATH, "utf-8"));
1156
+ sendJSON(res, 200, fileConfig);
1157
+ return;
1158
+ }
1159
+ } catch (err) {
1160
+ console.warn("[/config] Failed to read config file, falling back to runtime serialization:", err);
1161
+ }
1151
1162
  sendJSON(res, 200, serializeConfig(config));
1152
1163
  return;
1153
1164
  }
@@ -1460,6 +1471,8 @@ function createDedicatedServerInstance(config, tools, callTool, state, mcpServer
1460
1471
  }
1461
1472
 
1462
1473
  // src/server/serverless.ts
1474
+ var fs2 = __toESM(require("fs"));
1475
+ var CONFIG_FILE_PATH2 = ".skedyul/config.json";
1463
1476
  function createServerlessInstance(config, tools, callTool, state, mcpServer) {
1464
1477
  const headers = getDefaultHeaders(config.cors);
1465
1478
  const registry = config.tools;
@@ -1720,6 +1733,14 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer) {
1720
1733
  return createResponse(200, state.getHealthStatus(), headers);
1721
1734
  }
1722
1735
  if (path === "/config" && method === "GET") {
1736
+ try {
1737
+ if (fs2.existsSync(CONFIG_FILE_PATH2)) {
1738
+ const fileConfig = JSON.parse(fs2.readFileSync(CONFIG_FILE_PATH2, "utf-8"));
1739
+ return createResponse(200, fileConfig, headers);
1740
+ }
1741
+ } catch (err) {
1742
+ console.warn("[/config] Failed to read config file, falling back to runtime serialization:", err);
1743
+ }
1723
1744
  return createResponse(200, serializeConfig(config), headers);
1724
1745
  }
1725
1746
  if (path === "/mcp" && method === "POST") {
@@ -446,6 +446,7 @@ function createCallToolHandler(registry, state, onMaxRequests) {
446
446
  }
447
447
 
448
448
  // src/server/dedicated.ts
449
+ import * as fs from "fs";
449
450
  import http from "http";
450
451
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
451
452
 
@@ -1089,6 +1090,7 @@ function isMethodAllowed(webhookRegistry, handle, method) {
1089
1090
  }
1090
1091
 
1091
1092
  // src/server/dedicated.ts
1093
+ var CONFIG_FILE_PATH = ".skedyul/config.json";
1092
1094
  function createDedicatedServerInstance(config, tools, callTool, state, mcpServer) {
1093
1095
  const port = getListeningPort(config);
1094
1096
  const registry = config.tools;
@@ -1109,6 +1111,15 @@ function createDedicatedServerInstance(config, tools, callTool, state, mcpServer
1109
1111
  return;
1110
1112
  }
1111
1113
  if (pathname === "/config" && req.method === "GET") {
1114
+ try {
1115
+ if (fs.existsSync(CONFIG_FILE_PATH)) {
1116
+ const fileConfig = JSON.parse(fs.readFileSync(CONFIG_FILE_PATH, "utf-8"));
1117
+ sendJSON(res, 200, fileConfig);
1118
+ return;
1119
+ }
1120
+ } catch (err) {
1121
+ console.warn("[/config] Failed to read config file, falling back to runtime serialization:", err);
1122
+ }
1112
1123
  sendJSON(res, 200, serializeConfig(config));
1113
1124
  return;
1114
1125
  }
@@ -1421,6 +1432,8 @@ function createDedicatedServerInstance(config, tools, callTool, state, mcpServer
1421
1432
  }
1422
1433
 
1423
1434
  // src/server/serverless.ts
1435
+ import * as fs2 from "fs";
1436
+ var CONFIG_FILE_PATH2 = ".skedyul/config.json";
1424
1437
  function createServerlessInstance(config, tools, callTool, state, mcpServer) {
1425
1438
  const headers = getDefaultHeaders(config.cors);
1426
1439
  const registry = config.tools;
@@ -1681,6 +1694,14 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer) {
1681
1694
  return createResponse(200, state.getHealthStatus(), headers);
1682
1695
  }
1683
1696
  if (path === "/config" && method === "GET") {
1697
+ try {
1698
+ if (fs2.existsSync(CONFIG_FILE_PATH2)) {
1699
+ const fileConfig = JSON.parse(fs2.readFileSync(CONFIG_FILE_PATH2, "utf-8"));
1700
+ return createResponse(200, fileConfig, headers);
1701
+ }
1702
+ } catch (err) {
1703
+ console.warn("[/config] Failed to read config file, falling back to runtime serialization:", err);
1704
+ }
1684
1705
  return createResponse(200, serializeConfig(config), headers);
1685
1706
  }
1686
1707
  if (path === "/mcp" && method === "POST") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skedyul",
3
- "version": "1.2.23",
3
+ "version": "1.2.25",
4
4
  "description": "The Skedyul SDK for Node.js",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",