Skip to content

Commit 04b045f

Browse files
authored
Merge pull request #5276 from Shopify/Drive_DCDD_from_server_specification
Drive DCDD from server specifications
2 parents 517f04e + 7be6815 commit 04b045f

File tree

8 files changed

+26
-57
lines changed

8 files changed

+26
-57
lines changed

packages/app/src/cli/models/app/app.test-data.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,23 @@ const testRemoteSpecifications: RemoteSpecification[] = [
966966
'{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","additionalProperties":false,"properties":{"pattern":{"type":"string"},"name":{"type":"string"},"localization":{"type":"object","properties":{"marketing_channel":{"type":"string"}},"required":["marketing_channel"]}},"required":["pattern","localization"]}',
967967
},
968968
},
969+
{
970+
name: 'Remote Extension With Schema, Without local spec, config-style management',
971+
externalName: 'Extension Test 4',
972+
identifier: 'remote_only_extension_schema_config_style',
973+
externalIdentifier: 'remote_only_extension_schema_config_style_external',
974+
gated: false,
975+
experience: 'configuration',
976+
options: {
977+
managementExperience: 'cli',
978+
registrationLimit: 1,
979+
uidIsClientProvided: false,
980+
},
981+
validationSchema: {
982+
jsonSchema:
983+
'{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","additionalProperties":false,"properties":{"pattern":{"type":"string"},"name":{"type":"string"}},"required":["pattern"]}',
984+
},
985+
},
969986
]
970987

971988
const productSubscriptionUIExtensionTemplate: ExtensionTemplate = {

packages/app/src/cli/models/app/app.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ export type SchemaForConfig<TConfig extends {path: string}> = ZodObjectOf<Omit<T
131131

132132
export function getAppVersionedSchema(
133133
specs: ExtensionSpecification[],
134-
allowDynamicallySpecifiedConfigs = false,
134+
allowDynamicallySpecifiedConfigs = true,
135135
): ZodObjectOf<Omit<CurrentAppConfiguration, 'path'>> {
136136
// eslint-disable-next-line @typescript-eslint/no-explicit-any
137137
const schema = specs.reduce<any>((schema, spec) => spec.contributeToAppConfigurationSchema(schema), AppSchema)

packages/app/src/cli/models/app/loader.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ import {WebhookSubscriptionSpecIdentifier} from '../extensions/specifications/ap
3333
import {WebhooksSchema} from '../extensions/specifications/app_config_webhook_schemas/webhooks_schema.js'
3434
import {loadLocalExtensionsSpecifications} from '../extensions/load-specifications.js'
3535
import {UIExtensionSchemaType} from '../extensions/specifications/ui_extension.js'
36-
import {deepStrict, zod} from '@shopify/cli-kit/node/schema'
3736
import {fileExists, readFile, glob, findPathUp, fileExistsSync, writeFile, mkdir} from '@shopify/cli-kit/node/fs'
37+
import {zod} from '@shopify/cli-kit/node/schema'
3838
import {readAndParseDotEnv, DotEnvFile} from '@shopify/cli-kit/node/dot-env'
3939
import {
4040
getDependencies,
@@ -916,11 +916,7 @@ async function loadAppConfigurationFromState<
916916
}
917917
}
918918

919-
const parseStrictSchemaEnabled = specifications.length > 0
920919
schemaForConfigurationFile = appSchema
921-
if (parseStrictSchemaEnabled) {
922-
schemaForConfigurationFile = deepStrict(appSchema)
923-
}
924920
}
925921

