Skip to content

Commit fa04b0c

Browse files
committed
Notify users when Liquid files are rewritten remotely
1 parent 7297a1f commit fa04b0c

File tree

17 files changed

+378
-72
lines changed

17 files changed

+378
-72
lines changed

.changeset/sour-boats-grab.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@shopify/cli-kit': minor
3+
'@shopify/theme': minor
4+
---
5+
6+
Add ability to notify user when Liquid files are rewritten remotely

packages/cli-kit/src/cli/api/graphql/admin/generated/theme_files_upsert.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export type ThemeFilesUpsertMutationVariables = Types.Exact<{
1010

1111
export type ThemeFilesUpsertMutation = {
1212
themeFilesUpsert?: {
13-
upsertedThemeFiles?: {filename: string}[] | null
13+
upsertedThemeFiles?: {filename: string; checksumMd5?: string | null}[] | null
1414
userErrors: {filename?: string | null; message: string}[]
1515
} | null
1616
}
@@ -71,6 +71,7 @@ export const ThemeFilesUpsert = {
7171
kind: 'SelectionSet',
7272
selections: [
7373
{kind: 'Field', name: {kind: 'Name', value: 'filename'}},
74+
{kind: 'Field', name: {kind: 'Name', value: 'checksumMd5'}},
7475
{kind: 'Field', name: {kind: 'Name', value: '__typename'}},
7576
],
7677
},

packages/cli-kit/src/cli/api/graphql/admin/mutations/theme_files_upsert.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ mutation themeFilesUpsert($files: [OnlineStoreThemeFilesUpsertFileInput!]!, $the
22
themeFilesUpsert(files: $files, themeId: $themeId) {
33
upsertedThemeFiles {
44
filename
5+
checksumMd5
56
}
67
userErrors {
78
filename

packages/cli-kit/src/public/node/themes/api.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,11 +553,19 @@ describe('bulkUploadThemeAssets', async () => {
553553
key: 'snippets/product-variant-picker.liquid',
554554
success: true,
555555
operation: Operation.Upload,
556+
asset: {
557+
checksum: '',
558+
key: 'snippets/product-variant-picker.liquid',
559+
},
556560
},
557561
{
558562
key: 'templates/404.json',
559563
success: true,
560564
operation: Operation.Upload,
565+
asset: {
566+
checksum: '',
567+
key: 'templates/404.json',
568+
},
561569
},
562570
])
563571
})

packages/cli-kit/src/public/node/themes/api.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,10 @@ function processUploadResults(uploadResults: ThemeFilesUpsertMutation): Result[]
316316
key: file.filename,
317317
success: true,
318318
operation: Operation.Upload,
319+
asset: {
320+
key: file.filename,
321+
checksum: file.checksumMd5 ?? '',
322+
},
319323
})
320324
})
321325

packages/theme/src/cli/services/dev.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,10 @@ export async function dev(options: DevOptions) {
120120
},
121121
}
122122

123-
const {serverStart, renderDevSetupProgress, backgroundJobPromise} = setupDevServer(options.theme, ctx)
123+
const {serverStart, renderDevSetupProgress, backgroundJobPromise, syncRewrittenFilesPromise} = setupDevServer(
124+
options.theme,
125+
ctx,
126+
)
124127

125128
readline.emitKeypressEvents(process.stdin)
126129
if (process.stdin.isTTY) {
@@ -140,6 +143,7 @@ export async function dev(options: DevOptions) {
140143
openURLSafely(urls.local, 'development server')
141144
}
142145
}),
146+
syncRewrittenFilesPromise(),
143147
])
144148
}
145149

packages/theme/src/cli/services/push.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ describe('push', () => {
4949
workPromise: Promise.resolve(),
5050
uploadResults: new Map(),
5151
renderThemeSyncProgress: () => Promise.resolve(),
52+
syncRewrittenFilesPromise: Promise.resolve(),
5253
})
5354
vi.mocked(ensureThemeStore).mockReturnValue('example.myshopify.com')
5455
vi.mocked(ensureAuthenticatedThemes).mockResolvedValue(adminSession)
@@ -93,6 +94,7 @@ describe('push', () => {
9394
workPromise: Promise.resolve(),
9495
uploadResults,
9596
renderThemeSyncProgress: () => Promise.resolve(),
97+
syncRewrittenFilesPromise: Promise.resolve(),
9698
})
9799

98100
// When

packages/theme/src/cli/services/push.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,16 +205,20 @@ async function executePush(
205205
const themeFileSystem = mountThemeFileSystem(options.path, {filters: options})
206206
recordTiming('theme-service:push:file-system')
207207

208-
const {uploadResults, renderThemeSyncProgress} = uploadTheme(
208+
const {uploadResults, renderThemeSyncProgress, syncRewrittenFilesPromise} = uploadTheme(
209209
theme,
210210
session,
211211
themeChecksums,
212212
themeFileSystem,
213-
options,
213+
{
214+
...options,
215+
handleRewrittenFiles: 'warn',
216+
},
214217
context,
215218
)
216219

217220
await renderThemeSyncProgress()
221+
await syncRewrittenFilesPromise
218222

219223
if (options.publish) {
220224
await themePublish(theme.id, session)

packages/theme/src/cli/utilities/asset-checksum.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,34 @@ import {isTextFile} from './theme-fs.js'
22
import {Checksum} from '@shopify/cli-kit/node/themes/types'
33
import {fileHash} from '@shopify/cli-kit/node/crypto'
44

5-
export function calculateChecksum(fileKey: string, fileContent: string | Buffer | undefined) {
5+
export function calculateChecksum(
6+
fileKey: string,
7+
fileContent: string | Buffer | undefined,
8+
options?: {replaceNewlines: boolean},
9+
) {
610
if (!fileContent) {
711
return ''
812
}
913

10-
if (Buffer.isBuffer(fileContent)) {
11-
return md5(fileContent)
14+
let filteredContent = fileContent
15+
16+
if (options?.replaceNewlines) {
17+
filteredContent = fileContent.toString().replace(/\r\n/g, '\n')
18+
}
19+
20+
if (Buffer.isBuffer(filteredContent)) {
21+
return md5(filteredContent)
1222
}
1323

1424
/**
1525
* Settings data files are always minified before persistence, so their
1626
* checksum calculation accounts for that minification.
1727
*/
1828
if (isSettingsData(fileKey)) {
19-
return minifiedJSONFileChecksum(fileContent)
29+
return minifiedJSONFileChecksum(filteredContent)
2030
}
2131

22-
return regularFileChecksum(fileKey, fileContent)
32+
return regularFileChecksum(fileKey, filteredContent)
2333
}
2434

2535
function minifiedJSONFileChecksum(fileContent: string) {

packages/theme/src/cli/utilities/theme-downloader.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,12 @@ function buildDownloadTasks(
8686
return batches
8787
}
8888

89-
async function downloadFiles(theme: Theme, fileSystem: ThemeFileSystem, filenames: string[], session: AdminSession) {
89+
export async function downloadFiles(
90+
theme: Theme,
91+
fileSystem: ThemeFileSystem,
92+
filenames: string[],
93+
session: AdminSession,
94+
) {
9095
const assets = await fetchThemeAssets(theme.id, filenames, session)
9196
if (!assets) return
9297

0 commit comments

Comments
 (0)