Repository: twilio-labs/serverless-toolkit (ts)

Issue:
Debugger mode doesn't work with forked process
If you use the `--inspect` flag you can no longer attach the debugger since `--fork-process` is turned on by default because every request will spin up a new Node process that you'd have to attach to. To work around this we'll turn off fork-process when `--inspect` is turned on. 

Pull request description:
fix(twilio-run): turn off fork-process in inspect mode
<!-- Describe your Pull Request -->

Fixes #461 

**Contributing to Twilio**

> All third-party contributors acknowledge that any contributions they provide will be made under the same open-source license that the open-source project is provided under.

- [x] I acknowledge that all my contributions will be made under the project's license.


Patch:
diff --git a/.changeset/friendly-turtles-pretend.md b/.changeset/friendly-turtles-pretend.md
new file mode 100644
index 0000000..03d29d6
--- /dev/null
+++ b/.changeset/friendly-turtles-pretend.md
@@ -0,0 +1,5 @@
+---
+'@twilio/runtime-handler': patch
+---
+
+Don't check for exact Content-Type matches
diff --git a/.changeset/warm-moles-learn.md b/.changeset/warm-moles-learn.md
new file mode 100644
index 0000000..b3651dd
--- /dev/null
+++ b/.changeset/warm-moles-learn.md
@@ -0,0 +1,6 @@
+---
+'twilio-run': patch
+'@twilio-labs/plugin-serverless': patch
+---
+
+Fix of debug/inspect mode by disabling fork process
diff --git a/packages/runtime-handler/src/dev-runtime/internal/response.ts b/packages/runtime-handler/src/dev-runtime/internal/response.ts
index 20ec828..5f41888 100644
--- a/packages/runtime-handler/src/dev-runtime/internal/response.ts
+++ b/packages/runtime-handler/src/dev-runtime/internal/response.ts
@@ -79,7 +79,7 @@ export class Response implements TwilioResponse {
           this.headers[COOKIE_HEADER] = newHeaderValue;
         }
       } else {
-        this.headers[COOKIE_HEADER] = Array.isArray(value) ? value: [value];
+        this.headers[COOKIE_HEADER] = Array.isArray(value) ? value : [value];
       }
     } else {
       const existingValue = this.headers[key];
@@ -133,12 +133,17 @@ export class Response implements TwilioResponse {
   }
 
   serialize() {
+    const contentType = this.headers['Content-Type'];
+    let body = this.body;
+    if (
+      typeof contentType === 'string' &&
+      contentType.startsWith('application/json')
+    ) {
+      body = JSON.stringify(body);
+    }
     return {
       statusCode: this.statusCode,
-      body:
-        this.headers['Content-Type'] === 'application/json'
-          ? JSON.stringify(this.body)
-          : this.body,
+      body: body,
       headers: this.headers,
     };
   }
diff --git a/packages/twilio-run/src/config/start.ts b/packages/twilio-run/src/config/start.ts
index 5f5179b..2d5df6b 100644
--- a/packages/twilio-run/src/config/start.ts
+++ b/packages/twilio-run/src/config/start.ts
@@ -186,6 +186,12 @@ export async function getConfigFromCli(
   config.assetsFolderName = cli.assetsFolder;
   config.functionsFolderName = cli.functionsFolder;
   config.forkProcess = cli.forkProcess;
+
+  if (typeof config.inspect !== 'undefined') {
+    debug('Disabling fork-process in inspect mode.');
+    config.forkProcess = false;
+  }
+
   config.pkgJson = pkgJson;
 
   return config;


Test patch:
diff --git a/packages/runtime-handler/__tests__/dev-runtime/internal/response.test.ts b/packages/runtime-handler/__tests__/dev-runtime/internal/response.test.ts
index 8a54e45..aee8704 100644
--- a/packages/runtime-handler/__tests__/dev-runtime/internal/response.test.ts
+++ b/packages/runtime-handler/__tests__/dev-runtime/internal/response.test.ts
@@ -292,3 +292,21 @@ test('serializes a response with content type set to application/json', () => {
     'Set-Cookie': [],
   });
 });
+
+test('serializes a response with content type set to application/json with a charset', () => {
+  const response = new Response();
+  response.setBody({ url: 'https://dkundel.com' });
+  response.setStatusCode(200);
+  response.appendHeader('Content-Type', 'application/json; charset=UTF-8');
+
+  const serialized = response.serialize();
+
+  expect(serialized.body).toEqual(
+    JSON.stringify({ url: 'https://dkundel.com' })
+  );
+  expect(serialized.statusCode).toEqual(200);
+  expect(serialized.headers).toEqual({
+    'Content-Type': 'application/json; charset=UTF-8',
+    'Set-Cookie': [],
+  });
+});
diff --git a/packages/twilio-run/__tests__/config/start.test.ts b/packages/twilio-run/__tests__/config/start.test.ts
index 6ded1a0..0c269bc 100644
--- a/packages/twilio-run/__tests__/config/start.test.ts
+++ b/packages/twilio-run/__tests__/config/start.test.ts
@@ -285,4 +285,18 @@ describe('getConfigFromCli', () => {
       expect(startConfig.baseDir).toEqual(path.resolve(config.cwd));
     }
   });
+
+  test('turns off fork process if inspect is enabled', async () => {
+    require('../../src/config/utils/package-json').__setPackageJson({});
+    const config = {
+      dir: './other_dir',
+      inspect: '',
+    } as unknown as StartCliFlags;
+    if (config.dir) {
+      const startConfig = await getConfigFromCli(config);
+      expect(startConfig.baseDir).toEqual(path.resolve(config.dir));
+      expect(startConfig.forkProcess).toEqual(false);
+      expect(startConfig.inspect).not.toEqual(undefined);
+    }
+  });
 });