mirror of
https://github.com/vercel/commerce.git
synced 2025-05-12 04:37:51 +00:00
implement upload form functions
Signed-off-by: Chloe <pinkcloudvnn@gmail.com>
This commit is contained in:
parent
0bf01447f6
commit
5385b5ed67
38
components/form/file-input/actions.ts
Normal file
38
components/form/file-input/actions.ts
Normal file
@ -0,0 +1,38 @@
|
||||
'use server';
|
||||
|
||||
import { createFile, stageUploadFile, uploadFile } from 'lib/shopify';
|
||||
import { UploadInput } from 'lib/shopify/types';
|
||||
|
||||
export const createStagedUploadFiles = async (params: UploadInput) => {
|
||||
try {
|
||||
const stagedTargets = await stageUploadFile(params);
|
||||
if (!stagedTargets || stageUploadFile.length === 0) return null;
|
||||
|
||||
return JSON.parse(JSON.stringify(stagedTargets[0]));
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
export const onUploadFile = async ({
|
||||
url,
|
||||
formData,
|
||||
fileName,
|
||||
resourceUrl
|
||||
}: {
|
||||
url: string;
|
||||
formData: FormData;
|
||||
fileName: string;
|
||||
resourceUrl: string;
|
||||
}) => {
|
||||
try {
|
||||
await uploadFile({ url, formData });
|
||||
await createFile({
|
||||
alt: fileName,
|
||||
contentType: 'FILE',
|
||||
originalSource: resourceUrl
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
42
components/form/file-input/utils.ts
Normal file
42
components/form/file-input/utils.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { StagedUploadsCreatePayload } from 'lib/shopify/types';
|
||||
import { createStagedUploadFiles, onUploadFile } from './actions';
|
||||
|
||||
export const prepareFilePayload = ({
|
||||
stagedFileUpload,
|
||||
file
|
||||
}: {
|
||||
stagedFileUpload: StagedUploadsCreatePayload;
|
||||
file: File;
|
||||
}) => {
|
||||
const formData = new FormData();
|
||||
|
||||
const url = stagedFileUpload.url;
|
||||
|
||||
stagedFileUpload.parameters.forEach(({ name, value }) => {
|
||||
formData.append(name, value);
|
||||
});
|
||||
|
||||
formData.append('file', file);
|
||||
return { url, formData };
|
||||
};
|
||||
|
||||
export const handleUploadFile = async ({ file }: { file: File }) => {
|
||||
if (!file) return;
|
||||
const stagedTarget = await createStagedUploadFiles({
|
||||
filename: file.name,
|
||||
fileSize: String(file.size),
|
||||
httpMethod: 'POST',
|
||||
resource: 'FILE',
|
||||
mimeType: file.type
|
||||
});
|
||||
|
||||
if (stagedTarget) {
|
||||
const data = prepareFilePayload({ file, stagedFileUpload: stagedTarget });
|
||||
|
||||
await onUploadFile({
|
||||
...data,
|
||||
fileName: file.name,
|
||||
resourceUrl: stagedTarget.resourceUrl
|
||||
});
|
||||
}
|
||||
};
|
@ -25,6 +25,7 @@ import {
|
||||
removeFromCartMutation,
|
||||
setCartAttributesMutation
|
||||
} from './mutations/cart';
|
||||
import { createFileMutation, createStageUploads } from './mutations/file';
|
||||
import { getCartQuery } from './queries/cart';
|
||||
import {
|
||||
getCollectionProductsQuery,
|
||||
@ -50,6 +51,7 @@ import {
|
||||
Collection,
|
||||
Connection,
|
||||
Customer,
|
||||
FileCreateInput,
|
||||
Filter,
|
||||
Fulfillment,
|
||||
Image,
|
||||
@ -71,6 +73,7 @@ import {
|
||||
ShopifyCollectionProductsOperation,
|
||||
ShopifyCollectionsOperation,
|
||||
ShopifyCreateCartOperation,
|
||||
ShopifyCreateFileOperation,
|
||||
ShopifyCustomer,
|
||||
ShopifyCustomerOperation,
|
||||
ShopifyCustomerOrderOperation,
|
||||
@ -92,9 +95,11 @@ import {
|
||||
ShopifyProductsOperation,
|
||||
ShopifyRemoveFromCartOperation,
|
||||
ShopifySetCartAttributesOperation,
|
||||
ShopifyStagedUploadOperation,
|
||||
ShopifyUpdateCartOperation,
|
||||
Transaction,
|
||||
TransmissionType
|
||||
TransmissionType,
|
||||
UploadInput
|
||||
} from './types';
|
||||
|
||||
const domain = process.env.SHOPIFY_STORE_DOMAIN
|
||||
@ -1044,3 +1049,28 @@ export const getImage = async (id: string): Promise<Image> => {
|
||||
|
||||
return res.body.data.node.image;
|
||||
};
|
||||
|
||||
export const stageUploadFile = async (params: UploadInput) => {
|
||||
const res = await adminFetch<ShopifyStagedUploadOperation>({
|
||||
query: createStageUploads,
|
||||
variables: { input: [params] }
|
||||
});
|
||||
|
||||
return res.body.data.stagedUploadsCreate.stagedTargets;
|
||||
};
|
||||
|
||||
export const uploadFile = async ({ url, formData }: { url: string; formData: FormData }) => {
|
||||
return await fetch(url, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
};
|
||||
|
||||
export const createFile = async (params: FileCreateInput) => {
|
||||
const res = await adminFetch<ShopifyCreateFileOperation>({
|
||||
query: createFileMutation,
|
||||
variables: { files: [params] }
|
||||
});
|
||||
|
||||
return res.body.data;
|
||||
};
|
||||
|
31
lib/shopify/mutations/file.ts
Normal file
31
lib/shopify/mutations/file.ts
Normal file
@ -0,0 +1,31 @@
|
||||
export const createStageUploads = /* GraphQL */ `
|
||||
mutation stagedUploadsCreate($input: [StagedUploadInput!]!) {
|
||||
stagedUploadsCreate(input: $input) {
|
||||
stagedTargets {
|
||||
url
|
||||
resourceUrl
|
||||
parameters {
|
||||
name
|
||||
value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const createFileMutation = /* GraphQL */ `
|
||||
mutation fileCreate($files: [FileCreateInput!]!) {
|
||||
fileCreate(files: $files) {
|
||||
files {
|
||||
fileStatus
|
||||
... on MediaImage {
|
||||
id
|
||||
}
|
||||
}
|
||||
userErrors {
|
||||
field
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
@ -783,3 +783,45 @@ export type CartAttributeInput = {
|
||||
key: string;
|
||||
value: string;
|
||||
};
|
||||
|
||||
export type UploadInput = {
|
||||
filename: string;
|
||||
mimeType: string;
|
||||
httpMethod: 'POST' | 'PUT';
|
||||
fileSize: string;
|
||||
resource: 'FILE' | 'IMAGE';
|
||||
};
|
||||
|
||||
export type StagedUploadsCreatePayload = {
|
||||
parameters: {
|
||||
name: string;
|
||||
value: string;
|
||||
}[];
|
||||
resourceUrl: string;
|
||||
url: string;
|
||||
};
|
||||
|
||||
export type ShopifyStagedUploadOperation = {
|
||||
data: {
|
||||
stagedUploadsCreate: {
|
||||
stagedTargets: StagedUploadsCreatePayload[];
|
||||
};
|
||||
};
|
||||
variables: { input: UploadInput[] };
|
||||
};
|
||||
|
||||
export type FileCreateInput = {
|
||||
alt: string;
|
||||
contentType: 'FILE' | 'IMAGE';
|
||||
originalSource: string;
|
||||
};
|
||||
|
||||
export type ShopifyCreateFileOperation = {
|
||||
data: {
|
||||
fileCreate: {
|
||||
files: { fileStatus: string; id: string }[];
|
||||
userErrors: { code: string; field: string; message: string }[];
|
||||
};
|
||||
};
|
||||
variables: { files: FileCreateInput[] };
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user