@shopify/shop-minis-react 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/index4.js +2 -2
- package/dist/_virtual/index5.js +3 -2
- package/dist/_virtual/index5.js.map +1 -1
- package/dist/_virtual/index6.js +2 -2
- package/dist/_virtual/index7.js +2 -2
- package/dist/_virtual/index8.js +2 -3
- package/dist/_virtual/index8.js.map +1 -1
- package/dist/hooks/navigation/useDeeplink.js +9 -9
- package/dist/hooks/navigation/useDeeplink.js.map +1 -1
- package/dist/mocks.js +1 -0
- package/dist/mocks.js.map +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/@radix-ui_react-use-is-hydrated@0.1.0_@types_react@19.1.6_react@19.1.0/node_modules/@radix-ui/react-use-is-hydrated/dist/index.js +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/@videojs_xhr@2.7.0/node_modules/@videojs/xhr/lib/index.js +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/color-string@1.9.1/node_modules/color-string/index.js +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/mpd-parser@1.3.1/node_modules/mpd-parser/dist/mpd-parser.es.js +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/querystringify@2.2.0/node_modules/querystringify/index.js +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/simple-swizzle@0.2.2/node_modules/simple-swizzle/index.js +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/use-sync-external-store@1.5.0_react@19.1.0/node_modules/use-sync-external-store/shim/index.js +1 -1
- package/eslint/README.md +201 -0
- package/eslint/config.cjs +32 -0
- package/eslint/index.cjs +17 -0
- package/eslint/rules/no-internal-imports.cjs +43 -0
- package/eslint/rules/prefer-sdk-components.cjs +153 -0
- package/eslint/rules/validate-manifest.cjs +607 -0
- package/generated-hook-maps/hook-actions-map.json +130 -0
- package/generated-hook-maps/hook-scopes-map.json +48 -0
- package/package.json +10 -4
- package/src/components/commerce/product-link.test.tsx +1 -0
- package/src/hooks/navigation/useDeeplink.test.ts +429 -0
- package/src/hooks/navigation/useDeeplink.ts +6 -3
- package/src/mocks.ts +1 -0
- package/src/test-utils.tsx +1 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESLint rule to prefer SDK components over native HTML elements
|
|
3
|
+
* @fileoverview Enforce using Shop Minis SDK components instead of native HTML
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
meta: {
|
|
8
|
+
type: 'suggestion',
|
|
9
|
+
docs: {
|
|
10
|
+
description:
|
|
11
|
+
'Prefer Shop Minis SDK components over native HTML elements for better functionality and styling',
|
|
12
|
+
category: 'Best Practices',
|
|
13
|
+
recommended: true,
|
|
14
|
+
},
|
|
15
|
+
fixable: 'code',
|
|
16
|
+
messages: {
|
|
17
|
+
preferSdkComponent:
|
|
18
|
+
'Use <{{sdkComponent}}> from @shopify/shop-minis-react instead of <{{nativeElement}}>. The SDK component provides optimized performance, consistent styling, and additional features.',
|
|
19
|
+
},
|
|
20
|
+
schema: [
|
|
21
|
+
{
|
|
22
|
+
type: 'object',
|
|
23
|
+
properties: {
|
|
24
|
+
components: {
|
|
25
|
+
type: 'object',
|
|
26
|
+
description: 'Map of native elements to SDK components',
|
|
27
|
+
additionalProperties: {
|
|
28
|
+
type: 'string',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
additionalProperties: false,
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
create(context) {
|
|
38
|
+
// Default component mappings
|
|
39
|
+
const defaultComponents = {
|
|
40
|
+
img: 'Image',
|
|
41
|
+
button: 'Button',
|
|
42
|
+
label: 'Label',
|
|
43
|
+
// Future additions will go here:
|
|
44
|
+
// input: 'Input',
|
|
45
|
+
// a: 'Link',
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Get user configuration or use defaults
|
|
49
|
+
const options = context.options[0] || {}
|
|
50
|
+
const componentMap = {
|
|
51
|
+
...defaultComponents,
|
|
52
|
+
...(options.components || {}),
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// eslint-disable-next-line @shopify/prefer-module-scope-constants
|
|
56
|
+
const SDK_PACKAGE = '@shopify/shop-minis-react'
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
JSXOpeningElement(node) {
|
|
60
|
+
const elementName = node.name.name
|
|
61
|
+
|
|
62
|
+
// Check if this is a native element we want to replace
|
|
63
|
+
if (componentMap[elementName]) {
|
|
64
|
+
const sdkComponent = componentMap[elementName]
|
|
65
|
+
|
|
66
|
+
context.report({
|
|
67
|
+
node,
|
|
68
|
+
messageId: 'preferSdkComponent',
|
|
69
|
+
data: {
|
|
70
|
+
nativeElement: elementName,
|
|
71
|
+
sdkComponent,
|
|
72
|
+
},
|
|
73
|
+
fix(fixer) {
|
|
74
|
+
const sourceCode = context.getSourceCode()
|
|
75
|
+
const openingElement = node
|
|
76
|
+
const jsxElement = node.parent
|
|
77
|
+
|
|
78
|
+
// Get the closing element if it exists
|
|
79
|
+
const closingElement = jsxElement.closingElement
|
|
80
|
+
|
|
81
|
+
const fixes = []
|
|
82
|
+
|
|
83
|
+
// Fix opening tag
|
|
84
|
+
const openingTagStart = openingElement.name.range[0]
|
|
85
|
+
const openingTagEnd = openingElement.name.range[1]
|
|
86
|
+
fixes.push(
|
|
87
|
+
fixer.replaceTextRange(
|
|
88
|
+
[openingTagStart, openingTagEnd],
|
|
89
|
+
sdkComponent
|
|
90
|
+
)
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
// Fix closing tag if it exists (not self-closing)
|
|
94
|
+
if (closingElement) {
|
|
95
|
+
const closingTagStart = closingElement.name.range[0]
|
|
96
|
+
const closingTagEnd = closingElement.name.range[1]
|
|
97
|
+
fixes.push(
|
|
98
|
+
fixer.replaceTextRange(
|
|
99
|
+
[closingTagStart, closingTagEnd],
|
|
100
|
+
sdkComponent
|
|
101
|
+
)
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Add import if it doesn't exist
|
|
106
|
+
const program = sourceCode.ast
|
|
107
|
+
const imports = program.body.filter(
|
|
108
|
+
importNode => importNode.type === 'ImportDeclaration'
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
// Check if we already import from the SDK
|
|
112
|
+
const sdkImport = imports.find(
|
|
113
|
+
importNode => importNode.source.value === SDK_PACKAGE
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
if (sdkImport) {
|
|
117
|
+
// Check if this component is already imported
|
|
118
|
+
const hasComponent = sdkImport.specifiers.some(
|
|
119
|
+
spec =>
|
|
120
|
+
spec.type === 'ImportSpecifier' &&
|
|
121
|
+
spec.imported.name === sdkComponent
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
if (!hasComponent) {
|
|
125
|
+
// Add component to existing import
|
|
126
|
+
const lastSpecifier =
|
|
127
|
+
sdkImport.specifiers[sdkImport.specifiers.length - 1]
|
|
128
|
+
fixes.push(
|
|
129
|
+
fixer.insertTextAfter(lastSpecifier, `, ${sdkComponent}`)
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
} else {
|
|
133
|
+
// Add new import statement
|
|
134
|
+
const firstNode = program.body[0]
|
|
135
|
+
const importStatement = `import {${sdkComponent}} from '${SDK_PACKAGE}'\n`
|
|
136
|
+
|
|
137
|
+
if (firstNode) {
|
|
138
|
+
fixes.push(fixer.insertTextBefore(firstNode, importStatement))
|
|
139
|
+
} else {
|
|
140
|
+
fixes.push(
|
|
141
|
+
fixer.insertTextAfterRange([0, 0], importStatement)
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return fixes
|
|
147
|
+
},
|
|
148
|
+
})
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
}
|