skedyul 1.1.1 → 1.1.2

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.
@@ -0,0 +1 @@
1
+ export declare function buildCommand(args: string[]): Promise<void>;
package/dist/cli/index.js CHANGED
@@ -3491,13 +3491,13 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer, reg
3491
3491
  hasLoggedStartup = true;
3492
3492
  }
3493
3493
  try {
3494
- const path12 = event.path || event.rawPath || "/";
3494
+ const path13 = event.path || event.rawPath || "/";
3495
3495
  const method = event.httpMethod || event.requestContext?.http?.method || "POST";
3496
3496
  if (method === "OPTIONS") {
3497
3497
  return createResponse(200, { message: "OK" }, headers);
3498
3498
  }
3499
- if (path12.startsWith("/webhooks/") && webhookRegistry) {
3500
- const handle = path12.slice("/webhooks/".length);
3499
+ if (path13.startsWith("/webhooks/") && webhookRegistry) {
3500
+ const handle = path13.slice("/webhooks/".length);
3501
3501
  const webhookDef = webhookRegistry[handle];
3502
3502
  if (!webhookDef) {
3503
3503
  return createResponse(404, { error: `Webhook handler '${handle}' not found` }, headers);
@@ -3574,11 +3574,11 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer, reg
3574
3574
  const protocol = forwardedProto ?? "https";
3575
3575
  const host = event.headers?.host ?? event.headers?.Host ?? "localhost";
3576
3576
  const queryString = event.queryStringParameters ? "?" + new URLSearchParams(event.queryStringParameters).toString() : "";
3577
- const webhookUrl = `${protocol}://${host}${path12}${queryString}`;
3577
+ const webhookUrl = `${protocol}://${host}${path13}${queryString}`;
3578
3578
  webhookRequest = {
3579
3579
  method,
3580
3580
  url: webhookUrl,
3581
- path: path12,
3581
+ path: path13,
3582
3582
  headers: event.headers,
3583
3583
  query: event.queryStringParameters ?? {},
3584
3584
  body: parsedBody,
@@ -3621,7 +3621,7 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer, reg
3621
3621
  body: body !== void 0 ? typeof body === "string" ? body : JSON.stringify(body) : ""
3622
3622
  };
3623
3623
  }
3624
- if (path12 === "/core" && method === "POST") {
3624
+ if (path13 === "/core" && method === "POST") {
3625
3625
  let coreBody;
3626
3626
  try {
3627
3627
  coreBody = event.body ? JSON.parse(event.body) : {};
@@ -3653,7 +3653,7 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer, reg
3653
3653
  const result = await handleCoreMethod(coreMethod, coreBody.params);
3654
3654
  return createResponse(result.status, result.payload, headers);
3655
3655
  }
3656
- if (path12 === "/core/webhook" && method === "POST") {
3656
+ if (path13 === "/core/webhook" && method === "POST") {
3657
3657
  const rawWebhookBody = event.body ?? "";
3658
3658
  let webhookBody;
3659
3659
  try {
@@ -3668,14 +3668,14 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer, reg
3668
3668
  const forwardedProto = event.headers?.["x-forwarded-proto"] ?? event.headers?.["X-Forwarded-Proto"];
3669
3669
  const protocol = forwardedProto ?? "https";
3670
3670
  const host = event.headers?.host ?? event.headers?.Host ?? "localhost";
3671
- const webhookUrl = `${protocol}://${host}${path12}`;
3671
+ const webhookUrl = `${protocol}://${host}${path13}`;
3672
3672
  const coreWebhookRequest = {
3673
3673
  method,
3674
3674
  headers: event.headers ?? {},
3675
3675
  body: webhookBody,
3676
3676
  query: event.queryStringParameters ?? {},
3677
3677
  url: webhookUrl,
3678
- path: path12,
3678
+ path: path13,
3679
3679
  rawBody: rawWebhookBody ? Buffer.from(rawWebhookBody, "utf-8") : void 0
3680
3680
  };
3681
3681
  const webhookResponse = await coreApiService.dispatchWebhook(
@@ -3687,7 +3687,7 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer, reg
3687
3687
  headers
3688
3688
  );
3689
3689
  }
3690
- if (path12 === "/estimate" && method === "POST") {
3690
+ if (path13 === "/estimate" && method === "POST") {
3691
3691
  let estimateBody;
3692
3692
  try {
3693
3693
  estimateBody = event.body ? JSON.parse(event.body) : {};
@@ -3753,7 +3753,7 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer, reg
3753
3753
  );
3754
3754
  }
3755
3755
  }
3756
- if (path12 === "/install" && method === "POST") {
3756
+ if (path13 === "/install" && method === "POST") {
3757
3757
  if (!config.hooks?.install) {
3758
3758
  return createResponse(404, { error: "Install handler not configured" }, headers);
3759
3759
  }
@@ -3825,7 +3825,7 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer, reg
3825
3825
  );
3826
3826
  }
3827
3827
  }
3828
- if (path12 === "/uninstall" && method === "POST") {
3828
+ if (path13 === "/uninstall" && method === "POST") {
3829
3829
  if (!config.hooks?.uninstall) {
3830
3830
  return createResponse(404, { error: "Uninstall handler not configured" }, headers);
3831
3831
  }
@@ -3889,7 +3889,7 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer, reg
3889
3889
  );
3890
3890
  }
3891
3891
  }
3892
- if (path12 === "/provision" && method === "POST") {
3892
+ if (path13 === "/provision" && method === "POST") {
3893
3893
  console.log("[serverless] /provision endpoint called");
3894
3894
  if (!config.hooks?.provision) {
3895
3895
  console.log("[serverless] No provision handler configured");
@@ -3962,7 +3962,7 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer, reg
3962
3962
  );
3963
3963
  }
3964
3964
  }
3965
- if (path12 === "/oauth_callback" && method === "POST") {
3965
+ if (path13 === "/oauth_callback" && method === "POST") {
3966
3966
  if (!config.hooks?.oauth_callback) {
3967
3967
  return createResponse(
3968
3968
  404,
@@ -4028,10 +4028,10 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer, reg
4028
4028
  );
4029
4029
  }
4030
4030
  }
4031
- if (path12 === "/health" && method === "GET") {
4031
+ if (path13 === "/health" && method === "GET") {
4032
4032
  return createResponse(200, state.getHealthStatus(), headers);
4033
4033
  }
4034
- if (path12 === "/mcp" && method === "POST") {
4034
+ if (path13 === "/mcp" && method === "POST") {
4035
4035
  let body;
4036
4036
  try {
4037
4037
  body = event.body ? JSON.parse(event.body) : {};
@@ -5056,7 +5056,16 @@ var CONFIG_FILE_NAMES = [
5056
5056
  ];
5057
5057
  async function transpileTypeScript(filePath) {
5058
5058
  const content = fs7.readFileSync(filePath, "utf-8");
5059
+ const configDir = path7.dirname(path7.resolve(filePath));
5059
5060
  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*$/, "}");
5061
+ transpiled = transpiled.replace(
5062
+ /import\s+(\w+)\s+from\s+['"](\.[^'"]+)['"]/g,
5063
+ (match, varName, relativePath) => {
5064
+ const absolutePath = path7.resolve(configDir, relativePath);
5065
+ return `const ${varName} = require('${absolutePath.replace(/\\/g, "/")}')`;
5066
+ }
5067
+ );
5068
+ transpiled = transpiled.replace(/import\s*\(\s*['"][^'"]+['"]\s*\)/g, "null");
5060
5069
  return transpiled;
5061
5070
  }
5062
5071
  async function loadConfig(configPath) {
@@ -7010,8 +7019,8 @@ async function handleCreateMany(modelHandle, flags) {
7010
7019
  console.error("Usage: skedyul instances create-many <model> --file data.json --workplace <subdomain>");
7011
7020
  process.exit(1);
7012
7021
  }
7013
- const fs12 = await import("fs");
7014
- const fileContent = fs12.readFileSync(filePath, "utf-8");
7022
+ const fs13 = await import("fs");
7023
+ const fileContent = fs13.readFileSync(filePath, "utf-8");
7015
7024
  const items = JSON.parse(fileContent);
7016
7025
  if (!Array.isArray(items)) {
7017
7026
  console.error("Error: File must contain a JSON array of items");
@@ -7038,8 +7047,8 @@ async function handleUpsertMany(modelHandle, flags) {
7038
7047
  console.error("Usage: skedyul instances upsert-many <model> --file data.json --match-field <field> --workplace <subdomain>");
7039
7048
  process.exit(1);
7040
7049
  }
7041
- const fs12 = await import("fs");
7042
- const fileContent = fs12.readFileSync(filePath, "utf-8");
7050
+ const fs13 = await import("fs");
7051
+ const fileContent = fs13.readFileSync(filePath, "utf-8");
7043
7052
  const items = JSON.parse(fileContent);
7044
7053
  if (!Array.isArray(items)) {
7045
7054
  console.error("Error: File must contain a JSON array of items");
@@ -7049,6 +7058,124 @@ async function handleUpsertMany(modelHandle, flags) {
7049
7058
  console.log(formatJson(result));
7050
7059
  }
7051
7060
 
7061
+ // src/cli/commands/build.ts
7062
+ var import_child_process = require("child_process");
7063
+ var fs12 = __toESM(require("fs"));
7064
+ var path12 = __toESM(require("path"));
7065
+ function printBuildHelp() {
7066
+ console.log(`
7067
+ SKEDYUL BUILD - Build your integration
7068
+ \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
7069
+
7070
+ Builds your integration using configuration from skedyul.config.ts.
7071
+ Automatically determines format (ESM/CJS) based on computeLayer and
7072
+ includes external dependencies from build.external.
7073
+
7074
+ USAGE
7075
+ $ skedyul build [options]
7076
+
7077
+ OPTIONS
7078
+ --watch, -w Watch for changes and rebuild automatically
7079
+ --help, -h Show this help message
7080
+
7081
+ EXAMPLES
7082
+ # Build once
7083
+ $ skedyul build
7084
+
7085
+ # Build and watch for changes
7086
+ $ skedyul build --watch
7087
+
7088
+ CONFIGURATION
7089
+ The build command reads from skedyul.config.ts:
7090
+
7091
+ export default defineConfig({
7092
+ computeLayer: 'serverless', // 'serverless' -> ESM, 'dedicated' -> CJS
7093
+ build: {
7094
+ external: ['twilio'], // Additional externals to exclude
7095
+ },
7096
+ })
7097
+
7098
+ Base externals (always included):
7099
+ - skedyul
7100
+ - skedyul/serverless or skedyul/dedicated
7101
+ - zod
7102
+ `);
7103
+ }
7104
+ async function buildCommand(args2) {
7105
+ if (args2.includes("--help") || args2.includes("-h")) {
7106
+ printBuildHelp();
7107
+ process.exit(0);
7108
+ }
7109
+ const watch = args2.includes("--watch") || args2.includes("-w");
7110
+ const cwd = process.cwd();
7111
+ let configPath = null;
7112
+ for (const name of CONFIG_FILE_NAMES) {
7113
+ const testPath = path12.join(cwd, name);
7114
+ if (fs12.existsSync(testPath)) {
7115
+ configPath = testPath;
7116
+ break;
7117
+ }
7118
+ }
7119
+ if (!configPath) {
7120
+ console.error("Error: No skedyul.config.ts found in current directory");
7121
+ console.error("Make sure you are in the root of your integration project.");
7122
+ process.exit(1);
7123
+ }
7124
+ console.log(`Loading config from ${path12.basename(configPath)}...`);
7125
+ try {
7126
+ const config = await loadConfig(configPath);
7127
+ const computeLayer = config.computeLayer ?? "serverless";
7128
+ const format = computeLayer === "serverless" ? "esm" : "cjs";
7129
+ const baseExternals = ["skedyul", `skedyul/${computeLayer}`, "zod"];
7130
+ const userExternals = config.build && "external" in config.build ? config.build.external ?? [] : [];
7131
+ const allExternals = [...baseExternals, ...userExternals];
7132
+ const tsupArgs = [
7133
+ "tsup",
7134
+ "src/server/mcp_server.ts",
7135
+ "--format",
7136
+ format,
7137
+ "--out-dir",
7138
+ "dist/server",
7139
+ "--target",
7140
+ "node22",
7141
+ "--clean",
7142
+ "--no-splitting",
7143
+ ...allExternals.flatMap((ext) => ["--external", ext])
7144
+ ];
7145
+ if (watch) {
7146
+ tsupArgs.push("--watch");
7147
+ }
7148
+ console.log(``);
7149
+ console.log(`Building ${config.name ?? "integration"}...`);
7150
+ console.log(` Compute layer: ${computeLayer}`);
7151
+ console.log(` Format: ${format}`);
7152
+ console.log(` Externals: ${allExternals.join(", ")}`);
7153
+ console.log(``);
7154
+ const tsup = (0, import_child_process.spawn)("npx", tsupArgs, {
7155
+ cwd,
7156
+ stdio: "inherit",
7157
+ shell: true
7158
+ });
7159
+ tsup.on("error", (error) => {
7160
+ console.error("Failed to start tsup:", error.message);
7161
+ process.exit(1);
7162
+ });
7163
+ tsup.on("close", (code) => {
7164
+ if (code === 0) {
7165
+ console.log(``);
7166
+ console.log(`Build completed successfully!`);
7167
+ }
7168
+ process.exit(code ?? 0);
7169
+ });
7170
+ } catch (error) {
7171
+ console.error(
7172
+ "Error loading config:",
7173
+ error instanceof Error ? error.message : String(error)
7174
+ );
7175
+ process.exit(1);
7176
+ }
7177
+ }
7178
+
7052
7179
  // src/cli/index.ts
7053
7180
  var args = process.argv.slice(2);
7054
7181
  function printUsage2() {
@@ -7072,6 +7199,7 @@ USAGE
7072
7199
  COMMANDS
7073
7200
  auth Authenticate with Skedyul (login, logout, status)
7074
7201
  config Manage global CLI configuration (ngrok, server URL)
7202
+ build Build your integration using skedyul.config.ts
7075
7203
  invoke Invoke a tool on a hosted app version
7076
7204
  instances Manage CRM instances (list, get, create, update, delete)
7077
7205
  dev Development tools for building and testing apps locally
@@ -7133,6 +7261,10 @@ USAGE
7133
7261
  $ skedyul dev <command> [options]
7134
7262
 
7135
7263
  COMMANDS
7264
+ Building
7265
+ \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
7266
+ build Build your integration using skedyul.config.ts
7267
+
7136
7268
  Testing & Debugging
7137
7269
  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
7138
7270
  invoke <tool> Invoke a single tool from your registry
@@ -7151,6 +7283,15 @@ COMMANDS
7151
7283
  diff Show what would change on deploy
7152
7284
  deploy Deploy your app to Skedyul
7153
7285
 
7286
+ BUILD COMMAND
7287
+ Build your integration with configuration from skedyul.config.ts:
7288
+
7289
+ $ skedyul build # Build once
7290
+ $ skedyul build --watch # Build and watch for changes
7291
+
7292
+ The build command reads computeLayer and build.external from your config
7293
+ and runs tsup with the correct options automatically.
7294
+
7154
7295
  STANDALONE MODE
7155
7296
  Test tools locally without connecting to Skedyul:
7156
7297
 
@@ -7172,6 +7313,9 @@ LINKED MODE (Sidecar)
7172
7313
  Now Skedyul will route tool calls to your local machine!
7173
7314
 
7174
7315
  EXAMPLES
7316
+ # Build your integration
7317
+ $ skedyul build
7318
+
7175
7319
  # List tools in your registry
7176
7320
  $ skedyul dev tools --registry ./dist/registry.js
7177
7321
 
@@ -7198,6 +7342,7 @@ OPTIONS
7198
7342
  --help, -h Show help for any command
7199
7343
 
7200
7344
  RUN COMMAND HELP
7345
+ $ skedyul build --help
7201
7346
  $ skedyul dev invoke --help
7202
7347
  $ skedyul dev serve --help
7203
7348
  $ skedyul dev link --help
@@ -7225,6 +7370,10 @@ async function main() {
7225
7370
  await instancesCommand(args.slice(1));
7226
7371
  return;
7227
7372
  }
7373
+ if (command === "build") {
7374
+ await buildCommand(args.slice(1));
7375
+ return;
7376
+ }
7228
7377
  if (command !== "dev") {
7229
7378
  console.error(`Unknown command: ${command}`);
7230
7379
  console.error(`Run 'skedyul --help' for usage information.`);
@@ -7264,6 +7413,9 @@ async function main() {
7264
7413
  case "install":
7265
7414
  await installCommand(subArgs);
7266
7415
  break;
7416
+ case "build":
7417
+ await buildCommand(subArgs);
7418
+ break;
7267
7419
  default:
7268
7420
  console.error(`Unknown dev command: ${subCommand}`);
7269
7421
  console.error(`Run 'skedyul dev --help' for usage information.`);
package/dist/index.js CHANGED
@@ -4187,7 +4187,16 @@ var CONFIG_FILE_NAMES = [
4187
4187
  ];
4188
4188
  async function transpileTypeScript(filePath) {
4189
4189
  const content = fs.readFileSync(filePath, "utf-8");
4190
+ const configDir = path.dirname(path.resolve(filePath));
4190
4191
  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*$/, "}");
4192
+ transpiled = transpiled.replace(
4193
+ /import\s+(\w+)\s+from\s+['"](\.[^'"]+)['"]/g,
4194
+ (match, varName, relativePath) => {
4195
+ const absolutePath = path.resolve(configDir, relativePath);
4196
+ return `const ${varName} = require('${absolutePath.replace(/\\/g, "/")}')`;
4197
+ }
4198
+ );
4199
+ transpiled = transpiled.replace(/import\s*\(\s*['"][^'"]+['"]\s*\)/g, "null");
4191
4200
  return transpiled;
4192
4201
  }
4193
4202
  async function loadConfig(configPath) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skedyul",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "The Skedyul SDK for Node.js",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",