Skip to content

Commit

Permalink
Fix support for extension creation in dev-console
Browse files Browse the repository at this point in the history
  • Loading branch information
isaacroldan committed Dec 18, 2024
1 parent a4ee61d commit 8b25260
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 18 deletions.
4 changes: 2 additions & 2 deletions packages/app/src/cli/models/extensions/extension-instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {DeveloperPlatformClient} from '../../utilities/developer-platform-client
import {AppConfigurationWithoutPath, CurrentAppConfiguration} from '../app/app.js'
import {ok} from '@shopify/cli-kit/node/result'
import {constantize, slugify} from '@shopify/cli-kit/common/string'
import {hashString, randomUUID} from '@shopify/cli-kit/node/crypto'
import {hashString, nonRandomUUID, randomUUID} from '@shopify/cli-kit/node/crypto'
import {partnersFqdn} from '@shopify/cli-kit/node/context/fqdn'
import {joinPath, basename} from '@shopify/cli-kit/node/path'
import {fileExists, touchFile, moveFile, writeFile, glob} from '@shopify/cli-kit/node/fs'
Expand Down Expand Up @@ -149,8 +149,8 @@ export class ExtensionInstance<TConfiguration extends BaseConfigType = BaseConfi
this.entrySourceFilePath = options.entryPath ?? ''
this.directory = options.directory
this.specification = options.specification
this.devUUID = `dev-${randomUUID()}`
this.handle = this.buildHandle()
this.devUUID = `dev-${nonRandomUUID(this.handle)}`
this.localIdentifier = this.handle
this.idEnvironmentVariableName = `SHOPIFY_${constantize(this.localIdentifier)}_ID`
this.outputPath = this.directory
Expand Down
48 changes: 32 additions & 16 deletions packages/app/src/cli/services/dev/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {setupWebsocketConnection} from './extension/websocket.js'
import {setupHTTPServer} from './extension/server.js'
import {ExtensionsPayloadStore, getExtensionsPayloadStoreRawPayload} from './extension/payload/store.js'
import {AppEvent, AppEventWatcher, EventType} from './app-events/app-event-watcher.js'
import {buildCartURLIfNeeded} from './extension/utilities.js'
import {ExtensionInstance} from '../../models/extensions/extension-instance.js'
import {AbortSignal} from '@shopify/cli-kit/node/abort'
import {outputDebug} from '@shopify/cli-kit/node/output'
Expand Down Expand Up @@ -109,49 +110,64 @@ export interface ExtensionDevOptions {
}

export async function devUIExtensions(options: ExtensionDevOptions): Promise<void> {
const payloadStoreOptions = {
const payloadOptions = {
...options,
websocketURL: getWebSocketUrl(options.url),
}
const bundlePath = options.appWatcher.buildOutputPath
const payloadStoreRawPayload = await getExtensionsPayloadStoreRawPayload(payloadStoreOptions, bundlePath)
const payloadStore = new ExtensionsPayloadStore(payloadStoreRawPayload, payloadStoreOptions)

outputDebug(`Setting up the UI extensions HTTP server...`, options.stdout)
const httpServer = setupHTTPServer({devOptions: options, payloadStore})
// NOTE: Always use `payloadOptions`, never `options` directly. This way we can mutate `payloadOptions` without
// affecting the original `options` object and we only need to care about `payloadOptions` in this function.

outputDebug(`Setting up the UI extensions Websocket server...`, options.stdout)
const websocketConnection = setupWebsocketConnection({...options, httpServer, payloadStore})
outputDebug(`Setting up the UI extensions bundler and file watching...`, options.stdout)
const bundlePath = payloadOptions.appWatcher.buildOutputPath
const payloadStoreRawPayload = await getExtensionsPayloadStoreRawPayload(payloadOptions, bundlePath)
const payloadStore = new ExtensionsPayloadStore(payloadStoreRawPayload, payloadOptions)

outputDebug(`Setting up the UI extensions HTTP server...`, payloadOptions.stdout)
const httpServer = setupHTTPServer({devOptions: payloadOptions, payloadStore})

outputDebug(`Setting up the UI extensions Websocket server...`, payloadOptions.stdout)
const websocketConnection = setupWebsocketConnection({...payloadOptions, httpServer, payloadStore})
outputDebug(`Setting up the UI extensions bundler and file watching...`, payloadOptions.stdout)

const eventHandler = async ({extensionEvents}: AppEvent) => {
for (const event of extensionEvents) {
const status = event.buildResult?.status === 'ok' ? 'success' : 'error'

switch (event.type) {
case EventType.Created:
payloadStoreOptions.extensions.push(event.extension)
payloadOptions.extensions.push(event.extension)
// const cartUrl = await buildCartURLIfNeeded([evnet.extension], storeFqdn, checkoutCartUrl)
if (!payloadOptions.checkoutCartUrl) {
// eslint-disable-next-line no-await-in-loop
const cartUrl = await buildCartURLIfNeeded(
payloadOptions.extensions,
payloadOptions.storeFqdn,
payloadOptions.checkoutCartUrl,
)
// eslint-disable-next-line require-atomic-updates
payloadOptions.checkoutCartUrl = cartUrl
}

// eslint-disable-next-line no-await-in-loop
await payloadStore.addExtension(event.extension, bundlePath)
break
case EventType.Updated:
// eslint-disable-next-line no-await-in-loop
await payloadStore.updateExtension(event.extension, options, bundlePath, {status})
await payloadStore.updateExtension(event.extension, payloadOptions, bundlePath, {status})
break
case EventType.Deleted:
payloadStoreOptions.extensions = payloadStoreOptions.extensions.filter(
(ext) => ext.devUUID !== event.extension.devUUID,
)
payloadOptions.extensions = payloadOptions.extensions.filter((ext) => ext.devUUID !== event.extension.devUUID)

// eslint-disable-next-line no-await-in-loop
await payloadStore.deleteExtension(event.extension)
break
}
}
}

options.appWatcher.onEvent(eventHandler).onStart(eventHandler)
payloadOptions.appWatcher.onEvent(eventHandler).onStart(eventHandler)

options.signal.addEventListener('abort', () => {
payloadOptions.signal.addEventListener('abort', () => {
outputDebug('Closing the UI extensions dev server...')
websocketConnection.close()
httpServer.close()
Expand Down

0 comments on commit 8b25260

Please sign in to comment.