926922
const configuration = (await parseConfigurationFile(

packages/app/src/cli/models/extensions/load-specifications.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import themeSpec from './specifications/theme.js'
2525
import uiExtensionSpec from './specifications/ui_extension.js'
2626
import webPixelSpec from './specifications/web_pixel_extension.js'
2727
import editorExtensionCollectionSpecification from './specifications/editor_extension_collection.js'
28-
import customDataSpec, {CustomDataSpecIdentifier} from './specifications/custom_data.js'
2928

3029
const SORTED_CONFIGURATION_SPEC_IDENTIFIERS = [
3130
BrandingSpecIdentifier,
@@ -36,7 +35,6 @@ const SORTED_CONFIGURATION_SPEC_IDENTIFIERS = [
3635
AppProxySpecIdentifier,
3736
PosSpecIdentifier,
3837
AppHomeSpecIdentifier,
39-
CustomDataSpecIdentifier,
4038
]
4139

4240
/**
@@ -59,7 +57,6 @@ function loadSpecifications() {
5957
appPrivacyComplienceSpec,
6058
appWebhooksSpec,
6159
appWebhookSubscriptionSpec,
62-
customDataSpec,
6360
]
6461
const moduleSpecs = [
6562
checkoutPostPurchaseSpec,

packages/app/src/cli/models/extensions/specification.ts

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -249,47 +249,6 @@ export function createConfigExtensionSpecification<TConfiguration extends BaseCo
249249
})
250250
}
251251

252-
/**
253-
* Create a zod object schema based on keys, but neutral as to content.
254-
*
255-
* Used for schemas that are supplemented by JSON schema contracts, but need to register top-level keys.
256-
*/
257-
function neutralTopLevelSchema<TKey extends string>(...keys: TKey[]): zod.ZodObject<{[k in TKey]: zod.ZodAny}> {
258-
return zod.object(
259-
Object.fromEntries(
260-
keys.map((key) => {
261-
return [key, zod.any()]
262-
}),
263-
),
264-
) as zod.ZodObject<{[k in TKey]: zod.ZodAny}>
265-
}
266-
267-
/**
268-
* Create a new app config extension spec that uses contract-based validation.
269-
*
270-
* See {@link createConfigExtensionSpecification} for more about app config extensions.
271-
*/
272-
export function createContractBasedConfigModuleSpecification<TKey extends string>(
273-
identifier: string,
274-
...topLevelKeys: TKey[]
275-
): ExtensionSpecification {
276-
const schema = neutralTopLevelSchema(...topLevelKeys)
277-
return createConfigExtensionSpecification({
278-
identifier,
279-
schema,
280-
transformConfig: {
281-
// outgoing config is already scoped to this module and passed directly along
282-
forward(obj) {
283-
return obj
284-
},
285-
// incoming config from the platform is included in app config as-is
286-
reverse(obj) {
287-
return obj
288-
},
289-
},
290-
})
291-
}
292-
293252
export function createContractBasedModuleSpecification<TConfiguration extends BaseConfigType = BaseConfigType>(
294253
identifier: string,
295254
appModuleFeatures?: ExtensionFeature[],

packages/app/src/cli/models/extensions/specifications/custom_data.ts

Lines changed: 0 additions & 7 deletions
This file was deleted.

packages/app/src/cli/services/generate/fetch-extension-specifications.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,19 @@ describe('fetchExtensionSpecifications', () => {
7777
expect.arrayContaining([
7878
expect.objectContaining({
7979
identifier: 'remote_only_extension_schema',
80+
uidStrategy: 'uuid',
8081
}),
8182
expect.objectContaining({
8283
identifier: 'remote_only_extension_schema_with_localization',
84+
uidStrategy: 'uuid',
8385
}),
8486
expect.not.objectContaining({
8587
identifier: 'remote_only_extension_without_schema',
8688
}),
89+
expect.objectContaining({
90+
identifier: 'remote_only_extension_schema_config_style',
91+
uidStrategy: 'single',
92+
}),
8793
]),
8894
)
8995

packages/app/src/cli/services/generate/fetch-extension-specifications.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ async function mergeLocalAndRemoteSpecs(
6969
const normalisedSchema = await normaliseJsonSchema(remoteSpec.validationSchema.jsonSchema)
7070
const hasLocalization = normalisedSchema.properties?.localization !== undefined
7171
localSpec = createContractBasedModuleSpecification(remoteSpec.identifier, hasLocalization ? ['localization'] : [])
72+
localSpec.uidStrategy = remoteSpec.options.uidIsClientProvided ? 'uuid' : 'single'
7273
}
7374
if (!localSpec) return undefined
7475

0 commit comments

Comments
 (0)