refactor: define options via Typescript

Bug: twpowertools:198
Change-Id: I1ccc45ecc27bf3f8fa8a8beb941dfe035c19bfbd
diff --git a/src/common/optionsPermissions.js b/src/common/optionsPermissions.js
index 4d5cc5a..bb84a88 100644
--- a/src/common/optionsPermissions.js
+++ b/src/common/optionsPermissions.js
@@ -1,5 +1,5 @@
 import actionApi from './actionApi.js';
-import optionsPrototype from './optionsPrototype.json5';
+import {optionsPrototype} from './optionsPrototype.ts';
 import {getOptions} from './optionsUtils.js';
 
 // Required permissions, including host permissions.
diff --git a/src/common/optionsPrototype.json5 b/src/common/optionsPrototype.json5
deleted file mode 100644
index eb7d892..0000000
--- a/src/common/optionsPrototype.json5
+++ /dev/null
@@ -1,214 +0,0 @@
-{
-  // Available options:
-  'list': {
-    defaultValue: true,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'thread': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'threadall': {
-    defaultValue: true,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'fixedtoolbar': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'redirect': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'history': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'loaddrafts': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'increasecontrast': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'stickysidebarheaders': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'profileindicator': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'profileindicatoralt': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'profileindicatoralt_months': {
-    defaultValue: 12,
-    context: 'options',
-    killSwitchType: 'ignore',
-  },
-  'ccdarktheme': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'ccdarktheme_mode': {
-    defaultValue: 'switch',
-    context: 'options',
-    killSwitchType: 'ignore',
-  },
-  'ccforcehidedrawer': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  // #!if ['chromium', 'chromium_mv3'].includes(browser_target)
-  'ccdragndropfix': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  // #!endif
-  'batchlock': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'enhancedannouncementsdot': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'repositionexpandthread': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'threadlistavatars': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'autorefreshlist': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'imagemaxheight': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  // #!if ['chromium', 'chromium_mv3'].includes(browser_target)
-  'blockdrafts': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  // #!endif
-  'perforumstats': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'interopthreadpage': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'interopthreadpage_mode': {
-    defaultValue: 'previous',
-    context: 'options',
-    killSwitchType: 'ignore',
-  },
-  'uispacing': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-  'flattenthreads': {
-    defaultValue: false,
-    context: 'options',
-    killSwitchType: 'option',
-  },
-
-  // Experiments:
-  'workflows': {
-    defaultValue: false,
-    context: 'experiments',
-    killSwitchType: 'experiment',
-  },
-  'extrainfo': {
-    defaultValue: false,
-    context: 'experiments',
-    killSwitchType: 'experiment',
-  },
-  'nestedreplies': {
-    defaultValue: false,
-    context: 'experiments',
-    killSwitchType: 'experiment',
-  },
-
-  // Internal options:
-  'ccdarktheme_switch_enabled': {
-    defaultValue: true,
-    context: 'internal',
-    killSwitchType: 'ignore',
-  },
-  'flattenthreads_switch_enabled': {
-    defaultValue: true,
-    context: 'internal',
-    killSwitchType: 'ignore',
-  },
-
-  // Internal kill switches:
-  'killswitch_xhrproxy': {
-    context: 'internal',
-    killSwitchType: 'internalKillSwitch',
-  },
-
-  // Deprecated options:
-  'escalatethreads': {
-    defaultValue: false,
-    context: 'deprecated',
-    killSwitchType: 'deprecated',
-  },
-  'movethreads': {
-    defaultValue: false,
-    context: 'deprecated',
-    killSwitchType: 'deprecated',
-  },
-  'batchduplicate': {
-    defaultValue: false,
-    context: 'deprecated',
-    killSwitchType: 'deprecated',
-  },
-  'smei_sortdirection': {
-    defaultValue: false,
-    context: 'deprecated',
-    killSwitchType: 'deprecated',
-  },
-  'forcemarkasread': {
-    defaultValue: false,
-    context: 'deprecated',
-    killSwitchType: 'deprecated',
-  },
-  'disableunifiedprofiles': {
-    defaultValue: false,
-    context: 'deprecated',
-    killSwitchType: 'deprecated',
-  },
-}
diff --git a/src/common/optionsPrototype.ts b/src/common/optionsPrototype.ts
new file mode 100644
index 0000000..58ad899
--- /dev/null
+++ b/src/common/optionsPrototype.ts
@@ -0,0 +1,233 @@
+interface BaseOptionConfig {
+  context: "options" | "experiments" | "internal" | "deprecated";
+}
+export type OptionConfig = BaseOptionConfig &
+  (
+    | {
+        defaultValue: any;
+        killSwitchType:
+          | "option"
+          | "experiment"
+          | "ignore"
+          | "deprecated";
+      }
+    | {
+        killSwitchType: "internalKillSwitch";
+      }
+  );
+export type OptionsPrototype = Record<string, OptionConfig>;
+
+export const optionsPrototype: OptionsPrototype = {
+  // Available options:
+  list: {
+    defaultValue: true,
+    context: "options",
+    killSwitchType: "option",
+  },
+  thread: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  threadall: {
+    defaultValue: true,
+    context: "options",
+    killSwitchType: "option",
+  },
+  fixedtoolbar: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  redirect: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  history: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  loaddrafts: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  increasecontrast: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  stickysidebarheaders: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  profileindicator: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  profileindicatoralt: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  profileindicatoralt_months: {
+    defaultValue: 12,
+    context: "options",
+    killSwitchType: "ignore",
+  },
+  ccdarktheme: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  ccdarktheme_mode: {
+    defaultValue: "switch",
+    context: "options",
+    killSwitchType: "ignore",
+  },
+  ccforcehidedrawer: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  // #!if ['chromium', 'chromium_mv3'].includes(browser_target)
+  ccdragndropfix: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  // #!endif
+  batchlock: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  enhancedannouncementsdot: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  repositionexpandthread: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  threadlistavatars: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  autorefreshlist: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  imagemaxheight: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  // #!if ['chromium', 'chromium_mv3'].includes(browser_target)
+  blockdrafts: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  // #!endif
+  perforumstats: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  interopthreadpage: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  interopthreadpage_mode: {
+    defaultValue: "previous",
+    context: "options",
+    killSwitchType: "ignore",
+  },
+  uispacing: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+  flattenthreads: {
+    defaultValue: false,
+    context: "options",
+    killSwitchType: "option",
+  },
+
+  // Experiments:
+  workflows: {
+    defaultValue: false,
+    context: "experiments",
+    killSwitchType: "experiment",
+  },
+  extrainfo: {
+    defaultValue: false,
+    context: "experiments",
+    killSwitchType: "experiment",
+  },
+  nestedreplies: {
+    defaultValue: false,
+    context: "experiments",
+    killSwitchType: "experiment",
+  },
+
+  // Internal options:
+  ccdarktheme_switch_enabled: {
+    defaultValue: true,
+    context: "internal",
+    killSwitchType: "ignore",
+  },
+  flattenthreads_switch_enabled: {
+    defaultValue: true,
+    context: "internal",
+    killSwitchType: "ignore",
+  },
+
+  // Internal kill switches:
+  killswitch_xhrproxy: {
+    context: "internal",
+    killSwitchType: "internalKillSwitch",
+  },
+
+  // Deprecated options:
+  escalatethreads: {
+    defaultValue: false,
+    context: "deprecated",
+    killSwitchType: "deprecated",
+  },
+  movethreads: {
+    defaultValue: false,
+    context: "deprecated",
+    killSwitchType: "deprecated",
+  },
+  batchduplicate: {
+    defaultValue: false,
+    context: "deprecated",
+    killSwitchType: "deprecated",
+  },
+  smei_sortdirection: {
+    defaultValue: false,
+    context: "deprecated",
+    killSwitchType: "deprecated",
+  },
+  forcemarkasread: {
+    defaultValue: false,
+    context: "deprecated",
+    killSwitchType: "deprecated",
+  },
+  disableunifiedprofiles: {
+    defaultValue: false,
+    context: "deprecated",
+    killSwitchType: "deprecated",
+  },
+};
diff --git a/src/common/optionsUtils.js b/src/common/optionsUtils.js
index 162fd93..8b4579d 100644
--- a/src/common/optionsUtils.js
+++ b/src/common/optionsUtils.js
@@ -1,5 +1,5 @@
 import {grantedOptPermissions, isPermissionsObjectEmpty, missingPermissions} from './optionsPermissions.js';
-import optionsPrototype from './optionsPrototype.json5';
+import {optionsPrototype} from './optionsPrototype.ts';
 import specialOptions from './specialOptions.json5';
 
 export {optionsPrototype, specialOptions};