Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ui_extension to support Unified config #2349

Merged
merged 31 commits into from
Jul 17, 2023
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
ee7fb52
New ui extension union schema
isaacroldan Jul 5, 2023
137c32b
Extract settings schema
isaacroldan Jul 5, 2023
f5fa23f
Improve transform
isaacroldan Jul 5, 2023
4731b47
Remove handle
isaacroldan Jul 5, 2023
c8871a8
Update schema to override global configs
isaacroldan Jul 5, 2023
884bc52
Update schema
isaacroldan Jul 6, 2023
9671be2
Merge branch 'main' into new-ui-extension-schema
isaacroldan Jul 11, 2023
25548b6
Merge branch 'main' into new-ui-extension-schema
isaacroldan Jul 12, 2023
f236c79
Simplify types in ui_extension
isaacroldan Jul 12, 2023
c9ac3ec
Remove targeting from BaseSchema
isaacroldan Jul 12, 2023
51e46e1
Simplified ui_extension schema
isaacroldan Jul 12, 2023
e7d59af
Updated ui_extension template
isaacroldan Jul 12, 2023
3b86b0f
Merge branch 'main' into new-ui-extension-schema
isaacroldan Jul 12, 2023
f62639d
Fix handle in template
isaacroldan Jul 12, 2023
a82f4b2
Clean up
isaacroldan Jul 12, 2023
3cf2679
Add test for targeting schema
isaacroldan Jul 12, 2023
6f05a27
Add new test to validate targeting presence
isaacroldan Jul 12, 2023
032c62b
Rever unnecessary changes
isaacroldan Jul 12, 2023
e0133a1
remvoe required from template
isaacroldan Jul 12, 2023
a32e7ef
Move handle to extension config
isaacroldan Jul 12, 2023
64e52d8
Merge branch 'main' into new-ui-extension-schema
isaacroldan Jul 13, 2023
5dd591b
Make handle mandatory for ui_extensions
isaacroldan Jul 13, 2023
c862b4b
Unified schema only parses specific fields
isaacroldan Jul 13, 2023
06f4510
Simplify unifiedSchema
isaacroldan Jul 13, 2023
ccc028e
Make handle optional for legacy ui_extensions
isaacroldan Jul 14, 2023
5f1acc9
Use BaseSchema for ui_extensions
isaacroldan Jul 14, 2023
85358ca
Merge branch 'main' into new-ui-extension-schema
isaacroldan Jul 14, 2023
abe8994
Merge branch 'main' into new-ui-extension-schema
isaacroldan Jul 14, 2023
8eaf31d
Show error if type is missing
isaacroldan Jul 14, 2023
917a941
Fix id-matching tests
isaacroldan Jul 14, 2023
cadea7a
Update tests with the new localIdentifier
isaacroldan Jul 17, 2023
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 @@ -6,6 +6,7 @@ import {describe, expect, test, vi} from 'vitest'
import {err, ok} from '@shopify/cli-kit/node/result'
import {inTemporaryDirectory, mkdir, touchFile} from '@shopify/cli-kit/node/fs'
import {joinPath} from '@shopify/cli-kit/node/path'
import {zod} from '@shopify/cli-kit/node/schema'

