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
4 changes: 2 additions & 2 deletions packages/app/src/cli/commands/app/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ export default class Build extends AppUnlinkedCommand {
cmd_app_dependency_installation_skipped: flags['skip-dependencies-installation'],
}))

const app = await localAppContext({
const {app, project} = await localAppContext({
directory: flags.path,
userProvidedConfigName: flags.config,
})

await build({app, skipDependenciesInstallation: flags['skip-dependencies-installation'], apiKey: clientId})
await build({app, project, skipDependenciesInstallation: flags['skip-dependencies-installation'], apiKey: clientId})

return {app}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/cli/commands/app/config/use.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default class ConfigUse extends AppUnlinkedCommand {
public async run(): Promise<AppUnlinkedCommandOutput> {
const {flags, args} = await this.parse(ConfigUse)

const app = await localAppContext({
const {app} = await localAppContext({
directory: flags.path,
userProvidedConfigName: args.config,
})
Expand Down
3 changes: 2 additions & 1 deletion packages/app/src/cli/commands/app/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export default class Deploy extends AppLinkedCommand {
}
this.failMissingNonTTYFlags(flags, requiredNonTTYFlags)

const {app, remoteApp, developerPlatformClient, organization} = await linkedAppContext({
const {app, project, remoteApp, developerPlatformClient, organization} = await linkedAppContext({
directory: flags.path,
clientId,
forceRelink: flags.reset,
Expand All @@ -116,6 +116,7 @@ export default class Deploy extends AppLinkedCommand {

const result = await deploy({
app,
project,
remoteApp,
organization,
developerPlatformClient,
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/cli/commands/app/function/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default class FunctionBuild extends AppUnlinkedCommand {
public async run(): Promise<AppUnlinkedCommandOutput> {
const {flags} = await this.parse(FunctionBuild)

const app = await localAppContext({
const {app} = await localAppContext({
directory: flags.path,
userProvidedConfigName: flags.config,
})
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/cli/commands/app/function/info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default class FunctionInfo extends AppUnlinkedCommand {
public async run(): Promise<AppUnlinkedCommandOutput> {
const {flags} = await this.parse(FunctionInfo)

const app = await localAppContext({
const {app} = await localAppContext({
directory: flags.path,
userProvidedConfigName: flags.config,
})
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/cli/commands/app/function/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default class FunctionRun extends AppUnlinkedCommand {

let functionExport = DEFAULT_FUNCTION_EXPORT

const app = await localAppContext({
const {app} = await localAppContext({
directory: flags.path,
userProvidedConfigName: flags.config,
})
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/cli/commands/app/function/typegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default class FunctionTypegen extends AppUnlinkedCommand {
public async run(): Promise<AppUnlinkedCommandOutput> {
const {flags} = await this.parse(FunctionTypegen)

const app = await localAppContext({
const {app} = await localAppContext({
directory: flags.path,
userProvidedConfigName: flags.config,
})
Expand Down
3 changes: 2 additions & 1 deletion packages/app/src/cli/commands/app/generate/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export default class AppGenerateExtension extends AppLinkedCommand {

await checkFolderIsValidApp(flags.path)

const {app, specifications, remoteApp, developerPlatformClient} = await linkedAppContext({
const {app, project, specifications, remoteApp, developerPlatformClient} = await linkedAppContext({
directory: flags.path,
clientId: flags['client-id'],
forceRelink: flags.reset,
Expand All @@ -92,6 +92,7 @@ export default class AppGenerateExtension extends AppLinkedCommand {
template: flags.template,
flavor: flags.flavor,
app,
project,
specifications,
remoteApp,
developerPlatformClient,
Expand Down
4 changes: 2 additions & 2 deletions packages/app/src/cli/commands/app/info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ export default class AppInfo extends AppLinkedCommand {
public async run(): Promise<AppLinkedCommandOutput> {
const {flags} = await this.parse(AppInfo)

const {app, remoteApp, organization, developerPlatformClient} = await linkedAppContext({
const {app, project, remoteApp, organization, developerPlatformClient} = await linkedAppContext({
directory: flags.path,
clientId: flags['client-id'],
forceRelink: flags.reset,
userProvidedConfigName: flags.config,
unsafeReportMode: true,
})
const results = await info(app, remoteApp, organization, {
const results = await info(app, remoteApp, organization, project, {
format: (flags.json ? 'json' : 'text') as Format,
webEnv: flags['web-env'],
configName: flags.config,
Expand Down
40 changes: 32 additions & 8 deletions packages/app/src/cli/models/app/app.test-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,14 @@ import {SchemaDefinitionByTargetQueryVariables} from '../../api/graphql/function
import {SchemaDefinitionByApiTypeQueryVariables} from '../../api/graphql/functions/generated/schema-definition-by-api-type.js'
import {AppHomeSpecIdentifier} from '../extensions/specifications/app_config_app_home.js'
import {AppProxySpecIdentifier} from '../extensions/specifications/app_config_app_proxy.js'
import {ExtensionSpecification, isAppConfigSpecification} from '../extensions/specification.js'
import {ExtensionSpecification} from '../extensions/specification.js'
import {AppLogsOptions} from '../../services/app-logs/utils.js'
import {AppLogsSubscribeMutationVariables} from '../../api/graphql/app-management/generated/app-logs-subscribe.js'
import {Project} from '../project/project.js'
import {Session} from '@shopify/cli-kit/node/session'
import {vi} from 'vitest'
import {joinPath} from '@shopify/cli-kit/node/path'
import {PackageManager} from '@shopify/cli-kit/node/node-package-manager'

export const DEFAULT_CONFIG = {
application_url: 'https://myapp.com',
Expand All @@ -104,9 +106,7 @@ export function testApp(app: Partial<AppInterface> = {}): AppInterface {
name: app.name ?? 'App',
directory: app.directory ?? '/tmp/project',
configPath: app.configPath ?? '/tmp/project/shopify.app.toml',
packageManager: app.packageManager ?? 'yarn',
configuration: app.configuration ?? getConfig(),
nodeDependencies: app.nodeDependencies ?? {},
webs: app.webs ?? [
{
directory: '',
Expand All @@ -117,7 +117,6 @@ export function testApp(app: Partial<AppInterface> = {}): AppInterface {
},
],
modules: app.allExtensions ?? [],
usesWorkspaces: app.usesWorkspaces ?? false,
dotenv: app.dotenv,
errors: app.errors,
specifications: app.specifications ?? [],
Expand All @@ -127,9 +126,6 @@ export function testApp(app: Partial<AppInterface> = {}): AppInterface {
devApplicationURLs: app.devApplicationURLs,
})

if (app.updateDependencies) {
Object.getPrototypeOf(newApp).updateDependencies = app.updateDependencies
}
if (app.extensionsForType) {
Object.getPrototypeOf(newApp).extensionsForType = app.extensionsForType
}
Expand All @@ -155,6 +151,34 @@ export function testAppWithConfig(options?: TestAppWithConfigOptions): AppLinked
return app
}

interface TestProjectOptions {
directory?: string
packageManager?: PackageManager
nodeDependencies?: Record<string, string>
usesWorkspaces?: boolean
}

/**
* Creates a minimal Project mock for testing.
* Use this when a service needs a Project for packageManager, usesWorkspaces, or directory.
*/
export function testProject(options: TestProjectOptions = {}): Project {
return {
directory: options.directory ?? '/tmp/project',
packageManager: options.packageManager ?? 'yarn',
nodeDependencies: options.nodeDependencies ?? {},
usesWorkspaces: options.usesWorkspaces ?? false,
appConfigFiles: [],
extensionConfigFiles: [],
webConfigFiles: [],
dotenvFiles: new Map(),
hiddenConfigRaw: {},
appConfigByName: () => undefined,
appConfigByClientId: () => undefined,
defaultAppConfig: undefined,
} as unknown as Project
}

export function getWebhookConfig(webhookConfigOverrides?: WebhooksConfig): CurrentAppConfiguration {
return {
...DEFAULT_CONFIG,
Expand Down Expand Up @@ -1526,5 +1550,5 @@ export async function buildVersionedAppSchema() {
}

export async function configurationSpecifications() {
return (await loadLocalExtensionsSpecifications()).filter(isAppConfigSpecification)
return (await loadLocalExtensionsSpecifications()).filter((spec) => spec.uidStrategy === 'single')
}
23 changes: 1 addition & 22 deletions packages/app/src/cli/models/app/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {WebhookSubscription} from '../extensions/specifications/types/app_config
import {joinPath} from '@shopify/cli-kit/node/path'
import {ZodObjectOf, zod} from '@shopify/cli-kit/node/schema'
import {DotEnvFile} from '@shopify/cli-kit/node/dot-env'
import {getDependencies, PackageManager, readAndParsePackageJson} from '@shopify/cli-kit/node/node-package-manager'
import {readAndParsePackageJson} from '@shopify/cli-kit/node/node-package-manager'
import {
fileExistsSync,
fileRealPath,
Expand Down Expand Up @@ -222,11 +222,8 @@ export interface AppInterface<
TModuleSpec extends ExtensionSpecification = ExtensionSpecification,
> extends AppConfigurationInterface<TConfig, TModuleSpec> {
name: string
packageManager: PackageManager
idEnvironmentVariableName: 'SHOPIFY_API_KEY'
nodeDependencies: {[key: string]: string}
webs: Web[]
usesWorkspaces: boolean
dotenv?: DotEnvFile
allExtensions: ExtensionInstance[]
realExtensions: ExtensionInstance[]
Expand All @@ -236,7 +233,6 @@ export interface AppInterface<
hiddenConfig: AppHiddenConfig
includeConfigOnDeploy: boolean | undefined
readonly devApplicationURLs?: ApplicationURLs
updateDependencies: () => Promise<void>
extensionsForType: (spec: {identifier: string; externalIdentifier: string}) => ExtensionInstance[]
updateExtensionUUIDS: (uuids: {[key: string]: string}) => void
preDeployValidation: () => Promise<void>
Expand Down Expand Up @@ -264,11 +260,8 @@ type AppConstructor<
TModuleSpec extends ExtensionSpecification = ExtensionSpecification,
> = AppConfigurationInterface<TConfig, TModuleSpec> & {
name: string
packageManager: PackageManager
nodeDependencies: {[key: string]: string}
webs: Web[]
modules: ExtensionInstance[]
usesWorkspaces: boolean
dotenv?: DotEnvFile
errors?: AppErrors
specifications: ExtensionSpecification[]
Expand All @@ -285,11 +278,8 @@ export class App<
idEnvironmentVariableName: 'SHOPIFY_API_KEY' = 'SHOPIFY_API_KEY' as const
directory: string
configPath: string
packageManager: PackageManager
configuration: TConfig
nodeDependencies: {[key: string]: string}
webs: Web[]
usesWorkspaces: boolean
dotenv?: DotEnvFile
errors?: AppErrors
specifications: TModuleSpec[]
Expand All @@ -303,12 +293,9 @@ export class App<
name,
directory,
configPath,
packageManager,
configuration,
nodeDependencies,
webs,
modules,
usesWorkspaces,
dotenv,
errors,
specifications,
Expand All @@ -320,14 +307,11 @@ export class App<
this.name = name
this.directory = directory
this.configPath = configPath
this.packageManager = packageManager
this.configuration = configuration
this.nodeDependencies = nodeDependencies
this.webs = webs
this.dotenv = dotenv
this.realExtensions = modules
this.errors = errors
this.usesWorkspaces = usesWorkspaces
this.specifications = specifications
this.configSchema = configSchema ?? AppSchema
this.remoteFlags = remoteFlags ?? []
Expand Down Expand Up @@ -381,11 +365,6 @@ export class App<
}
}

async updateDependencies() {
const nodeDependencies = await getDependencies(joinPath(this.directory, 'package.json'))
this.nodeDependencies = nodeDependencies
}

get hiddenConfig() {
return this._hiddenConfig
}
Expand Down
Loading
Loading