feat: ✨ directly interact with js File APIs and use go-js-promise helper to avoid JSON memory overhead
Some checks reported errors
continuous-integration/drone/push Build encountered an error
Some checks reported errors
continuous-integration/drone/push Build encountered an error
This commit is contained in:
parent
1e283d8946
commit
3e5484e9cd
1
go.mod
1
go.mod
@ -8,6 +8,7 @@ require (
|
|||||||
github.com/hhrutter/lzw v1.0.0 // indirect
|
github.com/hhrutter/lzw v1.0.0 // indirect
|
||||||
github.com/hhrutter/tiff v1.0.1 // indirect
|
github.com/hhrutter/tiff v1.0.1 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||||
|
github.com/nlepage/go-js-promise v1.1.0 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/rivo/uniseg v0.4.7 // indirect
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
golang.org/x/image v0.21.0 // indirect
|
golang.org/x/image v0.21.0 // indirect
|
||||||
|
2
go.sum
2
go.sum
@ -4,6 +4,8 @@ github.com/hhrutter/tiff v1.0.1 h1:MIus8caHU5U6823gx7C6jrfoEvfSTGtEFRiM8/LOzC0=
|
|||||||
github.com/hhrutter/tiff v1.0.1/go.mod h1:zU/dNgDm0cMIa8y8YwcYBeuEEveI4B0owqHyiPpJPHc=
|
github.com/hhrutter/tiff v1.0.1/go.mod h1:zU/dNgDm0cMIa8y8YwcYBeuEEveI4B0owqHyiPpJPHc=
|
||||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
|
github.com/nlepage/go-js-promise v1.1.0 h1:BfvywsIMo4cpNOKyoReBWkxEW8f9HMwXqGc45wEKPRs=
|
||||||
|
github.com/nlepage/go-js-promise v1.1.0/go.mod h1:bdOP0wObXu34euibyK39K1hoBCtlgTKXGc56AGflaRo=
|
||||||
github.com/pdfcpu/pdfcpu v0.9.1 h1:q8/KlBdHjkE7ZJU4ofhKG5Rjf7M6L324CVM6BMDySao=
|
github.com/pdfcpu/pdfcpu v0.9.1 h1:q8/KlBdHjkE7ZJU4ofhKG5Rjf7M6L324CVM6BMDySao=
|
||||||
github.com/pdfcpu/pdfcpu v0.9.1/go.mod h1:fVfOloBzs2+W2VJCCbq60XIxc3yJHAZ0Gahv1oO0gyI=
|
github.com/pdfcpu/pdfcpu v0.9.1/go.mod h1:fVfOloBzs2+W2VJCCbq60XIxc3yJHAZ0Gahv1oO0gyI=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
228
main.go
228
main.go
@ -4,7 +4,6 @@ import (
|
|||||||
"archive/zip"
|
"archive/zip"
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -14,81 +13,149 @@ import (
|
|||||||
|
|
||||||
"syscall/js"
|
"syscall/js"
|
||||||
|
|
||||||
|
promise "github.com/nlepage/go-js-promise"
|
||||||
pdfcpu "github.com/pdfcpu/pdfcpu/pkg/api"
|
pdfcpu "github.com/pdfcpu/pdfcpu/pkg/api"
|
||||||
"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/model"
|
"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Customer struct {
|
type Customer struct{ js.Value }
|
||||||
FirstName string `json:"firstName"`
|
|
||||||
LastName string `json:"lastName"`
|
func (customer Customer) GetFirstName() string {
|
||||||
|
return customer.Get("firstName").String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customer Customer) GetLastName() string {
|
||||||
|
return customer.Get("lastName").String()
|
||||||
}
|
}
|
||||||
|
|
||||||
type Document struct {
|
type Document struct {
|
||||||
ID string `json:"id"`
|
js.Value
|
||||||
Name string `json:"name"`
|
bytes []byte
|
||||||
Blob string `json:"blob"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CustomerFile struct {
|
func (document Document) GetID() string {
|
||||||
ID string `json:"id"`
|
return document.Get("id").String()
|
||||||
Documents []CustomerDocument `json:"documents"`
|
|
||||||
Suffix string `json:"suffix"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CustomerDocument struct {
|
func (document Document) GetName() string {
|
||||||
ID string `json:"id"`
|
return document.Get("file").Get("name").String()
|
||||||
SelectedPages []string `json:"selectedPages"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateArchiveInput struct {
|
func (document *Document) GetBytes() ([]byte, error) {
|
||||||
Customer Customer `json:"customer"`
|
if len(document.bytes) > 0 {
|
||||||
Documents []Document `json:"documents"`
|
return document.bytes, nil
|
||||||
Files []CustomerFile `json:"files"`
|
}
|
||||||
|
|
||||||
|
bytea, err := promise.Await(document.Get("file").Call("arrayBuffer"))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8Array := js.Global().Get("Uint8Array").New(bytea)
|
||||||
|
|
||||||
|
document.bytes = make([]byte, uint8Array.Length())
|
||||||
|
|
||||||
|
js.CopyBytesToGo(document.bytes, uint8Array)
|
||||||
|
|
||||||
|
return document.bytes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateArchiveResult struct {
|
type CustomerFile struct{ js.Value }
|
||||||
ResultArchive *string `json:"resultArchive"`
|
|
||||||
Error *string `json:"error"`
|
func (file CustomerFile) GetID() string {
|
||||||
|
return file.Get("id").String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (file CustomerFile) GetDocuments() []CustomerDocument {
|
||||||
|
ds := file.Get("documents")
|
||||||
|
|
||||||
|
cds := make([]CustomerDocument, ds.Length())
|
||||||
|
|
||||||
|
for i := range ds.Length() {
|
||||||
|
cds[i] = CustomerDocument{ds.Index(i)}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cds
|
||||||
|
}
|
||||||
|
|
||||||
|
func (file CustomerFile) GetSuffix() string {
|
||||||
|
return file.Get("suffix").String()
|
||||||
|
}
|
||||||
|
|
||||||
|
type CustomerDocument struct{ js.Value }
|
||||||
|
|
||||||
|
func (document CustomerDocument) GetID() string {
|
||||||
|
return document.Get("id").String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (document CustomerDocument) GetSelectedPages() (sps []string) {
|
||||||
|
sp := document.Get("selectedPages")
|
||||||
|
|
||||||
|
for i := range sp.Length() {
|
||||||
|
sps = append(sps, sp.Index(i).String())
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateArchiveInput struct{ js.Value }
|
||||||
|
|
||||||
|
func (input CreateArchiveInput) GetCustomer() Customer {
|
||||||
|
return Customer{input.Get("customer")}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (input CreateArchiveInput) GetDocuments() []Document {
|
||||||
|
ds := input.Get("documents")
|
||||||
|
|
||||||
|
documents := make([]Document, ds.Length())
|
||||||
|
|
||||||
|
for i := range ds.Length() {
|
||||||
|
documents[i] = Document{ds.Index(i), nil}
|
||||||
|
}
|
||||||
|
|
||||||
|
return documents
|
||||||
|
}
|
||||||
|
|
||||||
|
func (input CreateArchiveInput) GetFiles() []CustomerFile {
|
||||||
|
fs := input.Get("files")
|
||||||
|
|
||||||
|
cfs := make([]CustomerFile, fs.Length())
|
||||||
|
|
||||||
|
for i := range fs.Length() {
|
||||||
|
cfs[i] = CustomerFile{fs.Index(i)}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cfs
|
||||||
}
|
}
|
||||||
|
|
||||||
func createArchive(this js.Value, args []js.Value) any {
|
func createArchive(this js.Value, args []js.Value) any {
|
||||||
var input CreateArchiveInput
|
input := CreateArchiveInput{args[0]}
|
||||||
|
|
||||||
err := json.Unmarshal([]byte(args[0].String()), &input)
|
p, res, rej := promise.New()
|
||||||
|
|
||||||
handler := js.FuncOf(func(this js.Value, args []js.Value) any {
|
|
||||||
var (
|
|
||||||
resolve = args[0]
|
|
||||||
reject = args[1]
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
reject.Invoke(err.Error())
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
|
go func() {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
w := zip.NewWriter(buf)
|
w := zip.NewWriter(buf)
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
|
||||||
filePrefix := fmt.Sprintf("%s_%s_%s", now.Format("2006-01-02_15-04-05"), input.Customer.LastName, input.Customer.FirstName)
|
filePrefix := fmt.Sprintf("%s_%s_%s", now.Format("2006-01-02_15-04-05"), input.GetCustomer().GetLastName(), input.GetCustomer().GetFirstName())
|
||||||
|
|
||||||
var fileNames []string
|
var fileNames []string
|
||||||
|
|
||||||
for _, file := range input.Files {
|
for _, file := range input.GetFiles() {
|
||||||
if len(file.Documents) == 0 {
|
if len(file.GetDocuments()) == 0 {
|
||||||
reject.Invoke("At least one document must be provided")
|
rej("At least one document must be provided")
|
||||||
|
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var document *Document
|
var document *Document
|
||||||
|
|
||||||
for _, doc := range input.Documents {
|
for _, doc := range input.GetDocuments() {
|
||||||
if doc.ID == file.Documents[0].ID {
|
if doc.GetID() == file.GetDocuments()[0].GetID() {
|
||||||
document = &doc
|
document = &doc
|
||||||
|
|
||||||
break
|
break
|
||||||
@ -96,18 +163,18 @@ func createArchive(this js.Value, args []js.Value) any {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if document == nil {
|
if document == nil {
|
||||||
reject.Invoke("Couldn't find doc by ID: " + file.Documents[0].ID)
|
rej("Couldn't find doc by ID: " + file.GetDocuments()[0].GetID())
|
||||||
|
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ext := strings.ToLower(filepath.Ext(document.Name))
|
ext := strings.ToLower(filepath.Ext(document.GetName()))
|
||||||
|
|
||||||
fileName := fmt.Sprintf("%s_%s%s", filePrefix, file.Suffix, ext)
|
fileName := fmt.Sprintf("%s_%s%s", filePrefix, file.GetSuffix(), ext)
|
||||||
i := 1
|
i := 1
|
||||||
|
|
||||||
for slices.Index(fileNames, fileName) != -1 {
|
for slices.Index(fileNames, fileName) != -1 {
|
||||||
fileName = fmt.Sprintf("%s_%s-%d%s", filePrefix, file.Suffix, i, ext)
|
fileName = fmt.Sprintf("%s_%s-%d%s", filePrefix, file.GetSuffix(), i, ext)
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,49 +183,49 @@ func createArchive(this js.Value, args []js.Value) any {
|
|||||||
f, err := w.Create(fileName)
|
f, err := w.Create(fileName)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reject.Invoke(err.Error())
|
rej("Couldn't create file: " + err.Error())
|
||||||
|
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := base64.StdEncoding.DecodeString(document.Blob)
|
b, err := document.GetBytes()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reject.Invoke(err.Error())
|
rej("Couldn't get bytes:" + err.Error())
|
||||||
|
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if ext != ".pdf" {
|
if ext != ".pdf" {
|
||||||
_, err = f.Write(b)
|
_, err = f.Write(b)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reject.Invoke(err.Error())
|
rej("Couldn't write file:" + err.Error())
|
||||||
|
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(file.Documents) == 1 {
|
if len(file.GetDocuments()) == 1 {
|
||||||
if len(file.Documents[0].SelectedPages) > 0 {
|
if len(file.GetDocuments()[0].GetSelectedPages()) > 0 {
|
||||||
rs := bytes.NewReader(b)
|
rs := bytes.NewReader(b)
|
||||||
|
|
||||||
err = pdfcpu.Trim(rs, f, file.Documents[0].SelectedPages, nil)
|
err = pdfcpu.Trim(rs, f, file.GetDocuments()[0].GetSelectedPages(), nil)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reject.Invoke(err.Error())
|
rej("Couldn't trim PDF: " + err.Error())
|
||||||
|
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_, err = f.Write(b)
|
_, err = f.Write(b)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reject.Invoke(err.Error())
|
rej("219 - Couldn't write file:" + err.Error())
|
||||||
|
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,11 +234,11 @@ func createArchive(this js.Value, args []js.Value) any {
|
|||||||
|
|
||||||
var rsc []io.ReadSeeker
|
var rsc []io.ReadSeeker
|
||||||
|
|
||||||
for i := range file.Documents {
|
for i := range file.GetDocuments() {
|
||||||
var document *Document
|
var document *Document
|
||||||
|
|
||||||
for _, doc := range input.Documents {
|
for _, doc := range input.GetDocuments() {
|
||||||
if doc.ID == file.Documents[i].ID {
|
if doc.GetID() == file.GetDocuments()[i].GetID() {
|
||||||
document = &doc
|
document = &doc
|
||||||
|
|
||||||
break
|
break
|
||||||
@ -179,18 +246,18 @@ func createArchive(this js.Value, args []js.Value) any {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if document == nil {
|
if document == nil {
|
||||||
reject.Invoke("Couldn't find doc by ID: " + file.Documents[i].ID)
|
rej("Couldn't find doc by ID: " + file.GetDocuments()[i].GetID())
|
||||||
|
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
b, err = base64.StdEncoding.DecodeString(document.Blob)
|
b, err = document.GetBytes()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reject.Invoke(err.Error())
|
rej("251 - Couldn't get bytes:" + err.Error())
|
||||||
|
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,18 +265,18 @@ func createArchive(this js.Value, args []js.Value) any {
|
|||||||
rs = bytes.NewReader(b)
|
rs = bytes.NewReader(b)
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(file.Documents[i].SelectedPages) > 0 {
|
if len(file.GetDocuments()[i].GetSelectedPages()) > 0 {
|
||||||
var (
|
var (
|
||||||
buf []byte
|
buf []byte
|
||||||
res = bytes.NewBuffer(buf)
|
res = bytes.NewBuffer(buf)
|
||||||
)
|
)
|
||||||
|
|
||||||
err = pdfcpu.Trim(rs, res, file.Documents[i].SelectedPages, nil)
|
err = pdfcpu.Trim(rs, res, file.GetDocuments()[i].GetSelectedPages(), nil)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
reject.Invoke(err.Error())
|
rej("270 - Couldn't trim PDF: " + err.Error())
|
||||||
|
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
rsc = append(rsc, bytes.NewReader(res.Bytes()))
|
rsc = append(rsc, bytes.NewReader(res.Bytes()))
|
||||||
@ -221,19 +288,16 @@ func createArchive(this js.Value, args []js.Value) any {
|
|||||||
pdfcpu.MergeRaw(rsc, f, false, nil)
|
pdfcpu.MergeRaw(rsc, f, false, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = w.Close(); err != nil {
|
if err := w.Close(); err != nil {
|
||||||
reject.Invoke(err.Error())
|
rej("Couldn't close ZIP:" + err.Error())
|
||||||
|
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve.Invoke(base64.StdEncoding.EncodeToString(buf.Bytes()))
|
res(base64.StdEncoding.EncodeToString(buf.Bytes()))
|
||||||
|
}()
|
||||||
|
|
||||||
return nil
|
return p
|
||||||
})
|
|
||||||
|
|
||||||
promiseConstructor := js.Global().Get("Promise")
|
|
||||||
return promiseConstructor.New(handler)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -68,29 +68,17 @@ function FileOrganizer() {
|
|||||||
|
|
||||||
const handleSubmit = async ({ customer, files }: FormValues) => {
|
const handleSubmit = async ({ customer, files }: FormValues) => {
|
||||||
await createArchiveAndDownload(async () => {
|
await createArchiveAndDownload(async () => {
|
||||||
const f = await Promise.all(
|
|
||||||
files.map(async (f) => {
|
|
||||||
const dataURL = await getFileDataUrl(f.file);
|
|
||||||
|
|
||||||
return {
|
|
||||||
...f,
|
|
||||||
name: f.file.name,
|
|
||||||
blob: dataURL,
|
|
||||||
};
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const payload: CreateArchiveInput = {
|
const payload: CreateArchiveInput = {
|
||||||
customer,
|
customer,
|
||||||
documents: [],
|
documents: [],
|
||||||
files: [],
|
files: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
f.forEach(({ blob, name, suffix, selectedPages }) => {
|
files.forEach(({ file, suffix, selectedPages }) => {
|
||||||
const id = Math.random().toString(36).replace("0.", "doc_");
|
const id = Math.random().toString(36).replace("0.", "doc_");
|
||||||
const fileId = Math.random().toString(36).replace("0.", "file_");
|
const fileId = Math.random().toString(36).replace("0.", "file_");
|
||||||
|
|
||||||
payload.documents.push({ id, blob, name });
|
payload.documents.push({ id, file });
|
||||||
payload.files.push({
|
payload.files.push({
|
||||||
id: fileId,
|
id: fileId,
|
||||||
suffix,
|
suffix,
|
||||||
|
@ -2,7 +2,6 @@ import {
|
|||||||
ActionIcon,
|
ActionIcon,
|
||||||
AppShell,
|
AppShell,
|
||||||
Autocomplete,
|
Autocomplete,
|
||||||
Box,
|
|
||||||
Burger,
|
Burger,
|
||||||
Button,
|
Button,
|
||||||
Group,
|
Group,
|
||||||
@ -33,7 +32,6 @@ import {
|
|||||||
import {
|
import {
|
||||||
createArchiveAndDownload,
|
createArchiveAndDownload,
|
||||||
fileCategories,
|
fileCategories,
|
||||||
getFileDataUrl,
|
|
||||||
systemMessage,
|
systemMessage,
|
||||||
} from "./utils";
|
} from "./utils";
|
||||||
import { isNotEmpty, useForm } from "@mantine/form";
|
import { isNotEmpty, useForm } from "@mantine/form";
|
||||||
@ -235,13 +233,7 @@ function Organizrr() {
|
|||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
})),
|
})),
|
||||||
documents: await Promise.all(
|
documents,
|
||||||
documents.map(async (d) => ({
|
|
||||||
...d,
|
|
||||||
name: d.file.name,
|
|
||||||
blob: await getFileDataUrl(d.file),
|
|
||||||
}))
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
4
src/global.d.ts
vendored
4
src/global.d.ts
vendored
@ -1 +1,3 @@
|
|||||||
declare function createArchive(payload: string): Promise<string>;
|
import { CreateArchiveInput } from "./types";
|
||||||
|
|
||||||
|
declare function createArchive(payload: CreateArchiveInput): Promise<string>;
|
||||||
|
@ -5,8 +5,7 @@ export interface Customer {
|
|||||||
|
|
||||||
export interface Document {
|
export interface Document {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
file: File;
|
||||||
blob: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CustomerFile {
|
export interface CustomerFile {
|
||||||
|
@ -21,7 +21,7 @@ export const createArchiveAndDownload = async (
|
|||||||
const payload = await getPayload();
|
const payload = await getPayload();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const resultArchive = await createArchive(JSON.stringify(payload));
|
const resultArchive = await createArchive(payload);
|
||||||
|
|
||||||
notifications.update({
|
notifications.update({
|
||||||
id,
|
id,
|
||||||
|
Loading…
Reference in New Issue
Block a user