Conversation
Coverage report
Test suite run success3807 tests passing in 1457 suites. Report generated by 🧪jest coverage report action from 86501e1 |
06454b5 to
f131575
Compare
| devFlags.path = resolvedSource | ||
| } else { | ||
| recordEvent('theme-command:dev:override-session') | ||
| await createOverrideDevSession(resolvedSource, devFlags, adminSession) |
There was a problem hiding this comment.
Using this same pattern here to "create" a dev session even if we don't have a long running process yet. This will make it trivial to add hot reloading.
This comment has been minimized.
This comment has been minimized.
karreiro
left a comment
There was a problem hiding this comment.
Thank you for this PR, @dengjeffrey!
This feature is going to be really useful for developers — it feels like something they could use as a building block to create interesting things on top of.
I've left some comments. Once we tophat this, I'll revisit the review, try things end-to-end, and approve.
Thanks again!
| } | ||
|
|
||
| const fileContent = await readFile(options.overrideJson) | ||
| const overrides = JSON.parse(fileContent) as ThemeOverrides |
There was a problem hiding this comment.
May we handle JSON parser errors here?
| description: | ||
| 'The source for the dev server. Can be a directory or a JSON overrides file. When a directory is provided, it is used as the theme directory. When a JSON file is provided, overrides are applied to the theme specified by --theme.', | ||
| env: 'SHOPIFY_FLAG_SOURCE', | ||
| }), |
There was a problem hiding this comment.
While reviewing the flags for this command, I noticed we already have --path, so there are two options:
- When
--sourceis empty, document that the command uses the file system as the source and relies on--path. - Remove
--sourcein favor of--path, allowing you to pass either a--pathor an override file as a parameter.
I think option 2 is the cleaner approach. What do you think?
| 'preview-id': Flags.string({ | ||
| description: | ||
| 'An existing preview identifier to update instead of creating a new preview. Used with --source when pointing to a JSON overrides file.', | ||
| env: 'SHOPIFY_FLAG_PREVIEW_ID', | ||
| }), |
There was a problem hiding this comment.
When reading this as a user, I immediately wondered how I would get a --preview-id. I think we could mention that --preview-id is an optional field that you may get from previous preview runs.
| /** | ||
| * A scope supported by the Storefront Renderer API. | ||
| */ | ||
| export type StorefrontRendererScope = 'devtools' |
There was a problem hiding this comment.
Deferring review of this line to the @Shopify/app-inner-loop team, as they implemented the storefront renderer scopes and have more context on this area.
| overridesContent, | ||
| }: CreateThemePreviewOptions): Promise<ThemePreviewResult> { | ||
| recordTiming('theme-preview:create') | ||
| const baseUrl = buildBaseStorefrontUrl(session) |
There was a problem hiding this comment.
Did you have a chance to tophat this using the Theme Access app?
I wonder if changes will be required there to support the new API call. I think it should work out of the box, but worth double-checking (specially from scopes perspective).
There was a problem hiding this comment.
Will do! Now that everything required to test this has been merged, I will give it a go tomorrow.
fedff6f to
d9a45af
Compare
| ...defaultHeaders(), | ||
| Authorization: `Bearer ${storefrontToken}`, | ||
| 'Content-Type': 'application/json', | ||
| }, |
There was a problem hiding this comment.
Cookies are incorrectly spread into headers instead of being sent as a Cookie header
The code spreads cookie key/values directly into headers:
headers: {
...session.sessionCookies,
...defaultHeaders(),
Authorization: `Bearer ${storefrontToken}`,
'Content-Type': 'application/json',
}If session.sessionCookies is shaped like { storefront_digest: '...', _shopify_essential: '...' }, this produces custom headers named storefront_digest and _shopify_essential rather than a valid Cookie header. Servers may ignore these, causing preview creation/update to fail with auth/session errors.
|
🤖 Code Review · #projects-dev-ai for questions ✅ Complete - No issues 📋 History✅ 1 findings → ✅ 2 findings → ✅ No issues → ✅ No issues |
8d7b77c to
d94cecb
Compare
| recordEvent('theme-command:dev:override-session') | ||
| await createOverrideDevSession(devFlags.path, devFlags, adminSession) | ||
| return | ||
| } |
There was a problem hiding this comment.
--path non-directory values are treated as JSON mode (breaks existing usage when path is missing/invalid)
The command switches to override-preview mode whenever isDirectorySync(devFlags.path) is false:
if (!isDirectorySync(devFlags.path)) {
recordEvent('theme-command:dev:override-session')
await createOverrideDevSession(devFlags.path, devFlags, adminSession)
return
}This will also be true for non-existent directories, non-JSON file paths, and possibly undefined/empty values depending on defaults. In those cases, the command incorrectly requires --theme and attempts JSON parsing, producing confusing errors instead of the existing “directory not found” / “not a theme directory” behavior.
| metadata: { | ||
| ...existingMetadata, | ||
| theme_id: themeId, | ||
| }, |
There was a problem hiding this comment.
constructOverrides may throw or behave unexpectedly if metadata is not an object
constructOverrides assumes overrides.metadata is object-like:
const existingMetadata = (overrides.metadata ?? {}) as ThemeOverrides
// ...
metadata: {
...existingMetadata,
theme_id: themeId,
}If the override JSON has "metadata": "v1" or "metadata": [], spreading can throw or produce odd results (arrays spread into numeric keys).
| return ['graphql', 'themes', 'collaborator'] | ||
| case 'storefront-renderer': | ||
| return ['devtools'] | ||
| return ['devtools', 'graphql'] |
There was a problem hiding this comment.
have you updated the identity app to support this? reach out to me in slack for more details if not.
| path: { | ||
| ...themeFlags.path, | ||
| description: | ||
| 'The path for the dev server. It can be a directory or a JSON overrides file. When a directory is provided, it is used as the theme directory. When a JSON file is provided, overrides are applied to the theme specified by --theme. Defaults to the current working directory.', | ||
| } as typeof themeFlags.path, |
There was a problem hiding this comment.
path is a globally used flag and should keep its behaviour consistent over all commands (apps, theme...).
path means: execute the command in the given path instead of in the current directory.
It's not in globalFlags because not all commands are executed in a specific path, but maybe it should.
Anyway, I don't think we should change how path works in this specific command only. It'd be better to have a new flag
There was a problem hiding this comment.
I'll move it out to an --overrides flag
d94cecb to
22537f4
Compare
…eme previews uisng an override json
65a7479 to
c9446c1
Compare
c9446c1 to
86501e1
Compare
Differences in type declarationsWe detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:
New type declarationsWe found no new type declarations in this PR Existing type declarationspackages/cli-kit/dist/private/node/session.d.ts@@ -31,7 +31,7 @@ interface AppManagementAPIOauthOptions {
/**
* A scope supported by the Storefront Renderer API.
*/
-export type StorefrontRendererScope = 'devtools';
+export type StorefrontRendererScope = 'devtools' | 'graphql';
interface StorefrontRendererAPIOAuthOptions {
/** List of scopes to request permissions for. */
scopes: StorefrontRendererScope[];
|
WHY are these changes introduced?
Resolves https://github.com/shop/issues-growth-activation/issues/1902
WHAT is this pull request doing?
theme devto support temporarily overriding a theme via JSON and being able to preview itMore internal context: https://docs.google.com/document/d/13sa0iRs_DSgyPHbx9IIF64rvhh_KZCDLfJgwpSIxP4A/edit?usp=sharing
--sourceallows for either a theme directory or a JSON. We will document the JSON schema on shopify.dev--preview-idspecifies an existing preview session to be updated with the JSON value in sourceHow to test your changes?
https://docs.google.com/document/d/13sa0iRs_DSgyPHbx9IIF64rvhh_KZCDLfJgwpSIxP4A/edit?tab=t.0#bookmark=id.rhjcmeq18hn7
Post-release steps
Measuring impact
How do we know this change was effective? Please choose one:
Checklist