Update --customer-account-push to support multiple dev instances#3746
Update --customer-account-push to support multiple dev instances#3746
--customer-account-push to support multiple dev instances#3746Conversation
|
Oxygen deployed a preview of your
Learn more about Hydrogen's GitHub integration. |
| devOrigin: DEV_ORIGIN, | ||
| storefrontId: STOREFRONT_ID, | ||
| }), | ||
| ).rejects.toThrow(AbortError); |
There was a problem hiding this comment.
blocking: this test can pass when the feature it claims to test isn't working.
The test name says "throws AbortError with confidential access hint when applicable" but it only asserts that AbortError is thrown, which the previous test (line 160) already covers for a different error message. The confidentialAccessFound logic in the implementation adds a specific "Enable Public access for Hydrogen" link to nextSteps, but nothing here verifies that.
If we removed the entire confidentialAccessFound block from push.ts, this test would still pass.
Let's assert on the error content too. IIRC AbortError accepts nextSteps as the third constructor arg. Something like:
try {
await runCustomerAccountPush({
devOrigin: DEV_ORIGIN,
storefrontId: STOREFRONT_ID,
});
expect.fail('Expected AbortError');
} catch (error) {
expect(error).toBeInstanceOf(AbortError);
expect((error as AbortError).nextSteps).toContainEqual(
expect.objectContaining({
link: expect.objectContaining({
label: 'Enable Public access for Hydrogen',
}),
}),
);
}Or if AbortError exposes the next steps differently, adjust accordingly. The key thing is asserting the hint is actually present.
| '@shopify/cli-hydrogen': patch | ||
| --- | ||
|
|
||
| Updates `customer-account push` to support multiple concurrent dev servers. Previously, starting a second dev server with `--customer-account-push` would overwrite the callback URIs set by the first, breaking Customer Account sign-in for the first server. Now each server additively registers its own callbIck URIs and removes only its own on shutdown. |
There was a problem hiding this comment.
| Updates `customer-account push` to support multiple concurrent dev servers. Previously, starting a second dev server with `--customer-account-push` would overwrite the callback URIs set by the first, breaking Customer Account sign-in for the first server. Now each server additively registers its own callbIck URIs and removes only its own on shutdown. | |
| Updates `customer-account push` to support multiple concurrent dev servers. Previously, starting a second dev server with `--customer-account-push` would overwrite the callback URIs set by the first, breaking Customer Account sign-in for the first server. Now each server additively registers its own callback URIs and removes only its own on shutdown. |
|
|
||
| const {session, config} = await login(root); | ||
| const customerAccountConfig = config?.storefront?.customerAccountConfig; | ||
| const {session} = await login(root); |
There was a problem hiding this comment.
praise: the old code did const {session, config} = await login(root) and read config?.storefront?.customerAccountConfig to build removeRegex values. Now it's just const {session} = await login(root). The push path no longer depends on local state at all, which is the mechanism that makes multi-developer concurrency safe. The unused removeRegex?: string parameter was also removed from the function's type signature. Good cleanup.
| removeRegex: customerAccountConfig?.javascriptOrigin, | ||
| }, | ||
| logoutUris: { | ||
| add: logoutUri ? [logoutUri] : undefined, |
There was a problem hiding this comment.
non-blocking: (threading) Re: lines 189-193 (cleanup path). Pre-existing, not introduced by this PR, but worth noting: the cleanup passes raw URL strings (e.g. https://abc123.tryhydrogen.dev) as removeRegex values without escaping the . characters, which are regex metacharacters matching any character.
Under the new additive model where multiple dev sessions coexist, the blast radius of an unescaped regex match is wider than before. Previously, removeRegex ran in a single-session context. Now multiple sessions register URLs independently and each session's cleanup runs removeRegex against the shared URL list. If two dev origins share a similar pattern (e.g. abc123.tryhydrogen.dev vs abc123-tryhydrogen.dev), an unescaped regex could remove another session's URL during cleanup. Low probability given the subdomain structure, but the regex escaping follow-up is more important now than it was before.
| removeRegex: customerAccountConfig?.logoutUri, | ||
| }, | ||
| }, | ||
| ); |
There was a problem hiding this comment.
non-blocking: (threading) Re: line 97. const error: any = new Error(...) is pre-existing, not introduced by this PR. This pushes complexity upward since every catch handler that touches this error needs to know about the ad-hoc userErrors property. A proper typed error class (e.g. class MutationError extends Error { userErrors: UserError[] }) would let TypeScript enforce correct handling.
maybe as a follow up PR later?
WHY are these changes introduced?
When multiple developers (or the same developer) run
dev --customer-account-pushconcurrently on the same store, the second instance overwrites the Customer Account callback URIs set by the first. This breaks Customer Account sign-in for the first dev server because its tunnel URL is no longer registered as a valid callback URI.WHAT is this pull request doing?
Removes
removeRegexfrom the push path so that each dev server additively registers its own callback URIs without touching any other session's URLs. The cleanup function (invoked on dev server shutdown) still usesremoveRegexto remove only that session's specific URLs.HOW to test your changes?
npx shopify hydrogen dev --customer-account-pushin a Hydrogen project — confirm Customer Account sign-in works--customer-account-pushon the same storefrontUnit tests:
pnpm vitest packages/cli/src/commands/hydrogen/customer-account/push.test.tsChecklist