浏览代码

feat: refactor user registration steps into modular functions and implement step registry
- Replaced individual step imports with a centralized step registry in background.js
- Created separate modules for each registration step: open-chatgpt, submit-signup-email, fill-password, fetch-signup-code, fill-profile, oauth-login, fetch-login-code, confirm-oauth, platform-verify
- Updated tests to reflect changes in step imports and added new tests for step registry functionality

QLHazyCoder 4 月之前
父节点
当前提交
33c5f759d9

+ 22 - 22
background.js

@@ -4,15 +4,16 @@ importScripts(
   'background/panel-bridge.js',
   'background/generated-email-helpers.js',
   'background/signup-flow-helpers.js',
-  'background/steps/step1.js',
-  'background/steps/step2.js',
-  'background/steps/step3.js',
-  'background/steps/step4.js',
-  'background/steps/step5.js',
-  'background/steps/step6.js',
-  'background/steps/step7.js',
-  'background/steps/step8.js',
-  'background/steps/step9.js',
+  'background/steps/registry.js',
+  'background/steps/open-chatgpt.js',
+  'background/steps/submit-signup-email.js',
+  'background/steps/fill-password.js',
+  'background/steps/fetch-signup-code.js',
+  'background/steps/fill-profile.js',
+  'background/steps/oauth-login.js',
+  'background/steps/fetch-login-code.js',
+  'background/steps/confirm-oauth.js',
+  'background/steps/platform-verify.js',
   'data/names.js',
   'hotmail-utils.js',
   'microsoft-email.js',
@@ -5441,19 +5442,7 @@ async function executeStep(step, options = {}) {
   }
 
   try {
-    switch (step) {
-      case 1: await executeStep1(state); break;
-      case 2: await executeStep2(state); break;
-      case 3: await executeStep3(state); break;
-      case 4: await executeStep4(state); break;
-      case 5: await executeStep5(state); break;
-      case 6: await executeStep6(state); break;
-      case 7: await executeStep7(state); break;
-      case 8: await executeStep8(state); break;
-      case 9: await executeStep9(state); break;
-      default:
-        throw new Error(`未知步骤:${step}`);
-    }
+    await stepRegistry.executeStep(step, state);
   } catch (err) {
     if (isStopError(err)) {
       await setStepStatus(step, 'stopped');
@@ -6533,6 +6522,17 @@ const step9Executor = self.MultiPageBackgroundStep9?.createStep9Executor({
   shouldBypassStep9ForLocalCpa,
   SUB2API_STEP9_RESPONSE_TIMEOUT_MS,
 });
+const stepRegistry = self.MultiPageBackgroundStepRegistry?.createStepRegistry([
+  { id: 1, order: 10, key: 'open-chatgpt', title: '打开 ChatGPT 官网', execute: () => step1Executor.executeStep1() },
+  { id: 2, order: 20, key: 'submit-signup-email', title: '注册并输入邮箱', execute: (state) => step2Executor.executeStep2(state) },
+  { id: 3, order: 30, key: 'fill-password', title: '填写密码并继续', execute: (state) => step3Executor.executeStep3(state) },
+  { id: 4, order: 40, key: 'fetch-signup-code', title: '获取注册验证码', execute: (state) => step4Executor.executeStep4(state) },
+  { id: 5, order: 50, key: 'fill-profile', title: '填写姓名和生日', execute: (state) => step5Executor.executeStep5(state) },
+  { id: 6, order: 60, key: 'oauth-login', title: '刷新 OAuth 并登录', execute: (state) => step6Executor.executeStep6(state) },
+  { id: 7, order: 70, key: 'fetch-login-code', title: '获取登录验证码', execute: (state) => step7Executor.executeStep7(state) },
+  { id: 8, order: 80, key: 'confirm-oauth', title: '自动确认 OAuth', execute: (state) => step8Executor.executeStep8(state) },
+  { id: 9, order: 90, key: 'platform-verify', title: '平台回调验证', execute: (state) => step9Executor.executeStep9(state) },
+]);
 
 async function requestOAuthUrlFromPanel(state, options = {}) {
   return panelBridge.requestOAuthUrlFromPanel(state, options);

+ 0 - 0
background/steps/step8.js → background/steps/confirm-oauth.js


+ 0 - 0
background/steps/step7.js → background/steps/fetch-login-code.js


+ 0 - 0
background/steps/step4.js → background/steps/fetch-signup-code.js


+ 0 - 0
background/steps/step3.js → background/steps/fill-password.js


+ 0 - 0
background/steps/step5.js → background/steps/fill-profile.js


+ 0 - 0
background/steps/step6.js → background/steps/oauth-login.js


+ 0 - 0
background/steps/step1.js → background/steps/open-chatgpt.js


+ 0 - 0
background/steps/step9.js → background/steps/platform-verify.js


+ 48 - 0
background/steps/registry.js

@@ -0,0 +1,48 @@
+(function attachBackgroundStepRegistry(root, factory) {
+  root.MultiPageBackgroundStepRegistry = factory();
+})(typeof self !== 'undefined' ? self : globalThis, function createBackgroundStepRegistryModule() {
+  function createStepRegistry(definitions = []) {
+    const ordered = (Array.isArray(definitions) ? definitions : [])
+      .map((definition) => ({
+        id: Number(definition?.id),
+        order: Number(definition?.order),
+        key: String(definition?.key || '').trim(),
+        title: String(definition?.title || '').trim(),
+        execute: definition?.execute,
+      }))
+      .filter((definition) => Number.isFinite(definition.id) && typeof definition.execute === 'function')
+      .sort((left, right) => {
+        const leftOrder = Number.isFinite(left.order) ? left.order : left.id;
+        const rightOrder = Number.isFinite(right.order) ? right.order : right.id;
+        return leftOrder - rightOrder;
+      });
+
+    const byId = new Map(ordered.map((definition) => [definition.id, definition]));
+
+    function getStepDefinition(step) {
+      return byId.get(Number(step)) || null;
+    }
+
+    function getOrderedSteps() {
+      return ordered.slice();
+    }
+
+    function executeStep(step, state) {
+      const definition = getStepDefinition(step);
+      if (!definition) {
+        throw new Error(`未知步骤:${step}`);
+      }
+      return definition.execute(state);
+    }
+
+    return {
+      executeStep,
+      getOrderedSteps,
+      getStepDefinition,
+    };
+  }
+
+  return {
+    createStepRegistry,
+  };
+});

+ 0 - 0
background/steps/step2.js → background/steps/submit-signup-email.js


+ 9 - 9
tests/background-step-modules.test.js

@@ -6,15 +6,15 @@ test('background imports step 1~9 modules', () => {
   const source = fs.readFileSync('background.js', 'utf8');
 
   [
-    'background/steps/step1.js',
-    'background/steps/step2.js',
-    'background/steps/step3.js',
-    'background/steps/step4.js',
-    'background/steps/step5.js',
-    'background/steps/step6.js',
-    'background/steps/step7.js',
-    'background/steps/step8.js',
-    'background/steps/step9.js',
+    'background/steps/open-chatgpt.js',
+    'background/steps/submit-signup-email.js',
+    'background/steps/fill-password.js',
+    'background/steps/fetch-signup-code.js',
+    'background/steps/fill-profile.js',
+    'background/steps/oauth-login.js',
+    'background/steps/fetch-login-code.js',
+    'background/steps/confirm-oauth.js',
+    'background/steps/platform-verify.js',
   ].forEach((path) => {
     assert.match(source, new RegExp(path.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')));
   });

+ 11 - 0
tests/background-step-registry.test.js

@@ -0,0 +1,11 @@
+const test = require('node:test');
+const assert = require('node:assert/strict');
+const fs = require('node:fs');
+
+test('background imports step registry module and uses sparse order values', () => {
+  const source = fs.readFileSync('background.js', 'utf8');
+  assert.match(source, /background\/steps\/registry\.js/);
+  assert.match(source, /order:\s*10/);
+  assert.match(source, /order:\s*90/);
+  assert.match(source, /stepRegistry\.executeStep\(step,\s*state\)/);
+});

+ 1 - 1
tests/step8-stop-cleanup.test.js

@@ -2,7 +2,7 @@ const assert = require('assert');
 const fs = require('fs');
 
 const helperSource = fs.readFileSync('background.js', 'utf8');
-const step8ModuleSource = fs.readFileSync('background/steps/step8.js', 'utf8');
+const step8ModuleSource = fs.readFileSync('background/steps/confirm-oauth.js', 'utf8');
 
 function extractFunction(source, name) {
   const markers = [`async function ${name}(`, `function ${name}(`];