@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.
Files changed (32) hide show
  1. package/dist/_virtual/index4.js +2 -2
  2. package/dist/_virtual/index5.js +3 -2
  3. package/dist/_virtual/index5.js.map +1 -1
  4. package/dist/_virtual/index6.js +2 -2
  5. package/dist/_virtual/index7.js +2 -2
  6. package/dist/_virtual/index8.js +2 -3
  7. package/dist/_virtual/index8.js.map +1 -1
  8. package/dist/hooks/navigation/useDeeplink.js +9 -9
  9. package/dist/hooks/navigation/useDeeplink.js.map +1 -1
  10. package/dist/mocks.js +1 -0
  11. package/dist/mocks.js.map +1 -1
  12. 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
  13. package/dist/shop-minis-react/node_modules/.pnpm/@videojs_xhr@2.7.0/node_modules/@videojs/xhr/lib/index.js +1 -1
  14. package/dist/shop-minis-react/node_modules/.pnpm/color-string@1.9.1/node_modules/color-string/index.js +1 -1
  15. package/dist/shop-minis-react/node_modules/.pnpm/mpd-parser@1.3.1/node_modules/mpd-parser/dist/mpd-parser.es.js +1 -1
  16. package/dist/shop-minis-react/node_modules/.pnpm/querystringify@2.2.0/node_modules/querystringify/index.js +1 -1
  17. package/dist/shop-minis-react/node_modules/.pnpm/simple-swizzle@0.2.2/node_modules/simple-swizzle/index.js +1 -1
  18. 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
  19. package/eslint/README.md +201 -0
  20. package/eslint/config.cjs +32 -0
  21. package/eslint/index.cjs +17 -0
  22. package/eslint/rules/no-internal-imports.cjs +43 -0
  23. package/eslint/rules/prefer-sdk-components.cjs +153 -0
  24. package/eslint/rules/validate-manifest.cjs +607 -0
  25. package/generated-hook-maps/hook-actions-map.json +130 -0
  26. package/generated-hook-maps/hook-scopes-map.json +48 -0
  27. package/package.json +10 -4
  28. package/src/components/commerce/product-link.test.tsx +1 -0
  29. package/src/hooks/navigation/useDeeplink.test.ts +429 -0
  30. package/src/hooks/navigation/useDeeplink.ts +6 -3
  31. package/src/mocks.ts +1 -0
  32. package/src/test-utils.tsx +1 -0
@@ -1,5 +1,5 @@
1
- var r = {};
1
+ var e = { exports: {} };
2
2
  export {
3
- r as __exports
3
+ e as __module
4
4
  };
5
5
  //# sourceMappingURL=index4.js.map
@@ -1,5 +1,6 @@
1
- var e = { exports: {} };
1
+ import { __require as r } from "../shop-minis-react/node_modules/.pnpm/@xmldom_xmldom@0.8.10/node_modules/@xmldom/xmldom/lib/index.js";
2
+ var i = r();
2
3
  export {
3
- e as __module
4
+ i as l
4
5
  };
5
6
  //# sourceMappingURL=index5.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index5.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
