@shopify/shop-minis-react 0.0.24 → 0.0.25
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 +3 -2
- package/dist/_virtual/index4.js.map +1 -1
- package/dist/_virtual/index5.js +2 -3
- package/dist/_virtual/index5.js.map +1 -1
- package/dist/_virtual/index6.js +3 -2
- package/dist/_virtual/index6.js.map +1 -1
- package/dist/_virtual/index7.js +2 -3
- package/dist/_virtual/index7.js.map +1 -1
- package/dist/hooks/content/useCreateImageContent.js +37 -0
- package/dist/hooks/content/useCreateImageContent.js.map +1 -0
- package/dist/hooks/storage/useImageUpload.js +49 -40
- package/dist/hooks/storage/useImageUpload.js.map +1 -1
- package/dist/index.js +57 -53
- package/dist/index.js.map +1 -1
- package/dist/mocks.js +62 -45
- 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/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/utils/imageToDataUri.js +10 -0
- package/dist/utils/imageToDataUri.js.map +1 -0
- package/package.json +2 -2
- package/src/hooks/content/useCreateImageContent.ts +65 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/storage/useImageUpload.ts +27 -11
- package/src/mocks.ts +17 -0
- package/src/utils/imageToDataUri.ts +8 -0
- package/src/utils/index.ts +1 -0
package/dist/_virtual/index4.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
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();
|
|
2
3
|
export {
|
|
3
|
-
|
|
4
|
+
i as s
|
|
4
5
|
};
|
|
5
6
|
//# sourceMappingURL=index4.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index4.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index4.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
|
package/dist/_virtual/index5.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
var i = r();
|
|
1
|
+
var e = { exports: {} };
|
|
3
2
|
export {
|
|
4
|
-
|
|
3
|
+
e as __module
|
|
5
4
|
};
|
|
6
5
|
//# 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":";"}
|
package/dist/_virtual/index6.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index6.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index6.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
|
package/dist/_virtual/index7.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index7.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index7.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { useCallback as s } from "react";
|
|
2
|
+
import { useHandleAction as p } from "../../internal/useHandleAction.js";
|
|
3
|
+
import { useShopActions as c } from "../../internal/useShopActions.js";
|
|
4
|
+
import { useImageUpload as u } from "../storage/useImageUpload.js";
|
|
5
|
+
import { fileToDataUri as g } from "../../utils/imageToDataUri.js";
|
|
6
|
+
const C = () => {
|
|
7
|
+
const { createContent: t } = c(), { uploadImage: o } = u(), a = s(
|
|
8
|
+
async (i) => {
|
|
9
|
+
const { image: e, contentTitle: n, visibility: m } = i;
|
|
10
|
+
if (!e.type)
|
|
11
|
+
throw new Error("Unable to determine file type");
|
|
12
|
+
if (!e.type.startsWith("image/"))
|
|
13
|
+
throw new Error("Invalid file type: must be an image");
|
|
14
|
+
const [l] = await o([
|
|
15
|
+
{
|
|
16
|
+
mimeType: e.type,
|
|
17
|
+
uri: await g(e)
|
|
18
|
+
}
|
|
19
|
+
]), r = l.imageUrl;
|
|
20
|
+
if (!r)
|
|
21
|
+
throw new Error("Image upload failed");
|
|
22
|
+
return t({
|
|
23
|
+
title: n,
|
|
24
|
+
imageUrl: r,
|
|
25
|
+
visibility: m
|
|
26
|
+
});
|
|
27
|
+
},
|
|
28
|
+
[t, o]
|
|
29
|
+
);
|
|
30
|
+
return {
|
|
31
|
+
createImageContent: p(a)
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
export {
|
|
35
|
+
C as useCreateImageContent
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=useCreateImageContent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCreateImageContent.js","sources":["../../../src/hooks/content/useCreateImageContent.ts"],"sourcesContent":["import {useCallback} from 'react'\n\nimport {ContentVisibility} from '@shopify/shop-minis-platform'\nimport {CreateContentResponse} from '@shopify/shop-minis-platform/actions'\n\nimport {useHandleAction} from '../../internal/useHandleAction'\nimport {useShopActions} from '../../internal/useShopActions'\nimport {fileToDataUri} from '../../utils'\nimport {useImageUpload} from '../storage/useImageUpload'\n\ninterface CreateImageContentParams {\n image: File\n contentTitle: string\n visibility?: ContentVisibility[] | null\n}\n\ninterface UseCreateImageContentReturns {\n /**\n * Upload an image and create content.\n */\n createImageContent: (\n params: CreateImageContentParams\n ) => Promise<CreateContentResponse>\n}\n\nexport const useCreateImageContent = (): UseCreateImageContentReturns => {\n const {createContent} = useShopActions()\n const {uploadImage} = useImageUpload()\n\n const createImageContent = useCallback(\n async (params: CreateImageContentParams) => {\n const {image, contentTitle, visibility} = params\n\n if (!image.type) {\n throw new Error('Unable to determine file type')\n }\n if (!image.type.startsWith('image/')) {\n throw new Error('Invalid file type: must be an image')\n }\n\n const [uploadImageResult] = await uploadImage([\n {\n mimeType: image.type,\n uri: await fileToDataUri(image),\n },\n ])\n const uploadImageUrl = uploadImageResult.imageUrl\n\n if (!uploadImageUrl) {\n throw new Error('Image upload failed')\n }\n\n return createContent({\n title: contentTitle,\n imageUrl: uploadImageUrl,\n visibility,\n })\n },\n [createContent, uploadImage]\n )\n\n return {\n createImageContent: useHandleAction(createImageContent),\n }\n}\n"],"names":["useCreateImageContent","createContent","useShopActions","uploadImage","useImageUpload","createImageContent","useCallback","params","image","contentTitle","visibility","uploadImageResult","fileToDataUri","uploadImageUrl","useHandleAction"],"mappings":";;;;;AAyBO,MAAMA,IAAwB,MAAoC;AACjE,QAAA,EAAC,eAAAC,EAAa,IAAIC,EAAe,GACjC,EAAC,aAAAC,EAAW,IAAIC,EAAe,GAE/BC,IAAqBC;AAAA,IACzB,OAAOC,MAAqC;AAC1C,YAAM,EAAC,OAAAC,GAAO,cAAAC,GAAc,YAAAC,EAAc,IAAAH;AAEtC,UAAA,CAACC,EAAM;AACH,cAAA,IAAI,MAAM,+BAA+B;AAEjD,UAAI,CAACA,EAAM,KAAK,WAAW,QAAQ;AAC3B,cAAA,IAAI,MAAM,qCAAqC;AAGvD,YAAM,CAACG,CAAiB,IAAI,MAAMR,EAAY;AAAA,QAC5C;AAAA,UACE,UAAUK,EAAM;AAAA,UAChB,KAAK,MAAMI,EAAcJ,CAAK;AAAA,QAAA;AAAA,MAChC,CACD,GACKK,IAAiBF,EAAkB;AAEzC,UAAI,CAACE;AACG,cAAA,IAAI,MAAM,qBAAqB;AAGvC,aAAOZ,EAAc;AAAA,QACnB,OAAOQ;AAAA,QACP,UAAUI;AAAA,QACV,YAAAH;AAAA,MAAA,CACD;AAAA,IACH;AAAA,IACA,CAACT,GAAeE,CAAW;AAAA,EAC7B;AAEO,SAAA;AAAA,IACL,oBAAoBW,EAAgBT,CAAkB;AAAA,EACxD;AACF;"}
|
|
@@ -1,62 +1,71 @@
|
|
|
1
|
-
import { useCallback as
|
|
1
|
+
import { useCallback as m } from "react";
|
|
2
2
|
import { useShopActions as u } from "../../internal/useShopActions.js";
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
const d = async (e) => {
|
|
4
|
+
const r = await (await fetch(e.uri)).blob();
|
|
5
|
+
return {
|
|
6
|
+
...e,
|
|
7
|
+
fileSize: e.fileSize ?? r.size,
|
|
8
|
+
fileBlob: r
|
|
9
|
+
};
|
|
10
|
+
}, f = async (e, o) => {
|
|
11
|
+
const r = new FormData();
|
|
12
|
+
o.parameters.forEach(({ name: l, value: t }) => {
|
|
13
|
+
r.append(l, t);
|
|
14
|
+
}), r.append("file", e.fileBlob);
|
|
15
|
+
const a = await fetch(o.url, {
|
|
9
16
|
method: "POST",
|
|
10
|
-
body:
|
|
17
|
+
body: r
|
|
11
18
|
});
|
|
12
|
-
return
|
|
13
|
-
response: await
|
|
19
|
+
return a.ok ? {} : (console.error("Failed to upload image", {
|
|
20
|
+
response: await a.text()
|
|
14
21
|
}), { error: "Failed to upload image" });
|
|
15
|
-
},
|
|
16
|
-
const { createImageUploadLink:
|
|
22
|
+
}, h = () => {
|
|
23
|
+
const { createImageUploadLink: e, completeImageUpload: o } = u();
|
|
17
24
|
return {
|
|
18
|
-
uploadImage:
|
|
19
|
-
async (
|
|
20
|
-
if (
|
|
25
|
+
uploadImage: m(
|
|
26
|
+
async (a) => {
|
|
27
|
+
if (a.length > 1)
|
|
21
28
|
throw new Error("Multiple image upload is not supported yet");
|
|
22
|
-
const
|
|
23
|
-
input:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
const l = a[0], t = await d(l), s = await e({
|
|
30
|
+
input: [
|
|
31
|
+
{
|
|
32
|
+
mimeType: t.mimeType,
|
|
33
|
+
fileSize: t.fileSize
|
|
34
|
+
}
|
|
35
|
+
]
|
|
27
36
|
});
|
|
28
|
-
if (!
|
|
29
|
-
throw new Error(
|
|
30
|
-
const { error:
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
if (!s.ok)
|
|
38
|
+
throw new Error(s.error.message);
|
|
39
|
+
const { error: p } = await f(
|
|
40
|
+
t,
|
|
41
|
+
s?.data?.targets?.[0]
|
|
33
42
|
);
|
|
34
|
-
if (
|
|
35
|
-
throw new Error(
|
|
36
|
-
let
|
|
37
|
-
for (;
|
|
38
|
-
const
|
|
39
|
-
resourceUrls:
|
|
43
|
+
if (p)
|
|
44
|
+
throw new Error(p);
|
|
45
|
+
let c = 0;
|
|
46
|
+
for (; c < 30; ) {
|
|
47
|
+
const i = await o({
|
|
48
|
+
resourceUrls: s?.data?.targets?.map((n) => n.resourceUrl) || []
|
|
40
49
|
});
|
|
41
|
-
if (!
|
|
42
|
-
throw new Error(
|
|
43
|
-
if (
|
|
50
|
+
if (!i.ok)
|
|
51
|
+
throw new Error(i.error.message);
|
|
52
|
+
if (i.data?.files?.[0]?.fileStatus === "READY")
|
|
44
53
|
return [
|
|
45
54
|
{
|
|
46
|
-
id:
|
|
47
|
-
imageUrl:
|
|
48
|
-
resourceUrl:
|
|
55
|
+
id: i.data.files[0].id,
|
|
56
|
+
imageUrl: i.data.files[0].image?.url,
|
|
57
|
+
resourceUrl: s?.data?.targets?.[0]?.resourceUrl
|
|
49
58
|
}
|
|
50
59
|
];
|
|
51
|
-
await new Promise((
|
|
60
|
+
await new Promise((n) => setTimeout(n, 1e3)), c++;
|
|
52
61
|
}
|
|
53
62
|
throw new Error("Image upload completion timed out");
|
|
54
63
|
},
|
|
55
|
-
[
|
|
64
|
+
[e, o]
|
|
56
65
|
)
|
|
57
66
|
};
|
|
58
67
|
};
|
|
59
68
|
export {
|
|
60
|
-
|
|
69
|
+
h as useImageUpload
|
|
61
70
|
};
|
|
62
71
|
//# sourceMappingURL=useImageUpload.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useImageUpload.js","sources":["../../../src/hooks/storage/useImageUpload.ts"],"sourcesContent":["import {useCallback} from 'react'\n\nimport {useShopActions} from '../../internal/useShopActions'\n\nimport type {UploadTarget} from '@shopify/shop-minis-platform/actions'\n\nexport interface UploadImageParams {\n /**\n * The MIME type of the image.\n */\n mimeType: string\n /**\n * The size of the image in bytes.\n */\n fileSize
|
|
1
|
+
{"version":3,"file":"useImageUpload.js","sources":["../../../src/hooks/storage/useImageUpload.ts"],"sourcesContent":["import {useCallback} from 'react'\n\nimport {useShopActions} from '../../internal/useShopActions'\n\nimport type {UploadTarget} from '@shopify/shop-minis-platform/actions'\n\nexport interface UploadImageParams {\n /**\n * The MIME type of the image.\n */\n mimeType: string\n /**\n * The size of the image in bytes.\n */\n fileSize?: number\n /**\n * The URI of the image to upload.\n */\n uri: string\n}\n\nexport interface UploadedImage {\n /**\n * The ID of the uploaded image.\n */\n id: string\n /**\n * The URL of the uploaded image.\n */\n imageUrl?: string\n /**\n * The resource URL of the uploaded image.\n */\n resourceUrl?: string\n}\n\ninterface UseImageUploadReturns {\n /**\n * Upload an image attached to the current user.\n */\n uploadImage: (params: UploadImageParams[]) => Promise<UploadedImage[]>\n}\n\n// Fetch file data and detect file sizes if not provided\n// Works with file://, data:, and http(s):// URIs\nconst processFileData = async (image: UploadImageParams) => {\n const response = await fetch(image.uri)\n const blob = await response.blob()\n\n return {\n ...image,\n fileSize: image.fileSize ?? blob.size,\n fileBlob: blob,\n }\n}\n\nconst uploadFileToGCS = async (\n image: UploadImageParams & {fileSize: number; fileBlob: Blob},\n target: UploadTarget\n) => {\n const formData = new FormData()\n target.parameters.forEach(({name, value}: {name: string; value: string}) => {\n formData.append(name, value)\n })\n\n formData.append('file', image.fileBlob)\n\n const uploadResponse = await fetch(target.url, {\n method: 'POST',\n body: formData,\n })\n\n if (!uploadResponse.ok) {\n console.error('Failed to upload image', {\n response: await uploadResponse.text(),\n })\n return {error: 'Failed to upload image'}\n }\n\n return {}\n}\n\nexport const useImageUpload = (): UseImageUploadReturns => {\n const {createImageUploadLink, completeImageUpload} = useShopActions()\n\n const uploadImage = useCallback(\n async (params: UploadImageParams[]) => {\n if (params.length > 1) {\n throw new Error('Multiple image upload is not supported yet')\n }\n\n const imageParams = params[0]\n const processedImageParams = await processFileData(imageParams)\n\n const links = await createImageUploadLink({\n input: [\n {\n mimeType: processedImageParams.mimeType,\n fileSize: processedImageParams.fileSize,\n },\n ],\n })\n\n if (!links.ok) {\n throw new Error(links.error.message)\n }\n\n // Upload single file to GCS\n const {error: uploadError} = await uploadFileToGCS(\n processedImageParams,\n links?.data?.targets?.[0]!\n )\n\n if (uploadError) {\n throw new Error(uploadError)\n }\n\n // 10 second polling for image upload\n let count = 0\n while (count < 30) {\n const result = await completeImageUpload({\n resourceUrls:\n links?.data?.targets?.map(target => target.resourceUrl) || [],\n })\n\n if (!result.ok) {\n throw new Error(result.error.message)\n }\n\n if (result.data?.files?.[0]?.fileStatus === 'READY') {\n return [\n {\n id: result.data.files[0].id,\n imageUrl: result.data.files[0].image?.url,\n resourceUrl: links?.data?.targets?.[0]?.resourceUrl,\n },\n ]\n }\n\n await new Promise(resolve => setTimeout(resolve, 1000))\n count++\n }\n\n throw new Error('Image upload completion timed out')\n },\n [createImageUploadLink, completeImageUpload]\n )\n\n return {\n uploadImage,\n }\n}\n"],"names":["processFileData","image","blob","uploadFileToGCS","target","formData","name","value","uploadResponse","useImageUpload","createImageUploadLink","completeImageUpload","useShopActions","useCallback","params","imageParams","processedImageParams","links","uploadError","count","result","resolve"],"mappings":";;AA6CA,MAAMA,IAAkB,OAAOC,MAA6B;AAEpD,QAAAC,IAAO,OADI,MAAM,MAAMD,EAAM,GAAG,GACV,KAAK;AAE1B,SAAA;AAAA,IACL,GAAGA;AAAA,IACH,UAAUA,EAAM,YAAYC,EAAK;AAAA,IACjC,UAAUA;AAAA,EACZ;AACF,GAEMC,IAAkB,OACtBF,GACAG,MACG;AACG,QAAAC,IAAW,IAAI,SAAS;AAC9B,EAAAD,EAAO,WAAW,QAAQ,CAAC,EAAC,MAAAE,GAAM,OAAAC,QAA0C;AACjE,IAAAF,EAAA,OAAOC,GAAMC,CAAK;AAAA,EAAA,CAC5B,GAEQF,EAAA,OAAO,QAAQJ,EAAM,QAAQ;AAEtC,QAAMO,IAAiB,MAAM,MAAMJ,EAAO,KAAK;AAAA,IAC7C,QAAQ;AAAA,IACR,MAAMC;AAAA,EAAA,CACP;AAEG,SAACG,EAAe,KAOb,CAAC,KANN,QAAQ,MAAM,0BAA0B;AAAA,IACtC,UAAU,MAAMA,EAAe,KAAK;AAAA,EAAA,CACrC,GACM,EAAC,OAAO,yBAAwB;AAI3C,GAEaC,IAAiB,MAA6B;AACzD,QAAM,EAAC,uBAAAC,GAAuB,qBAAAC,EAAmB,IAAIC,EAAe;AAiE7D,SAAA;AAAA,IACL,aAhEkBC;AAAA,MAClB,OAAOC,MAAgC;AACjC,YAAAA,EAAO,SAAS;AACZ,gBAAA,IAAI,MAAM,4CAA4C;AAGxD,cAAAC,IAAcD,EAAO,CAAC,GACtBE,IAAuB,MAAMhB,EAAgBe,CAAW,GAExDE,IAAQ,MAAMP,EAAsB;AAAA,UACxC,OAAO;AAAA,YACL;AAAA,cACE,UAAUM,EAAqB;AAAA,cAC/B,UAAUA,EAAqB;AAAA,YAAA;AAAA,UACjC;AAAA,QACF,CACD;AAEG,YAAA,CAACC,EAAM;AACT,gBAAM,IAAI,MAAMA,EAAM,MAAM,OAAO;AAIrC,cAAM,EAAC,OAAOC,EAAW,IAAI,MAAMf;AAAA,UACjCa;AAAA,UACAC,GAAO,MAAM,UAAU,CAAC;AAAA,QAC1B;AAEA,YAAIC;AACI,gBAAA,IAAI,MAAMA,CAAW;AAI7B,YAAIC,IAAQ;AACZ,eAAOA,IAAQ,MAAI;AACX,gBAAAC,IAAS,MAAMT,EAAoB;AAAA,YACvC,cACEM,GAAO,MAAM,SAAS,IAAI,CAAUb,MAAAA,EAAO,WAAW,KAAK,CAAA;AAAA,UAAC,CAC/D;AAEG,cAAA,CAACgB,EAAO;AACV,kBAAM,IAAI,MAAMA,EAAO,MAAM,OAAO;AAGtC,cAAIA,EAAO,MAAM,QAAQ,CAAC,GAAG,eAAe;AACnC,mBAAA;AAAA,cACL;AAAA,gBACE,IAAIA,EAAO,KAAK,MAAM,CAAC,EAAE;AAAA,gBACzB,UAAUA,EAAO,KAAK,MAAM,CAAC,EAAE,OAAO;AAAA,gBACtC,aAAaH,GAAO,MAAM,UAAU,CAAC,GAAG;AAAA,cAAA;AAAA,YAE5C;AAGF,gBAAM,IAAI,QAAQ,CAAAI,MAAW,WAAWA,GAAS,GAAI,CAAC,GACtDF;AAAA,QAAA;AAGI,cAAA,IAAI,MAAM,mCAAmC;AAAA,MACrD;AAAA,MACA,CAACT,GAAuBC,CAAmB;AAAA,IAC7C;AAAA,EAIA;AACF;"}
|
package/dist/index.js
CHANGED
|
@@ -2,11 +2,11 @@ import { DATA_NAVIGATION_TYPE_ATTRIBUTE as o, NAVIGATION_TYPES as t } from "./ty
|
|
|
2
2
|
import { MinisContainer as i } from "./components/MinisContainer.js";
|
|
3
3
|
import { ProductCard as p } from "./components/commerce/product-card.js";
|
|
4
4
|
import { ProductLink as s } from "./components/commerce/product-link.js";
|
|
5
|
-
import { MerchantCard as
|
|
5
|
+
import { MerchantCard as f, MerchantCardPrimitive as u } from "./components/commerce/merchant-card.js";
|
|
6
6
|
import { ProductCardSkeleton as c } from "./components/commerce/product-card-skeleton.js";
|
|
7
7
|
import { MerchantCardSkeleton as g } from "./components/commerce/merchant-card-skeleton.js";
|
|
8
8
|
import { QuantitySelector as D } from "./components/commerce/quantity-selector.js";
|
|
9
|
-
import { TransitionContainer as
|
|
9
|
+
import { TransitionContainer as A } from "./components/navigation/transition-container.js";
|
|
10
10
|
import { TransitionLink as T } from "./components/navigation/transition-link.js";
|
|
11
11
|
import { Button as I } from "./components/atoms/button.js";
|
|
12
12
|
import { FavoriteButton as v } from "./components/atoms/favorite-button.js";
|
|
@@ -16,28 +16,28 @@ import { Touchable as E } from "./components/atoms/touchable.js";
|
|
|
16
16
|
import { AlertDialogAtom as N } from "./components/atoms/alert-dialog.js";
|
|
17
17
|
import { List as L } from "./components/atoms/list.js";
|
|
18
18
|
import { VideoPlayer as H } from "./components/atoms/video-player.js";
|
|
19
|
-
import { Accordion as
|
|
19
|
+
import { Accordion as U, AccordionContent as V, AccordionItem as z, AccordionTrigger as _ } from "./components/ui/accordion.js";
|
|
20
20
|
import { Alert as Q, AlertDescription as W, AlertTitle as j } from "./components/ui/alert.js";
|
|
21
21
|
import { AlertDialog as J, AlertDialogAction as K, AlertDialogCancel as X, AlertDialogContent as Z, AlertDialogDescription as $, AlertDialogFooter as rr, AlertDialogHeader as er, AlertDialogOverlay as or, AlertDialogPortal as tr, AlertDialogTitle as ar, AlertDialogTrigger as ir } from "./components/ui/alert-dialog.js";
|
|
22
22
|
import { Avatar as pr, AvatarFallback as mr, AvatarImage as sr } from "./components/ui/avatar.js";
|
|
23
|
-
import { Badge as
|
|
24
|
-
import { Card as cr, CardAction as dr, CardContent as gr, CardDescription as Sr, CardFooter as Dr, CardHeader as
|
|
23
|
+
import { Badge as fr, badgeVariants as ur } from "./components/ui/badge.js";
|
|
24
|
+
import { Card as cr, CardAction as dr, CardContent as gr, CardDescription as Sr, CardFooter as Dr, CardHeader as Cr, CardTitle as Ar } from "./components/ui/card.js";
|
|
25
25
|
import { Carousel as Tr, CarouselContent as hr, CarouselItem as Ir, CarouselNext as wr, CarouselPrevious as vr } from "./components/ui/carousel.js";
|
|
26
26
|
import { Checkbox as br } from "./components/ui/checkbox.js";
|
|
27
27
|
import { Dialog as kr, DialogClose as Br, DialogContent as Er, DialogDescription as Mr, DialogFooter as Nr, DialogHeader as yr, DialogOverlay as Lr, DialogPortal as Gr, DialogTitle as Hr, DialogTrigger as Or } from "./components/ui/dialog.js";
|
|
28
|
-
import { Drawer as
|
|
28
|
+
import { Drawer as Vr, DrawerClose as zr, DrawerContent as _r, DrawerDescription as Yr, DrawerFooter as Qr, DrawerHeader as Wr, DrawerOverlay as jr, DrawerPortal as qr, DrawerTitle as Jr, DrawerTrigger as Kr } from "./components/ui/drawer.js";
|
|
29
29
|
import { Input as Zr } from "./components/ui/input.js";
|
|
30
30
|
import { Label as re } from "./components/ui/label.js";
|
|
31
31
|
import { Progress as oe } from "./components/ui/progress.js";
|
|
32
32
|
import { RadioGroup as ae, RadioGroupItem as ie } from "./components/ui/radio-group.js";
|
|
33
33
|
import { ResizableHandle as pe, ResizablePanel as me, ResizablePanelGroup as se } from "./components/ui/resizable.js";
|
|
34
|
-
import { ScrollArea as
|
|
35
|
-
import { Select as ce, SelectContent as de, SelectGroup as ge, SelectItem as Se, SelectLabel as De, SelectScrollDownButton as
|
|
34
|
+
import { ScrollArea as fe, ScrollBar as ue } from "./components/ui/scroll-area.js";
|
|
35
|
+
import { Select as ce, SelectContent as de, SelectGroup as ge, SelectItem as Se, SelectLabel as De, SelectScrollDownButton as Ce, SelectScrollUpButton as Ae, SelectSeparator as Pe, SelectTrigger as Te, SelectValue as he } from "./components/ui/select.js";
|
|
36
36
|
import { Separator as we } from "./components/ui/separator.js";
|
|
37
37
|
import { Sheet as Re, SheetClose as be, SheetContent as Fe, SheetDescription as ke, SheetFooter as Be, SheetHeader as Ee, SheetTitle as Me, SheetTrigger as Ne } from "./components/ui/sheet.js";
|
|
38
38
|
import { Toaster as Le } from "./components/ui/sonner.js";
|
|
39
39
|
import { Skeleton as He } from "./components/ui/skeleton.js";
|
|
40
|
-
import { useRecentProducts as
|
|
40
|
+
import { useRecentProducts as Ue } from "./hooks/user/useRecentProducts.js";
|
|
41
41
|
import { useRecentShops as ze } from "./hooks/user/useRecentShops.js";
|
|
42
42
|
import { useSavedProducts as Ye } from "./hooks/user/useSavedProducts.js";
|
|
43
43
|
import { useSavedProductsActions as We } from "./hooks/user/useSavedProductsActions.js";
|
|
@@ -50,10 +50,10 @@ import { useProductListActions as ao } from "./hooks/product/useProductListActio
|
|
|
50
50
|
import { useProductLists as lo } from "./hooks/product/useProductLists.js";
|
|
51
51
|
import { useProductList as mo } from "./hooks/product/useProductList.js";
|
|
52
52
|
import { useProduct as no } from "./hooks/product/useProduct.js";
|
|
53
|
-
import { useProducts as
|
|
53
|
+
import { useProducts as uo } from "./hooks/product/useProducts.js";
|
|
54
54
|
import { useProductVariants as co } from "./hooks/product/useProductVariants.js";
|
|
55
55
|
import { useProductMedia as So } from "./hooks/product/useProductMedia.js";
|
|
56
|
-
import { useProductSearch as
|
|
56
|
+
import { useProductSearch as Co } from "./hooks/product/useProductSearch.js";
|
|
57
57
|
import { useRecommendedProducts as Po } from "./hooks/product/useRecommendedProducts.js";
|
|
58
58
|
import { usePopularProducts as ho } from "./hooks/product/usePopularProducts.js";
|
|
59
59
|
import { useCuratedProducts as wo } from "./hooks/product/useCuratedProducts.js";
|
|
@@ -64,20 +64,22 @@ import { useShopNavigation as Mo } from "./hooks/navigation/useShopNavigation.js
|
|
|
64
64
|
import { useCloseMini as yo } from "./hooks/navigation/useCloseMini.js";
|
|
65
65
|
import { useDeeplink as Go } from "./hooks/navigation/useDeeplink.js";
|
|
66
66
|
import { useNavigateWithTransition as Oo } from "./hooks/navigation/useNavigateWithTransition.js";
|
|
67
|
-
import { useShop as
|
|
67
|
+
import { useShop as Vo } from "./hooks/shop/useShop.js";
|
|
68
68
|
import { useShopCartActions as _o } from "./hooks/shop/useShopCartActions.js";
|
|
69
69
|
import { useRecommendedShops as Qo } from "./hooks/shop/useRecommendedShops.js";
|
|
70
|
-
import {
|
|
71
|
-
import {
|
|
72
|
-
import {
|
|
73
|
-
import {
|
|
74
|
-
import {
|
|
75
|
-
import {
|
|
76
|
-
import {
|
|
77
|
-
import {
|
|
70
|
+
import { useCreateImageContent as jo } from "./hooks/content/useCreateImageContent.js";
|
|
71
|
+
import { useErrorToast as Jo } from "./hooks/util/useErrorToast.js";
|
|
72
|
+
import { useErrorScreen as Xo } from "./hooks/util/useErrorScreen.js";
|
|
73
|
+
import { useShare as $o } from "./hooks/util/useShare.js";
|
|
74
|
+
import { useImagePicker as et } from "./hooks/util/useImagePicker.js";
|
|
75
|
+
import { MiniEntityNotFoundError as tt, MiniError as at, MiniNetworkError as it, formatError as lt } from "./utils/errors.js";
|
|
76
|
+
import { extractBrandTheme as mt, formatReviewCount as st, getFeaturedImages as nt, normalizeRating as ft } from "./utils/merchant-card.js";
|
|
77
|
+
import { parseUrl as xt } from "./utils/parseUrl.js";
|
|
78
|
+
import { fileToDataUri as dt } from "./utils/imageToDataUri.js";
|
|
79
|
+
import { Consent as St, ConsentStatus as Dt } from "./shop-minis-platform/src/types/permissions.js";
|
|
78
80
|
export {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
+
U as Accordion,
|
|
82
|
+
V as AccordionContent,
|
|
81
83
|
z as AccordionItem,
|
|
82
84
|
_ as AccordionTrigger,
|
|
83
85
|
Q as Alert,
|
|
@@ -98,23 +100,23 @@ export {
|
|
|
98
100
|
pr as Avatar,
|
|
99
101
|
mr as AvatarFallback,
|
|
100
102
|
sr as AvatarImage,
|
|
101
|
-
|
|
103
|
+
fr as Badge,
|
|
102
104
|
I as Button,
|
|
103
105
|
cr as Card,
|
|
104
106
|
dr as CardAction,
|
|
105
107
|
gr as CardContent,
|
|
106
108
|
Sr as CardDescription,
|
|
107
109
|
Dr as CardFooter,
|
|
108
|
-
|
|
109
|
-
|
|
110
|
+
Cr as CardHeader,
|
|
111
|
+
Ar as CardTitle,
|
|
110
112
|
Tr as Carousel,
|
|
111
113
|
hr as CarouselContent,
|
|
112
114
|
Ir as CarouselItem,
|
|
113
115
|
wr as CarouselNext,
|
|
114
116
|
vr as CarouselPrevious,
|
|
115
117
|
br as Checkbox,
|
|
116
|
-
|
|
117
|
-
|
|
118
|
+
St as Consent,
|
|
119
|
+
Dt as ConsentStatus,
|
|
118
120
|
o as DATA_NAVIGATION_TYPE_ATTRIBUTE,
|
|
119
121
|
kr as Dialog,
|
|
120
122
|
Br as DialogClose,
|
|
@@ -126,7 +128,7 @@ export {
|
|
|
126
128
|
Gr as DialogPortal,
|
|
127
129
|
Hr as DialogTitle,
|
|
128
130
|
Or as DialogTrigger,
|
|
129
|
-
|
|
131
|
+
Vr as Drawer,
|
|
130
132
|
zr as DrawerClose,
|
|
131
133
|
_r as DrawerContent,
|
|
132
134
|
Yr as DrawerDescription,
|
|
@@ -141,12 +143,12 @@ export {
|
|
|
141
143
|
Zr as Input,
|
|
142
144
|
re as Label,
|
|
143
145
|
L as List,
|
|
144
|
-
|
|
145
|
-
|
|
146
|
+
f as MerchantCard,
|
|
147
|
+
u as MerchantCardPrimitive,
|
|
146
148
|
g as MerchantCardSkeleton,
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
149
|
+
tt as MiniEntityNotFoundError,
|
|
150
|
+
at as MiniError,
|
|
151
|
+
it as MiniNetworkError,
|
|
150
152
|
i as MinisContainer,
|
|
151
153
|
t as NAVIGATION_TYPES,
|
|
152
154
|
p as ProductCard,
|
|
@@ -159,15 +161,15 @@ export {
|
|
|
159
161
|
pe as ResizableHandle,
|
|
160
162
|
me as ResizablePanel,
|
|
161
163
|
se as ResizablePanelGroup,
|
|
162
|
-
|
|
163
|
-
|
|
164
|
+
fe as ScrollArea,
|
|
165
|
+
ue as ScrollBar,
|
|
164
166
|
ce as Select,
|
|
165
167
|
de as SelectContent,
|
|
166
168
|
ge as SelectGroup,
|
|
167
169
|
Se as SelectItem,
|
|
168
170
|
De as SelectLabel,
|
|
169
|
-
|
|
170
|
-
|
|
171
|
+
Ce as SelectScrollDownButton,
|
|
172
|
+
Ae as SelectScrollUpButton,
|
|
171
173
|
Pe as SelectSeparator,
|
|
172
174
|
Te as SelectTrigger,
|
|
173
175
|
he as SelectValue,
|
|
@@ -184,27 +186,29 @@ export {
|
|
|
184
186
|
k as ThumbhashImage,
|
|
185
187
|
Le as Toaster,
|
|
186
188
|
E as Touchable,
|
|
187
|
-
|
|
189
|
+
A as TransitionContainer,
|
|
188
190
|
T as TransitionLink,
|
|
189
191
|
H as VideoPlayer,
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
192
|
+
ur as badgeVariants,
|
|
193
|
+
mt as extractBrandTheme,
|
|
194
|
+
dt as fileToDataUri,
|
|
195
|
+
lt as formatError,
|
|
196
|
+
st as formatReviewCount,
|
|
197
|
+
nt as getFeaturedImages,
|
|
198
|
+
ft as normalizeRating,
|
|
199
|
+
xt as parseUrl,
|
|
197
200
|
Ro as useAsyncStorage,
|
|
198
201
|
oo as useBuyerAttributes,
|
|
199
202
|
yo as useCloseMini,
|
|
203
|
+
jo as useCreateImageContent,
|
|
200
204
|
wo as useCuratedProducts,
|
|
201
205
|
Ze as useCurrentUser,
|
|
202
206
|
Go as useDeeplink,
|
|
203
|
-
|
|
204
|
-
|
|
207
|
+
Xo as useErrorScreen,
|
|
208
|
+
Jo as useErrorToast,
|
|
205
209
|
qe as useFollowedShops,
|
|
206
210
|
Ke as useFollowedShopsActions,
|
|
207
|
-
|
|
211
|
+
et as useImagePicker,
|
|
208
212
|
Bo as useImageUpload,
|
|
209
213
|
Oo as useNavigateWithTransition,
|
|
210
214
|
ro as useOrders,
|
|
@@ -214,18 +218,18 @@ export {
|
|
|
214
218
|
ao as useProductListActions,
|
|
215
219
|
lo as useProductLists,
|
|
216
220
|
So as useProductMedia,
|
|
217
|
-
|
|
221
|
+
Co as useProductSearch,
|
|
218
222
|
co as useProductVariants,
|
|
219
|
-
|
|
220
|
-
|
|
223
|
+
uo as useProducts,
|
|
224
|
+
Ue as useRecentProducts,
|
|
221
225
|
ze as useRecentShops,
|
|
222
226
|
Po as useRecommendedProducts,
|
|
223
227
|
Qo as useRecommendedShops,
|
|
224
228
|
Ye as useSavedProducts,
|
|
225
229
|
We as useSavedProductsActions,
|
|
226
230
|
Fo as useSecureStorage,
|
|
227
|
-
|
|
228
|
-
|
|
231
|
+
$o as useShare,
|
|
232
|
+
Vo as useShop,
|
|
229
233
|
_o as useShopCartActions,
|
|
230
234
|
Mo as useShopNavigation
|
|
231
235
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/mocks.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
const e = (t, o,
|
|
1
|
+
const e = (t, o, r = "99.99", s) => ({
|
|
2
2
|
id: t,
|
|
3
3
|
title: o,
|
|
4
|
-
price: { amount:
|
|
4
|
+
price: { amount: r, currencyCode: "USD" },
|
|
5
5
|
...s && {
|
|
6
6
|
compareAtPrice: { amount: s, currencyCode: "USD" }
|
|
7
7
|
},
|
|
8
8
|
reviewAnalytics: { averageRating: 4.5, reviewCount: 10 },
|
|
9
|
-
shop:
|
|
9
|
+
shop: i("shop1", "Mock Shop"),
|
|
10
10
|
defaultVariantId: `variant-${t}`,
|
|
11
11
|
isFavorited: !1,
|
|
12
12
|
featuredImage: {
|
|
13
13
|
url: "https://cdn.shopify.com/s/files/1/0621/0463/3599/files/61ChhrRjK9L._AC_SL1000_1639abe8-4cd3-4bee-9867-73f26b0acf0a.jpg?v=1702559955",
|
|
14
14
|
altText: o
|
|
15
15
|
}
|
|
16
|
-
}),
|
|
16
|
+
}), i = (t, o, r) => {
|
|
17
17
|
const c = Array.from({ length: 3 }, (m, n) => ({
|
|
18
18
|
url: `https://picsum.photos/400/400?random=${t}-${n}`,
|
|
19
19
|
sensitive: !1,
|
|
@@ -36,19 +36,19 @@ const e = (t, o, a = "99.99", s) => ({
|
|
|
36
36
|
brandSettings: void 0
|
|
37
37
|
}
|
|
38
38
|
};
|
|
39
|
-
},
|
|
39
|
+
}, a = (t = !1) => ({
|
|
40
40
|
hasNextPage: t,
|
|
41
41
|
endCursor: t ? "cursor123" : null
|
|
42
|
-
}),
|
|
42
|
+
}), d = (t, o, r = []) => ({
|
|
43
43
|
id: t,
|
|
44
44
|
publicId: `public-${t}`,
|
|
45
45
|
name: o,
|
|
46
|
-
products:
|
|
46
|
+
products: r
|
|
47
47
|
});
|
|
48
48
|
function p(t, o) {
|
|
49
|
-
return (
|
|
49
|
+
return (r) => (console.log(`[Mock Action] ${String(t)}`, r), Promise.resolve({ ok: !0, data: o }));
|
|
50
50
|
}
|
|
51
|
-
function
|
|
51
|
+
function l() {
|
|
52
52
|
const t = {
|
|
53
53
|
followShop: !0,
|
|
54
54
|
unfollowShop: !1,
|
|
@@ -123,20 +123,20 @@ function u() {
|
|
|
123
123
|
reportContentImpression: void 0,
|
|
124
124
|
getProductLists: {
|
|
125
125
|
data: [
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
d("list-1", "Wishlist"),
|
|
127
|
+
d("list-2", "Favorites")
|
|
128
128
|
],
|
|
129
|
-
pageInfo:
|
|
129
|
+
pageInfo: a()
|
|
130
130
|
},
|
|
131
131
|
getProductList: {
|
|
132
|
-
data:
|
|
132
|
+
data: d("list-1", "Wishlist", [
|
|
133
133
|
e("prod-1", "Sample Product")
|
|
134
134
|
]),
|
|
135
|
-
pageInfo:
|
|
135
|
+
pageInfo: a()
|
|
136
136
|
},
|
|
137
|
-
addProductList:
|
|
137
|
+
addProductList: d("list-3", "New List"),
|
|
138
138
|
removeProductList: void 0,
|
|
139
|
-
renameProductList:
|
|
139
|
+
renameProductList: d("list-1", "Updated Wishlist"),
|
|
140
140
|
addProductListItem: void 0,
|
|
141
141
|
removeProductListItem: void 0,
|
|
142
142
|
getRecommendedProducts: {
|
|
@@ -151,21 +151,21 @@ function u() {
|
|
|
151
151
|
e("rec-8", "Recommended Product 8", "69.99"),
|
|
152
152
|
e("rec-9", "Recommended Product 9", "129.99")
|
|
153
153
|
],
|
|
154
|
-
pageInfo:
|
|
154
|
+
pageInfo: a()
|
|
155
155
|
},
|
|
156
156
|
getRecommendedShops: {
|
|
157
157
|
data: [
|
|
158
|
-
|
|
159
|
-
|
|
158
|
+
i("shop-1", "Amazing Store"),
|
|
159
|
+
i("shop-2", "Best Deals Shop")
|
|
160
160
|
],
|
|
161
|
-
pageInfo:
|
|
161
|
+
pageInfo: a()
|
|
162
162
|
},
|
|
163
163
|
searchProductsByShop: {
|
|
164
164
|
data: [
|
|
165
165
|
e("search-1", "Search Result 1", "59.99"),
|
|
166
166
|
e("search-2", "Search Result 2", "89.99")
|
|
167
167
|
],
|
|
168
|
-
pageInfo:
|
|
168
|
+
pageInfo: a()
|
|
169
169
|
},
|
|
170
170
|
getOrders: {
|
|
171
171
|
data: [
|
|
@@ -180,10 +180,10 @@ function u() {
|
|
|
180
180
|
product: null
|
|
181
181
|
}
|
|
182
182
|
],
|
|
183
|
-
shop:
|
|
183
|
+
shop: i("shop-1", "Sample Shop")
|
|
184
184
|
}
|
|
185
185
|
],
|
|
186
|
-
pageInfo:
|
|
186
|
+
pageInfo: a()
|
|
187
187
|
},
|
|
188
188
|
getBuyerAttributes: {
|
|
189
189
|
data: {
|
|
@@ -208,7 +208,7 @@ function u() {
|
|
|
208
208
|
e("pop-9", "Playstation 4", "299.95"),
|
|
209
209
|
e("pop-10", "Nintendo 3DS", "89.95")
|
|
210
210
|
],
|
|
211
|
-
pageInfo:
|
|
211
|
+
pageInfo: a()
|
|
212
212
|
},
|
|
213
213
|
share: {
|
|
214
214
|
message: "Shared!",
|
|
@@ -219,19 +219,19 @@ function u() {
|
|
|
219
219
|
e("cur-1", "Curated Product 1", "79.99"),
|
|
220
220
|
e("cur-2", "Curated Product 2", "129.99")
|
|
221
221
|
],
|
|
222
|
-
pageInfo:
|
|
222
|
+
pageInfo: a()
|
|
223
223
|
},
|
|
224
224
|
getSavedProducts: {
|
|
225
225
|
data: [e("saved-1", "Saved Product 1", "49.99")],
|
|
226
|
-
pageInfo:
|
|
226
|
+
pageInfo: a()
|
|
227
227
|
},
|
|
228
228
|
getRecentProducts: {
|
|
229
229
|
data: [e("recent-1", "Recent Product 1", "59.99")],
|
|
230
|
-
pageInfo:
|
|
230
|
+
pageInfo: a()
|
|
231
231
|
},
|
|
232
232
|
getProductSearch: {
|
|
233
233
|
data: [e("search-3", "Search Product 3", "39.99")],
|
|
234
|
-
pageInfo:
|
|
234
|
+
pageInfo: a()
|
|
235
235
|
},
|
|
236
236
|
getProducts: { data: [e("prod-2", "Product 2", "19.99")] },
|
|
237
237
|
getProduct: { data: e("prod-1", "Sample Product") },
|
|
@@ -245,7 +245,7 @@ function u() {
|
|
|
245
245
|
compareAtPrice: { amount: "29.99", currencyCode: "USD" }
|
|
246
246
|
}
|
|
247
247
|
],
|
|
248
|
-
pageInfo:
|
|
248
|
+
pageInfo: a()
|
|
249
249
|
},
|
|
250
250
|
getProductMedia: {
|
|
251
251
|
data: [
|
|
@@ -256,31 +256,48 @@ function u() {
|
|
|
256
256
|
alt: "Sample product image"
|
|
257
257
|
}
|
|
258
258
|
],
|
|
259
|
-
pageInfo:
|
|
259
|
+
pageInfo: a()
|
|
260
260
|
},
|
|
261
|
-
getShop: { data:
|
|
261
|
+
getShop: { data: i("shop-1", "Sample Shop") },
|
|
262
262
|
getRecentShops: {
|
|
263
|
-
data: [
|
|
264
|
-
pageInfo:
|
|
263
|
+
data: [i("recent-shop-1", "Recent Shop 1")],
|
|
264
|
+
pageInfo: a()
|
|
265
265
|
},
|
|
266
266
|
getFollowedShops: {
|
|
267
|
-
data: [
|
|
268
|
-
pageInfo:
|
|
267
|
+
data: [i("followed-shop-1", "Followed Shop 1")],
|
|
268
|
+
pageInfo: a()
|
|
269
269
|
},
|
|
270
|
-
previewProductInAr: void 0
|
|
270
|
+
previewProductInAr: void 0,
|
|
271
|
+
createContent: {
|
|
272
|
+
data: {
|
|
273
|
+
publicId: "content-123",
|
|
274
|
+
externalId: null,
|
|
275
|
+
image: {
|
|
276
|
+
id: "img-123",
|
|
277
|
+
url: "https://example.com/content-image.jpg",
|
|
278
|
+
width: 800,
|
|
279
|
+
height: 600
|
|
280
|
+
},
|
|
281
|
+
title: "Mock Content",
|
|
282
|
+
description: "This is a mock content item",
|
|
283
|
+
visibility: ["DISCOVERABLE"],
|
|
284
|
+
shareableUrl: "https://example.com/content/123",
|
|
285
|
+
products: null
|
|
286
|
+
}
|
|
287
|
+
}
|
|
271
288
|
}, o = {};
|
|
272
|
-
for (const
|
|
273
|
-
Object.prototype.hasOwnProperty.call(t,
|
|
274
|
-
|
|
275
|
-
t[
|
|
289
|
+
for (const r in t)
|
|
290
|
+
Object.prototype.hasOwnProperty.call(t, r) && (o[r] = p(
|
|
291
|
+
r,
|
|
292
|
+
t[r]
|
|
276
293
|
));
|
|
277
294
|
return o;
|
|
278
295
|
}
|
|
279
|
-
const
|
|
280
|
-
const t = navigator.userAgent.toLowerCase(), o = /iphone|ipad|ipod/.test(t),
|
|
281
|
-
return o ||
|
|
296
|
+
const u = () => {
|
|
297
|
+
const t = navigator.userAgent.toLowerCase(), o = /iphone|ipad|ipod/.test(t), r = /android/.test(t);
|
|
298
|
+
return o || r;
|
|
282
299
|
}, g = () => {
|
|
283
|
-
|
|
300
|
+
u() || window.minisSDK || (window.minisSDK = l(), window.minisParams = {
|
|
284
301
|
handle: "mock-handle",
|
|
285
302
|
initialUrl: "/mock-initial-url",
|
|
286
303
|
platform: "web"
|
|
@@ -288,7 +305,7 @@ const l = () => {
|
|
|
288
305
|
};
|
|
289
306
|
export {
|
|
290
307
|
e as createProduct,
|
|
291
|
-
|
|
308
|
+
i as createShop,
|
|
292
309
|
g as injectMocks
|
|
293
310
|
};
|
|
294
311
|
//# sourceMappingURL=mocks.js.map
|
package/dist/mocks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mocks.js","sources":["../src/mocks.ts"],"sourcesContent":["import {Product, Gender} 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/s/files/1/0621/0463/3599/files/61ChhrRjK9L._AC_SL1000_1639abe8-4cd3-4bee-9867-73f26b0acf0a.jpg?v=1702559955`,\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\nfunction makeMockActions(): ShopActions {\n const results: {\n [K in keyof ShopActions]: ShopActionDataType<ShopActions[K]>\n } = {\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 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 } 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 = () => {\n // Only inject mocks if we aren't on a mobile device\n if (isMobile()) {\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","mock","isMobile","userAgent","isIOS","isAndroid","injectMocks"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mocks.js","sources":["../src/mocks.ts"],"sourcesContent":["import {Product, Gender} 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/s/files/1/0621/0463/3599/files/61ChhrRjK9L._AC_SL1000_1639abe8-4cd3-4bee-9867-73f26b0acf0a.jpg?v=1702559955`,\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\nfunction makeMockActions(): ShopActions {\n const results: {\n [K in keyof ShopActions]: ShopActionDataType<ShopActions[K]>\n } = {\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 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://example.com/content-image.jpg',\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 } 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 = () => {\n // Only inject mocks if we aren't on a mobile device\n if (isMobile()) {\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","mock","isMobile","userAgent","isIOS","isAndroid","injectMocks"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __module as q } from "../../../../../../../../_virtual/
|
|
1
|
+
import { __module as q } from "../../../../../../../../_virtual/index5.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";
|
|
@@ -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/
|
|
5
|
+
import { l as Q } from "../../../../../../../_virtual/index6.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];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imageToDataUri.js","sources":["../../src/utils/imageToDataUri.ts"],"sourcesContent":["export function fileToDataUri(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onloadend = () => resolve(reader.result as string)\n reader.onerror = reject\n reader.readAsDataURL(file)\n })\n}\n"],"names":["fileToDataUri","file","resolve","reject","reader"],"mappings":"AAAO,SAASA,EAAcC,GAA6B;AACzD,SAAO,IAAI,QAAQ,CAACC,GAASC,MAAW;AAChC,UAAAC,IAAS,IAAI,WAAW;AAC9B,IAAAA,EAAO,YAAY,MAAMF,EAAQE,EAAO,MAAgB,GACxDA,EAAO,UAAUD,GACjBC,EAAO,cAAcH,CAAI;AAAA,EAAA,CAC1B;AACH;"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shopify/shop-minis-react",
|
|
3
3
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.25",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"typescript": ">=5.0.0"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@shopify/shop-minis-platform": "0.0.
|
|
41
|
+
"@shopify/shop-minis-platform": "0.0.8",
|
|
42
42
|
"@tailwindcss/vite": "4.1.8",
|
|
43
43
|
"@types/url-parse": "1.4.9",
|
|
44
44
|
"@types/video.js": "7.3.58",
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {useCallback} from 'react'
|
|
2
|
+
|
|
3
|
+
import {ContentVisibility} from '@shopify/shop-minis-platform'
|
|
4
|
+
import {CreateContentResponse} from '@shopify/shop-minis-platform/actions'
|
|
5
|
+
|
|
6
|
+
import {useHandleAction} from '../../internal/useHandleAction'
|
|
7
|
+
import {useShopActions} from '../../internal/useShopActions'
|
|
8
|
+
import {fileToDataUri} from '../../utils'
|
|
9
|
+
import {useImageUpload} from '../storage/useImageUpload'
|
|
10
|
+
|
|
11
|
+
interface CreateImageContentParams {
|
|
12
|
+
image: File
|
|
13
|
+
contentTitle: string
|
|
14
|
+
visibility?: ContentVisibility[] | null
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface UseCreateImageContentReturns {
|
|
18
|
+
/**
|
|
19
|
+
* Upload an image and create content.
|
|
20
|
+
*/
|
|
21
|
+
createImageContent: (
|
|
22
|
+
params: CreateImageContentParams
|
|
23
|
+
) => Promise<CreateContentResponse>
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const useCreateImageContent = (): UseCreateImageContentReturns => {
|
|
27
|
+
const {createContent} = useShopActions()
|
|
28
|
+
const {uploadImage} = useImageUpload()
|
|
29
|
+
|
|
30
|
+
const createImageContent = useCallback(
|
|
31
|
+
async (params: CreateImageContentParams) => {
|
|
32
|
+
const {image, contentTitle, visibility} = params
|
|
33
|
+
|
|
34
|
+
if (!image.type) {
|
|
35
|
+
throw new Error('Unable to determine file type')
|
|
36
|
+
}
|
|
37
|
+
if (!image.type.startsWith('image/')) {
|
|
38
|
+
throw new Error('Invalid file type: must be an image')
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const [uploadImageResult] = await uploadImage([
|
|
42
|
+
{
|
|
43
|
+
mimeType: image.type,
|
|
44
|
+
uri: await fileToDataUri(image),
|
|
45
|
+
},
|
|
46
|
+
])
|
|
47
|
+
const uploadImageUrl = uploadImageResult.imageUrl
|
|
48
|
+
|
|
49
|
+
if (!uploadImageUrl) {
|
|
50
|
+
throw new Error('Image upload failed')
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return createContent({
|
|
54
|
+
title: contentTitle,
|
|
55
|
+
imageUrl: uploadImageUrl,
|
|
56
|
+
visibility,
|
|
57
|
+
})
|
|
58
|
+
},
|
|
59
|
+
[createContent, uploadImage]
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
createImageContent: useHandleAction(createImageContent),
|
|
64
|
+
}
|
|
65
|
+
}
|
package/src/hooks/index.ts
CHANGED
|
@@ -12,7 +12,7 @@ export interface UploadImageParams {
|
|
|
12
12
|
/**
|
|
13
13
|
* The size of the image in bytes.
|
|
14
14
|
*/
|
|
15
|
-
fileSize
|
|
15
|
+
fileSize?: number
|
|
16
16
|
/**
|
|
17
17
|
* The URI of the image to upload.
|
|
18
18
|
*/
|
|
@@ -41,16 +41,29 @@ interface UseImageUploadReturns {
|
|
|
41
41
|
uploadImage: (params: UploadImageParams[]) => Promise<UploadedImage[]>
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
// Fetch file data and detect file sizes if not provided
|
|
45
|
+
// Works with file://, data:, and http(s):// URIs
|
|
46
|
+
const processFileData = async (image: UploadImageParams) => {
|
|
47
|
+
const response = await fetch(image.uri)
|
|
48
|
+
const blob = await response.blob()
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
...image,
|
|
52
|
+
fileSize: image.fileSize ?? blob.size,
|
|
53
|
+
fileBlob: blob,
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
44
57
|
const uploadFileToGCS = async (
|
|
45
|
-
image: UploadImageParams,
|
|
58
|
+
image: UploadImageParams & {fileSize: number; fileBlob: Blob},
|
|
46
59
|
target: UploadTarget
|
|
47
60
|
) => {
|
|
48
61
|
const formData = new FormData()
|
|
49
62
|
target.parameters.forEach(({name, value}: {name: string; value: string}) => {
|
|
50
63
|
formData.append(name, value)
|
|
51
64
|
})
|
|
52
|
-
|
|
53
|
-
formData.append('file',
|
|
65
|
+
|
|
66
|
+
formData.append('file', image.fileBlob)
|
|
54
67
|
|
|
55
68
|
const uploadResponse = await fetch(target.url, {
|
|
56
69
|
method: 'POST',
|
|
@@ -76,11 +89,16 @@ export const useImageUpload = (): UseImageUploadReturns => {
|
|
|
76
89
|
throw new Error('Multiple image upload is not supported yet')
|
|
77
90
|
}
|
|
78
91
|
|
|
92
|
+
const imageParams = params[0]
|
|
93
|
+
const processedImageParams = await processFileData(imageParams)
|
|
94
|
+
|
|
79
95
|
const links = await createImageUploadLink({
|
|
80
|
-
input:
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
96
|
+
input: [
|
|
97
|
+
{
|
|
98
|
+
mimeType: processedImageParams.mimeType,
|
|
99
|
+
fileSize: processedImageParams.fileSize,
|
|
100
|
+
},
|
|
101
|
+
],
|
|
84
102
|
})
|
|
85
103
|
|
|
86
104
|
if (!links.ok) {
|
|
@@ -88,9 +106,8 @@ export const useImageUpload = (): UseImageUploadReturns => {
|
|
|
88
106
|
}
|
|
89
107
|
|
|
90
108
|
// Upload single file to GCS
|
|
91
|
-
// TODO: Upload multiple files to GCS
|
|
92
109
|
const {error: uploadError} = await uploadFileToGCS(
|
|
93
|
-
|
|
110
|
+
processedImageParams,
|
|
94
111
|
links?.data?.targets?.[0]!
|
|
95
112
|
)
|
|
96
113
|
|
|
@@ -110,7 +127,6 @@ export const useImageUpload = (): UseImageUploadReturns => {
|
|
|
110
127
|
throw new Error(result.error.message)
|
|
111
128
|
}
|
|
112
129
|
|
|
113
|
-
// TODO: Add support for multiple files
|
|
114
130
|
if (result.data?.files?.[0]?.fileStatus === 'READY') {
|
|
115
131
|
return [
|
|
116
132
|
{
|
package/src/mocks.ts
CHANGED
|
@@ -405,6 +405,23 @@ function makeMockActions(): ShopActions {
|
|
|
405
405
|
pageInfo: createPagination(),
|
|
406
406
|
},
|
|
407
407
|
previewProductInAr: undefined,
|
|
408
|
+
createContent: {
|
|
409
|
+
data: {
|
|
410
|
+
publicId: 'content-123',
|
|
411
|
+
externalId: null,
|
|
412
|
+
image: {
|
|
413
|
+
id: 'img-123',
|
|
414
|
+
url: 'https://example.com/content-image.jpg',
|
|
415
|
+
width: 800,
|
|
416
|
+
height: 600,
|
|
417
|
+
},
|
|
418
|
+
title: 'Mock Content',
|
|
419
|
+
description: 'This is a mock content item',
|
|
420
|
+
visibility: ['DISCOVERABLE'],
|
|
421
|
+
shareableUrl: 'https://example.com/content/123',
|
|
422
|
+
products: null,
|
|
423
|
+
},
|
|
424
|
+
},
|
|
408
425
|
} as const
|
|
409
426
|
|
|
410
427
|
const mock: Partial<ShopActions> = {}
|
package/src/utils/index.ts
CHANGED