diff --git a/background.js b/background.js index c4d848b..37ec740 100644 --- a/background.js +++ b/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); diff --git a/background/steps/step8.js b/background/steps/confirm-oauth.js similarity index 100% rename from background/steps/step8.js rename to background/steps/confirm-oauth.js diff --git a/background/steps/step7.js b/background/steps/fetch-login-code.js similarity index 100% rename from background/steps/step7.js rename to background/steps/fetch-login-code.js diff --git a/background/steps/step4.js b/background/steps/fetch-signup-code.js similarity index 100% rename from background/steps/step4.js rename to background/steps/fetch-signup-code.js diff --git a/background/steps/step3.js b/background/steps/fill-password.js similarity index 100% rename from background/steps/step3.js rename to background/steps/fill-password.js diff --git a/background/steps/step5.js b/background/steps/fill-profile.js similarity index 100% rename from background/steps/step5.js rename to background/steps/fill-profile.js diff --git a/background/steps/step6.js b/background/steps/oauth-login.js similarity index 100% rename from background/steps/step6.js rename to background/steps/oauth-login.js diff --git a/background/steps/step1.js b/background/steps/open-chatgpt.js similarity index 100% rename from background/steps/step1.js rename to background/steps/open-chatgpt.js diff --git a/background/steps/step9.js b/background/steps/platform-verify.js similarity index 100% rename from background/steps/step9.js rename to background/steps/platform-verify.js diff --git a/background/steps/registry.js b/background/steps/registry.js new file mode 100644 index 0000000..1eac283 --- /dev/null +++ b/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, + }; +}); diff --git a/background/steps/step2.js b/background/steps/submit-signup-email.js similarity index 100% rename from background/steps/step2.js rename to background/steps/submit-signup-email.js diff --git a/tests/background-step-modules.test.js b/tests/background-step-modules.test.js index 16da9f9..9079df4 100644 --- a/tests/background-step-modules.test.js +++ b/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, '\\$&'))); }); diff --git a/tests/background-step-registry.test.js b/tests/background-step-registry.test.js new file mode 100644 index 0000000..ca2e303 --- /dev/null +++ b/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\)/); +}); diff --git a/tests/step8-stop-cleanup.test.js b/tests/step8-stop-cleanup.test.js index eba5a7f..f7dc732 100644 --- a/tests/step8-stop-cleanup.test.js +++ b/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}(`];