@sinch/functions-runtime 0.3.4 → 0.3.6

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.
@@ -161,6 +161,7 @@ function setupJsonParsing(app, options = {}) {
161
161
  import { createRequire as createRequire2 } from "module";
162
162
  import { pathToFileURL } from "url";
163
163
  import * as nodePath from "path";
164
+ import * as nodeFs from "fs";
164
165
  var requireCjs2 = createRequire2(import.meta.url);
165
166
  var LANDING_PAGE_HTML = `<!DOCTYPE html>
166
167
  <html lang="en">
@@ -247,7 +248,8 @@ function extractFunctionName(path6, body) {
247
248
  if (body?.event && isVoiceCallback(body.event)) {
248
249
  return body.event;
249
250
  }
250
- const segments = path6.split("/").filter((s) => s && s !== "*");
251
+ const pathname = path6.split("?")[0];
252
+ const segments = pathname.split("/").filter((s) => s && s !== "*");
251
253
  if (segments.length === 1 && isVoiceCallback(segments[0])) {
252
254
  return segments[0];
253
255
  }
@@ -349,7 +351,11 @@ function buildBaseContext(req, config = {}) {
349
351
  environment: config.environment || "development",
350
352
  variables: config.variables
351
353
  },
352
- cache: noOpCache
354
+ cache: noOpCache,
355
+ assets: (filename) => {
356
+ const filePath = nodePath.join(process.cwd(), "assets", filename);
357
+ return nodeFs.promises.readFile(filePath, "utf-8");
358
+ }
353
359
  };
354
360
  }
355
361
  async function handleVoiceCallback(functionName, userFunction, context, callbackData, logger) {
@@ -409,10 +415,11 @@ async function handleCustomEndpoint(functionName, userFunction, context, request
409
415
  function createApp(options = {}) {
410
416
  const express = requireCjs2("express");
411
417
  const app = express();
412
- if (options.staticDir) {
413
- app.use(express.static(options.staticDir, {
418
+ const staticDir = options.staticDir ?? (nodeFs.existsSync("./public") ? "./public" : void 0);
419
+ if (staticDir) {
420
+ app.use(express.static(staticDir, {
414
421
  index: false,
415
- // Don't serve index.html for /, landing page handles that
422
+ // Don't serve index.html for /, we handle that below
416
423
  dotfiles: "ignore"
417
424
  }));
418
425
  }
@@ -445,7 +452,7 @@ function setupRequestHandler(app, options = {}) {
445
452
  res.type("image/svg+xml").send(svg);
446
453
  return;
447
454
  }
448
- if (req.method === "GET" && req.path === "/" && landingPageEnabled) {
455
+ if (req.method === "GET" && req.originalUrl === "/" && landingPageEnabled) {
449
456
  const acceptHeader = req.headers.accept || "";
450
457
  if (acceptHeader.includes("text/html")) {
451
458
  const html = getLandingPageHtml();
@@ -453,8 +460,15 @@ function setupRequestHandler(app, options = {}) {
453
460
  return;
454
461
  }
455
462
  }
463
+ if (req.method === "GET" && req.originalUrl === "/" && !landingPageEnabled) {
464
+ const indexPath = nodePath.join(process.cwd(), "public", "index.html");
465
+ if (nodeFs.existsSync(indexPath)) {
466
+ res.type("html").sendFile(indexPath);
467
+ return;
468
+ }
469
+ }
456
470
  try {
457
- const functionName = extractFunctionName(req.baseUrl, req.body);
471
+ const functionName = extractFunctionName(req.originalUrl, req.body);
458
472
  logger(`[${(/* @__PURE__ */ new Date()).toISOString()}] ${req.method} ${req.path} -> ${functionName}`);
459
473
  onRequestStart({ functionName, req });
460
474
  const context = buildContext(req);
@@ -513,7 +527,7 @@ function setupRequestHandler(app, options = {}) {
513
527
  logger("Function execution error:", {
514
528
  error: error.message,
515
529
  stack: error.stack,
516
- function: extractFunctionName(req.path, req.body)
530
+ function: extractFunctionName(req.originalUrl, req.body)
517
531
  });
518
532
  res.status(500).json({
519
533
  error: "Internal server error",
@@ -521,7 +535,7 @@ function setupRequestHandler(app, options = {}) {
521
535
  ...process.env.NODE_ENV === "development" && { stack: error.stack }
522
536
  });
523
537
  onRequestEnd({
524
- functionName: extractFunctionName(req.path, req.body),
538
+ functionName: extractFunctionName(req.originalUrl, req.body),
525
539
  req,
526
540
  error,
527
541
  duration,
@@ -927,7 +941,7 @@ async function configureConversationWebhooks(tunnelUrl, config) {
927
941
  console.log("\u{1F4A1} Conversation API not fully configured - skipping webhook setup");
928
942
  return;
929
943
  }
930
- const webhookUrl = `${tunnelUrl}/conversation`;
944
+ const webhookUrl = `${tunnelUrl}/webhook`;
931
945
  console.log(`\u{1F4AC} Conversation webhook URL: ${webhookUrl}`);
932
946
  const sinchClient = new SinchClient2({
933
947
  projectId,
@@ -1189,8 +1203,11 @@ var TunnelClient = class {
1189
1203
  * Configure all webhooks (Voice, Conversation, ElevenLabs)
1190
1204
  */
1191
1205
  async configureWebhooks() {
1192
- const autoConfigVoice = process.env.AUTO_CONFIGURE_VOICE !== "false";
1193
- const autoConfigConversation = process.env.AUTO_CONFIGURE_CONVERSATION !== "false";
1206
+ const hasNewFormat = "AUTO_CONFIGURE" in process.env;
1207
+ const autoEnabled = process.env.AUTO_CONFIGURE === "true";
1208
+ const sinchServices = (process.env.SINCH_SERVICES ?? "").split(",").map((s) => s.trim());
1209
+ const autoConfigVoice = hasNewFormat ? autoEnabled && sinchServices.includes("voice") : process.env.AUTO_CONFIGURE_VOICE !== "false" && !!process.env.VOICE_APPLICATION_KEY;
1210
+ const autoConfigConversation = hasNewFormat ? autoEnabled && sinchServices.includes("conversation") : process.env.AUTO_CONFIGURE_CONVERSATION !== "false" && !!process.env.CONVERSATION_APP_ID;
1194
1211
  if (autoConfigVoice && process.env.VOICE_APPLICATION_KEY) {
1195
1212
  await this.configureVoiceWebhooks();
1196
1213
  }