describe('ui_extension', async () => {
interface GetUIExtensionProps {
Expand Down Expand Up @@ -65,6 +66,70 @@ describe('ui_extension', async () => {
})
})

test('targeting object is transformed into extension_points. metafields are inherited', async () => {
const allSpecs = await loadFSExtensionsSpecifications()
const specification = allSpecs.find((spec) => spec.identifier === 'ui_extension')!
const configuration = {
targeting: [
{
target: 'EXTENSION::POINT::A',
module: './src/ExtensionPointA.js',
},
],
api_version: '2023-01' as const,
name: 'UI Extension',
type: 'ui_extension',
metafields: [{namespace: 'test', key: 'test'}],
Copy link
Member

Choose a reason for hiding this comment

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

Can we make sure that this stripped out of the payload when deploying/dev? We don't actually support this config at the extension level in the backend or front end. It's only supported in the TOML for convenience

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not included in the deployConfig for sure, not sure about how we build the dev payload, but I didn't change that 🤔

Copy link
Member

Choose a reason for hiding this comment

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

Ok, I will take care of that on the PR I'm working on to update the dev payload to get rid of label on extension points

capabilities: {
block_progress: false,
network_access: false,
api_access: false,
},
settings: {},
}

// When
const got = specification.schema.parse(configuration)

// Then
expect(got.extension_points).toStrictEqual([
{
target: 'EXTENSION::POINT::A',
module: './src/ExtensionPointA.js',
metafields: [{namespace: 'test', key: 'test'}],
},
])
})

test('returns error if there is no targeting or extension_points', async () => {
// Given
const allSpecs = await loadFSExtensionsSpecifications()
const specification = allSpecs.find((spec) => spec.identifier === 'ui_extension')!
const configuration = {
api_version: '2023-01' as const,
name: 'UI Extension',
type: 'ui_extension',
metafields: [{namespace: 'test', key: 'test'}],
capabilities: {
block_progress: false,
network_access: false,
api_access: false,
},
settings: {},
}

// When/Then
expect(() => specification.schema.parse(configuration)).toThrowError(
new zod.ZodError([
{
code: zod.ZodIssueCode.custom,
message: 'No extension targets defined, add a `targeting` field to your configuration',
path: [],
},
]),
)
})

test('returns err(message) when extensionPoints[n].module does not map to a file', async () => {
await inTemporaryDirectory(async (tmpDir) => {
// Given
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,34 @@ import {NewExtensionPointSchemaType, NewExtensionPointsSchema, BaseSchema} from
import {loadLocalesConfig} from '../../../utilities/extensions/locales-configuration.js'
import {configurationFileNames} from '../../../constants.js'
import {getExtensionPointTargetSurface} from '../../../services/dev/extension/utilities.js'
import {zod} from '@shopify/cli-kit/node/schema'
import {err, ok, Result} from '@shopify/cli-kit/node/result'
import {fileExists} from '@shopify/cli-kit/node/fs'
import {joinPath} from '@shopify/cli-kit/node/path'
import {outputContent, outputToken} from '@shopify/cli-kit/node/output'

const dependency = '@shopify/checkout-ui-extensions'

const validatePoints = (config: {extension_points?: unknown[]; targeting?: unknown[]}) => {
return config.extension_points !== undefined || config.targeting !== undefined
}

const missingExtensionPointsMessage = 'No extension targets defined, add a `targeting` field to your configuration'

const UIExtensionSchema = BaseSchema.extend({
settings: zod
.object({
fields: zod.any().optional(),
})
.optional(),
extension_points: NewExtensionPointsSchema,
extension_points: NewExtensionPointsSchema.optional(),
targeting: NewExtensionPointsSchema.optional(),
})
.refine((config) => validatePoints(config), missingExtensionPointsMessage)
.transform((config) => {
const extensionPoints = (config.targeting ?? config.extension_points ?? []).map((targeting) => {
return {
target: targeting.target,
module: targeting.module,
metafields: targeting.metafields ?? config.metafields ?? [],
}
})
return {...config, extension_points: extensionPoints}
})

const spec = createExtensionSpecification({
identifier: 'ui_extension',
Expand Down Expand Up @@ -81,6 +93,10 @@ async function validateUIExtensionPointConfig(
const uniqueTargets: string[] = []
const duplicateTargets: string[] = []

if (!extensionPoints || extensionPoints.length === 0) {
return err(missingExtensionPointsMessage)
}

for await (const {module, target} of extensionPoints) {
const fullPath = joinPath(directory, module)
const exists = await fileExists(fullPath)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
name = "{{ name }}"
type = "ui_extension"
api_version = "2022-10"

[capabilities]
api_access = true
network_access = true
block_progress = true

[[extension_points]]
target = "Checkout::Dynamic::Render"
[[extensions]]
Copy link
Member

Choose a reason for hiding this comment

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

I think we should just delete this template. We should be creating a new version of the Checkout extension in the template repo and expose it through Partner's instead of having it be tied to the CLI.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is it safe If I remove it in this PR then?

Copy link
Member

Choose a reason for hiding this comment

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

I think so? No one should be using this publicly for Checkout but we better ask @jamesvidler and @kumar303. They should be working on a new template soon for Checkout.

Bundles is using it but @kmdavis is working on a new template. We just need to merge the new template before the next release of the CLI goes out.

Copy link
Contributor

Choose a reason for hiding this comment

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

No one is using this template publicly, yet. Though we have used to test things. Where would the new template be stored?

Copy link
Member

Choose a reason for hiding this comment

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

type = "ui_extension"
handle = "{{ handle }}"

[[extensions.targeting]]
module = "./src/CheckoutDynamicRender.{{ srcFileExtension }}"
target = "Checkout::Dynamic::Render"

# [[extension_points.metafields]]
# [[extensions.metafields]]
# namespace = "my-namespace"
# key = "my-key"

Expand Down
1 change: 0 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.