1
+ {"version":3,"file":"index5.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
@@ -1,6 +1,6 @@
1
- import { __require as r } from "../shop-minis-react/node_modules/.pnpm/@xmldom_xmldom@0.8.10/node_modules/@xmldom/xmldom/lib/index.js";
1
+ import { __require as r } from "../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";
2
2
  var i = r();
3
3
  export {
4
- i as l
4
+ i as s
5
5
  };
6
6
  //# sourceMappingURL=index6.js.map
@@ -1,5 +1,5 @@
1
- var o = { exports: {} };
1
+ var r = {};
2
2
  export {
3
- o as __module
3
+ r as __exports
4
4
  };
5
5
  //# sourceMappingURL=index7.js.map
@@ -1,6 +1,5 @@
1
- import { __require as r } from "../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";
2
- var i = r();
1
+ var o = { exports: {} };
3
2
  export {
4
- i as s
3
+ o as __module
5
4
  };
6
5
  //# sourceMappingURL=index8.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index8.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
1
+ {"version":3,"file":"index8.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -1,23 +1,23 @@
1
- import { useMemo as e } from "react";
2
- import { parseUrl as s } from "../../utils/parseUrl.js";
3
- const t = () => {
4
- const { initialUrl: r } = window.minisParams;
5
- return e(() => {
1
+ import { useMemo as i } from "react";
2
+ import { parseUrl as n } from "../../utils/parseUrl.js";
3
+ const m = () => {
4
+ const { initialUrl: r, handle: e } = window.minisParams;
5
+ return i(() => {
6
6
  if (!r)
7
7
  return {
8
8
  path: void 0,
9
9
  queryParams: void 0,
10
10
  hash: void 0
11
11
  };
12
- const a = s(r);
12
+ const a = n(r), t = `/mini/${e}`;
13
13
  return {
14
- path: a.pathname,
14
+ path: a.pathname.startsWith(t) ? a.pathname.replace(t, "") : a.pathname,
15
15
  queryParams: a.query,
16
16
  hash: a.hash
17
17
  };
18
- }, [r]);
18
+ }, [e, r]);
19
19
  };
20
20
  export {
21
- t as useDeeplink
21
+ m as useDeeplink
22
22
  };
23
23
  //# sourceMappingURL=useDeeplink.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useDeeplink.js","sources":["../../../src/hooks/navigation/useDeeplink.ts"],"sourcesContent":["import {useMemo} from 'react'\n\nimport {parseUrl} from '../../utils/parseUrl'\n\ninterface UseDeeplinkReturnType {\n /**\n * The path of the deeplink.\n */\n path?: string\n /**\n * The query parameters of the deeplink.\n */\n queryParams?: {[key: string]: string | undefined}\n /**\n * The hash of the deeplink.\n */\n hash?: string\n}\n\nexport const useDeeplink = (): UseDeeplinkReturnType => {\n const {initialUrl} = window.minisParams\n\n return useMemo(() => {\n if (!initialUrl) {\n return {\n path: undefined,\n queryParams: undefined,\n hash: undefined,\n }\n }\n\n const parsedUrl = parseUrl(initialUrl)\n\n return {\n path: parsedUrl.pathname,\n queryParams: parsedUrl.query,\n hash: parsedUrl.hash,\n }\n }, [initialUrl])\n}\n"],"names":["useDeeplink","initialUrl","useMemo","parsedUrl","parseUrl"],"mappings":";;AAmBO,MAAMA,IAAc,MAA6B;AAChD,QAAA,EAAC,YAAAC,MAAc,OAAO;AAE5B,SAAOC,EAAQ,MAAM;AACnB,QAAI,CAACD;AACI,aAAA;AAAA,QACL,MAAM;AAAA,QACN,aAAa;AAAA,QACb,MAAM;AAAA,MACR;AAGI,UAAAE,IAAYC,EAASH,CAAU;AAE9B,WAAA;AAAA,MACL,MAAME,EAAU;AAAA,MAChB,aAAaA,EAAU;AAAA,MACvB,MAAMA,EAAU;AAAA,IAClB;AAAA,EAAA,GACC,CAACF,CAAU,CAAC;AACjB;"}
1
+ {"version":3,"file":"useDeeplink.js","sources":["../../../src/hooks/navigation/useDeeplink.ts"],"sourcesContent":["import {useMemo} from 'react'\n\nimport {parseUrl} from '../../utils/parseUrl'\n\ninterface UseDeeplinkReturnType {\n /**\n * The path of the deeplink.\n */\n path?: string\n /**\n * The query parameters of the deeplink.\n */\n queryParams?: {[key: string]: string | undefined}\n /**\n * The hash of the deeplink.\n */\n hash?: string\n}\n\nexport const useDeeplink = (): UseDeeplinkReturnType => {\n const {initialUrl, handle} = window.minisParams\n\n return useMemo(() => {\n if (!initialUrl) {\n return {\n path: undefined,\n queryParams: undefined,\n hash: undefined,\n }\n }\n\n const parsedUrl = parseUrl(initialUrl)\n const deeplinkPathnamePrefix = `/mini/${handle}`\n\n return {\n path: parsedUrl.pathname.startsWith(deeplinkPathnamePrefix)\n ? parsedUrl.pathname.replace(deeplinkPathnamePrefix, '')\n : parsedUrl.pathname,\n queryParams: parsedUrl.query,\n hash: parsedUrl.hash,\n }\n }, [handle, initialUrl])\n}\n"],"names":["useDeeplink","initialUrl","handle","useMemo","parsedUrl","parseUrl","deeplinkPathnamePrefix"],"mappings":";;AAmBO,MAAMA,IAAc,MAA6B;AACtD,QAAM,EAAC,YAAAC,GAAY,QAAAC,EAAM,IAAI,OAAO;AAEpC,SAAOC,EAAQ,MAAM;AACnB,QAAI,CAACF;AACI,aAAA;AAAA,QACL,MAAM;AAAA,QACN,aAAa;AAAA,QACb,MAAM;AAAA,MACR;AAGI,UAAAG,IAAYC,EAASJ,CAAU,GAC/BK,IAAyB,SAASJ,CAAM;AAEvC,WAAA;AAAA,MACL,MAAME,EAAU,SAAS,WAAWE,CAAsB,IACtDF,EAAU,SAAS,QAAQE,GAAwB,EAAE,IACrDF,EAAU;AAAA,MACd,aAAaA,EAAU;AAAA,MACvB,MAAMA,EAAU;AAAA,IAClB;AAAA,EAAA,GACC,CAACF,GAAQD,CAAU,CAAC;AACzB;"}
package/dist/mocks.js CHANGED
@@ -247,6 +247,7 @@ function m() {
247
247
  data: [
248
248
  {
249
249
  id: "variant-1",
250
+ title: "Variant 1",
250
251
  isFavorited: !1,
251
252
  image: { url: "https://example.com/variant-1.jpg" },
252
253
  price: { amount: "19.99", currencyCode: "USD" },
package/dist/mocks.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mocks.js","sources":["../src/mocks.ts"],"sourcesContent":["import {\n Product,\n Gender,\n UserState,\n MinisContentStatus,\n} from '@shopify/shop-minis-platform'\nimport {ShopActions} from '@shopify/shop-minis-platform/actions'\n\n// Helper functions for common data structures\nexport const createProduct = (\n id: string,\n title: string,\n price = '99.99',\n compareAtPrice?: string\n): Product => ({\n id,\n title,\n price: {amount: price, currencyCode: 'USD'},\n ...(compareAtPrice && {\n compareAtPrice: {amount: compareAtPrice, currencyCode: 'USD'},\n }),\n reviewAnalytics: {averageRating: 4.5, reviewCount: 10},\n shop: createShop('shop1', 'Mock Shop'),\n defaultVariantId: `variant-${id}`,\n isFavorited: false,\n featuredImage: {\n url: `https://cdn.shopify.com/static/sample-images/teapot.jpg`,\n altText: title,\n },\n})\n\nexport const createShop = (\n id: string,\n name: string,\n options?: {\n themeType?: 'coverImage' | 'brandColor' | 'logoColor' | 'none'\n withBrandSettings?: boolean\n primaryColor?: string\n logoDominantColor?: string\n logoAverageColor?: string\n coverDominantColor?: string\n wordmarkUrl?: string\n coverImageUrl?: string\n featuredImagesLimit?: number\n }\n) => {\n // Determine theme configuration\n const themeType = options?.themeType || 'none'\n const shouldHaveBrandSettings =\n options?.withBrandSettings || themeType !== 'none'\n\n // Generate featured images\n const featuredImagesCount = options?.featuredImagesLimit || 3\n const featuredImages = Array.from({length: featuredImagesCount}, (_, i) => ({\n url: `https://picsum.photos/400/400?random=${id}-${i}`,\n sensitive: false,\n altText: `${name} featured image ${i + 1}`,\n }))\n\n // Configure colors based on theme type\n const getThemeColors = () => {\n switch (themeType) {\n case 'coverImage':\n return {\n primary: options?.primaryColor,\n logoDominant: options?.logoDominantColor,\n logoAverage: options?.logoAverageColor,\n coverDominant: options?.coverDominantColor || '#FF6B35',\n }\n case 'brandColor':\n return {\n primary: options?.primaryColor || '#27AE60',\n logoDominant: options?.logoDominantColor,\n logoAverage: options?.logoAverageColor,\n coverDominant: options?.coverDominantColor,\n }\n case 'logoColor':\n return {\n primary: options?.primaryColor,\n logoDominant: options?.logoDominantColor || '#E74C3C',\n logoAverage: options?.logoAverageColor,\n coverDominant: options?.coverDominantColor,\n }\n default:\n return {\n primary: options?.primaryColor,\n logoDominant: options?.logoDominantColor,\n logoAverage: options?.logoAverageColor,\n coverDominant: options?.coverDominantColor,\n }\n }\n }\n\n // Configure header theme\n const createHeaderTheme = () => {\n if (themeType === 'coverImage' || options?.coverImageUrl) {\n return {\n id: `header-theme-${id}`,\n coverImage: {\n url:\n options?.coverImageUrl ||\n 'https://images.unsplash.com/photo-1441986300917-64674bd600d8?w=800&h=400&fit=crop',\n altText: `${name} cover image`,\n sensitive: false,\n thumbhash: 'k9oGHQRnh493V4dIeHeXh4h3iIeI',\n },\n wordmark:\n options?.wordmarkUrl || themeType === 'coverImage'\n ? {\n url:\n options?.wordmarkUrl ||\n 'https://merrypeople.com/cdn/shop/files/Transparent_Background_1.png?v=1696465429&width=1024',\n altText: `${name} wordmark`,\n sensitive: false,\n }\n : undefined,\n }\n }\n\n if (options?.wordmarkUrl) {\n return {\n id: `header-theme-${id}`,\n wordmark: {\n url: options.wordmarkUrl,\n altText: `${name} wordmark`,\n sensitive: false,\n },\n }\n }\n\n return undefined\n }\n\n return {\n id,\n name,\n primaryDomain: {\n url: `https://${name.toLowerCase().replace(/\\s+/g, '-')}.com`,\n },\n reviewAnalytics: {averageRating: 4.3, reviewCount: 50},\n visualTheme: {\n id: `visual-theme-${id}`,\n featuredImages,\n logoImage: {\n url: `https://picsum.photos/100/100?random=${id}`,\n sensitive: false,\n },\n brandSettings: shouldHaveBrandSettings\n ? {\n id: `brand-settings-${id}`,\n colors: {\n id: `colors-${id}`,\n ...getThemeColors(),\n },\n headerTheme: createHeaderTheme(),\n }\n : undefined,\n },\n }\n}\n\nconst createPagination = (hasNext = false) => ({\n hasNextPage: hasNext,\n endCursor: hasNext ? 'cursor123' : null,\n})\n\nconst createProductList = (id: string, name: string, products: any[] = []) => ({\n id,\n publicId: `public-${id}`,\n name,\n products,\n})\n\n// Helper type to extract the data type from a ShopAction\ntype ShopActionDataType<T> = T extends (\n ...args: any[]\n) => Promise<{ok: true; data: infer R} | {ok: false; error: any}>\n ? R\n : never\n\nfunction makeMockMethod<K extends keyof ShopActions>(\n key: K,\n result: ShopActionDataType<ShopActions[K]>\n): ShopActions[K] {\n return ((params: Parameters<ShopActions[K]>[0]) => {\n console.log(`[Mock Action] ${String(key)}`, params)\n return Promise.resolve({ok: true as const, data: result})\n }) as ShopActions[K]\n}\n\nexport function makeMockActions(): ShopActions {\n const results: {\n [K in keyof ShopActions]: ShopActionDataType<ShopActions[K]>\n } = {\n translateContentUp: undefined,\n translateContentDown: undefined,\n followShop: true,\n unfollowShop: false,\n favorite: undefined,\n unfavorite: undefined,\n getShopAppInformation: {\n appVersion: '1.0.0',\n buildNumber: '12345',\n buildId: 'dev-build-123',\n },\n productRecommendationImpression: undefined,\n productRecommendationClick: undefined,\n hideEntryPoint: undefined,\n closeMini: undefined,\n getAccountInformation: {\n status: 'available',\n value: 'user@example.com',\n },\n getCurrentUser: {\n data: {\n displayName: 'John Doe',\n avatarImage: {url: 'https://example.com/avatar.jpg'},\n },\n },\n createOrderAttribution: undefined,\n addToCart: undefined,\n buyProduct: undefined,\n buyProducts: undefined,\n showErrorScreen: undefined,\n showErrorToast: undefined,\n getDeeplinkPaths: {\n matchers: ['/products', '/collections', '/cart'],\n },\n navigateToDeeplink: undefined,\n navigateToShop: undefined,\n navigateToProduct: undefined,\n navigateToOrder: undefined,\n navigateToCheckout: undefined,\n createImageUploadLink: {\n targets: [\n {\n url: 'https://example.com/upload',\n resourceUrl: 'https://example.com/resource',\n parameters: [{name: 'key', value: 'upload-123'}],\n },\n ],\n },\n completeImageUpload: {\n files: [\n {\n id: 'file-123',\n fileStatus: 'READY',\n image: {url: 'https://example.com/image.jpg'},\n },\n ],\n },\n getPersistedItem: 'stored-value',\n setPersistedItem: undefined,\n removePersistedItem: undefined,\n getAllPersistedKeys: ['key1', 'key2', 'key3'],\n clearPersistedItems: undefined,\n getInternalPersistedItem: 'internal-value',\n setInternalPersistedItem: undefined,\n removeInternalPersistedItem: undefined,\n getAllInternalPersistedKeys: ['internal-key1', 'internal-key2'],\n clearInternalPersistedItems: undefined,\n getSecret: 'secret-value',\n setSecret: undefined,\n removeSecret: undefined,\n reportInteraction: undefined,\n reportImpression: undefined,\n reportContentImpression: undefined,\n getProductLists: {\n data: [\n createProductList('list-1', 'Wishlist'),\n createProductList('list-2', 'Favorites'),\n ],\n pageInfo: createPagination(),\n },\n getProductList: {\n data: createProductList('list-1', 'Wishlist', [\n createProduct('prod-1', 'Sample Product'),\n ]),\n pageInfo: createPagination(),\n },\n addProductList: createProductList('list-3', 'New List'),\n removeProductList: undefined,\n renameProductList: createProductList('list-1', 'Updated Wishlist'),\n addProductListItem: undefined,\n removeProductListItem: undefined,\n getRecommendedProducts: {\n data: [\n createProduct('rec-1', 'Recommended Product 1', '79.99'),\n createProduct('rec-2', 'Recommended Product 2', '129.99'),\n createProduct('rec-3', 'Recommended Product 3', '129.99'),\n createProduct('rec-4', 'Recommended Product 4', '29.99'),\n createProduct('rec-5', 'Recommended Product 5', '39.99'),\n createProduct('rec-6', 'Recommended Product 6', '49.99'),\n createProduct('rec-7', 'Recommended Product 7', '59.99'),\n createProduct('rec-8', 'Recommended Product 8', '69.99'),\n createProduct('rec-9', 'Recommended Product 9', '129.99'),\n ],\n pageInfo: createPagination(),\n },\n getRecommendedShops: {\n data: [\n createShop('shop-1', 'Amazing Store'),\n createShop('shop-2', 'Best Deals Shop'),\n ],\n pageInfo: createPagination(),\n },\n searchProductsByShop: {\n data: [\n createProduct('search-1', 'Search Result 1', '59.99'),\n createProduct('search-2', 'Search Result 2', '89.99'),\n ],\n pageInfo: createPagination(),\n },\n getOrders: {\n data: [\n {\n id: 'order-1',\n name: '#1001',\n lineItems: [\n {\n productTitle: 'Sample Product',\n variantTitle: 'Medium',\n quantity: 2,\n product: null,\n },\n ],\n shop: createShop('shop-1', 'Sample Shop'),\n },\n ],\n pageInfo: createPagination(),\n },\n getBuyerAttributes: {\n data: {\n genderAffinity: 'NEUTRAL' as Gender,\n categoryAffinities: [\n {id: 'cat1', name: 'Electronics'},\n {id: 'cat2', name: 'Clothing'},\n ],\n },\n },\n showFeedbackSheet: undefined,\n getPopularProducts: {\n data: [\n createProduct('pop-1', 'The Hero Snowboard', '702.95'),\n createProduct('pop-2', 'Snow Jacket', '605.95', '702.00'),\n createProduct('pop-3', 'Winter Gloves', '89.95'),\n createProduct('pop-4', 'Summer Gloves', '89.95'),\n createProduct('pop-5', 'Spring Gloves', '89.95'),\n createProduct('pop-6', 'Playstation 5', '499.95'),\n createProduct('pop-7', 'Xbox Series X', '499.95'),\n createProduct('pop-8', 'Nintendo Switch', '299.95'),\n createProduct('pop-9', 'Playstation 4', '299.95'),\n createProduct('pop-10', 'Nintendo 3DS', '89.95'),\n ],\n pageInfo: createPagination(),\n },\n share: {\n message: 'Shared!',\n success: true,\n },\n shareSingle: {\n message: 'Shared!',\n success: true,\n },\n getCuratedProducts: {\n data: [\n createProduct('cur-1', 'Curated Product 1', '79.99'),\n createProduct('cur-2', 'Curated Product 2', '129.99'),\n ],\n pageInfo: createPagination(),\n },\n getSavedProducts: {\n data: [createProduct('saved-1', 'Saved Product 1', '49.99')],\n pageInfo: createPagination(),\n },\n getRecentProducts: {\n data: [createProduct('recent-1', 'Recent Product 1', '59.99')],\n pageInfo: createPagination(),\n },\n getProductSearch: {\n data: [createProduct('search-3', 'Search Product 3', '39.99')],\n pageInfo: createPagination(),\n },\n getProducts: {data: [createProduct('prod-2', 'Product 2', '19.99')]},\n getProduct: {data: createProduct('prod-1', 'Sample Product')},\n getProductVariants: {\n data: [\n {\n id: 'variant-1',\n isFavorited: false,\n image: {url: 'https://example.com/variant-1.jpg'},\n price: {amount: '19.99', currencyCode: 'USD'},\n compareAtPrice: {amount: '29.99', currencyCode: 'USD'},\n },\n ],\n pageInfo: createPagination(),\n },\n getProductMedia: {\n data: [\n {\n id: 'media-1',\n image: {url: 'https://example.com/media-1.jpg'},\n mediaContentType: 'IMAGE',\n alt: 'Sample product image',\n },\n ],\n pageInfo: createPagination(),\n },\n getShop: {data: createShop('shop-1', 'Sample Shop')},\n getRecentShops: {\n data: [createShop('recent-shop-1', 'Recent Shop 1')],\n pageInfo: createPagination(),\n },\n getFollowedShops: {\n data: [createShop('followed-shop-1', 'Followed Shop 1')],\n pageInfo: createPagination(),\n },\n previewProductInAr: undefined,\n createContent: {\n data: {\n publicId: 'content-123',\n externalId: null,\n image: {\n id: 'img-123',\n url: 'https://cdn.shopify.com/s/files/1/0633/6574/2742/files/Namnlosdesign-47.png?v=1740438079',\n width: 800,\n height: 600,\n },\n title: 'Mock Content',\n description: 'This is a mock content item',\n visibility: ['DISCOVERABLE'],\n shareableUrl: 'https://example.com/content/123',\n products: null,\n },\n },\n getContent: {\n data: [\n {\n publicId: 'content-123',\n image: {\n id: 'img-123',\n url: 'https://cdn.shopify.com/s/files/1/0633/6574/2742/files/Namnlosdesign-47.png?v=1740438079',\n width: 800,\n height: 600,\n },\n title: 'Mock Content',\n visibility: ['DISCOVERABLE'],\n status: MinisContentStatus.READY,\n },\n ],\n },\n generateUserToken: {\n data: {\n token: 'user-token-123',\n expiresAt: '2025-01-01',\n userState: UserState.VERIFIED,\n },\n },\n navigateToCart: undefined,\n requestPermission: {\n granted: true,\n },\n } as const\n\n const mock: Partial<ShopActions> = {}\n for (const key in results) {\n if (Object.prototype.hasOwnProperty.call(results, key)) {\n // @ts-expect-error: dynamic assignment is safe due to exhaustive mapping\n mock[key] = makeMockMethod(\n key as keyof ShopActions,\n results[key as keyof typeof results]\n )\n }\n }\n return mock as ShopActions\n}\n\n// Detect if running on a mobile device\nconst isMobile = (): boolean => {\n const userAgent = navigator.userAgent.toLowerCase()\n const isIOS = /iphone|ipad|ipod/.test(userAgent)\n const isAndroid = /android/.test(userAgent)\n\n return isIOS || isAndroid\n}\n\nexport const injectMocks = ({force}: {force?: boolean} = {}) => {\n // Only inject mocks if we aren't on a mobile device or we force it\n if (isMobile() && !force) {\n return\n }\n\n if (!window.minisSDK) {\n window.minisSDK = makeMockActions()\n window.minisParams = {\n handle: 'mock-handle',\n initialUrl: '/mock-initial-url',\n platform: 'web',\n }\n }\n}\n"],"names":["createProduct","id","title","price","compareAtPrice","createShop","name","options","featuredImages","_","i","createPagination","hasNext","createProductList","products","makeMockMethod","key","result","params","makeMockActions","results","MinisContentStatus","UserState","mock","isMobile","userAgent","isIOS","isAndroid","injectMocks","force"],"mappings":"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"}
1
+ {"version":3,"file":"mocks.js","sources":["../src/mocks.ts"],"sourcesContent":["import {\n Product,\n Gender,\n UserState,\n MinisContentStatus,\n} from '@shopify/shop-minis-platform'\nimport {ShopActions} from '@shopify/shop-minis-platform/actions'\n\n// Helper functions for common data structures\nexport const createProduct = (\n id: string,\n title: string,\n price = '99.99',\n compareAtPrice?: string\n): Product => ({\n id,\n title,\n price: {amount: price, currencyCode: 'USD'},\n ...(compareAtPrice && {\n compareAtPrice: {amount: compareAtPrice, currencyCode: 'USD'},\n }),\n reviewAnalytics: {averageRating: 4.5, reviewCount: 10},\n shop: createShop('shop1', 'Mock Shop'),\n defaultVariantId: `variant-${id}`,\n isFavorited: false,\n featuredImage: {\n url: `https://cdn.shopify.com/static/sample-images/teapot.jpg`,\n altText: title,\n },\n})\n\nexport const createShop = (\n id: string,\n name: string,\n options?: {\n themeType?: 'coverImage' | 'brandColor' | 'logoColor' | 'none'\n withBrandSettings?: boolean\n primaryColor?: string\n logoDominantColor?: string\n logoAverageColor?: string\n coverDominantColor?: string\n wordmarkUrl?: string\n coverImageUrl?: string\n featuredImagesLimit?: number\n }\n) => {\n // Determine theme configuration\n const themeType = options?.themeType || 'none'\n const shouldHaveBrandSettings =\n options?.withBrandSettings || themeType !== 'none'\n\n // Generate featured images\n const featuredImagesCount = options?.featuredImagesLimit || 3\n const featuredImages = Array.from({length: featuredImagesCount}, (_, i) => ({\n url: `https://picsum.photos/400/400?random=${id}-${i}`,\n sensitive: false,\n altText: `${name} featured image ${i + 1}`,\n }))\n\n // Configure colors based on theme type\n const getThemeColors = () => {\n switch (themeType) {\n case 'coverImage':\n return {\n primary: options?.primaryColor,\n logoDominant: options?.logoDominantColor,\n logoAverage: options?.logoAverageColor,\n coverDominant: options?.coverDominantColor || '#FF6B35',\n }\n case 'brandColor':\n return {\n primary: options?.primaryColor || '#27AE60',\n logoDominant: options?.logoDominantColor,\n logoAverage: options?.logoAverageColor,\n coverDominant: options?.coverDominantColor,\n }\n case 'logoColor':\n return {\n primary: options?.primaryColor,\n logoDominant: options?.logoDominantColor || '#E74C3C',\n logoAverage: options?.logoAverageColor,\n coverDominant: options?.coverDominantColor,\n }\n default:\n return {\n primary: options?.primaryColor,\n logoDominant: options?.logoDominantColor,\n logoAverage: options?.logoAverageColor,\n coverDominant: options?.coverDominantColor,\n }\n }\n }\n\n // Configure header theme\n const createHeaderTheme = () => {\n if (themeType === 'coverImage' || options?.coverImageUrl) {\n return {\n id: `header-theme-${id}`,\n coverImage: {\n url:\n options?.coverImageUrl ||\n 'https://images.unsplash.com/photo-1441986300917-64674bd600d8?w=800&h=400&fit=crop',\n altText: `${name} cover image`,\n sensitive: false,\n thumbhash: 'k9oGHQRnh493V4dIeHeXh4h3iIeI',\n },\n wordmark:\n options?.wordmarkUrl || themeType === 'coverImage'\n ? {\n url:\n options?.wordmarkUrl ||\n 'https://merrypeople.com/cdn/shop/files/Transparent_Background_1.png?v=1696465429&width=1024',\n altText: `${name} wordmark`,\n sensitive: false,\n }\n : undefined,\n }\n }\n\n if (options?.wordmarkUrl) {\n return {\n id: `header-theme-${id}`,\n wordmark: {\n url: options.wordmarkUrl,\n altText: `${name} wordmark`,\n sensitive: false,\n },\n }\n }\n\n return undefined\n }\n\n return {\n id,\n name,\n primaryDomain: {\n url: `https://${name.toLowerCase().replace(/\\s+/g, '-')}.com`,\n },\n reviewAnalytics: {averageRating: 4.3, reviewCount: 50},\n visualTheme: {\n id: `visual-theme-${id}`,\n featuredImages,\n logoImage: {\n url: `https://picsum.photos/100/100?random=${id}`,\n sensitive: false,\n },\n brandSettings: shouldHaveBrandSettings\n ? {\n id: `brand-settings-${id}`,\n colors: {\n id: `colors-${id}`,\n ...getThemeColors(),\n },\n headerTheme: createHeaderTheme(),\n }\n : undefined,\n },\n }\n}\n\nconst createPagination = (hasNext = false) => ({\n hasNextPage: hasNext,\n endCursor: hasNext ? 'cursor123' : null,\n})\n\nconst createProductList = (id: string, name: string, products: any[] = []) => ({\n id,\n publicId: `public-${id}`,\n name,\n products,\n})\n\n// Helper type to extract the data type from a ShopAction\ntype ShopActionDataType<T> = T extends (\n ...args: any[]\n) => Promise<{ok: true; data: infer R} | {ok: false; error: any}>\n ? R\n : never\n\nfunction makeMockMethod<K extends keyof ShopActions>(\n key: K,\n result: ShopActionDataType<ShopActions[K]>\n): ShopActions[K] {\n return ((params: Parameters<ShopActions[K]>[0]) => {\n console.log(`[Mock Action] ${String(key)}`, params)\n return Promise.resolve({ok: true as const, data: result})\n }) as ShopActions[K]\n}\n\nexport function makeMockActions(): ShopActions {\n const results: {\n [K in keyof ShopActions]: ShopActionDataType<ShopActions[K]>\n } = {\n translateContentUp: undefined,\n translateContentDown: undefined,\n followShop: true,\n unfollowShop: false,\n favorite: undefined,\n unfavorite: undefined,\n getShopAppInformation: {\n appVersion: '1.0.0',\n buildNumber: '12345',\n buildId: 'dev-build-123',\n },\n productRecommendationImpression: undefined,\n productRecommendationClick: undefined,\n hideEntryPoint: undefined,\n closeMini: undefined,\n getAccountInformation: {\n status: 'available',\n value: 'user@example.com',\n },\n getCurrentUser: {\n data: {\n displayName: 'John Doe',\n avatarImage: {url: 'https://example.com/avatar.jpg'},\n },\n },\n createOrderAttribution: undefined,\n addToCart: undefined,\n buyProduct: undefined,\n buyProducts: undefined,\n showErrorScreen: undefined,\n showErrorToast: undefined,\n getDeeplinkPaths: {\n matchers: ['/products', '/collections', '/cart'],\n },\n navigateToDeeplink: undefined,\n navigateToShop: undefined,\n navigateToProduct: undefined,\n navigateToOrder: undefined,\n navigateToCheckout: undefined,\n createImageUploadLink: {\n targets: [\n {\n url: 'https://example.com/upload',\n resourceUrl: 'https://example.com/resource',\n parameters: [{name: 'key', value: 'upload-123'}],\n },\n ],\n },\n completeImageUpload: {\n files: [\n {\n id: 'file-123',\n fileStatus: 'READY',\n image: {url: 'https://example.com/image.jpg'},\n },\n ],\n },\n getPersistedItem: 'stored-value',\n setPersistedItem: undefined,\n removePersistedItem: undefined,\n getAllPersistedKeys: ['key1', 'key2', 'key3'],\n clearPersistedItems: undefined,\n getInternalPersistedItem: 'internal-value',\n setInternalPersistedItem: undefined,\n removeInternalPersistedItem: undefined,\n getAllInternalPersistedKeys: ['internal-key1', 'internal-key2'],\n clearInternalPersistedItems: undefined,\n getSecret: 'secret-value',\n setSecret: undefined,\n removeSecret: undefined,\n reportInteraction: undefined,\n reportImpression: undefined,\n reportContentImpression: undefined,\n getProductLists: {\n data: [\n createProductList('list-1', 'Wishlist'),\n createProductList('list-2', 'Favorites'),\n ],\n pageInfo: createPagination(),\n },\n getProductList: {\n data: createProductList('list-1', 'Wishlist', [\n createProduct('prod-1', 'Sample Product'),\n ]),\n pageInfo: createPagination(),\n },\n addProductList: createProductList('list-3', 'New List'),\n removeProductList: undefined,\n renameProductList: createProductList('list-1', 'Updated Wishlist'),\n addProductListItem: undefined,\n removeProductListItem: undefined,\n getRecommendedProducts: {\n data: [\n createProduct('rec-1', 'Recommended Product 1', '79.99'),\n createProduct('rec-2', 'Recommended Product 2', '129.99'),\n createProduct('rec-3', 'Recommended Product 3', '129.99'),\n createProduct('rec-4', 'Recommended Product 4', '29.99'),\n createProduct('rec-5', 'Recommended Product 5', '39.99'),\n createProduct('rec-6', 'Recommended Product 6', '49.99'),\n createProduct('rec-7', 'Recommended Product 7', '59.99'),\n createProduct('rec-8', 'Recommended Product 8', '69.99'),\n createProduct('rec-9', 'Recommended Product 9', '129.99'),\n ],\n pageInfo: createPagination(),\n },\n getRecommendedShops: {\n data: [\n createShop('shop-1', 'Amazing Store'),\n createShop('shop-2', 'Best Deals Shop'),\n ],\n pageInfo: createPagination(),\n },\n searchProductsByShop: {\n data: [\n createProduct('search-1', 'Search Result 1', '59.99'),\n createProduct('search-2', 'Search Result 2', '89.99'),\n ],\n pageInfo: createPagination(),\n },\n getOrders: {\n data: [\n {\n id: 'order-1',\n name: '#1001',\n lineItems: [\n {\n productTitle: 'Sample Product',\n variantTitle: 'Medium',\n quantity: 2,\n product: null,\n },\n ],\n shop: createShop('shop-1', 'Sample Shop'),\n },\n ],\n pageInfo: createPagination(),\n },\n getBuyerAttributes: {\n data: {\n genderAffinity: 'NEUTRAL' as Gender,\n categoryAffinities: [\n {id: 'cat1', name: 'Electronics'},\n {id: 'cat2', name: 'Clothing'},\n ],\n },\n },\n showFeedbackSheet: undefined,\n getPopularProducts: {\n data: [\n createProduct('pop-1', 'The Hero Snowboard', '702.95'),\n createProduct('pop-2', 'Snow Jacket', '605.95', '702.00'),\n createProduct('pop-3', 'Winter Gloves', '89.95'),\n createProduct('pop-4', 'Summer Gloves', '89.95'),\n createProduct('pop-5', 'Spring Gloves', '89.95'),\n createProduct('pop-6', 'Playstation 5', '499.95'),\n createProduct('pop-7', 'Xbox Series X', '499.95'),\n createProduct('pop-8', 'Nintendo Switch', '299.95'),\n createProduct('pop-9', 'Playstation 4', '299.95'),\n createProduct('pop-10', 'Nintendo 3DS', '89.95'),\n ],\n pageInfo: createPagination(),\n },\n share: {\n message: 'Shared!',\n success: true,\n },\n shareSingle: {\n message: 'Shared!',\n success: true,\n },\n getCuratedProducts: {\n data: [\n createProduct('cur-1', 'Curated Product 1', '79.99'),\n createProduct('cur-2', 'Curated Product 2', '129.99'),\n ],\n pageInfo: createPagination(),\n },\n getSavedProducts: {\n data: [createProduct('saved-1', 'Saved Product 1', '49.99')],\n pageInfo: createPagination(),\n },\n getRecentProducts: {\n data: [createProduct('recent-1', 'Recent Product 1', '59.99')],\n pageInfo: createPagination(),\n },\n getProductSearch: {\n data: [createProduct('search-3', 'Search Product 3', '39.99')],\n pageInfo: createPagination(),\n },\n getProducts: {data: [createProduct('prod-2', 'Product 2', '19.99')]},\n getProduct: {data: createProduct('prod-1', 'Sample Product')},\n getProductVariants: {\n data: [\n {\n id: 'variant-1',\n title: 'Variant 1',\n isFavorited: false,\n image: {url: 'https://example.com/variant-1.jpg'},\n price: {amount: '19.99', currencyCode: 'USD'},\n compareAtPrice: {amount: '29.99', currencyCode: 'USD'},\n },\n ],\n pageInfo: createPagination(),\n },\n getProductMedia: {\n data: [\n {\n id: 'media-1',\n image: {url: 'https://example.com/media-1.jpg'},\n mediaContentType: 'IMAGE',\n alt: 'Sample product image',\n },\n ],\n pageInfo: createPagination(),\n },\n getShop: {data: createShop('shop-1', 'Sample Shop')},\n getRecentShops: {\n data: [createShop('recent-shop-1', 'Recent Shop 1')],\n pageInfo: createPagination(),\n },\n getFollowedShops: {\n data: [createShop('followed-shop-1', 'Followed Shop 1')],\n pageInfo: createPagination(),\n },\n previewProductInAr: undefined,\n createContent: {\n data: {\n publicId: 'content-123',\n externalId: null,\n image: {\n id: 'img-123',\n url: 'https://cdn.shopify.com/s/files/1/0633/6574/2742/files/Namnlosdesign-47.png?v=1740438079',\n width: 800,\n height: 600,\n },\n title: 'Mock Content',\n description: 'This is a mock content item',\n visibility: ['DISCOVERABLE'],\n shareableUrl: 'https://example.com/content/123',\n products: null,\n },\n },\n getContent: {\n data: [\n {\n publicId: 'content-123',\n image: {\n id: 'img-123',\n url: 'https://cdn.shopify.com/s/files/1/0633/6574/2742/files/Namnlosdesign-47.png?v=1740438079',\n width: 800,\n height: 600,\n },\n title: 'Mock Content',\n visibility: ['DISCOVERABLE'],\n status: MinisContentStatus.READY,\n },\n ],\n },\n generateUserToken: {\n data: {\n token: 'user-token-123',\n expiresAt: '2025-01-01',\n userState: UserState.VERIFIED,\n },\n },\n navigateToCart: undefined,\n requestPermission: {\n granted: true,\n },\n } as const\n\n const mock: Partial<ShopActions> = {}\n for (const key in results) {\n if (Object.prototype.hasOwnProperty.call(results, key)) {\n // @ts-expect-error: dynamic assignment is safe due to exhaustive mapping\n mock[key] = makeMockMethod(\n key as keyof ShopActions,\n results[key as keyof typeof results]\n )\n }\n }\n return mock as ShopActions\n}\n\n// Detect if running on a mobile device\nconst isMobile = (): boolean => {\n const userAgent = navigator.userAgent.toLowerCase()\n const isIOS = /iphone|ipad|ipod/.test(userAgent)\n const isAndroid = /android/.test(userAgent)\n\n return isIOS || isAndroid\n}\n\nexport const injectMocks = ({force}: {force?: boolean} = {}) => {\n // Only inject mocks if we aren't on a mobile device or we force it\n if (isMobile() && !force) {\n return\n }\n\n if (!window.minisSDK) {\n window.minisSDK = makeMockActions()\n window.minisParams = {\n handle: 'mock-handle',\n initialUrl: '/mock-initial-url',\n platform: 'web',\n }\n }\n}\n"],"names":["createProduct","id","title","price","compareAtPrice","createShop","name","options","featuredImages","_","i","createPagination","hasNext","createProductList","products","makeMockMethod","key","result","params","makeMockActions","results","MinisContentStatus","UserState","mock","isMobile","userAgent","isIOS","isAndroid","injectMocks","force"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { s as r } from "../../../../../../../../_virtual/index8.js";
1
+ import { s as r } from "../../../../../../../../_virtual/index6.js";
2
2
  function s() {
3
3
  return r.useSyncExternalStore(
4
4
  e,
@@ -1,4 +1,4 @@
1
- import { __module as q } from "../../../../../../../../_virtual/index5.js";
1
+ import { __module as q } from "../../../../../../../../_virtual/index4.js";
2
2
  import { __require as F } from "../../../../../global@4.4.0/node_modules/global/window.js";
3
3
  import { __require as N } from "../../../../../@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/extends.js";
4
4
  import { __require as J } from "../../../../../is-function@1.0.2/node_modules/is-function/index.js";
@@ -1,4 +1,4 @@
1
- import { __module as p } from "../../../../../../_virtual/index7.js";
1
+ import { __module as p } from "../../../../../../_virtual/index8.js";
2
2
  import { __require as F } from "../../../color-name@1.1.4/node_modules/color-name/index.js";
3
3
  import { __require as x } from "../../../simple-swizzle@0.2.2/node_modules/simple-swizzle/index.js";
4
4
  var M;
@@ -2,7 +2,7 @@ import L from "../../../../@videojs_vhs-utils@4.1.1/node_modules/@videojs/vhs-ut
2
2
  import T from "../../../../../../../_virtual/window.js";
3
3
  import { forEachMediaGroup as Z } from "../../../../@videojs_vhs-utils@4.1.1/node_modules/@videojs/vhs-utils/es/media-groups.js";
4
4
  import J from "../../../../@videojs_vhs-utils@4.1.1/node_modules/@videojs/vhs-utils/es/decode-b64-to-uint8-array.js";
5
- import { l as Q } from "../../../../../../../_virtual/index6.js";
5
+ import { l as Q } from "../../../../../../../_virtual/index5.js";
6
6
  /*! @name mpd-parser @version 1.3.1 @license Apache-2.0 */
7
7
  const w = (e) => !!e && typeof e == "object", E = (...e) => e.reduce((n, t) => (typeof t != "object" || Object.keys(t).forEach((r) => {
8
8
  Array.isArray(n[r]) && Array.isArray(t[r]) ? n[r] = n[r].concat(t[r]) : w(n[r]) && w(t[r]) ? n[r] = E(n[r], t[r]) : n[r] = t[r];
@@ -1,4 +1,4 @@
1
- import { __exports as i } from "../../../../../../_virtual/index4.js";
1
+ import { __exports as i } from "../../../../../../_virtual/index7.js";
2
2
  var c;
3
3
  function d() {
4
4
  if (c) return i;
@@ -1,4 +1,4 @@
1
- import { __module as t } from "../../../../../../_virtual/index10.js";
1
+ import { __module as t } from "../../../../../../_virtual/index11.js";
2
2
  import { __require as z } from "../../../is-arrayish@0.3.2/node_modules/is-arrayish/index.js";
3
3
  var l;
4
4
  function v() {
@@ -1,4 +1,4 @@
1
- import { __module as r } from "../../../../../../../_virtual/index11.js";
1
+ import { __module as r } from "../../../../../../../_virtual/index10.js";
2
2
  import { __require as o } from "../cjs/use-sync-external-store-shim.production.js";
3
3
  import { __require as i } from "../cjs/use-sync-external-store-shim.development.js";
4
4
  var e;
@@ -0,0 +1,201 @@
1
+ # Shop Minis ESLint Plugin
2
+
3
+ Custom ESLint rules for Shop Minis apps. ESLint is included with the SDK.
4
+
5
+ ## Quick Setup
6
+
7
+ Create **`eslint.config.js`** (NOT `.eslintrc.js`):
8
+
9
+ ```javascript
10
+ const shopMinisConfig = require('@shopify/shop-minis-react/eslint/config')
11
+
12
+ module.exports = [shopMinisConfig]
13
+ ```
14
+
15
+ **That's it!** TypeScript and JSX are supported out of the box.
16
+
17
+ **Important:**
18
+ - File must be named `eslint.config.js` (no dot, no "rc")
19
+ - This will lint all `.js`, `.jsx`, `.ts`, `.tsx` files in your project
20
+ - TypeScript and JSX parsing is configured automatically
21
+
22
+ ## Usage
23
+
24
+ ```bash
25
+ # Check for errors
26
+ npx eslint .
27
+
28
+ # Auto-fix (converts <img> to <Image> AND adds import!)
29
+ npx eslint . --fix
30
+ ```
31
+
32
+ ## What You Get
33
+
34
+ - ✅ No internal imports allowed
35
+ - ✅ Warnings for `<img>`, `<button>`, `<label>` tags (auto-fixes with imports)
36
+ - ✅ Manifest scope validation - ensures manifest.json has scopes for hooks you use (auto-fixes manifest)
37
+
38
+ ## Rules
39
+
40
+ ### `no-internal-imports`
41
+
42
+ Prevents importing from internal SDK directories.
43
+
44
+ ```tsx
45
+ // ❌ Error
46
+ import {something} from '@shopify/shop-minis-react/internal'
47
+
48
+ // ✅ Correct
49
+ import {Component} from '@shopify/shop-minis-react'
50
+ ```
51
+
52
+ ### `prefer-sdk-components`
53
+
54
+ Suggests using SDK components instead of native HTML elements. **Fully auto-fixable** - fixes both tags and imports!
55
+
56
+ **Before:**
57
+ ```tsx
58
+ const MyComponent = () => (
59
+ <img src="product.jpg" alt="Product" />
60
+ )
61
+ ```
62
+
63
+ **After running `npx eslint . --fix`:**
64
+ ```tsx
65
+ import {Image} from '@shopify/shop-minis-react'
66
+
67
+ const MyComponent = () => (
68
+ <Image src="product.jpg" alt="Product" />
69
+ )
70
+ ```
71
+
72
+ **Supported Components:**
73
+ - `<img>` → `<Image>`
74
+ - `<button>` → `<Button>`
75
+ - `<label>` → `<Label>`
76
+
77
+ **Auto-fix does TWO things:**
78
+ 1. ✅ Replaces native element with SDK component
79
+ 2. ✅ Adds import statement automatically (or adds to existing import)
80
+
81
+ ### `validate-manifest`
82
+
83
+ Validates `src/manifest.json` configuration for scopes and permissions. **Auto-fixable** - adds missing values to manifest!
84
+
85
+ #### Scopes
86
+
87
+ Checks that hooks have required scopes:
88
+
89
+ ```tsx
90
+ // If you use this hook:
91
+ import {useCurrentUser} from '@shopify/shop-minis-react'
92
+
93
+ // Manifest must include:
94
+ {
95
+ "scopes": ["USER_SETTINGS_READ"]
96
+ }
97
+ ```
98
+
99
+ **Scope Requirements:**
100
+ - `useCurrentUser` → `USER_SETTINGS_READ`
101
+ - `useSavedProducts` → `FAVORITES`
102
+ - `useOrders` → `ORDERS`
103
+
104
+ #### Permissions
105
+
106
+ Checks for native permission usage:
107
+
108
+ ```tsx
109
+ // If you use this hook:
110
+ import {useImagePicker} from '@shopify/shop-minis-react'
111
+
112
+ // Or browser APIs:
113
+ navigator.mediaDevices.getUserMedia({video: true})
114
+
115
+ // Manifest must include:
116
+ {
117
+ "permissions": ["CAMERA"]
118
+ }
119
+ ```
120
+
121
+ **Supported Permissions:**
122
+ - `CAMERA` - Required for `useImagePicker` hook or getUserMedia video
123
+ - `MICROPHONE` - Required for getUserMedia audio
124
+ - `MOTION` - Required for DeviceOrientation/DeviceMotion events
125
+
126
+ #### Trusted Domains
127
+
128
+ Checks that external URLs are in trusted_domains. Detects:
129
+
130
+ **Network Requests:**
131
+ - `fetch('https://api.example.com/data')`
132
+ - `new XMLHttpRequest().open('GET', 'https://...')`
133
+ - `new WebSocket('wss://api.example.com')`
134
+ - `new EventSource('https://api.example.com/events')`
135
+ - `navigator.sendBeacon('https://analytics.example.com')`
136
+ - `window.open('https://external.com')`
137
+
138
+ **Media & Resources:**
139
+ - `<img src="https://cdn.shopify.com/image.jpg" />`
140
+ - `<video src="https://videos.example.com/video.mp4" />`
141
+ - `<video poster="https://cdn.example.com/poster.jpg" />`
142
+ - `<audio src="https://audio.example.com/sound.mp3" />`
143
+ - `<source src="https://media.example.com/video.mp4" />`
144
+ - `<track src="https://cdn.example.com/captions.vtt" />`
145
+ - `<object data="https://cdn.example.com/file.pdf" />`
146
+ - `<embed src="https://cdn.example.com/file.swf" />`
147
+ - `<form action="https://api.example.com/submit" />`
148
+
149
+ **Note:** External scripts (`<script>`), stylesheets (`<link>`), and iframes are not supported and excluded from validation.
150
+
151
+ **Example manifest:**
152
+ ```json
153
+ {
154
+ "trusted_domains": [
155
+ "api.example.com",
156
+ "cdn.shopify.com",
157
+ "videos.example.com"
158
+ ]
159
+ }
160
+ ```
161
+
162
+ **Wildcard support:**
163
+ ```json
164
+ {
165
+ "trusted_domains": [
166
+ "*.shopify.com", // Matches any Shopify subdomain
167
+ "api.example.com", // Exact domain
168
+ "cdn.example.com/assets" // Specific path
169
+ ]
170
+ }
171
+ ```
172
+
173
+ **Auto-fix:**
174
+ ```bash
175
+ npx eslint . --fix
176
+ # Automatically updates src/manifest.json
177
+ ```
178
+
179
+ **Example errors:**
180
+ ```
181
+ Hook "useCurrentUser" requires scope "USER_SETTINGS_READ" in src/manifest.json.
182
+ Hook "useImagePicker" requires permission "CAMERA" in src/manifest.json.
183
+ fetch() call loads from "api.example.com" which is not in trusted_domains.
184
+ <img> src attribute loads from "cdn.shopify.com" which is not in trusted_domains.
185
+ ```
186
+
187
+ ## Extending Rules
188
+
189
+ To add more component mappings to `prefer-sdk-components`, edit `eslint/rules/prefer-sdk-components.cjs`:
190
+
191
+ ```javascript
192
+ const defaultComponents = {
193
+ img: 'Image',
194
+ button: 'Button',
195
+ label: 'Label',
196
+ input: 'Input', // Add this
197
+ a: 'TransitionLink', // Add this
198
+ }
199
+ ```
200
+
201
+ All consumers automatically get new rules - no config changes needed!
@@ -0,0 +1,32 @@
1
+ /* eslint-disable import/extensions */
2
+ /**
3
+ * ESLint config for projects using @shopify/shop-minis-react
4
+ * @fileoverview Recommended ESLint configuration for Shop Minis apps
5
+ *
6
+ * This config uses ESLint flat config format (supported in ESLint 8.57+)
7
+ */
8
+
9
+ // Import the plugin directly so consumers don't need to install it separately
10
+ const shopMinisPlugin = require('./index.cjs')
11
+
12
+ module.exports = {
13
+ files: ['**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx'],
14
+ languageOptions: {
15
+ parser: require('@typescript-eslint/parser'),
16
+ ecmaVersion: 'latest',
17
+ sourceType: 'module',
18
+ parserOptions: {
19
+ ecmaFeatures: {
20
+ jsx: true,
21
+ },
22
+ },
23
+ },
24
+ plugins: {
25
+ 'shop-minis': shopMinisPlugin,
26
+ },
27
+ rules: {
28
+ 'shop-minis/no-internal-imports': 'error',
29
+ 'shop-minis/prefer-sdk-components': 'warn',
30
+ 'shop-minis/validate-manifest': 'error',
31
+ },
32
+ }
@@ -0,0 +1,17 @@
1
+ /* eslint-disable import/extensions */
2
+ /**
3
+ * ESLint plugin for @shopify/shop-minis-react
4
+ * @fileoverview Custom ESLint rules for Shop Minis React SDK
5
+ */
6
+
7
+ const noInternalImports = require('./rules/no-internal-imports.cjs')
8
+ const preferSdkComponents = require('./rules/prefer-sdk-components.cjs')
9
+ const validateManifest = require('./rules/validate-manifest.cjs')
10
+
11
+ module.exports = {
12
+ rules: {
13
+ 'no-internal-imports': noInternalImports,
14
+ 'prefer-sdk-components': preferSdkComponents,
15
+ 'validate-manifest': validateManifest,
16
+ },
17
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * ESLint rule to prevent importing from internal directories
3
+ * @fileoverview Disallow importing from @shopify/shop-minis-react/internal
4
+ */
5
+
6
+ module.exports = {
7
+ meta: {
8
+ type: 'problem',
9
+ docs: {
10
+ description:
11
+ 'Disallow importing from internal directories of @shopify/shop-minis-react',
12
+ category: 'Best Practices',
13
+ recommended: true,
14
+ },
15
+ messages: {
16
+ noInternalImports:
17
+ 'Do not import from "{{importPath}}". Internal APIs are not part of the public API and may change without notice. Use the public exports from @shopify/shop-minis-react instead.',
18
+ },
19
+ schema: [],
20
+ },
21
+
22
+ create(context) {
23
+ return {
24
+ ImportDeclaration(node) {
25
+ const importPath = node.source.value
26
+
27
+ // Check if importing from internal directory
28
+ if (
29
+ importPath.includes('@shopify/shop-minis-react/internal') ||
30
+ importPath.includes('@shopify/shop-minis-react/src/internal')
31
+ ) {
32
+ context.report({
33
+ node: node.source,
34
+ messageId: 'noInternalImports',
35
+ data: {
36
+ importPath,
37
+ },
38
+ })
39
+ }
40
+ },
41
+ }
42
+ },
43
+ }