Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions packages/app/src/cli/models/app/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,20 +331,22 @@ export async function loadAppFromContext<TModuleSpec extends ExtensionSpecificat

// Build the module registry and merge remote spec values into it so
// descriptors have up-to-date identity data from the platform API.
const moduleRegistry = loadModuleRegistry()
const remoteSpecsForMerge = specifications.map((spec) => ({
name: spec.externalName,
externalName: spec.externalName,
identifier: spec.identifier,
gated: false,
externalIdentifier: spec.externalIdentifier,
experience: spec.experience as 'extension' | 'configuration' | 'deprecated',
managementExperience: 'cli' as const,
registrationLimit: spec.registrationLimit,
uidStrategy: spec.uidStrategy,
surface: spec.surface,
}))
moduleRegistry.mergeRemoteSpecs(remoteSpecsForMerge)
const moduleRegistry = loadModuleRegistry?.() ?? new ModuleRegistry()
if (moduleRegistry.size > 0) {
const remoteSpecsForMerge = specifications.map((spec) => ({
name: spec.externalName,
externalName: spec.externalName,
identifier: spec.identifier,
gated: false,
externalIdentifier: spec.externalIdentifier,
experience: spec.experience as 'extension' | 'configuration' | 'deprecated',
managementExperience: 'cli' as const,
registrationLimit: spec.registrationLimit,
uidStrategy: spec.uidStrategy,
surface: spec.surface,
}))
moduleRegistry.mergeRemoteSpecs(remoteSpecsForMerge)
}

const loadedConfiguration: ConfigurationLoaderResult<CurrentAppConfiguration, TModuleSpec> = {
directory: project.directory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ import themeSpec from './specifications/theme.js'
import uiExtensionSpec from './specifications/ui_extension.js'
import webPixelSpec from './specifications/web_pixel_extension.js'
import editorExtensionCollectionSpecification from './specifications/editor_extension_collection.js'
import channelSpecificationSpec from './specifications/channel.js'
import adminSpecificationSpec from './specifications/admin.js'
import {channelDescriptor} from './specifications/channel_module.js'

const SORTED_CONFIGURATION_SPEC_IDENTIFIERS = [
BrandingSpecIdentifier,
Expand Down Expand Up @@ -59,7 +59,7 @@ export async function loadLocalExtensionsSpecifications(): Promise<ExtensionSpec
*/
export function loadModuleRegistry(): ModuleRegistry {
const registry = new ModuleRegistry()
// Descriptors will be registered here as specs are migrated.
registry.register(channelDescriptor)
return registry
}

Expand Down Expand Up @@ -91,7 +91,6 @@ function loadSpecifications() {
uiExtensionSpec,
webPixelSpec,
editorExtensionCollectionSpecification,
channelSpecificationSpec,
]

return [...configModuleSpecs, ...moduleSpecs] as ExtensionSpecification[]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import {ApplicationModule, ExtensionDeployConfigOptions} from '../application-module.js'
import type {ExtensionFeature, BuildConfig} from '../application-module.js'
import {ClientSteps} from '../../../services/build/client-steps.js'
import {ModuleDescriptor} from '../module-descriptor.js'
import {BaseConfigType, BaseSchema} from '../schemas.js'
import {configWithoutFirstClassFields} from '../specification.js'
import {loadLocalesConfig} from '../../../utilities/extensions/locales-configuration.js'
import {joinPath} from '@shopify/cli-kit/node/path'
import {zod} from '@shopify/cli-kit/node/schema'
import {blocks} from '../../../constants.js'

const SUBDIRECTORY_NAME = 'specifications'
const FILE_EXTENSIONS = ['json', 'toml', 'yaml', 'yml', 'svg']

export const ChannelModuleIdentifier = 'channel_config'

class ChannelModule extends ApplicationModule {
appModuleFeatures(): ExtensionFeature[] {
return []
}

override get buildConfig(): BuildConfig {
return {
mode: 'copy_files',
filePatterns: FILE_EXTENSIONS.map((ext) => joinPath(SUBDIRECTORY_NAME, '**', `*.${ext}`)),
}
}

override get clientSteps(): ClientSteps {
return [
{
lifecycle: 'deploy',
steps: [
{
id: 'copy-files',
name: 'Copy Files',
type: 'include_assets',
config: {
inclusions: [
{
type: 'pattern',
baseDir: SUBDIRECTORY_NAME,
destination: SUBDIRECTORY_NAME,
include: FILE_EXTENSIONS.map((ext) => `**/*.${ext}`),
},
],
},
},
],
},
]
}

override async deployConfig(_options: ExtensionDeployConfigOptions): Promise<Record<string, unknown> | undefined> {
let parsedConfig = configWithoutFirstClassFields(this.configuration)
if (this.appModuleFeatures().includes('localization')) {
const localization = await loadLocalesConfig(this.directory, this.identifier)
parsedConfig = {...parsedConfig, localization}
}
return parsedConfig
}
}

export const channelDescriptor: ModuleDescriptor = {
identifier: ChannelModuleIdentifier,
additionalIdentifiers: [],
externalIdentifier: `${ChannelModuleIdentifier}_external`,
externalName: 'Channel config',
partnersWebIdentifier: ChannelModuleIdentifier,
surface: 'test-surface',
registrationLimit: blocks.extensions.defaultRegistrationLimit,
experience: 'extension',
uidStrategy: 'single',
schema: zod.any({}) as unknown as typeof BaseSchema,
contributeToAppConfigurationSchema: (schema) => schema,
parseConfigurationObject: (configurationObject: object) => {
return {state: 'ok' as const, data: configurationObject as BaseConfigType, errors: undefined}
},
createModule: (options) => new ChannelModule(options),
}
Loading