Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@ vi.mock('@shopify/cli-kit/node/fs')

describe('hosted_app_home', () => {
describe('transform', () => {
test('should return the transformed object with static_root', () => {
test('should return the transformed object preserving admin nesting', () => {
const object = {
static_root: 'public',
admin: {static_root: 'public'},
}
const appConfigSpec = spec

const result = appConfigSpec.transformLocalToRemote!(object, placeholderAppConfiguration)

expect(result).toMatchObject({
static_root: 'public',
admin: {static_root: 'public'},
})
})

test('should return empty object when static_root is not provided', () => {
test('should return empty object when admin.static_root is not provided', () => {
const object = {}
const appConfigSpec = spec

Expand All @@ -31,16 +31,16 @@ describe('hosted_app_home', () => {
})

describe('reverseTransform', () => {
test('should return the reversed transformed object with static_root', () => {
test('should return the reversed transformed object preserving admin nesting', () => {
const object = {
static_root: 'public',
admin: {static_root: 'public'},
}
const appConfigSpec = spec

const result = appConfigSpec.transformRemoteToLocal!(object)

expect(result).toMatchObject({
static_root: 'public',
admin: {static_root: 'public'},
})
})

Expand All @@ -57,7 +57,7 @@ describe('hosted_app_home', () => {
describe('copyStaticAssets', () => {
test('should copy static assets from source to output directory', async () => {
vi.mocked(copyDirectoryContents).mockResolvedValue(undefined)
const config = {static_root: 'public'}
const config = {admin: {static_root: 'public'}}
const directory = '/app/root'
const outputPath = '/output/dist/bundle.js'

Expand All @@ -66,7 +66,7 @@ describe('hosted_app_home', () => {
expect(copyDirectoryContents).toHaveBeenCalledWith('/app/root/public', '/output/dist')
})

test('should not copy assets when static_root is not provided', async () => {
test('should not copy assets when admin.static_root is not provided', async () => {
const config = {}
const directory = '/app/root'
const outputPath = '/output/dist/bundle.js'
Expand All @@ -78,7 +78,7 @@ describe('hosted_app_home', () => {

test('should throw error when copy fails', async () => {
vi.mocked(copyDirectoryContents).mockRejectedValue(new Error('Permission denied'))
const config = {static_root: 'public'}
const config = {admin: {static_root: 'public'}}
const directory = '/app/root'
const outputPath = '/output/dist/bundle.js'

Expand All @@ -96,7 +96,7 @@ describe('hosted_app_home', () => {

describe('identifier', () => {
test('should have correct identifier', () => {
expect(spec.identifier).toBe('hosted_app_home')
expect(spec.identifier).toBe('admin')
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,28 @@ import {dirname, joinPath} from '@shopify/cli-kit/node/path'
import {zod} from '@shopify/cli-kit/node/schema'

const HostedAppHomeSchema = BaseSchemaWithoutHandle.extend({
static_root: zod.string().optional(),
admin: zod
.object({
static_root: zod.string().optional(),
})
.optional(),
})

const HostedAppHomeTransformConfig: TransformationConfig = {
static_root: 'static_root',
admin: 'admin',
}

export const HostedAppHomeSpecIdentifier = 'hosted_app_home'
export const HostedAppHomeSpecIdentifier = 'admin'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Identifier renamed to admin without alias/back-compat handling

The config extension spec identifier was changed from hosted_app_home to admin (export const HostedAppHomeSpecIdentifier = 'admin'). This identifier is used to match/route config modules (e.g., included in CONFIG_EXTENSION_IDS, used in spec list sorting). If existing projects/platform still send/expect hosted_app_home, the CLI may not recognize the module, may fail schema validation, or may fail to load/copy assets. This is high-risk because it can break builds/deploys for users on older config versions.


const hostedAppHomeSpec = createConfigExtensionSpecification({
identifier: HostedAppHomeSpecIdentifier,
buildConfig: {mode: 'hosted_app_home'} as const,
schema: HostedAppHomeSchema,
transformConfig: HostedAppHomeTransformConfig,
copyStaticAssets: async (config, directory, outputPath) => {
if (!config.static_root) return
const sourceDir = joinPath(directory, config.static_root)
const staticRoot = config.admin?.static_root
if (!staticRoot) return
const sourceDir = joinPath(directory, staticRoot)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Schema changed to admin.static_root without migration/fallback from legacy static_root

The schema changed from top-level static_root to a nested optional object (admin: zod.object({ static_root: zod.string().optional() }).optional()), and asset copying now reads config.admin?.static_root. Existing configs that still set static_root: "public" at the top level will result in no assets being copied (silent failure), which can break runtime behavior without obvious errors.

const outputDir = dirname(outputPath)

return copyDirectoryContents(sourceDir, outputDir).catch((error) => {
Expand Down