diff --git a/.env b/.env index 1077d067..8b541732 100644 --- a/.env +++ b/.env @@ -1,15 +1,5 @@ -VITE_DM_API_URL=http://localhost:3000 +VITE_DM_SOCKET_URL=http://localhost:3000 +VITE_EDGECREATOR_SOCKET_URL=http://localhost:3001 VITE_DM_URL=http://localhost:8001 -VITE_EDGECREATOR_API_URL=http://localhost:3001 VITE_EDGES_URL=http://localhost:8001/edges VITE_FONT_SEARCH_URL=https://www.myfonts.com/WhatTheFont/ - -CLOUDINARY_URL=cloudinary://955445841324817:fqXP5YDdv8n1vwNjzgDRlFHDVto@dl7hskxab -FONT_BASE_URL=https://www.myfonts.com/fonts/ -FONT_IMAGE_GEN_URL=https://render.myfonts.net/fonts/font_rend.php -FONT_PRODUCT_BASE_URL=https://www.myfonts.com/products/ - -# Used only in the backend, so with the api directory as basis -EDGES_PATH=../DucksManager/edges - -TOKEN_SECRET=3543c30fe79047b4f73cfb61aa1eb52cb3173de4b3941e0fc4ec1b127bbeed6019695a1a453a81c33c2eea964ccc577e69c7df994124bd2751e262a311ea23a1 diff --git a/.eslintcache b/.eslintcache deleted file mode 100644 index 32d185e6..00000000 --- a/.eslintcache +++ /dev/null @@ -1 +0,0 @@ -[{"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/_utils.ts":"1","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/axios-helper.ts":"2","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/generate-route-types.ts":"3","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/index.ts":"4","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/_auth.ts":"5","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/_express-call.ts":"6","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/_upload_utils.ts":"7","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/fs/base64.ts":"8","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/fs/browse/:imageType/:country/:magazine.ts":"9","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/fs/browseEdges.ts":"10","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/fs/generateDefaultEdge.ts":"11","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/fs/save.ts":"12","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/fs/text.ts":"13","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/fs/upload-base64.ts":"14","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/fs/upload.ts":"15","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/axios-helper.ts":"16","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/App.vue":"17","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/ConfirmEditMultipleValues.vue":"18","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/Dimensions.vue":"19","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/EdgeCanvas.vue":"20","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/EdgeGallery.vue":"21","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/EdgeLink.vue":"22","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/FormColorInputRow.vue":"23","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/FormInputRow.vue":"24","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/Gallery.vue":"25","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/IssueSelect.vue":"26","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/ModelEdit.vue":"27","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/MultipleTargetOptions.vue":"28","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/Popover.vue":"29","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/PositionHelper.vue":"30","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/PublishedEdge.vue":"31","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/SaveModelButton.vue":"32","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/SessionInfo.vue":"33","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/TopBar.vue":"34","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/Upload.vue":"35","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/from-dm/Issue.vue":"36","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/from-dm/Medal.vue":"37","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/from-dm/MedalProgress.vue":"38","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/from-dm/Publication.vue":"39","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/from-dm/UploadableEdgesCarousel.vue":"40","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/ArcCircleRender.vue":"41","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/FillRender.vue":"42","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/GradientRender.vue":"43","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/ImageRender.vue":"44","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/PolygonRender.vue":"45","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/RectangleRender.vue":"46","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/StapleRender.vue":"47","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/TextRender.vue":"48","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useBase64Legacy.ts":"49","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useCondition.ts":"50","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useLegacyDb.ts":"51","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useLocales.ts":"52","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useMedal.ts":"53","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useModelLoad.ts":"54","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useRedirect.ts":"55","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useSaveEdge.ts":"56","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useStepOptions.ts":"57","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useSurroundingEdge.ts":"58","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useSvgUtils.ts":"59","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useTextTemplate.ts":"60","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/i18n.ts":"61","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/layouts/default.vue":"62","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/main.ts":"63","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/pages/[...all].vue":"64","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/pages/edit/[...all].vue":"65","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/pages/edit/new.vue":"66","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/pages/upload.vue":"67","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/api.ts":"68","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/coa.ts":"69","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/collection.ts":"70","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/edgeCatalog.ts":"71","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/editingStep.ts":"72","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/hoveredStep.ts":"73","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/images.ts":"74","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/main.ts":"75","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/renders.ts":"76","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/step.ts":"77","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/ui.ts":"78","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/users.ts":"79","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/EdgeDimensions.ts":"80","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/GalleryItem.ts":"81","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/LegacyComponent.ts":"82","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/OptionNameAndValue.ts":"83","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/OptionValue.ts":"84","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/Step.ts":"85","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/StepOptionBaseProps.ts":"86","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/StepOptions.ts":"87","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/StepsPerIssuenumber.ts":"88","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/Call.ts":"89","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/Crop.ts":"90","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/ExportPaths.ts":"91","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/ModelContributor.ts":"92","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/SessionUser.ts":"93","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/SimpleUser.ts":"94","/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/routes.ts":"95"},{"size":243,"mtime":1715520653186},{"size":3171,"mtime":1715520653187},{"size":3162,"mtime":1715520653187},{"size":1377,"mtime":1715520653187},{"size":2299,"mtime":1715520653187},{"size":334,"mtime":1715520653187},{"size":243,"mtime":1715520653187,"results":"96","hashOfConfig":"97"},{"size":1026,"mtime":1715520653188,"results":"98","hashOfConfig":"97"},{"size":776,"mtime":1715520653188},{"size":1383,"mtime":1715520653188},{"size":1815,"mtime":1715520653188},{"size":3097,"mtime":1715520653188},{"size":3195,"mtime":1715520653188},{"size":1458,"mtime":1715520653188},{"size":6515,"mtime":1715520653188},{"size":3171,"mtime":1715520653189},{"size":1010,"mtime":1715520653213},{"size":828,"mtime":1715520653213,"results":"99","hashOfConfig":"97"},{"size":1472,"mtime":1715520653214},{"size":6433,"mtime":1715520653214},{"size":4963,"mtime":1715520653214},{"size":899,"mtime":1715520653214,"results":"100","hashOfConfig":"97"},{"size":6207,"mtime":1715520653214},{"size":3166,"mtime":1715520653214},{"size":3845,"mtime":1715520653214},{"size":7716,"mtime":1715520653214},{"size":13855,"mtime":1715520653214},{"size":361,"mtime":1715520653214,"results":"101","hashOfConfig":"97"},{"size":1384,"mtime":1715520653215,"results":"102","hashOfConfig":"97"},{"size":348,"mtime":1715520653215,"results":"103","hashOfConfig":"97"},{"size":674,"mtime":1715520653215,"results":"104","hashOfConfig":"97"},{"size":8600,"mtime":1715527625768,"results":"105","hashOfConfig":"97"},{"size":1076,"mtime":1715520653215,"results":"106","hashOfConfig":"97"},{"size":10820,"mtime":1715520653215},{"size":2815,"mtime":1715520653215},{"size":1308,"mtime":1715520653215,"results":"107","hashOfConfig":"97"},{"size":4870,"mtime":1715520653215},{"size":2197,"mtime":1715520653215,"results":"108","hashOfConfig":"97"},{"size":747,"mtime":1715520653215,"results":"109","hashOfConfig":"97"},{"size":1735,"mtime":1715520653216,"results":"110","hashOfConfig":"97"},{"size":1252,"mtime":1715520653216,"results":"111","hashOfConfig":"97"},{"size":502,"mtime":1715520653216,"results":"112","hashOfConfig":"97"},{"size":1431,"mtime":1715520653216,"results":"113","hashOfConfig":"97"},{"size":1725,"mtime":1715520653216},{"size":2111,"mtime":1715520653216},{"size":752,"mtime":1715520653216,"results":"114","hashOfConfig":"97"},{"size":2383,"mtime":1715520653216},{"size":7224,"mtime":1715520653216},{"size":1096,"mtime":1715520653216},{"size":1885,"mtime":1715520653217},{"size":8117,"mtime":1715520653217},{"size":431,"mtime":1715520653217,"results":"115","hashOfConfig":"97"},{"size":2446,"mtime":1715520653217},{"size":9057,"mtime":1715520653217},{"size":687,"mtime":1715520653217},{"size":1484,"mtime":1715520653217},{"size":4748,"mtime":1715520653217},{"size":734,"mtime":1715520653217,"results":"116","hashOfConfig":"97"},{"size":1522,"mtime":1715520653217},{"size":602,"mtime":1715520653217},{"size":647,"mtime":1715520653217},{"size":41,"mtime":1715520653218,"results":"117","hashOfConfig":"97"},{"size":1104,"mtime":1715524761349,"results":"118","hashOfConfig":"97"},{"size":8982,"mtime":1715520653218},{"size":10805,"mtime":1715520653218},{"size":1480,"mtime":1715520653218},{"size":8773,"mtime":1715520653218},{"size":307,"mtime":1715520653218},{"size":4606,"mtime":1715520653218},{"size":4267,"mtime":1715520653218},{"size":11307,"mtime":1715520653218},{"size":1477,"mtime":1715520653218},{"size":191,"mtime":1715520653219,"results":"119","hashOfConfig":"97"},{"size":219,"mtime":1715520653219,"results":"120","hashOfConfig":"97"},{"size":7764,"mtime":1715527536204},{"size":1385,"mtime":1715520653219,"results":"121","hashOfConfig":"97"},{"size":10442,"mtime":1715520653219},{"size":463,"mtime":1715520653219,"results":"122","hashOfConfig":"97"},{"size":581,"mtime":1715520653219,"results":"123","hashOfConfig":"97"},{"size":71,"mtime":1715520653219,"results":"124","hashOfConfig":"97"},{"size":123,"mtime":1715520653219,"results":"125","hashOfConfig":"97"},{"size":1706,"mtime":1715520653219,"results":"126","hashOfConfig":"97"},{"size":136,"mtime":1715520653219,"results":"127","hashOfConfig":"97"},{"size":72,"mtime":1715520653220,"results":"128","hashOfConfig":"97"},{"size":101,"mtime":1715520653220,"results":"129","hashOfConfig":"97"},{"size":188,"mtime":1715520653220,"results":"130","hashOfConfig":"97"},{"size":119,"mtime":1715520653220,"results":"131","hashOfConfig":"97"},{"size":96,"mtime":1715520653220,"results":"132","hashOfConfig":"97"},{"size":952,"mtime":1715520653220},{"size":192,"mtime":1715520653220,"results":"133","hashOfConfig":"97"},{"size":73,"mtime":1715520653220,"results":"134","hashOfConfig":"97"},{"size":239,"mtime":1715520653220},{"size":287,"mtime":1715520653220,"results":"135","hashOfConfig":"97"},{"size":107,"mtime":1715520653220,"results":"136","hashOfConfig":"97"},{"size":2701,"mtime":1715520653221,"results":"137","hashOfConfig":"97"},{"filePath":"138","messages":"139","suppressedMessages":"140","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"qjf7lk",{"filePath":"141","messages":"142","suppressedMessages":"143","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"144","messages":"145","suppressedMessages":"146","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"147","messages":"148","suppressedMessages":"149","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"150","messages":"151","suppressedMessages":"152","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"153","messages":"154","suppressedMessages":"155","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"156","messages":"157","suppressedMessages":"158","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"159","messages":"160","suppressedMessages":"161","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"162","messages":"163","suppressedMessages":"164","errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"165","messages":"166","suppressedMessages":"167","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"168","messages":"169","suppressedMessages":"170","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"171","messages":"172","suppressedMessages":"173","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"174","messages":"175","suppressedMessages":"176","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"177","messages":"178","suppressedMessages":"179","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"180","messages":"181","suppressedMessages":"182","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"183","messages":"184","suppressedMessages":"185","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"186","messages":"187","suppressedMessages":"188","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"189","messages":"190","suppressedMessages":"191","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"192","messages":"193","suppressedMessages":"194","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"195","messages":"196","suppressedMessages":"197","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"198","messages":"199","suppressedMessages":"200","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"201","messages":"202","suppressedMessages":"203","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"204","messages":"205","suppressedMessages":"206","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"207","messages":"208","suppressedMessages":"209","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"210","messages":"211","suppressedMessages":"212","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"213","messages":"214","suppressedMessages":"215","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"216","messages":"217","suppressedMessages":"218","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"219","messages":"220","suppressedMessages":"221","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"222","messages":"223","suppressedMessages":"224","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"225","messages":"226","suppressedMessages":"227","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"228","messages":"229","suppressedMessages":"230","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"231","messages":"232","suppressedMessages":"233","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"234","messages":"235","suppressedMessages":"236","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"237","messages":"238","suppressedMessages":"239","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"240","messages":"241","suppressedMessages":"242","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"243","messages":"244","suppressedMessages":"245","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"246","messages":"247","suppressedMessages":"248","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"249","messages":"250","suppressedMessages":"251","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"252","messages":"253","suppressedMessages":"254","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"255","messages":"256","suppressedMessages":"257","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"258","messages":"259","suppressedMessages":"260","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/_upload_utils.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/api/routes/fs/base64.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/ConfirmEditMultipleValues.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/EdgeLink.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/MultipleTargetOptions.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/Popover.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/PositionHelper.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/PublishedEdge.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/SaveModelButton.vue",["261"],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/SessionInfo.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/from-dm/Issue.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/from-dm/MedalProgress.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/from-dm/Publication.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/from-dm/UploadableEdgesCarousel.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/ArcCircleRender.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/FillRender.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/GradientRender.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/components/renders/RectangleRender.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useLocales.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/composables/useSurroundingEdge.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/layouts/default.vue",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/main.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/hoveredStep.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/images.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/renders.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/ui.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/stores/users.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/EdgeDimensions.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/GalleryItem.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/LegacyComponent.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/OptionNameAndValue.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/OptionValue.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/Step.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/StepOptionBaseProps.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/StepOptions.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/src/types/StepsPerIssuenumber.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/Crop.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/ExportPaths.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/SessionUser.ts",[],["262"],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/SimpleUser.ts",[],[],"/Users/bperel/Documents/workspace/perso/dm/apps/edgecreator/types/routes.ts",[],[],{"ruleId":"263","severity":2,"message":"264","line":152,"column":7,"nodeType":"265","messageId":"266","endLine":152,"endColumn":19},{"ruleId":"267","severity":2,"message":"268","line":10,"column":3,"nodeType":"269","messageId":"270","endLine":14,"endColumn":4,"suppressions":"271"},"@typescript-eslint/no-unused-vars","'progressLeft' is assigned a value but never used.","Identifier","unusedVar","@typescript-eslint/no-namespace","ES2015 module syntax is preferred over namespaces.","TSModuleDeclaration","moduleSyntaxIsPreferred",["272"],{"kind":"273","justification":"274"},"directive",""] \ No newline at end of file diff --git a/.eslintrc-auto-import.json b/.eslintrc-auto-import.json new file mode 100644 index 00000000..055835b3 --- /dev/null +++ b/.eslintrc-auto-import.json @@ -0,0 +1,323 @@ +{ + "globals": { + "Component": true, + "ComponentPublicInstance": true, + "ComputedRef": true, + "EffectScope": true, + "ExtractDefaultPropTypes": true, + "ExtractPropTypes": true, + "ExtractPublicPropTypes": true, + "InjectionKey": true, + "IssueSuggestionList": true, + "PropType": true, + "Ref": true, + "VNode": true, + "WritableComputedRef": true, + "acceptHMRUpdate": true, + "asyncComputed": true, + "autoResetRef": true, + "availableLocales": true, + "computed": true, + "computedAsync": true, + "computedEager": true, + "computedInject": true, + "computedWithControl": true, + "controlledComputed": true, + "controlledRef": true, + "createApp": true, + "createEventHook": true, + "createGlobalState": true, + "createInjectionState": true, + "createPinia": true, + "createReactiveFn": true, + "createReusableTemplate": true, + "createSharedComposable": true, + "createTemplatePromise": true, + "createUnrefFn": true, + "customRef": true, + "debouncedRef": true, + "debouncedWatch": true, + "defineAsyncComponent": true, + "defineComponent": true, + "defineStore": true, + "eagerComputed": true, + "edgecreatorSocketInjectionKey": true, + "effectScope": true, + "exclude": true, + "extendRef": true, + "getActivePinia": true, + "getCurrentInstance": true, + "getCurrentLocaleShortKey": true, + "getCurrentScope": true, + "h": true, + "ignorableWatch": true, + "inject": true, + "injectLocal": true, + "isDefined": true, + "isProxy": true, + "isReactive": true, + "isReadonly": true, + "isRef": true, + "makeDestructurable": true, + "mapActions": true, + "mapGetters": true, + "mapState": true, + "mapStores": true, + "mapWritableState": true, + "markRaw": true, + "nextTick": true, + "onActivated": true, + "onBeforeMount": true, + "onBeforeRouteLeave": true, + "onBeforeRouteUpdate": true, + "onBeforeUnmount": true, + "onBeforeUpdate": true, + "onClickOutside": true, + "onDeactivated": true, + "onErrorCaptured": true, + "onKeyStroke": true, + "onLongPress": true, + "onMounted": true, + "onRenderTracked": true, + "onRenderTriggered": true, + "onScopeDispose": true, + "onServerPrefetch": true, + "onStartTyping": true, + "onUnmounted": true, + "onUpdated": true, + "pausableWatch": true, + "provide": true, + "provideLocal": true, + "reactify": true, + "reactifyObject": true, + "reactive": true, + "reactiveComputed": true, + "reactiveOmit": true, + "reactivePick": true, + "readonly": true, + "ref": true, + "refAutoReset": true, + "refDebounced": true, + "refDefault": true, + "refThrottled": true, + "refWithControl": true, + "resolveComponent": true, + "resolveRef": true, + "resolveUnref": true, + "setActivePinia": true, + "setMapStoreSuffix": true, + "shallowReactive": true, + "shallowReadonly": true, + "shallowRef": true, + "storeToRefs": true, + "syncRef": true, + "syncRefs": true, + "templateRef": true, + "throttledRef": true, + "throttledWatch": true, + "toRaw": true, + "toReactive": true, + "toRef": true, + "toRefs": true, + "toValue": true, + "triggerRef": true, + "tryOnBeforeMount": true, + "tryOnBeforeUnmount": true, + "tryOnMounted": true, + "tryOnScopeDispose": true, + "tryOnUnmounted": true, + "unref": true, + "unrefElement": true, + "until": true, + "useActiveElement": true, + "useAnimate": true, + "useArrayDifference": true, + "useArrayEvery": true, + "useArrayFilter": true, + "useArrayFind": true, + "useArrayFindIndex": true, + "useArrayFindLast": true, + "useArrayIncludes": true, + "useArrayJoin": true, + "useArrayMap": true, + "useArrayReduce": true, + "useArraySome": true, + "useArrayUnique": true, + "useAsyncQueue": true, + "useAsyncState": true, + "useAttrs": true, + "useBase64": true, + "useBase64Legacy": true, + "useBattery": true, + "useBluetooth": true, + "useBreakpoints": true, + "useBroadcastChannel": true, + "useBrowserLocation": true, + "useCached": true, + "useClipboard": true, + "useClipboardItems": true, + "useCloned": true, + "useColorMode": true, + "useCondition": true, + "useConfirmDialog": true, + "useCounter": true, + "useCssModule": true, + "useCssVar": true, + "useCssVars": true, + "useCurrentElement": true, + "useCycleList": true, + "useDark": true, + "useDateFormat": true, + "useDebounce": true, + "useDebounceFn": true, + "useDebouncedRefHistory": true, + "useDeviceMotion": true, + "useDeviceOrientation": true, + "useDevicePixelRatio": true, + "useDevicesList": true, + "useDisplayMedia": true, + "useDocumentVisibility": true, + "useDraggable": true, + "useDropZone": true, + "useEdgecreatorSocket": true, + "useElementBounding": true, + "useElementByPoint": true, + "useElementHover": true, + "useElementSize": true, + "useElementVisibility": true, + "useEventBus": true, + "useEventListener": true, + "useEventSource": true, + "useEyeDropper": true, + "useFavicon": true, + "useFetch": true, + "useFileDialog": true, + "useFileSystemAccess": true, + "useFocus": true, + "useFocusWithin": true, + "useFps": true, + "useFullscreen": true, + "useGamepad": true, + "useGeolocation": true, + "useIdle": true, + "useImage": true, + "useInfiniteScroll": true, + "useIntersectionObserver": true, + "useInterval": true, + "useIntervalFn": true, + "useKeyModifier": true, + "useLastChanged": true, + "useLegacyDb": true, + "useLink": true, + "useLocalStorage": true, + "useMagicKeys": true, + "useManualRefHistory": true, + "useMedal": true, + "useMediaControls": true, + "useMediaQuery": true, + "useMemoize": true, + "useMemory": true, + "useModelLoad": true, + "useMounted": true, + "useMouse": true, + "useMouseInElement": true, + "useMousePressed": true, + "useMutationObserver": true, + "useNavigatorLanguage": true, + "useNetwork": true, + "useNow": true, + "useObjectUrl": true, + "useOffsetPagination": true, + "useOnline": true, + "usePageLeave": true, + "useParallax": true, + "useParentElement": true, + "usePerformanceObserver": true, + "usePermission": true, + "usePointer": true, + "usePointerLock": true, + "usePointerSwipe": true, + "usePreferredColorScheme": true, + "usePreferredContrast": true, + "usePreferredDark": true, + "usePreferredLanguages": true, + "usePreferredReducedMotion": true, + "usePrevious": true, + "useRafFn": true, + "useRedirect": true, + "useRefHistory": true, + "useResizeObserver": true, + "useRoute": true, + "useRouter": true, + "useSaveEdge": true, + "useScreenOrientation": true, + "useScreenSafeArea": true, + "useScriptTag": true, + "useScroll": true, + "useScrollLock": true, + "useSessionStorage": true, + "useShare": true, + "useSlots": true, + "useSorted": true, + "useSpeechRecognition": true, + "useSpeechSynthesis": true, + "useStepOptions": true, + "useStepper": true, + "useStorage": true, + "useStorageAsync": true, + "useStyleTag": true, + "useSupported": true, + "useSurroundingEdge": true, + "useSvgUtils": true, + "useSwipe": true, + "useTemplateRefsList": true, + "useTextDirection": true, + "useTextSelection": true, + "useTextTemplate": true, + "useTextareaAutosize": true, + "useThrottle": true, + "useThrottleFn": true, + "useThrottledRefHistory": true, + "useTimeAgo": true, + "useTimeout": true, + "useTimeoutFn": true, + "useTimeoutPoll": true, + "useTimestamp": true, + "useTitle": true, + "useToNumber": true, + "useToString": true, + "useToggle": true, + "useTransition": true, + "useUrlSearchParams": true, + "useUserMedia": true, + "useVModel": true, + "useVModels": true, + "useVibrate": true, + "useVirtualList": true, + "useWakeLock": true, + "useWebNotification": true, + "useWebSocket": true, + "useWebWorker": true, + "useWebWorkerFn": true, + "useWindowFocus": true, + "useWindowScroll": true, + "useWindowSize": true, + "watch": true, + "watchArray": true, + "watchAtMost": true, + "watchDebounced": true, + "watchDeep": true, + "watchEffect": true, + "watchIgnorable": true, + "watchImmediate": true, + "watchOnce": true, + "watchPausable": true, + "watchPostEffect": true, + "watchSyncEffect": true, + "watchThrottled": true, + "watchTriggerable": true, + "watchWithFilter": true, + "whenever": true, + "useI18n": true + } +} diff --git a/.eslintrc.js b/.eslintrc.json similarity index 71% rename from .eslintrc.js rename to .eslintrc.json index 6204c7f3..627ccf4c 100644 --- a/.eslintrc.js +++ b/.eslintrc.json @@ -1,5 +1,5 @@ -module.exports = { - extends: [ +{ + "extends": [ // add more generic rulesets here, such as: // 'eslint:recommended', "plugin:vue/vue3-recommended", @@ -7,19 +7,19 @@ module.exports = { "prettier", "plugin:@typescript-eslint/recommended" ], - parser: "vue-eslint-parser", - parserOptions: { - parser: "@typescript-eslint/parser", - project: true, - extraFileExtensions: [".vue"] + "parser": "vue-eslint-parser", + "parserOptions": { + "parser": "@typescript-eslint/parser", + "project": true, + "extraFileExtensions": [".vue"] }, - overrides: [ + "overrides": [ { - files: ["*.ts", "*.vue"] + "files": ["*.ts", "*.vue"] } ], - root: true, - rules: { + "root": true, + "rules": { "@typescript-eslint/no-floating-promises": "off", "@typescript-eslint/no-non-null-assertion": "off", "simple-import-sort/exports": "error", @@ -31,26 +31,27 @@ module.exports = { "vue/no-v-text-v-html-on-component": "off", "vue/define-emits-declaration": "error", "vue/define-props-declaration": "error", + "@typescript-eslint/consistent-type-imports": "error", "vue/component-name-in-template-casing": [ "error", "kebab-case", { - registeredComponentsOnly: true, - ignores: [] + "registeredComponentsOnly": true, + "ignores": [] } ] }, - plugins: [ + "plugins": [ "simple-import-sort", "prettier", "@typescript-eslint", "unused-imports" ], - ignorePatterns: [ + "ignorePatterns": [ "**/node_modules", "**/dist", "*.d.ts", "vendor", "vite.config.ts" ] -}; +} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 66823a65..f7662aff 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -4,14 +4,20 @@ on: workflow_dispatch: push: branches: - - 'nuxt-to-vue3-and-express' + - "websocket" jobs: deploy: runs-on: ubuntu-latest environment: production steps: - name: Check out repository - uses: actions/checkout@master + uses: actions/checkout@v3 + with: + repository: ducksmanager/core + submodules: recursive + + - name: Debug + run: pwd && ls -la - name: Download .env file uses: nicklasfrahm/scp-action@main @@ -25,10 +31,10 @@ jobs: target: .env.prod - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Login to GitHub Container Registry - uses: docker/login-action@v2.1.0 + uses: docker/login-action@v3 with: registry: ghcr.io username: bperel @@ -37,22 +43,24 @@ jobs: - name: Build and push app uses: docker/build-push-action@v3 with: - context: . + context: ./apps/edgecreator platforms: linux/x86_64 + file: ./apps/edgecreator/Dockerfile push: true - target: app cache-from: type=registry,ref=ghcr.io/bperel/edgecreator-app:buildcache cache-to: type=registry,ref=ghcr.io/bperel/edgecreator-app:buildcache,mode=max tags: | ghcr.io/bperel/edgecreator-app:latest + - uses: oven-sh/setup-bun@v1 + - run: cd apps/edgecreator/api && bun build ./index.ts --outdir dist --minify --target node + - name: Build and push api uses: docker/build-push-action@v3 with: - context: . + context: ./apps/edgecreator/api platforms: linux/x86_64 push: true - target: api cache-from: type=registry,ref=ghcr.io/bperel/edgecreator-api:buildcache cache-to: type=registry,ref=ghcr.io/bperel/edgecreator-api:buildcache,mode=max tags: | @@ -66,7 +74,7 @@ jobs: fingerprint: ${{ secrets.PRODUCTION_SSH_FINGERPRINT }} username: ${{ secrets.PRODUCTION_SSH_USER }} key: ${{ secrets.PRODUCTION_SSH_KEY }} - source: docker-compose.yml + source: apps/edgecreator/docker-compose.yml target: /home/bperel/workspace/EdgeCreator2/docker-compose.yml - name: Upload Sentry config @@ -77,7 +85,7 @@ jobs: fingerprint: ${{ secrets.PRODUCTION_SSH_FINGERPRINT }} username: ${{ secrets.PRODUCTION_SSH_USER }} key: ${{ secrets.PRODUCTION_SSH_KEY }} - source: config/sentry-relay/config.yml + source: apps/edgecreator/config/sentry-relay/config.yml target: /home/bperel/workspace/EdgeCreator2/config/sentry-relay/config.yml - name: Upload Sentry project config @@ -88,11 +96,11 @@ jobs: fingerprint: ${{ secrets.PRODUCTION_SSH_FINGERPRINT }} username: ${{ secrets.PRODUCTION_SSH_USER }} key: ${{ secrets.PRODUCTION_SSH_KEY }} - source: config/sentry-relay/projects/5595460.json + source: apps/edgecreator/config/sentry-relay/projects/5595460.json target: /home/bperel/workspace/EdgeCreator2/config/sentry-relay/projects/5595460.json - name: Recreate container - uses: appleboy/ssh-action@v0.1.7 + uses: appleboy/ssh-action@v1.0.3 env: DOCKER_REGISTRY_TOKEN: ${{ secrets.DOCKER_REGISTRY_TOKEN }} with: diff --git a/.gitignore b/.gitignore index a3ab6e36..50479f84 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,6 @@ dist-ssr *.sln *.sw? -.env.* \ No newline at end of file +.env.* +.eslintcache +/*.d.ts diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index f053ebf7..00000000 --- a/.prettierrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = {}; diff --git a/Dockerfile b/Dockerfile index b1291406..f29af659 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,58 +1,6 @@ -FROM node:16 as pnpm +FROM nginx +LABEL org.opencontainers.image.authors="Bruno Perel" +WORKDIR /usr/share/nginx/html -RUN npm i -g pnpm - -FROM pnpm AS app-install - -WORKDIR /app -COPY package.json pnpm-lock.yaml .eslintrc.js ./ -RUN pnpm i - -FROM app-install AS api-build - -WORKDIR /app/api - -COPY api/package.json api/pnpm-lock.yaml ./ -RUN pnpm i - -COPY .env.prod ./.env - -COPY types /app/types -COPY api . -RUN mv tsconfig.prod.json tsconfig.json -RUN mkdir dm_types && cp -r node_modules/ducksmanager/types/* dm_types/ -RUN mkdir prisma_clients && cp -r node_modules/ducksmanager/api/dist/prisma/* prisma_clients/ -RUN sed -i 's#../api/dist/prisma#~prisma_clients#g' dm_types/*.ts -RUN pnpm run generate-route-types -RUN pnpm run build - -FROM app-install AS app-build - -WORKDIR /app - -COPY . . -COPY .env.prod ./.env -COPY --from=api-build /app/api api -COPY --from=api-build /app/types/routes.ts types/routes.ts -RUN pnpm run build - -FROM nginx AS app -LABEL org.opencontainers.image.authors="admin@ducksmanager.net" - -COPY nginx.conf /etc/nginx/nginx.conf -COPY --from=app-build /app/dist /usr/share/nginx/html - -FROM pnpm AS api -LABEL org.opencontainers.image.authors="admin@ducksmanager.net" - -WORKDIR /app - -COPY --from=api-build /app/api/package*.json /app/api/.env /app/ -RUN pnpm install --production - -COPY --from=api-build /app/api/dist /app/ - -EXPOSE 3000 - -WORKDIR /app/api -CMD ["node", "index.js"] +COPY --from=dm-build /prod/edgecreator/dist /usr/share/nginx/html +# COPY apps/web/nginx.conf /etc/nginx/nginx.conf \ No newline at end of file diff --git a/api/.env b/api/.env new file mode 100644 index 00000000..8262f1ef --- /dev/null +++ b/api/.env @@ -0,0 +1,11 @@ +CLOUDINARY_URL=cloudinary://955445841324817:fqXP5YDdv8n1vwNjzgDRlFHDVto@dl7hskxab +FONT_BASE_URL=https://www.myfonts.com/fonts/ +FONT_IMAGE_GEN_URL=https://render.myfonts.net/fonts/font_rend.php +FONT_PRODUCT_BASE_URL=https://www.myfonts.com/products/ + +# Used only in the backend, so with the api directory as basis +EDGES_PATH=../DucksManager/edges + +TOKEN_SECRET=3543c30fe79047b4f73cfb61aa1eb52cb3173de4b3941e0fc4ec1b127bbeed6019695a1a453a81c33c2eea964ccc577e69c7df994124bd2751e262a311ea23a1 + +DM_SOCKET_URL=http://localhost:3000 diff --git a/api/Dockerfile b/api/Dockerfile new file mode 100644 index 00000000..37c612b1 --- /dev/null +++ b/api/Dockerfile @@ -0,0 +1,11 @@ +FROM pnpm +LABEL org.opencontainers.image.authors="Bruno Perel" +WORKDIR /app + +RUN apt update && apt install -y imagemagick && apt clean && rm -rf /var/lib/apt/lists/* + +COPY dist/index.js /app/index.mjs + +EXPOSE 3000 + +CMD ["node", "index.mjs"] diff --git a/api/assets/default.svg b/api/assets/default.svg new file mode 100644 index 00000000..e8d8338c --- /dev/null +++ b/api/assets/default.svg @@ -0,0 +1,18 @@ + + + + + + + + + My text + + + + + + \ No newline at end of file diff --git a/api/axios-helper.ts b/api/axios-helper.ts deleted file mode 100644 index 5fe4882c..00000000 --- a/api/axios-helper.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { useCookies } from "@vueuse/integrations/useCookies"; -import axios, { - AxiosInstance, - AxiosResponse, - InternalAxiosRequestConfig, -} from "axios"; -import { AxiosCacheInstance } from "axios-cache-interceptor"; - -import { Call, ContractWithMethodAndUrl } from "~types/Call"; - -export const addUrlParamsRequestInterceptor = < - Type extends AxiosInstance | AxiosCacheInstance, ->( - axiosInstance: Type, -) => { - axiosInstance.interceptors.request.use( - (config: InternalAxiosRequestConfig) => { - if (config.url) { - const currentUrl = new URL(config.url, config.baseURL); - currentUrl.pathname = Object.entries( - config.urlParams ?? ({} as Record), - ).reduce( - (pathname, [k, v]) => - pathname.replace(`:${k}`, encodeURIComponent(v)), - currentUrl.pathname, - ); - return { - ...config, - baseURL: `${currentUrl.protocol}//${currentUrl.host}`, - url: currentUrl.pathname, - }; - } - return config; - }, - ); - return axiosInstance; -}; - -declare module "axios" { - interface InternalAxiosRequestConfig { - urlParams?: Record | undefined; - } - - interface AxiosRequestConfig { - urlParams?: Record | undefined; - } -} - -type MyCall = Call; - -export const call = >( - instance: AxiosInstance | AxiosCacheInstance, - contract: Contract, -): Promise> => - instance.request({ - method: contract.getMethod(), - url: contract.getUrl(), - params: contract.call?.query || undefined, - urlParams: contract.call?.params ?? undefined, - data: (contract.call?.reqBody as never) || undefined, - }); - -export const getChunkedRequests = async < - Contract extends ContractWithMethodAndUrl, ->({ - callFn, - valuesToChunk, - chunkSize, -}: { - callFn: (chunk: string) => Promise>; - valuesToChunk: string[]; - chunkSize: number; - chunkOnQueryParam?: boolean; - parameterName?: string; -}): Promise => { - const slices = Array.from( - { length: Math.ceil(valuesToChunk.length / chunkSize) }, - (_, i) => valuesToChunk.slice(i * chunkSize, i * chunkSize + chunkSize), - ); - let acc: Contract["resBody"] = (await callFn(slices[0].join(","))).data; - for (const slice of slices.slice(1)) { - acc = Array.isArray(acc) - ? [ - ...(acc as never[]), - ...((await callFn(slice.join(","))).data as never[]), - ] - : { - ...(acc as Record), - ...((await callFn(slice.join(","))).data as Record), - }; - } - return acc; -}; - -export const createAxios = (baseURL: string) => { - const newInstance = axios.create({ baseURL }); - - newInstance.interceptors.request.use( - (config) => { - const token: string = useCookies().get("token"); - if (token) { - config.headers.Authorization = `Bearer ${token}`; - } - return config; - }, - (error) => Promise.reject(error), - ); - - addUrlParamsRequestInterceptor(newInstance); - - return newInstance; -}; diff --git a/api/generate-route-types.ts b/api/generate-route-types.ts deleted file mode 100644 index e8eeb596..00000000 --- a/api/generate-route-types.ts +++ /dev/null @@ -1,105 +0,0 @@ -import express from "express"; -import { router } from "express-file-routing"; -import { readdirSync, readFileSync, writeFileSync } from "fs"; - -const app = express(); - -interface Route { - path: string | RegExp; - methods: Record; -} -const routes: Route[] = []; - -(async () => { - app.use("/", await router({ directory: `${process.cwd()}/routes` })); - app._router.stack.forEach( - (middleware: { - route: Route; - name: string; - handle: { stack: [{ route: Route }] }; - }) => { - if (typeof middleware.route?.path === "string") { - // routes registered directly on the app - routes.push(middleware.route); - } else if (middleware.name === "router") { - // router middleware - middleware.handle.stack.forEach((handler) => { - if (typeof handler.route?.path === "string") { - routes.push(handler.route); - } - }); - } - }, - ); - - const imports: string[] = [ - "// noinspection ES6PreferShortImport", - "", - 'import { ContractWithMethodAndUrl } from "./Call";', - ]; - imports.push( - readdirSync("../types") - .filter((file) => file.endsWith(".ts") && /^[A-Z]/.test(file[0])) - .map( - (file) => - `import { ${[ - ...readFileSync(`../types/${file}`) - .toString() - .matchAll(/(?:(?<=export type )|(?<=export interface ))\w+/g)!, - ].join(", ")} } from "./${file.replace(/\.ts$/, "")}";`, - ) - .join("\n"), - ); - const types: string[] = []; - - let routeClassList = {} as Record; - routes.forEach((route) => { - routeClassList = Object.keys(route.methods) - .filter((method) => ["get", "post", "delete", "put"].includes(method)) - .reduce((acc, method) => { - const realMethod = method === "delete" ? "del" : method; - const routePathWithMethod = `${method.toUpperCase()} ${ - route.path as string - }`; - - let routeFile; - const routeBasePath = `routes/${(route.path as string).replace( - /^\//, - "", - )}`; - try { - routeFile = readFileSync(`${routeBasePath}/index.ts`); - } catch (e) { - routeFile = readFileSync(`${routeBasePath}.ts`); - } - const callType = new RegExp( - `export const ${realMethod} =.+?ExpressCall<( *.+?)>[ \\n]*\\) =>`, - "gms", - ).exec(routeFile.toString())![1]; - - acc[routePathWithMethod] = - ` extends ContractWithMethodAndUrl<${callType}> { - static readonly method = "${method}"; - static readonly url = "${route.path as string}"; - }`; - return acc; - }, routeClassList); - }); - writeFileSync( - "../types/routes.ts", - [ - imports.join("\n"), - types.join("\n"), - Object.entries(routeClassList) - .map( - ([routePathWithMethod, callback]) => - `export class ${routePathWithMethod - .replaceAll("/", "__") - .replaceAll(/ /g, "") - .replaceAll(/:/g, "$") - .replaceAll(/-/g, "_")} ${callback}`, - ) - .join("\n"), - ].join("\n"), - ); -})(); diff --git a/api/generateDefaultEdge.ts b/api/generateDefaultEdge.ts new file mode 100644 index 00000000..393bdc9b --- /dev/null +++ b/api/generateDefaultEdge.ts @@ -0,0 +1,51 @@ +import { exec } from "child_process"; +import type { Request, Response } from "express"; +import { readFileSync } from "fs"; +import { pipeline } from "stream"; + +const corsHeaders = { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Credentials": "true", + "Access-Control-Allow-Methods": "GET, OPTIONS", + "Access-Control-Allow-Headers": + "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With," + + "If-Modified-Since,Cache-Control,Content-Type,x-dm-user,x-dm-pass", +}; +export const get = (req: Request, res: Response) => { + const { countrycode, magazinecode, issuenumber, extension } = req.params!; + + if (countrycode && extension !== "png") { + res.writeHead(404, corsHeaders); + res.end(""); + return; + } + const text = `${countrycode}/${magazinecode} ${issuenumber}`; + + const convert = exec("convert svg:- png:-", { + encoding: "buffer", + }); + + convert.stdin!.write( + Buffer.from( + readFileSync("assets/default.svg") + .toString() + .replace("My text", decodeURIComponent(text)), + "utf8" + ) + ); + convert.stdin!.end(); + + res.setHeader("Content-Type", "image/png"); + + pipeline(convert.stdout!, res, (err) => { + if (err) { + console.error("Pipeline failed", err); + res.status(500).send("Conversion failed"); + } + }); +}; + +export const options = (req: Request, res: Response) => { + res.writeHead(200, corsHeaders); + return res.end(); +}; diff --git a/api/index.ts b/api/index.ts index 8f829b5a..a22fa121 100644 --- a/api/index.ts +++ b/api/index.ts @@ -1,19 +1,21 @@ import * as Sentry from "@sentry/node"; -import bodyParser from "body-parser"; -import cookieParser from "cookie-parser"; -import cors from "cors"; import dotenv from "dotenv"; import express from "express"; -import { router } from "express-file-routing"; +import { createServer } from "http"; +import multer from "multer"; +import { Server } from "socket.io"; -const parseForm = bodyParser.json(); -import { - authenticateToken, - checkUserIsAdminForExportOrIsEditorForSaveOrIsFirstFileForModel, - checkUserIsAdminOrEditor, - injectTokenIfValid, -} from "~routes/_auth"; +import { OptionalAuthMiddleware } from "~dm-services/auth/util"; +import type { SessionUser } from "~dm-types/SessionUser"; +import * as generateDefaultEdge from "./generateDefaultEdge"; +import { instrument } from "@socket.io/admin-ui"; + +import browse from "./services/browse"; +import imageInfo from "./services/image-info"; +import save from "./services/save"; +import text from "./services/text"; +import uploadServices, { upload } from "./services/upload"; dotenv.config({ path: "../.env", }); @@ -24,36 +26,81 @@ Sentry.init({ dsn: process.env.SENTRY_DSN, }); +class ServerWithUser extends Server< + Record, + Record, + Record, + { user?: SessionUser } +> {} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +(BigInt.prototype as any).toJSON = function () { + const int = Number.parseInt(this.toString()); + return int ?? this.toString(); +}; + +dotenv.config({ + path: "./.env", +}); + +Sentry.init({ + dsn: process.env.SENTRY_DSN, +}); + const app = express(); -app.use( - Sentry.Handlers.requestHandler({ - user: ["id", "username"], - }) as express.RequestHandler, -); -app.use( - cors({ - optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204 - }), +app.get("/upload", (req, res) => { + if (req.method === "POST") { + multer({ + dest: "/tmp/", + limits: { + fileSize: 3 * 1024 * 1024, + files: 1, + }, + }).array("files"); + upload(req, res); + } else { + res.writeHead(405); + } +}); + +app.get( + "/default-edge/edges/:countrycode/gen/:magazinecode([^.]+).:issuenumber([^.]+).:extension(svg|png)", + (req, res) => { + if (req.method === "OPTIONS") { + generateDefaultEdge.options(req, res); + } else if (req.method === "GET") { + multer({ + dest: "/tmp/", + limits: { + fileSize: 3 * 1024 * 1024, + files: 1, + }, + }).array("files"); + generateDefaultEdge.get(req, res); + } else { + res.writeHead(405); + } + } ); -app.use(cookieParser()); - -app.all(/^.+$/, injectTokenIfValid); -app.all(/^\/fs\/save$/, [ - authenticateToken, - parseForm, - checkUserIsAdminForExportOrIsEditorForSaveOrIsFirstFileForModel, -]); -app.all(/^\/fs\/(text|upload|upload-base64)$/, [ - authenticateToken, - checkUserIsAdminOrEditor, -]); - -app.use(Sentry.Handlers.errorHandler() as express.ErrorRequestHandler); - -(async () => { - app.use("/", await router({ directory: `${process.cwd()}/routes` })); - app.listen(port, () => - console.log(`EdgeCreator API listening on port ${port}`), - ); -})(); +const httpServer = createServer(app); +const io = new ServerWithUser(httpServer, { + cors: { + origin: "*", + }, +}); + +instrument(io, { + auth: false, +}); + +httpServer.listen(port); +console.log(`WebSocket open on port ${port}`); + +io.use(OptionalAuthMiddleware); + +text(io); +browse(io); +imageInfo(io); +save(io); +uploadServices(io); diff --git a/api/nodemon.json b/api/nodemon.json deleted file mode 100644 index bf2459af..00000000 --- a/api/nodemon.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "ignore": ["node_modules"], - "watch": ["."], - "exec": "npm start", - "ext": "ts" -} diff --git a/api/package.json b/api/package.json index 98035a41..0724599d 100644 --- a/api/package.json +++ b/api/package.json @@ -1,45 +1,44 @@ { - "name": "dm-api", + "name": "~edgecreator-api", + "type": "module", "version": "1.0.0", "scripts": { "clean": "rm -rf dist", - "build": "rm -rf dist/api dist/types && tsc && tsc-alias", - "start": "tsx index.ts", - "dev": "nodemon", - "generate-route-types": "tsx generate-route-types.ts", - "generate-route-types:clean": "tsx generate-route-types.ts && cd .. && node_modules/.bin/eslint --fix types/routes.ts" + "build": "rm -rf dist && tsc && tsc-alias", + "postbuild": "cp -r ../../../packages/prisma-clients/dist/client_* dist/packages/prisma-clients", + "dev": "concurrently -n bun,tsc \"bun --inspect run --hot index.ts\" \"tsc --noEmit --watch\"" }, "dependencies": { "@sentry/node": "^7.114.0", + "@socket.io/admin-ui": "^0.5.1", "@vueuse/integrations": "^10.9.0", "axios": "^1.6.8", - "body-parser": "^1.20.2", "cloudinary": "^1.41.3", - "cookie-parser": "^1.4.6", "cors": "^2.8.5", "dotenv": "^16.4.5", - "ducksmanager": "^0.0.51", "express": "^4.19.2", - "express-file-routing": "^3.0.3", "i18n": "^0.15.1", "image-size": "^1.1.1", "jsonwebtoken": "^9.0.2", "multer": "1.4.5-lts.1", "node-base64-image": "^2.0.6", - "nodemon": "^2.0.22", - "sharp": "^0.33.3", - "universal-cookie": "^4.0.4" + "socket.io": "^4.7.5", + "socket.io-client": "^4.7.5", + "universal-cookie": "^4.0.4", + "~api": "workspace:*", + "~dm-types": "workspace:*", + "~prisma-clients": "workspace:*", + "~socket.io-client-services": "workspace:*", + "~socket.io-services": "workspace:*" }, "devDependencies": { - "@types/body-parser": "^1.19.5", - "@types/busboy": "^1.5.4", - "@types/cookie-parser": "^1.4.7", "@types/cors": "^2.8.17", "@types/express": "^4.17.21", "@types/i18n": "^0.13.12", "@types/jsonwebtoken": "^9.0.6", "@types/multer": "^1.4.11", "@types/node": "^18.19.33", + "concurrently": "^8.2.2", "tsc-alias": "^1.8.9", "tsx": "^4.10.1", "typescript": "^5.4.5" diff --git a/api/pnpm-lock.yaml b/api/pnpm-lock.yaml index 11ec40ca..ea7ad8b1 100644 --- a/api/pnpm-lock.yaml +++ b/api/pnpm-lock.yaml @@ -10,37 +10,28 @@ importers: dependencies: '@sentry/node': specifier: ^7.114.0 - version: 7.114.0 + version: 7.116.0 + '@socket.io/admin-ui': + specifier: ^0.5.1 + version: 0.5.1(socket.io@4.7.5) '@vueuse/integrations': specifier: ^10.9.0 - version: 10.9.0(axios@1.6.8)(universal-cookie@4.0.4)(vue@3.3.4) + version: 10.9.0(axios@1.7.0)(universal-cookie@4.0.4)(vue@3.3.4) axios: specifier: ^1.6.8 - version: 1.6.8 - body-parser: - specifier: ^1.20.2 - version: 1.20.2 + version: 1.7.0 cloudinary: specifier: ^1.41.3 version: 1.41.3 - cookie-parser: - specifier: ^1.4.6 - version: 1.4.6 cors: specifier: ^2.8.5 version: 2.8.5 dotenv: specifier: ^16.4.5 version: 16.4.5 - ducksmanager: - specifier: ^0.0.51 - version: 0.0.51 express: specifier: ^4.19.2 version: 4.19.2 - express-file-routing: - specifier: ^3.0.3 - version: 3.0.3(express@4.19.2) i18n: specifier: ^0.15.1 version: 0.15.1 @@ -56,25 +47,31 @@ importers: node-base64-image: specifier: ^2.0.6 version: 2.0.6 - nodemon: - specifier: ^2.0.22 - version: 2.0.22 - sharp: - specifier: ^0.33.3 - version: 0.33.3 + socket.io: + specifier: ^4.7.5 + version: 4.7.5 + socket.io-client: + specifier: ^4.7.5 + version: 4.7.5 universal-cookie: specifier: ^4.0.4 version: 4.0.4 + ~api: + specifier: workspace:* + version: link:../../../packages/api + ~dm-types: + specifier: workspace:* + version: link:../../../packages/types + ~prisma-clients: + specifier: workspace:* + version: link:../../../packages/prisma-clients + ~socket.io-client-services: + specifier: workspace:* + version: link:../../../packages/socket.io-client-services + ~socket.io-services: + specifier: workspace:* + version: link:../../../packages/socket.io-services devDependencies: - '@types/body-parser': - specifier: ^1.19.5 - version: 1.19.5 - '@types/busboy': - specifier: ^1.5.4 - version: 1.5.4 - '@types/cookie-parser': - specifier: ^1.4.7 - version: 1.4.7 '@types/cors': specifier: ^2.8.17 version: 2.8.17 @@ -93,37 +90,41 @@ importers: '@types/node': specifier: ^18.19.33 version: 18.19.33 + concurrently: + specifier: ^8.2.2 + version: 8.2.2 tsc-alias: specifier: ^1.8.9 - version: 1.8.9 + version: 1.8.10 tsx: specifier: ^4.10.1 - version: 4.10.1 + version: 4.10.5 typescript: specifier: ^5.4.5 version: 5.4.5 packages: - '@babel/helper-string-parser@7.22.5': - resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} + '@babel/helper-string-parser@7.24.1': + resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.22.5': - resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} + '@babel/helper-validator-identifier@7.24.5': + resolution: {integrity: sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==} engines: {node: '>=6.9.0'} - '@babel/parser@7.22.7': - resolution: {integrity: sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==} + '@babel/parser@7.24.5': + resolution: {integrity: sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/types@7.22.5': - resolution: {integrity: sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==} + '@babel/runtime@7.24.5': + resolution: {integrity: sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==} engines: {node: '>=6.9.0'} - '@emnapi/runtime@1.1.1': - resolution: {integrity: sha512-3bfqkzuR1KLx57nZfjr2NLnFOobvyS0aTszaEGCGqmYMVDRaGvgIZbjGSV/MHSSmLgQ/b9JFHQ5xm5WRZYd+XQ==} + '@babel/types@7.24.5': + resolution: {integrity: sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==} + engines: {node: '>=6.9.0'} '@esbuild/aix-ppc64@0.20.2': resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} @@ -263,124 +264,11 @@ packages: cpu: [x64] os: [win32] - '@img/sharp-darwin-arm64@0.33.3': - resolution: {integrity: sha512-FaNiGX1MrOuJ3hxuNzWgsT/mg5OHG/Izh59WW2mk1UwYHUwtfbhk5QNKYZgxf0pLOhx9ctGiGa2OykD71vOnSw==} - engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} - cpu: [arm64] - os: [darwin] - - '@img/sharp-darwin-x64@0.33.3': - resolution: {integrity: sha512-2QeSl7QDK9ru//YBT4sQkoq7L0EAJZA3rtV+v9p8xTKl4U1bUqTIaCnoC7Ctx2kCjQgwFXDasOtPTCT8eCTXvw==} - engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-darwin-arm64@1.0.2': - resolution: {integrity: sha512-tcK/41Rq8IKlSaKRCCAuuY3lDJjQnYIW1UXU1kxcEKrfL8WR7N6+rzNoOxoQRJWTAECuKwgAHnPvqXGN8XfkHA==} - engines: {macos: '>=11', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} - cpu: [arm64] - os: [darwin] - - '@img/sharp-libvips-darwin-x64@1.0.2': - resolution: {integrity: sha512-Ofw+7oaWa0HiiMiKWqqaZbaYV3/UGL2wAPeLuJTx+9cXpCRdvQhCLG0IH8YGwM0yGWGLpsF4Su9vM1o6aer+Fw==} - engines: {macos: '>=10.13', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-linux-arm64@1.0.2': - resolution: {integrity: sha512-x7kCt3N00ofFmmkkdshwj3vGPCnmiDh7Gwnd4nUwZln2YjqPxV1NlTyZOvoDWdKQVDL911487HOueBvrpflagw==} - engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linux-arm@1.0.2': - resolution: {integrity: sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw==} - engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} - cpu: [arm] - os: [linux] - - '@img/sharp-libvips-linux-s390x@1.0.2': - resolution: {integrity: sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog==} - engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} - cpu: [s390x] - os: [linux] - - '@img/sharp-libvips-linux-x64@1.0.2': - resolution: {integrity: sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ==} - engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} - cpu: [x64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-arm64@1.0.2': - resolution: {integrity: sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ==} - engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-x64@1.0.2': - resolution: {integrity: sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw==} - engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} - cpu: [x64] - os: [linux] - - '@img/sharp-linux-arm64@0.33.3': - resolution: {integrity: sha512-Zf+sF1jHZJKA6Gor9hoYG2ljr4wo9cY4twaxgFDvlG0Xz9V7sinsPp8pFd1XtlhTzYo0IhDbl3rK7P6MzHpnYA==} - engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} - cpu: [arm64] - os: [linux] - - '@img/sharp-linux-arm@0.33.3': - resolution: {integrity: sha512-Q7Ee3fFSC9P7vUSqVEF0zccJsZ8GiiCJYGWDdhEjdlOeS9/jdkyJ6sUSPj+bL8VuOYFSbofrW0t/86ceVhx32w==} - engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} - cpu: [arm] - os: [linux] - - '@img/sharp-linux-s390x@0.33.3': - resolution: {integrity: sha512-vFk441DKRFepjhTEH20oBlFrHcLjPfI8B0pMIxGm3+yilKyYeHEVvrZhYFdqIseSclIqbQ3SnZMwEMWonY5XFA==} - engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} - cpu: [s390x] - os: [linux] - - '@img/sharp-linux-x64@0.33.3': - resolution: {integrity: sha512-Q4I++herIJxJi+qmbySd072oDPRkCg/SClLEIDh5IL9h1zjhqjv82H0Seupd+q2m0yOfD+/fJnjSoDFtKiHu2g==} - engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} - cpu: [x64] - os: [linux] - - '@img/sharp-linuxmusl-arm64@0.33.3': - resolution: {integrity: sha512-qnDccehRDXadhM9PM5hLvcPRYqyFCBN31kq+ErBSZtZlsAc1U4Z85xf/RXv1qolkdu+ibw64fUDaRdktxTNP9A==} - engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} - cpu: [arm64] - os: [linux] - - '@img/sharp-linuxmusl-x64@0.33.3': - resolution: {integrity: sha512-Jhchim8kHWIU/GZ+9poHMWRcefeaxFIs9EBqf9KtcC14Ojk6qua7ghKiPs0sbeLbLj/2IGBtDcxHyjCdYWkk2w==} - engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} - cpu: [x64] - os: [linux] - - '@img/sharp-wasm32@0.33.3': - resolution: {integrity: sha512-68zivsdJ0koE96stdUfM+gmyaK/NcoSZK5dV5CAjES0FUXS9lchYt8LAB5rTbM7nlWtxaU/2GON0HVN6/ZYJAQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} - cpu: [wasm32] - - '@img/sharp-win32-ia32@0.33.3': - resolution: {integrity: sha512-CyimAduT2whQD8ER4Ux7exKrtfoaUiVr7HG0zZvO0XTFn2idUWljjxv58GxNTkFb8/J9Ub9AqITGkJD6ZginxQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} - cpu: [ia32] - os: [win32] - - '@img/sharp-win32-x64@0.33.3': - resolution: {integrity: sha512-viT4fUIDKnli3IfOephGnolMzhz5VaTvDRkYqtZxOMIoMQ4MrAziO7pT1nVnOt2FAm7qW5aa+CCc13aEY6Le0g==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} - cpu: [x64] - os: [win32] - '@jridgewell/sourcemap-codec@1.4.15': resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - '@messageformat/core@3.2.0': - resolution: {integrity: sha512-ppbb/7OYqg/t4WdFk8VAfZEV2sNUq3+7VeBAo5sKFhmF786sh6gB7fUeXa2qLTDIcTHS49HivTBN7QNOU5OFTg==} + '@messageformat/core@3.3.0': + resolution: {integrity: sha512-YcXd3remTDdeMxAlbvW6oV9d/01/DZ8DHUFwSttO3LMzIZj3iO0NRw+u1xlsNNORFI+u0EQzD52ZX3+Udi0T3g==} '@messageformat/date-skeleton@1.0.1': resolution: {integrity: sha512-jPXy8fg+WMPIgmGjxSlnGJn68h/2InfT0TNSkVx0IGXgp4ynnvYkbZ51dGWmGySEK+pBiYUttbQdu5XEqX5CRg==} @@ -406,56 +294,64 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@sentry-internal/tracing@7.114.0': - resolution: {integrity: sha512-dOuvfJN7G+3YqLlUY4HIjyWHaRP8vbOgF+OsE5w2l7ZEn1rMAaUbPntAR8AF9GBA6j2zWNoSo8e7GjbJxVofSg==} + '@sentry-internal/tracing@7.116.0': + resolution: {integrity: sha512-y5ppEmoOlfr77c/HqsEXR72092qmGYS4QE5gSz5UZFn9CiinEwGfEorcg2xIrrCuU7Ry/ZU2VLz9q3xd04drRA==} engines: {node: '>=8'} - '@sentry/core@7.114.0': - resolution: {integrity: sha512-YnanVlmulkjgZiVZ9BfY9k6I082n+C+LbZo52MTvx3FY6RE5iyiPMpaOh67oXEZRWcYQEGm+bKruRxLVP6RlbA==} + '@sentry/core@7.116.0': + resolution: {integrity: sha512-J6Wmjjx+o7RwST0weTU1KaKUAlzbc8MGkJV1rcHM9xjNTWTva+nrcCM3vFBagnk2Gm/zhwv3h0PvWEqVyp3U1Q==} engines: {node: '>=8'} - '@sentry/integrations@7.114.0': - resolution: {integrity: sha512-BJIBWXGKeIH0ifd7goxOS29fBA8BkEgVVCahs6xIOXBjX1IRS6PmX0zYx/GP23nQTfhJiubv2XPzoYOlZZmDxg==} + '@sentry/integrations@7.116.0': + resolution: {integrity: sha512-UZb60gaF+7veh1Yv79RiGvgGYOnU6xA97H+hI6tKgc1uT20YpItO4X56Vhp0lvyEyUGFZzBRRH1jpMDPNGPkqw==} engines: {node: '>=8'} - '@sentry/node@7.114.0': - resolution: {integrity: sha512-cqvi+OHV1Hj64mIGHoZtLgwrh1BG6ntcRjDLlVNMqml5rdTRD3TvG21579FtlqHlwZpbpF7K5xkwl8e5KL2hGw==} + '@sentry/node@7.116.0': + resolution: {integrity: sha512-HB/4TrJWbnu6swNzkid+MlwzLwY/D/klGt3R0aatgrgWPo2jJm6bSl4LUT39Cr2eg5I1gsREQtXE2mAlC6gm8w==} engines: {node: '>=8'} - '@sentry/types@7.114.0': - resolution: {integrity: sha512-tsqkkyL3eJtptmPtT0m9W/bPLkU7ILY7nvwpi1hahA5jrM7ppoU0IMaQWAgTD+U3rzFH40IdXNBFb8Gnqcva4w==} + '@sentry/types@7.116.0': + resolution: {integrity: sha512-QCCvG5QuQrwgKzV11lolNQPP2k67Q6HHD9vllZ/C4dkxkjoIym8Gy+1OgAN3wjsR0f/kG9o5iZyglgNpUVRapQ==} engines: {node: '>=8'} - '@sentry/utils@7.114.0': - resolution: {integrity: sha512-319N90McVpupQ6vws4+tfCy/03AdtsU0MurIE4+W5cubHME08HtiEWlfacvAxX+yuKFhvdsO4K4BB/dj54ideg==} + '@sentry/utils@7.116.0': + resolution: {integrity: sha512-Vn9fcvwTq91wJvCd7WTMWozimqMi+dEZ3ie3EICELC2diONcN16ADFdzn65CQQbYwmUzRjN9EjDN2k41pKZWhQ==} engines: {node: '>=8'} - '@types/body-parser@1.19.5': - resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + '@socket.io/admin-ui@0.5.1': + resolution: {integrity: sha512-1dlGL2FGm6T+uL1e6iDvbo2eCINwvW7iVbjIblwh5kPPRM1SP8lmZrbFZf4QNJ/cqQ+JLcx49eXGM9WAB4TK7w==} + peerDependencies: + socket.io: '>=3.1.0' + + '@socket.io/component-emitter@3.1.2': + resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} - '@types/busboy@1.5.4': - resolution: {integrity: sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==} + '@types/bcryptjs@2.4.6': + resolution: {integrity: sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==} - '@types/connect@3.4.35': - resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} + '@types/body-parser@1.19.5': + resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} - '@types/cookie-parser@1.4.7': - resolution: {integrity: sha512-Fvuyi354Z+uayxzIGCwYTayFKocfV7TuDYZClCdIP9ckhvAu/ixDtCB6qx2TT0FKjPLf1f3P/J1rgf6lPs64mw==} + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} '@types/cookie@0.3.3': resolution: {integrity: sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==} + '@types/cookie@0.4.1': + resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==} + '@types/cors@2.8.17': resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==} - '@types/express-serve-static-core@4.17.35': - resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==} + '@types/express-serve-static-core@4.19.0': + resolution: {integrity: sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==} '@types/express@4.17.21': resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} - '@types/http-errors@2.0.1': - resolution: {integrity: sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==} + '@types/http-errors@2.0.4': + resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} '@types/i18n@0.13.12': resolution: {integrity: sha512-iAd2QjKh+0ToBXocmCS3m38GskiaGzmSV1MTQz2GaOraqSqBiLf46J7u3EGINl+st+Uk4lO3OL7QyIjTJlrWIg==} @@ -463,32 +359,26 @@ packages: '@types/jsonwebtoken@9.0.6': resolution: {integrity: sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==} - '@types/mime@1.3.2': - resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==} - - '@types/mime@3.0.1': - resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==} + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} '@types/multer@1.4.11': resolution: {integrity: sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==} - '@types/node@16.18.38': - resolution: {integrity: sha512-6sfo1qTulpVbkxECP+AVrHV9OoJqhzCsfTNp5NIG+enM4HyM3HvZCO798WShIXBN0+QtDIcutJCjsVYnQP5rIQ==} - '@types/node@18.19.33': resolution: {integrity: sha512-NR9+KrpSajr2qBVp/Yt5TU/rp+b5Mayi3+OlMlcg2cVCfRmcG5PWZ7S4+MG9PZ5gWBoc9Pd0BKSRViuBCRPu0A==} - '@types/qs@6.9.7': - resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} + '@types/qs@6.9.15': + resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} - '@types/range-parser@1.2.4': - resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - '@types/send@0.17.1': - resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==} + '@types/send@0.17.4': + resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} - '@types/serve-static@1.15.2': - resolution: {integrity: sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==} + '@types/serve-static@1.15.7': + resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} '@types/web-bluetooth@0.0.20': resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} @@ -575,13 +465,18 @@ packages: '@vueuse/shared@10.9.0': resolution: {integrity: sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==} - abbrev@1.1.1: - resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} - accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} @@ -602,14 +497,18 @@ packages: axios@1.6.0: resolution: {integrity: sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==} - axios@1.6.8: - resolution: {integrity: sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==} + axios@1.7.0: + resolution: {integrity: sha512-IiB0wQeKyPRdsFVhBgIo31FbzOyf2M6wYl7/NVutFwFBRMiAbjNiydJIHKeLmPugF4kJLfA1uWZ82Is2QzqqFA==} - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + base64id@2.0.0: + resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} + engines: {node: ^4.5.0 || >= 5.9} - binary-extensions@2.2.0: - resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + bcryptjs@2.4.3: + resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} body-parser@1.20.2: @@ -619,9 +518,6 @@ packages: boolean@3.2.0: resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} @@ -640,15 +536,24 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} - call-bind@1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} - chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} - cloudinary-core@2.13.0: - resolution: {integrity: sha512-Nt0Q5I2FtenmJghtC4YZ3MZZbGg1wLm84SsxcuVwZ83OyJqG9CNIGp86CiI6iDv3QobaqBUpOT7vg+HqY5HxEA==} + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + cloudinary-core@2.13.1: + resolution: {integrity: sha512-z53GPNWnvU0Zi+ns8CIVbZBfj7ps/++zDvwIyiFuq5p1MoK+KUCg0k5mBceDDHTnx1gHmHUd9aohS+gDxPNt6w==} peerDependencies: lodash: '>=4.0' @@ -663,13 +568,6 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - color-string@1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} - - color@4.2.3: - resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} - engines: {node: '>=12.5.0'} - combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -678,13 +576,15 @@ packages: resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} engines: {node: ^12.20.0 || >=14} - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - concat-stream@1.6.2: resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} engines: {'0': node >= 0.8} + concurrently@8.2.2: + resolution: {integrity: sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==} + engines: {node: ^14.13.0 || >=16.0.0} + hasBin: true + content-disposition@0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} @@ -693,17 +593,9 @@ packages: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} - cookie-parser@1.4.6: - resolution: {integrity: sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==} - engines: {node: '>= 0.8.0'} - cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - cookie@0.4.1: - resolution: {integrity: sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==} - engines: {node: '>= 0.6'} - cookie@0.4.2: resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} engines: {node: '>= 0.6'} @@ -712,8 +604,8 @@ packages: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} - core-js@3.31.1: - resolution: {integrity: sha512-2sKLtfq1eFST7l7v62zaqXacPc7uG8ZAya8ogijLhTtaKNcpzpB4TMoTw2Si+8GYKRwFPMMtUT0263QFWFfqyQ==} + core-js@3.37.1: + resolution: {integrity: sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==} core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -722,8 +614,12 @@ packages: resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} engines: {node: '>= 0.10'} - csstype@3.1.2: - resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + date-fns@2.30.0: + resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} + engines: {node: '>=0.11'} debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} @@ -733,14 +629,6 @@ packages: supports-color: optional: true - debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -750,6 +638,10 @@ packages: supports-color: optional: true + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -762,10 +654,6 @@ packages: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - detect-libc@2.0.3: - resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} - engines: {node: '>=8'} - dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -774,24 +662,47 @@ packages: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} - ducksmanager@0.0.51: - resolution: {integrity: sha512-0BFbwMOAQv0wEhF/ezoxdQrAh5iwAGZYwVbMlq70PsrNeuhCqnI2D9VcW1Dch1COUlA/OgtKknzRD14lJhg4Jw==} - ecdsa-sig-formatter@1.0.11: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + encodeurl@1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} + engine.io-client@6.5.3: + resolution: {integrity: sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==} + + engine.io-parser@5.2.2: + resolution: {integrity: sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==} + engines: {node: '>=10.0.0'} + + engine.io@6.5.4: + resolution: {integrity: sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==} + engines: {node: '>=10.2.0'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + esbuild@0.20.2: resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} engines: {node: '>=12'} hasBin: true + escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} @@ -802,25 +713,20 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} - express-file-routing@3.0.3: - resolution: {integrity: sha512-0936IhPc64moJHAG1Fz3SLCi0Upt6ahsbocrC6hdPUgmHY2018wjVrbln0HP67JoWFUdmmzypYiIHjF898s0hA==} - peerDependencies: - express: '>4.1.2' - express@4.19.2: resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} engines: {node: '>= 0.10.0'} - fast-glob@3.3.0: - resolution: {integrity: sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==} + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} fast-printf@1.6.9: resolution: {integrity: sha512-FChq8hbz65WMj4rstcQsFB0O7Cy++nmbNfLYnD9cYv2cRn8EG6k/MGn9kO/tjO66t09DLDugj3yL+V2o6Qftrg==} engines: {node: '>=10.0'} - fastq@1.15.0: - resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} @@ -830,15 +736,6 @@ packages: resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} engines: {node: '>= 0.8'} - follow-redirects@1.15.2: - resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - follow-redirects@1.15.6: resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} engines: {node: '>=4.0'} @@ -860,21 +757,21 @@ packages: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} - fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] - function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} - get-intrinsic@1.2.1: - resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} get-tsconfig@4.7.5: resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} @@ -887,21 +784,27 @@ packages: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} - has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - has-proto@1.0.1: - resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} engines: {node: '>= 0.4'} has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} - has@1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} @@ -915,11 +818,8 @@ packages: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} - ignore-by-default@1.0.1: - resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} - - ignore@5.2.4: - resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} image-size@1.1.1: @@ -937,9 +837,6 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} - is-arrayish@0.3.2: - resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} - is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -948,6 +845,10 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -999,16 +900,11 @@ packages: lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - - magic-string@0.30.1: - resolution: {integrity: sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==} - engines: {node: '>=12'} + magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} - make-plural@7.3.0: - resolution: {integrity: sha512-/K3BC0KIsO+WK2i94LkMPv3wslMrazrQhfi5We9fMbLlLjzoOSJWr7TAdupLlDWaJcWxwoNosBkhFDejiu5VDw==} + make-plural@7.4.0: + resolution: {integrity: sha512-4/gC9KVNTV6pvYg2gFeQYTW3mWaoJt7WZE5vrp1KnQDgW92JtYZnzmZT81oj/dUTqAIu0ufI2x3dkgu3bB1tYg==} math-interval-parser@2.0.1: resolution: {integrity: sha512-VmlAmb0UJwlvMyx8iPhXUDnVW1F9IrGEd9CIOmv+XL8AErCUUuozoDMrgImvnYt2A+53qVX/tPW6YJurMKYsvA==} @@ -1046,9 +942,6 @@ packages: engines: {node: '>=4'} hasBin: true - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -1080,8 +973,8 @@ packages: resolution: {integrity: sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==} engines: {node: '>=12.0.0'} - nanoid@3.3.6: - resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -1093,15 +986,6 @@ packages: resolution: {integrity: sha512-fUioszu6tGacTl5QkUI1CERjg1y5loOwSMb2LMiHt98DMkWxirhVg35kEnLghbeLQjZ9Mik5NbaV881jcC2tow==} engines: {node: '>=16'} - nodemon@2.0.22: - resolution: {integrity: sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==} - engines: {node: '>=8.10.0'} - hasBin: true - - nopt@1.0.10: - resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==} - hasBin: true - normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -1110,8 +994,8 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - object-inspect@1.12.3: - resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} @@ -1128,18 +1012,19 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - plimit-lit@1.5.0: - resolution: {integrity: sha512-Eb/MqCb1Iv/ok4m1FqIXqvUKPISufcjZ605hl3KM/n8GaX8zfhtgdLwZU3vKjuHGh2O9Rjog/bHTq8ofIShdng==} + plimit-lit@1.6.1: + resolution: {integrity: sha512-B7+VDyb8Tl6oMJT9oSO2CW8XC/T4UcJGrwOVoNGwOQsQYhlpfajmrMj5xeejqaASq3V/EqThyOeATEOMuSEXiA==} + engines: {node: '>=12'} - postcss@8.4.26: - resolution: {integrity: sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw==} + postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} engines: {node: ^10 || ^12 || >=14} process-nextick-args@2.0.1: @@ -1152,9 +1037,6 @@ packages: proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - pstree.remy@1.1.8: - resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} - q@1.5.1: resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==} engines: {node: '>=0.6.0', teleport: '>=0.2.0'} @@ -1163,8 +1045,9 @@ packages: resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} engines: {node: '>=0.6'} - queue-lit@1.5.0: - resolution: {integrity: sha512-IslToJ4eiCEE9xwMzq3viOO5nH8sUWUCwoElrhNMozzr9IIt2qqvB4I+uHu/zJTQVqc9R5DFwok4ijNK1pU3fA==} + queue-lit@1.5.2: + resolution: {integrity: sha512-tLc36IOPeMAubu8BkW8YDBV+WyIgKlYU7zUNs0J5Vk9skSZ4JfGlPOqplP0aHdfv7HL0B2Pg6nwiq60Qc6M2Hw==} + engines: {node: '>=12'} queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -1187,6 +1070,13 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} @@ -1197,6 +1087,9 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} @@ -1209,19 +1102,6 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - semver@5.7.2: - resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} - hasBin: true - - semver@7.0.0: - resolution: {integrity: sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==} - hasBin: true - - semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} - engines: {node: '>=10'} - hasBin: true - semver@7.6.2: resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} engines: {node: '>=10'} @@ -1235,31 +1115,46 @@ packages: resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} engines: {node: '>= 0.8.0'} + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - sharp@0.33.3: - resolution: {integrity: sha512-vHUeXJU1UvlO/BNwTpT0x/r53WkLUVxrmb5JTgW92fdFCFk0ispLMAeu/jPO2vjkXM1fYUi3K7/qcLF47pwM1A==} - engines: {libvips: '>=8.15.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shell-quote@1.8.1: + resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} - side-channel@1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} - - simple-swizzle@0.2.2: - resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} - - simple-update-notifier@1.1.0: - resolution: {integrity: sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==} - engines: {node: '>=8.10.0'} + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} - source-map-js@1.0.2: - resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + socket.io-adapter@2.5.4: + resolution: {integrity: sha512-wDNHGXGewWAjQPt3pyeYBtpWSq9cLE5UW1ZUPL/2eGK9jtse/FpXib7epSTsz0Q0m+6sg6Y4KtcFTlah1bdOVg==} + + socket.io-client@4.7.5: + resolution: {integrity: sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==} + engines: {node: '>=10.0.0'} + + socket.io-parser@4.2.4: + resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==} + engines: {node: '>=10.0.0'} + + socket.io@4.7.5: + resolution: {integrity: sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==} + engines: {node: '>=10.2.0'} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} + spawn-command@0.0.2: + resolution: {integrity: sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==} + statuses@2.0.1: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} @@ -1268,12 +1163,24 @@ packages: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} - supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} @@ -1287,19 +1194,19 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} - touch@3.1.0: - resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==} + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true - tsc-alias@1.8.9: - resolution: {integrity: sha512-Bkxu+LlUp/VG2qkcXGmj9wBkJuJID0mEC9t+bZaEbl9kyk/QJX6uo8/+z8DxTqUoqKPcbSApO2Ep42bsIVm9DA==} + tsc-alias@1.8.10: + resolution: {integrity: sha512-Ibv4KAWfFkFdKJxnWfVtdOmB0Zi1RJVxcbPGiCDsFpCQSsmpWyuzHG3rQyI5YkobWwxFPEyQfu1hdo4qLG2zPw==} hasBin: true tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - tsx@4.10.1: - resolution: {integrity: sha512-G+CcyTOopwhuI81FU+KpzGN5UBhHgGEDlGt8mHAXKxv8pDGr6WI7hI7aRjTRol5WzFVsSNuzl3ekCZ0eLIJlEQ==} + tsx@4.10.5: + resolution: {integrity: sha512-twDSbf7Gtea4I2copqovUiNTEDrT8XNFXsuHpfGbdpW/z9ZW4fTghzzhAG0WfrCuJmJiOEY1nLIjq4u3oujRWQ==} engines: {node: '>=18.0.0'} hasBin: true @@ -1315,9 +1222,6 @@ packages: engines: {node: '>=14.17'} hasBin: true - undefsafe@2.0.5: - resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} - undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} @@ -1353,33 +1257,61 @@ packages: vue@3.3.4: resolution: {integrity: sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==} + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + ws@8.11.0: + resolution: {integrity: sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xmlhttprequest-ssl@2.0.0: + resolution: {integrity: sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==} + engines: {node: '>=0.4.0'} + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} snapshots: - '@babel/helper-string-parser@7.22.5': {} + '@babel/helper-string-parser@7.24.1': {} - '@babel/helper-validator-identifier@7.22.5': {} + '@babel/helper-validator-identifier@7.24.5': {} - '@babel/parser@7.22.7': + '@babel/parser@7.24.5': dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.24.5 - '@babel/types@7.22.5': + '@babel/runtime@7.24.5': dependencies: - '@babel/helper-string-parser': 7.22.5 - '@babel/helper-validator-identifier': 7.22.5 - to-fast-properties: 2.0.0 + regenerator-runtime: 0.14.1 - '@emnapi/runtime@1.1.1': + '@babel/types@7.24.5': dependencies: - tslib: 2.6.2 - optional: true + '@babel/helper-string-parser': 7.24.1 + '@babel/helper-validator-identifier': 7.24.5 + to-fast-properties: 2.0.0 '@esbuild/aix-ppc64@0.20.2': optional: true @@ -1450,90 +1382,15 @@ snapshots: '@esbuild/win32-x64@0.20.2': optional: true - '@img/sharp-darwin-arm64@0.33.3': - optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.0.2 - optional: true - - '@img/sharp-darwin-x64@0.33.3': - optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.0.2 - optional: true - - '@img/sharp-libvips-darwin-arm64@1.0.2': - optional: true - - '@img/sharp-libvips-darwin-x64@1.0.2': - optional: true - - '@img/sharp-libvips-linux-arm64@1.0.2': - optional: true - - '@img/sharp-libvips-linux-arm@1.0.2': - optional: true - - '@img/sharp-libvips-linux-s390x@1.0.2': - optional: true - - '@img/sharp-libvips-linux-x64@1.0.2': - optional: true - - '@img/sharp-libvips-linuxmusl-arm64@1.0.2': - optional: true - - '@img/sharp-libvips-linuxmusl-x64@1.0.2': - optional: true - - '@img/sharp-linux-arm64@0.33.3': - optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.0.2 - optional: true - - '@img/sharp-linux-arm@0.33.3': - optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.0.2 - optional: true - - '@img/sharp-linux-s390x@0.33.3': - optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.0.2 - optional: true - - '@img/sharp-linux-x64@0.33.3': - optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.0.2 - optional: true - - '@img/sharp-linuxmusl-arm64@0.33.3': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.0.2 - optional: true - - '@img/sharp-linuxmusl-x64@0.33.3': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.0.2 - optional: true - - '@img/sharp-wasm32@0.33.3': - dependencies: - '@emnapi/runtime': 1.1.1 - optional: true - - '@img/sharp-win32-ia32@0.33.3': - optional: true - - '@img/sharp-win32-x64@0.33.3': - optional: true - '@jridgewell/sourcemap-codec@1.4.15': {} - '@messageformat/core@3.2.0': + '@messageformat/core@3.3.0': dependencies: '@messageformat/date-skeleton': 1.0.1 '@messageformat/number-skeleton': 1.2.0 '@messageformat/parser': 5.1.0 '@messageformat/runtime': 3.0.1 - make-plural: 7.3.0 + make-plural: 7.4.0 safe-identifier: 0.4.2 '@messageformat/date-skeleton@1.0.1': {} @@ -1546,7 +1403,7 @@ snapshots: '@messageformat/runtime@3.0.1': dependencies: - make-plural: 7.3.0 + make-plural: 7.4.0 '@nodelib/fs.scandir@2.1.5': dependencies: @@ -1558,122 +1415,125 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.15.0 + fastq: 1.17.1 - '@sentry-internal/tracing@7.114.0': + '@sentry-internal/tracing@7.116.0': dependencies: - '@sentry/core': 7.114.0 - '@sentry/types': 7.114.0 - '@sentry/utils': 7.114.0 + '@sentry/core': 7.116.0 + '@sentry/types': 7.116.0 + '@sentry/utils': 7.116.0 - '@sentry/core@7.114.0': + '@sentry/core@7.116.0': dependencies: - '@sentry/types': 7.114.0 - '@sentry/utils': 7.114.0 + '@sentry/types': 7.116.0 + '@sentry/utils': 7.116.0 - '@sentry/integrations@7.114.0': + '@sentry/integrations@7.116.0': dependencies: - '@sentry/core': 7.114.0 - '@sentry/types': 7.114.0 - '@sentry/utils': 7.114.0 + '@sentry/core': 7.116.0 + '@sentry/types': 7.116.0 + '@sentry/utils': 7.116.0 localforage: 1.10.0 - '@sentry/node@7.114.0': + '@sentry/node@7.116.0': dependencies: - '@sentry-internal/tracing': 7.114.0 - '@sentry/core': 7.114.0 - '@sentry/integrations': 7.114.0 - '@sentry/types': 7.114.0 - '@sentry/utils': 7.114.0 + '@sentry-internal/tracing': 7.116.0 + '@sentry/core': 7.116.0 + '@sentry/integrations': 7.116.0 + '@sentry/types': 7.116.0 + '@sentry/utils': 7.116.0 - '@sentry/types@7.114.0': {} + '@sentry/types@7.116.0': {} - '@sentry/utils@7.114.0': + '@sentry/utils@7.116.0': dependencies: - '@sentry/types': 7.114.0 + '@sentry/types': 7.116.0 - '@types/body-parser@1.19.5': + '@socket.io/admin-ui@0.5.1(socket.io@4.7.5)': dependencies: - '@types/connect': 3.4.35 - '@types/node': 16.18.38 + '@types/bcryptjs': 2.4.6 + bcryptjs: 2.4.3 + debug: 4.3.4 + socket.io: 4.7.5 + transitivePeerDependencies: + - supports-color - '@types/busboy@1.5.4': - dependencies: - '@types/node': 16.18.38 + '@socket.io/component-emitter@3.1.2': {} - '@types/connect@3.4.35': + '@types/bcryptjs@2.4.6': {} + + '@types/body-parser@1.19.5': dependencies: - '@types/node': 16.18.38 + '@types/connect': 3.4.38 + '@types/node': 18.19.33 - '@types/cookie-parser@1.4.7': + '@types/connect@3.4.38': dependencies: - '@types/express': 4.17.21 + '@types/node': 18.19.33 '@types/cookie@0.3.3': {} + '@types/cookie@0.4.1': {} + '@types/cors@2.8.17': dependencies: - '@types/node': 16.18.38 + '@types/node': 18.19.33 - '@types/express-serve-static-core@4.17.35': + '@types/express-serve-static-core@4.19.0': dependencies: - '@types/node': 16.18.38 - '@types/qs': 6.9.7 - '@types/range-parser': 1.2.4 - '@types/send': 0.17.1 + '@types/node': 18.19.33 + '@types/qs': 6.9.15 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.4 '@types/express@4.17.21': dependencies: '@types/body-parser': 1.19.5 - '@types/express-serve-static-core': 4.17.35 - '@types/qs': 6.9.7 - '@types/serve-static': 1.15.2 + '@types/express-serve-static-core': 4.19.0 + '@types/qs': 6.9.15 + '@types/serve-static': 1.15.7 - '@types/http-errors@2.0.1': {} + '@types/http-errors@2.0.4': {} '@types/i18n@0.13.12': {} '@types/jsonwebtoken@9.0.6': dependencies: - '@types/node': 16.18.38 - - '@types/mime@1.3.2': {} + '@types/node': 18.19.33 - '@types/mime@3.0.1': {} + '@types/mime@1.3.5': {} '@types/multer@1.4.11': dependencies: '@types/express': 4.17.21 - '@types/node@16.18.38': {} - '@types/node@18.19.33': dependencies: undici-types: 5.26.5 - '@types/qs@6.9.7': {} + '@types/qs@6.9.15': {} - '@types/range-parser@1.2.4': {} + '@types/range-parser@1.2.7': {} - '@types/send@0.17.1': + '@types/send@0.17.4': dependencies: - '@types/mime': 1.3.2 - '@types/node': 16.18.38 + '@types/mime': 1.3.5 + '@types/node': 18.19.33 - '@types/serve-static@1.15.2': + '@types/serve-static@1.15.7': dependencies: - '@types/http-errors': 2.0.1 - '@types/mime': 3.0.1 - '@types/node': 16.18.38 + '@types/http-errors': 2.0.4 + '@types/node': 18.19.33 + '@types/send': 0.17.4 '@types/web-bluetooth@0.0.20': {} '@vue/compiler-core@3.3.4': dependencies: - '@babel/parser': 7.22.7 + '@babel/parser': 7.24.5 '@vue/shared': 3.3.4 estree-walker: 2.0.2 - source-map-js: 1.0.2 + source-map-js: 1.2.0 '@vue/compiler-dom@3.3.4': dependencies: @@ -1682,16 +1542,16 @@ snapshots: '@vue/compiler-sfc@3.3.4': dependencies: - '@babel/parser': 7.22.7 + '@babel/parser': 7.24.5 '@vue/compiler-core': 3.3.4 '@vue/compiler-dom': 3.3.4 '@vue/compiler-ssr': 3.3.4 '@vue/reactivity-transform': 3.3.4 '@vue/shared': 3.3.4 estree-walker: 2.0.2 - magic-string: 0.30.1 - postcss: 8.4.26 - source-map-js: 1.0.2 + magic-string: 0.30.10 + postcss: 8.4.38 + source-map-js: 1.2.0 '@vue/compiler-ssr@3.3.4': dependencies: @@ -1700,11 +1560,11 @@ snapshots: '@vue/reactivity-transform@3.3.4': dependencies: - '@babel/parser': 7.22.7 + '@babel/parser': 7.24.5 '@vue/compiler-core': 3.3.4 '@vue/shared': 3.3.4 estree-walker: 2.0.2 - magic-string: 0.30.1 + magic-string: 0.30.10 '@vue/reactivity@3.3.4': dependencies: @@ -1719,7 +1579,7 @@ snapshots: dependencies: '@vue/runtime-core': 3.3.4 '@vue/shared': 3.3.4 - csstype: 3.1.2 + csstype: 3.1.3 '@vue/server-renderer@3.3.4(vue@3.3.4)': dependencies: @@ -1739,13 +1599,13 @@ snapshots: - '@vue/composition-api' - vue - '@vueuse/integrations@10.9.0(axios@1.6.8)(universal-cookie@4.0.4)(vue@3.3.4)': + '@vueuse/integrations@10.9.0(axios@1.7.0)(universal-cookie@4.0.4)(vue@3.3.4)': dependencies: '@vueuse/core': 10.9.0(vue@3.3.4) '@vueuse/shared': 10.9.0(vue@3.3.4) vue-demi: 0.14.7(vue@3.3.4) optionalDependencies: - axios: 1.6.8 + axios: 1.7.0 universal-cookie: 4.0.4 transitivePeerDependencies: - '@vue/composition-api' @@ -1760,13 +1620,17 @@ snapshots: - '@vue/composition-api' - vue - abbrev@1.1.1: {} - accepts@1.3.8: dependencies: mime-types: 2.1.35 negotiator: 0.6.3 + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 @@ -1782,13 +1646,13 @@ snapshots: axios@1.6.0: dependencies: - follow-redirects: 1.15.2 + follow-redirects: 1.15.6 form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug - axios@1.6.8: + axios@1.7.0: dependencies: follow-redirects: 1.15.6 form-data: 4.0.0 @@ -1796,9 +1660,11 @@ snapshots: transitivePeerDependencies: - debug - balanced-match@1.0.2: {} + base64id@2.0.0: {} - binary-extensions@2.2.0: {} + bcryptjs@2.4.3: {} + + binary-extensions@2.3.0: {} body-parser@1.20.2: dependencies: @@ -1819,11 +1685,6 @@ snapshots: boolean@3.2.0: {} - brace-expansion@1.1.11: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - braces@3.0.2: dependencies: fill-range: 7.0.1 @@ -1838,12 +1699,20 @@ snapshots: bytes@3.1.2: {} - call-bind@1.0.2: + call-bind@1.0.7: dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.2.1 + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 - chokidar@3.5.3: + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chokidar@3.6.0: dependencies: anymatch: 3.1.3 braces: 3.0.2 @@ -1853,16 +1722,22 @@ snapshots: normalize-path: 3.0.0 readdirp: 3.6.0 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 - cloudinary-core@2.13.0(lodash@4.17.21): + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + cloudinary-core@2.13.1(lodash@4.17.21): dependencies: lodash: 4.17.21 cloudinary@1.41.3: dependencies: - cloudinary-core: 2.13.0(lodash@4.17.21) - core-js: 3.31.1 + cloudinary-core: 2.13.1(lodash@4.17.21) + core-js: 3.37.1 lodash: 4.17.21 q: 1.5.1 @@ -1872,24 +1747,12 @@ snapshots: color-name@1.1.4: {} - color-string@1.9.1: - dependencies: - color-name: 1.1.4 - simple-swizzle: 0.2.2 - - color@4.2.3: - dependencies: - color-convert: 2.0.1 - color-string: 1.9.1 - combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 commander@9.5.0: {} - concat-map@0.0.1: {} - concat-stream@1.6.2: dependencies: buffer-from: 1.1.2 @@ -1897,26 +1760,31 @@ snapshots: readable-stream: 2.3.8 typedarray: 0.0.6 + concurrently@8.2.2: + dependencies: + chalk: 4.1.2 + date-fns: 2.30.0 + lodash: 4.17.21 + rxjs: 7.8.1 + shell-quote: 1.8.1 + spawn-command: 0.0.2 + supports-color: 8.1.1 + tree-kill: 1.2.2 + yargs: 17.7.2 + content-disposition@0.5.4: dependencies: safe-buffer: 5.2.1 content-type@1.0.5: {} - cookie-parser@1.4.6: - dependencies: - cookie: 0.4.1 - cookie-signature: 1.0.6 - cookie-signature@1.0.6: {} - cookie@0.4.1: {} - cookie@0.4.2: {} cookie@0.6.0: {} - core-js@3.31.1: {} + core-js@3.37.1: {} core-util-is@1.0.3: {} @@ -1925,46 +1793,85 @@ snapshots: object-assign: 4.1.1 vary: 1.1.2 - csstype@3.1.2: {} + csstype@3.1.3: {} - debug@2.6.9: + date-fns@2.30.0: dependencies: - ms: 2.0.0 + '@babel/runtime': 7.24.5 - debug@3.2.7(supports-color@5.5.0): + debug@2.6.9: dependencies: - ms: 2.1.3 - optionalDependencies: - supports-color: 5.5.0 + ms: 2.0.0 debug@4.3.4: dependencies: ms: 2.1.2 + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + delayed-stream@1.0.0: {} depd@2.0.0: {} destroy@1.2.0: {} - detect-libc@2.0.3: {} - dir-glob@3.0.1: dependencies: path-type: 4.0.0 dotenv@16.4.5: {} - ducksmanager@0.0.51: {} - ecdsa-sig-formatter@1.0.11: dependencies: safe-buffer: 5.2.1 ee-first@1.1.1: {} + emoji-regex@8.0.0: {} + encodeurl@1.0.2: {} + engine.io-client@6.5.3: + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.3.4 + engine.io-parser: 5.2.2 + ws: 8.11.0 + xmlhttprequest-ssl: 2.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + engine.io-parser@5.2.2: {} + + engine.io@6.5.4: + dependencies: + '@types/cookie': 0.4.1 + '@types/cors': 2.8.17 + '@types/node': 18.19.33 + accepts: 1.3.8 + base64id: 2.0.0 + cookie: 0.4.2 + cors: 2.8.5 + debug: 4.3.4 + engine.io-parser: 5.2.2 + ws: 8.11.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + esbuild@0.20.2: optionalDependencies: '@esbuild/aix-ppc64': 0.20.2 @@ -1991,16 +1898,14 @@ snapshots: '@esbuild/win32-ia32': 0.20.2 '@esbuild/win32-x64': 0.20.2 + escalade@3.1.2: {} + escape-html@1.0.3: {} estree-walker@2.0.2: {} etag@1.8.1: {} - express-file-routing@3.0.3(express@4.19.2): - dependencies: - express: 4.19.2 - express@4.19.2: dependencies: accepts: 1.3.8 @@ -2037,7 +1942,7 @@ snapshots: transitivePeerDependencies: - supports-color - fast-glob@3.3.0: + fast-glob@3.3.2: dependencies: '@nodelib/fs.stat': 2.0.5 '@nodelib/fs.walk': 1.2.8 @@ -2049,7 +1954,7 @@ snapshots: dependencies: boolean: 3.2.0 - fastq@1.15.0: + fastq@1.17.1: dependencies: reusify: 1.0.4 @@ -2069,8 +1974,6 @@ snapshots: transitivePeerDependencies: - supports-color - follow-redirects@1.15.2: {} - follow-redirects@1.15.6: {} form-data@4.0.0: @@ -2083,20 +1986,20 @@ snapshots: fresh@0.5.2: {} - fsevents@2.3.2: - optional: true - fsevents@2.3.3: optional: true - function-bind@1.1.1: {} + function-bind@1.1.2: {} + + get-caller-file@2.0.5: {} - get-intrinsic@1.2.1: + get-intrinsic@1.2.4: dependencies: - function-bind: 1.1.1 - has: 1.0.3 - has-proto: 1.0.1 + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 has-symbols: 1.0.3 + hasown: 2.0.2 get-tsconfig@4.7.5: dependencies: @@ -2110,20 +2013,28 @@ snapshots: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.3.0 - ignore: 5.2.4 + fast-glob: 3.3.2 + ignore: 5.3.1 merge2: 1.4.1 slash: 3.0.0 - has-flag@3.0.0: {} + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 - has-proto@1.0.1: {} + has-proto@1.0.3: {} has-symbols@1.0.3: {} - has@1.0.3: + hasown@2.0.2: dependencies: - function-bind: 1.1.1 + function-bind: 1.1.2 http-errors@2.0.0: dependencies: @@ -2135,10 +2046,10 @@ snapshots: i18n@0.15.1: dependencies: - '@messageformat/core': 3.2.0 + '@messageformat/core': 3.3.0 debug: 4.3.4 fast-printf: 1.6.9 - make-plural: 7.3.0 + make-plural: 7.4.0 math-interval-parser: 2.0.1 mustache: 4.2.0 transitivePeerDependencies: @@ -2148,9 +2059,7 @@ snapshots: dependencies: safer-buffer: 2.1.2 - ignore-by-default@1.0.1: {} - - ignore@5.2.4: {} + ignore@5.3.1: {} image-size@1.1.1: dependencies: @@ -2162,14 +2071,14 @@ snapshots: ipaddr.js@1.9.1: {} - is-arrayish@0.3.2: {} - is-binary-path@2.1.0: dependencies: - binary-extensions: 2.2.0 + binary-extensions: 2.3.0 is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 @@ -2189,7 +2098,7 @@ snapshots: lodash.isstring: 4.0.1 lodash.once: 4.1.1 ms: 2.1.3 - semver: 7.5.4 + semver: 7.6.2 jwa@1.4.1: dependencies: @@ -2226,15 +2135,11 @@ snapshots: lodash@4.17.21: {} - lru-cache@6.0.0: - dependencies: - yallist: 4.0.0 - - magic-string@0.30.1: + magic-string@0.30.10: dependencies: '@jridgewell/sourcemap-codec': 1.4.15 - make-plural@7.3.0: {} + make-plural@7.4.0: {} math-interval-parser@2.0.1: {} @@ -2259,10 +2164,6 @@ snapshots: mime@1.6.0: {} - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.11 - minimist@1.2.8: {} mkdirp@0.5.6: @@ -2291,7 +2192,7 @@ snapshots: mylas@2.1.13: {} - nanoid@3.3.6: {} + nanoid@3.3.7: {} negotiator@0.6.3: {} @@ -2301,28 +2202,11 @@ snapshots: transitivePeerDependencies: - debug - nodemon@2.0.22: - dependencies: - chokidar: 3.5.3 - debug: 3.2.7(supports-color@5.5.0) - ignore-by-default: 1.0.1 - minimatch: 3.1.2 - pstree.remy: 1.1.8 - semver: 5.7.2 - simple-update-notifier: 1.1.0 - supports-color: 5.5.0 - touch: 3.1.0 - undefsafe: 2.0.5 - - nopt@1.0.10: - dependencies: - abbrev: 1.1.1 - normalize-path@3.0.0: {} object-assign@4.1.1: {} - object-inspect@1.12.3: {} + object-inspect@1.13.1: {} on-finished@2.4.1: dependencies: @@ -2334,19 +2218,19 @@ snapshots: path-type@4.0.0: {} - picocolors@1.0.0: {} + picocolors@1.0.1: {} picomatch@2.3.1: {} - plimit-lit@1.5.0: + plimit-lit@1.6.1: dependencies: - queue-lit: 1.5.0 + queue-lit: 1.5.2 - postcss@8.4.26: + postcss@8.4.38: dependencies: - nanoid: 3.3.6 - picocolors: 1.0.0 - source-map-js: 1.0.2 + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 process-nextick-args@2.0.1: {} @@ -2357,15 +2241,13 @@ snapshots: proxy-from-env@1.1.0: {} - pstree.remy@1.1.8: {} - q@1.5.1: {} qs@6.11.0: dependencies: - side-channel: 1.0.4 + side-channel: 1.0.6 - queue-lit@1.5.0: {} + queue-lit@1.5.2: {} queue-microtask@1.2.3: {} @@ -2396,6 +2278,10 @@ snapshots: dependencies: picomatch: 2.3.1 + regenerator-runtime@0.14.1: {} + + require-directory@2.1.1: {} + resolve-pkg-maps@1.0.0: {} reusify@1.0.4: {} @@ -2404,6 +2290,10 @@ snapshots: dependencies: queue-microtask: 1.2.3 + rxjs@7.8.1: + dependencies: + tslib: 2.6.2 + safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} @@ -2412,14 +2302,6 @@ snapshots: safer-buffer@2.1.2: {} - semver@5.7.2: {} - - semver@7.0.0: {} - - semver@7.5.4: - dependencies: - lru-cache: 6.0.0 - semver@7.6.2: {} send@0.18.0: @@ -2449,63 +2331,98 @@ snapshots: transitivePeerDependencies: - supports-color + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + setprototypeof@1.2.0: {} - sharp@0.33.3: + shell-quote@1.8.1: {} + + side-channel@1.0.6: dependencies: - color: 4.2.3 - detect-libc: 2.0.3 - semver: 7.6.2 - optionalDependencies: - '@img/sharp-darwin-arm64': 0.33.3 - '@img/sharp-darwin-x64': 0.33.3 - '@img/sharp-libvips-darwin-arm64': 1.0.2 - '@img/sharp-libvips-darwin-x64': 1.0.2 - '@img/sharp-libvips-linux-arm': 1.0.2 - '@img/sharp-libvips-linux-arm64': 1.0.2 - '@img/sharp-libvips-linux-s390x': 1.0.2 - '@img/sharp-libvips-linux-x64': 1.0.2 - '@img/sharp-libvips-linuxmusl-arm64': 1.0.2 - '@img/sharp-libvips-linuxmusl-x64': 1.0.2 - '@img/sharp-linux-arm': 0.33.3 - '@img/sharp-linux-arm64': 0.33.3 - '@img/sharp-linux-s390x': 0.33.3 - '@img/sharp-linux-x64': 0.33.3 - '@img/sharp-linuxmusl-arm64': 0.33.3 - '@img/sharp-linuxmusl-x64': 0.33.3 - '@img/sharp-wasm32': 0.33.3 - '@img/sharp-win32-ia32': 0.33.3 - '@img/sharp-win32-x64': 0.33.3 - - side-channel@1.0.4: - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 - object-inspect: 1.12.3 - - simple-swizzle@0.2.2: - dependencies: - is-arrayish: 0.3.2 - - simple-update-notifier@1.1.0: - dependencies: - semver: 7.0.0 + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.1 slash@3.0.0: {} - source-map-js@1.0.2: {} + socket.io-adapter@2.5.4: + dependencies: + debug: 4.3.4 + ws: 8.11.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + socket.io-client@4.7.5: + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.3.4 + engine.io-client: 6.5.3 + socket.io-parser: 4.2.4 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + socket.io-parser@4.2.4: + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + + socket.io@4.7.5: + dependencies: + accepts: 1.3.8 + base64id: 2.0.0 + cors: 2.8.5 + debug: 4.3.4 + engine.io: 6.5.4 + socket.io-adapter: 2.5.4 + socket.io-parser: 4.2.4 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + source-map-js@1.2.0: {} + + spawn-command@0.0.2: {} statuses@2.0.1: {} streamsearch@1.1.0: {} + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + string_decoder@1.1.1: dependencies: safe-buffer: 5.1.2 - supports-color@5.5.0: + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: dependencies: - has-flag: 3.0.0 + has-flag: 4.0.0 to-fast-properties@2.0.0: {} @@ -2515,23 +2432,20 @@ snapshots: toidentifier@1.0.1: {} - touch@3.1.0: - dependencies: - nopt: 1.0.10 + tree-kill@1.2.2: {} - tsc-alias@1.8.9: + tsc-alias@1.8.10: dependencies: - chokidar: 3.5.3 + chokidar: 3.6.0 commander: 9.5.0 globby: 11.1.0 mylas: 2.1.13 normalize-path: 3.0.0 - plimit-lit: 1.5.0 + plimit-lit: 1.6.1 - tslib@2.6.2: - optional: true + tslib@2.6.2: {} - tsx@4.10.1: + tsx@4.10.5: dependencies: esbuild: 0.20.2 get-tsconfig: 4.7.5 @@ -2547,8 +2461,6 @@ snapshots: typescript@5.4.5: {} - undefsafe@2.0.5: {} - undici-types@5.26.5: {} universal-cookie@4.0.4: @@ -2576,6 +2488,28 @@ snapshots: '@vue/server-renderer': 3.3.4(vue@3.3.4) '@vue/shared': 3.3.4 + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + ws@8.11.0: {} + + xmlhttprequest-ssl@2.0.0: {} + xtend@4.0.2: {} - yallist@4.0.0: {} + y18n@5.0.8: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.1.2 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 diff --git a/api/routes/_express-call.ts b/api/routes/_express-call.ts deleted file mode 100644 index 696698ef..00000000 --- a/api/routes/_express-call.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Busboy } from "busboy"; -import { Request, Response } from "express"; - -export type ExpressCall< - T extends { - resBody?: object; - params?: object; - reqBody?: object; - query?: object; - }, -> = [ - Request & { - busboy: Busboy; - }, - - Response, -]; diff --git a/api/routes/fs/base64.ts b/api/routes/fs/base64.ts deleted file mode 100644 index d2f396fe..00000000 --- a/api/routes/fs/base64.ts +++ /dev/null @@ -1,36 +0,0 @@ -import axios from "axios"; -import sizeOf from "image-size"; - -import { ExpressCall } from "~routes/_express-call"; - -export const get = async ( - ...[req, res]: ExpressCall<{ - resBody: { - dimensions: { width: number; height: number }; - base64: string; - url: string; - }; - query: { targetUrl: string }; - }> -) => { - const targetUrl = req.query.targetUrl; - const url = targetUrl.startsWith("https://res.cloudinary.com") - ? targetUrl - : `${process.env.VITE_EDGES_URL!}/${targetUrl}`; - - const response = await axios.get(url); - if (response.status === 200) { - try { - const buffer = Buffer.from(response.data); - const dimensions = sizeOf(buffer) as { width: number; height: number }; - const base64 = `data:${ - response.headers["Content-Type"] - };base64,${buffer.toString()}`; - return res.json({ dimensions, base64, url }); - } catch (e) { - console.error(`${targetUrl} : ${e as string}`); - res.writeHead(404); - return res.end(); - } - } -}; diff --git a/api/routes/fs/browse/:imageType/:country/:magazine.ts b/api/routes/fs/browse/:imageType/:country/:magazine.ts deleted file mode 100644 index a3dc54ef..00000000 --- a/api/routes/fs/browse/:imageType/:country/:magazine.ts +++ /dev/null @@ -1,35 +0,0 @@ -import fs from "fs"; - -import { ExpressCall } from "~routes/_express-call"; - -export const get = ( - ...[req, res]: ExpressCall<{ - params: { - imageType: "elements" | "photos"; - country: string; - magazine: string; - }; - resBody: string[]; - }> -) => { - const { country, imageType, magazine } = req.params; - if ( - !/^(elements)|(photos)$/.test(imageType) || - !/^[a-z]+$/.test(country) || - !/^[-A-Z0-9]+$/.test(magazine) - ) { - res.writeHead(400); - return res.end(); - } - try { - return res.json( - fs - .readdirSync(`${process.env.EDGES_PATH!}/${country}/${imageType}`) - .filter((item) => - new RegExp(`(?:^|[. ])${magazine}(?:[. ]|$)`).test(item), - ), - ); - } catch (e) { - return res.json([]); - } -}; diff --git a/api/routes/fs/browseEdges.ts b/api/routes/fs/browseEdges.ts deleted file mode 100644 index 7e88ac98..00000000 --- a/api/routes/fs/browseEdges.ts +++ /dev/null @@ -1,46 +0,0 @@ -import fs from "fs"; -import path from "path"; - -import { ExpressCall } from "~routes/_express-call"; - -const edgesPath = `${process.env.PWD!}/../${process.env.EDGES_PATH!}`; -const REGEX_IS_BROWSABLE_FILE = /^[-+(). _A-Za-z\d]+$/; -const REGEX_IS_SVG_FILE = /^_?.+\.svg$/; -export const get = ( - ...[, res]: ExpressCall<{ - resBody: { - current: { filename: string; mtime: string }[]; - published: { filename: string; mtime: string }[]; - }; - }> -) => { - const findInDir = (dir: string) => { - try { - const files = fs.readdirSync(dir); - const filteredFiles = files.filter((file) => - REGEX_IS_BROWSABLE_FILE.test(file), - ); - for (const file of filteredFiles) { - const filePath = path.join(dir, file); - if (!file.includes(".")) { - findInDir(filePath); - } else if (REGEX_IS_SVG_FILE.test(file)) { - const edgeStatus = file.startsWith("_") ? "current" : "published"; - fileList[edgeStatus].push({ - filename: filePath.replace(/.+\/edges\//, ""), - mtime: fs.statSync(filePath).mtime.toISOString(), - }); - } - } - } catch (e) { - console.error(e); - } - }; - - const fileList = { - current: [] as { filename: string; mtime: string }[], - published: [] as { filename: string; mtime: string }[], - }; - findInDir(edgesPath); - return res.json(fileList); -}; diff --git a/api/routes/fs/generateDefaultEdge.ts b/api/routes/fs/generateDefaultEdge.ts deleted file mode 100644 index a8b68197..00000000 --- a/api/routes/fs/generateDefaultEdge.ts +++ /dev/null @@ -1,68 +0,0 @@ -import fs from "fs"; -import sharp from "sharp"; - -import { ExpressCall } from "~routes/_express-call"; -// eslint-disable-next-line max-len -const REGEX_EDGE_URL = - /^edges\/(?[^/]+)\/gen\/_?(?[^.]+)\.(?[^.]+)\.(?[^?]+)?(?:\?.+)?$/; - -const corsHeaders = { - "Access-Control-Allow-Origin": "*", - "Access-Control-Allow-Credentials": "true", - "Access-Control-Allow-Methods": "GET, OPTIONS", - "Access-Control-Allow-Headers": - "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With," + - "If-Modified-Since,Cache-Control,Content-Type,x-dm-user,x-dm-pass", -}; -export const get = ( - ...[req, res]: ExpressCall<{ - resBody: { - current: string[]; - published: string[]; - }; - }> -) => { - const input = req.url.replace(/^\//, ""); - let text; - const match = input.match(REGEX_EDGE_URL); - if (match) { - const { countryCode, magazineCode, issueNumber, extension } = match.groups!; - - if (countryCode && extension !== "png") { - res.writeHead(404, corsHeaders); - res.end(""); - return; - } - text = `${countryCode}/${magazineCode} ${issueNumber}`; - } else { - text = input; - } - - const content = Buffer.from( - fs - .readFileSync("assets/default.svg") - .toString() - .replace("My text", decodeURIComponent(text)), - "utf8", - ); - sharp(content).toBuffer((error, buffer) => { - if (error) { - res.writeHead(500, corsHeaders); - return res.end(`Error : ${JSON.stringify({ error })}`); - } - res.writeHead(200, { ...corsHeaders, "Content-Type": "image/png" }); - return res.end(buffer); - }); -}; - -export const options = ( - ...[, res]: ExpressCall<{ - resBody: { - current: string[]; - published: string[]; - }; - }> -) => { - res.writeHead(200, corsHeaders); - return res.end(); -}; diff --git a/api/routes/fs/save.ts b/api/routes/fs/save.ts deleted file mode 100644 index 006ff7c0..00000000 --- a/api/routes/fs/save.ts +++ /dev/null @@ -1,116 +0,0 @@ -import fs from "fs"; -import path from "path"; -import sharp from "sharp"; - -import { getSvgPath } from "~/_utils"; -import { - PUT__edgecreator__publish__$country__$magazine__$issuenumber, - PUT__edgecreator__submit, -} from "~dm_types/routes"; -import { ExpressCall } from "~routes/_express-call"; -import { ExportPaths } from "~types/ExportPaths"; -import { ModelContributor } from "~types/ModelContributor"; - -import { call, createAxios } from "../../axios-helper"; - -const dmApi = createAxios(process.env.VITE_DM_API_URL!); -// const edgesPath = `${process.env.PWD}/../${process.env.EDGES_PATH!}`; - -export const post = async ( - ...[req, res]: ExpressCall<{ - resBody: { paths: ExportPaths; isNew: boolean }; - reqBody: { - runExport: boolean; - runSubmit: boolean; - country: string; - magazine: string; - issuenumber: string; - contributors: ModelContributor[]; - content: string; - }; - }> -) => { - const { - runExport, - runSubmit, - country, - magazine, - issuenumber, - contributors, - content, - } = req.body; - const svgPath = getSvgPath(runExport, country, magazine, issuenumber); - - const publicationcode = `${country}/${magazine}`; - - fs.mkdirSync(path.dirname(svgPath), { recursive: true }); - fs.writeFileSync(svgPath, content); - let paths: ExportPaths = { svgPath }; - if (runExport) { - const pngPath = svgPath.replace(".svg", ".png"); - try { - await sharp(svgPath).png().toFile(pngPath); - } catch (error: unknown) { - res.writeHead(500); - return res.end({ error }); - } - - paths = { ...paths, pngPath }; - - const designers = contributors - .filter(({ contributionType }) => contributionType === "createur") - .map(({ user }) => user.username); - - const photographers = contributors - .filter(({ contributionType }) => contributionType === "photographe") - .map(({ user }) => user.username); - - try { - const { isNew } = ( - await call( - dmApi, - new PUT__edgecreator__publish__$country__$magazine__$issuenumber({ - params: { country, magazine, issuenumber }, - reqBody: { - designers, - photographers, - }, - }), - ) - ).data; - try { - fs.unlinkSync(getSvgPath(false, country, magazine, issuenumber)); - } catch (error) { - if ((error as { code?: string }).code === "ENOENT") { - console.log("No temporary SVG file to delete was found"); - } else { - res.writeHead(500); - return res.end({ error }); - } - } - - return res.json({ paths, isNew }); - } catch (e) { - res.writeHead(500); - return res.end({ error: e }); - } - } else { - if (runSubmit) { - try { - await call( - dmApi, - new PUT__edgecreator__submit({ - reqBody: { - publicationcode, - issuenumber, - }, - }), - ); - } catch (error) { - res.writeHead(500); - return res.end({ error }); - } - } - return res.json({ paths, isNew: false }); - } -}; diff --git a/api/routes/fs/text.ts b/api/routes/fs/text.ts deleted file mode 100644 index 93a537b4..00000000 --- a/api/routes/fs/text.ts +++ /dev/null @@ -1,119 +0,0 @@ -import axios from "axios"; -import { v2 as cloudinary } from "cloudinary"; - -import { ExpressCall } from "~routes/_express-call"; - -const sessionHashes: Record = {}; - -export const get = async ( - ...[req, res]: ExpressCall<{ - resBody: - | { - width: number; - height: number; - url: string; - } - | { error: string }; - query: { - color: string; - colorBackground: string; - width: number; - font: string; - text: string; - }; - }> -) => { - const { color, colorBackground, width, font, text } = req.query; - const context: Record = { - color, - colorBackground, - width, - text, - }; - await cloudinary.search - .expression( - `tags=${font} AND ${Object.keys(context) - .reduce( - (acc, key) => [...acc, `context.${key}="${String(context[key])}"`], - [], - ) - .join(" AND ")}`, - ) - .execute() - .then( - ({ - resources, - }: { - resources: { width: number; height: number; secure_url: string }[]; - }) => { - if (resources.length) { - console.log(`Found an existing text`); - const { width, height, secure_url: url } = resources[0]; - return res.json({ width, height, url }); - } else { - console.log(`Found no existing text, generating text image...`); - generateImage(req.query) - .then(({ width, height, secure_url: url }) => { - console.log(`Text image generated: url=${url}`); - return res.json({ width, height, url }); - }) - .catch((response: Error) => { - res.status(500).send({ error: response.message }); - }); - } - }, - ) - .catch((e) => { - console.error(e); - }); -}; - -const generateImage = (parameters: { - color: string; - colorBackground: string; - width: number; - font: string; - text: string; -}) => - axios - .get( - parameters.font.includes("/") - ? process.env.FONT_BASE_URL! - : `${process.env.FONT_PRODUCT_BASE_URL!}${parameters.font}`, - ) - .then(({ data }: { data: string }) => { - const sessionHashMatch = data.match(/(?<=font_rend.php\?id=)[a-z\d]+/); - if (sessionHashMatch) { - sessionHashes[parameters.font] = sessionHashMatch[0]; - } else { - throw new Error( - `No session ID found in URL ${process.env.FONT_BASE_URL!}${ - parameters.font - }`, - ); - } - }) - .then(() => - cloudinary.uploader.upload( - `${process.env.FONT_IMAGE_GEN_URL!}?${new URLSearchParams({ - id: sessionHashes[parameters.font], - rbe: "fixed", - rt: parameters.text, - fg: parameters.color, - bg: parameters.colorBackground, - }).toString()}`, - { - folder: "texts", - async: false, - tags: [parameters.font], - context: parameters, - }, - (error, result) => { - if (error) { - console.error(error); - } - const { width, height, secure_url: url } = result!; - return { width, height, url }; - }, - ), - ); diff --git a/api/routes/fs/upload-base64.ts b/api/routes/fs/upload-base64.ts deleted file mode 100644 index 295de977..00000000 --- a/api/routes/fs/upload-base64.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { decode } from "node-base64-image"; - -import { PUT__edgecreator__multiple_edge_photo__v2 } from "~dm_types/routes"; -import { ExpressCall } from "~routes/_express-call"; -import { getNextAvailableFile } from "~routes/_upload_utils"; - -import { call, createAxios } from "../../axios-helper"; -const edgesPath: string = process.env.EDGES_PATH!; - -const dmApi = createAxios(process.env.VITE_DM_API_URL!); -export const post = async ( - ...[req, res]: ExpressCall<{ - resBody: { fileName: string }; - reqBody: { - data: string; - country: string; - magazine: string; - issuenumber: string; - }; - }> -) => { - const { country, issuenumber, magazine, data } = req.body; - const path = `${edgesPath}/${country}/photos`; - const tentativeFileName = `${magazine}.${issuenumber}.photo`; - const fileName = getNextAvailableFile( - `${path}/${tentativeFileName}`, - "jpg", - ).match(/\/([^/]+)$/)![1]; - - await decode(data, { - fname: `${path}/${fileName.replace(/.jpg$/, "")}`, - ext: "jpg", - }); - - try { - const publicationcode = `${country}/${magazine}`; - - await call( - dmApi, - new PUT__edgecreator__multiple_edge_photo__v2({ - reqBody: { - publicationcode, - issuenumber, - }, - }), - ); - } catch (e) { - res.writeHead(500); - return res.end(e); - } - - res.writeHead(200, { - Connection: "close", - "Content-Type": "application/text", - }); - return res.json({ fileName }); -}; diff --git a/api/routes/fs/upload.ts b/api/routes/fs/upload.ts deleted file mode 100644 index 36feec45..00000000 --- a/api/routes/fs/upload.ts +++ /dev/null @@ -1,256 +0,0 @@ -import crypto from "crypto"; -import fs from "fs"; -import multer from "multer"; -import { dirname } from "path"; - -import { getUserCredentials } from "~routes/_auth"; -import { ExpressCall } from "~routes/_express-call"; -import { getNextAvailableFile } from "~routes/_upload_utils"; - -import { call, createAxios } from "../../axios-helper"; -const dmApi = createAxios(process.env.VITE_DM_API_URL!); -import { - GET__edgecreator__elements__images__$filename, - GET__edgecreator__multiple_edge_photo__check_today_limit, - GET__edgecreator__multiple_edge_photo__hash__$hash, - PUT__edgecreator__multiple_edge_photo, -} from "~dm_types/routes"; - -const edgesPath: string = process.env.EDGES_PATH!; - -const upload = multer({ - dest: "/tmp/", - limits: { - fileSize: 3 * 1024 * 1024, - files: 1, - }, -}); - -export const post = [ - upload.array("files"), - async ( - ...[req, res]: ExpressCall<{ - resBody: { fileName: string }[]; - reqBody: { - photo: boolean; - multiple: boolean; - edge: { - country: string; - magazine: string; - issuenumber: string; - }; - }; - }> - ) => { - const userCredentials = getUserCredentials(req.user!); - - let allowedMimeTypes: string[]; - - const { - photo: isEdgePhoto, - multiple: isMultipleEdgePhoto, - edge, - } = req.body; - const files = req.files! as Express.Multer.File[]; - const targetFilesnames = []; - for (const { - originalname: filename, - mimetype: mimetype, - path: temporaryPath, - } of files) { - allowedMimeTypes = isEdgePhoto - ? ["image/jpg", "image/jpeg"] - : ["image/png"]; - - const targetFilename = getTargetFilename( - filename, - isMultipleEdgePhoto, - edge, - isEdgePhoto, - ); - try { - const { hash } = await validateUpload( - mimetype, - targetFilename, - allowedMimeTypes, - isEdgePhoto, - userCredentials, - edge, - temporaryPath, - ); - saveFile(temporaryPath, targetFilename); - await storePhotoHash(targetFilename, hash); - targetFilesnames.push( - targetFilename.replace( - process.env.EDGES_PATH!, - process.env.VITE_EDGES_URL!, - ), - ); - } catch (e: unknown) { - res.writeHead(400, { - Connection: "close", - "Content-Type": "application/json", - }); - res.end((e as Error).message); - } - } - res.writeHead(200, { Connection: "close" }); - return res.json(targetFilesnames.map((fileName) => ({ fileName }))); - }, -]; - -const getTargetFilename = ( - filename: string, - isMultipleEdgePhoto: boolean, - edge: { - country: string; - magazine: string; - issuenumber: string; - }, - isEdgePhoto: boolean, -) => { - filename = filename.normalize("NFD").replace(/[\u0300-\u036F]/g, ""); - - if (isMultipleEdgePhoto) { - return getNextAvailableFile( - `${edgesPath}/tranches_multiples/photo.multiple`, - "jpg", - ); - } else { - const { country, issuenumber, magazine } = edge; - if (isEdgePhoto) { - return getNextAvailableFile( - `${edgesPath}/${country}/photos/${magazine}.${issuenumber}.photo`, - "jpg", - ); - } else { - return `${edgesPath}/${country}/elements/${ - filename.includes(magazine) ? filename : `${magazine}.${filename}` - }`; - } - } -}; - -const validateUpload = async ( - mimetype: string, - filename: string, - allowedMimeTypes: string[], - isEdgePhoto: boolean, - userCredentials: Record, - edge: { - country: string; - magazine: string; - issuenumber: string; - }, - filePath: string, -): Promise<{ hash: string }> => { - if (!allowedMimeTypes.includes(mimetype)) { - throw new Error( - JSON.stringify({ - error: - "Invalid file type: {mimetype}, the following types are allowed: {allowedMimeTypes}", - placeholders: { mimetype, allowedMimeTypes }, - }), - ); - } - const { hash } = readContentsAndCalculateHash(filePath); - if (isEdgePhoto) { - if (await hasReachedDailyUploadLimit()) { - throw new Error( - JSON.stringify({ - error: "You have reached your daily upload limit", - }), - ); - } - if (await hasAlreadySentPhoto(hash)) { - throw new Error( - JSON.stringify({ error: "You have already sent this photo" }), - ); - } - } else { - // await readFile(filestream); - const otherElementUses = await getFilenameUsagesInOtherModels( - filename, - edge, - ); - if (fs.existsSync(filename) && otherElementUses.length) { - throw new Error( - JSON.stringify({ - error: - "This file name is already used in other models, please rename your file", - placeholders: { - otherElementUses: JSON.stringify(otherElementUses), - }, - }), - ); - } - } - return { hash }; -}; - -const hasReachedDailyUploadLimit = async () => - ( - await call( - dmApi, - new GET__edgecreator__multiple_edge_photo__check_today_limit(), - ) - ).data.uploadedFilesToday.length > 10; - -const hasAlreadySentPhoto = async (hash: string) => - ( - await call( - dmApi, - new GET__edgecreator__multiple_edge_photo__hash__$hash({ - params: { - hash, - }, - }), - ) - ).data !== undefined; - -const readContentsAndCalculateHash = ( - fileName: string, -): { contents: Buffer; hash: string } => { - const fileBuffer = fs.readFileSync(fileName); - const hashSum = crypto.createHash("sha256"); - hashSum.update(fileBuffer); - - return { contents: fileBuffer, hash: hashSum.digest("hex") }; -}; - -const getFilenameUsagesInOtherModels = async ( - filename: string, - currentModel: { country: string; magazine: string; issuenumber: string }, -) => - ( - await call( - dmApi, - new GET__edgecreator__elements__images__$filename({ - params: { - filename, - }, - }), - ) - ).data.filter( - (otherUse) => - currentModel.country !== otherUse.country || - currentModel.magazine !== otherUse.magazine || - currentModel.issuenumber !== otherUse.issuenumberStart, - ); - -const saveFile = (temporaryPath: string, finalPath: string) => { - fs.mkdirSync(dirname(finalPath), { recursive: true }); - fs.renameSync(temporaryPath, finalPath); -}; - -const storePhotoHash = async (filename: string, hash: string) => { - await call( - dmApi, - new PUT__edgecreator__multiple_edge_photo({ - reqBody: { - hash, - filename, - }, - }), - ); -}; diff --git a/api/routes/_auth.ts b/api/services/_auth.ts similarity index 68% rename from api/routes/_auth.ts rename to api/services/_auth.ts index 5b44f7ad..0f5b08e3 100644 --- a/api/routes/_auth.ts +++ b/api/services/_auth.ts @@ -1,42 +1,19 @@ -import { Request, Response } from "express"; +import type { Request, Response } from "express"; import fs from "fs"; import jwt from "jsonwebtoken"; import { getSvgPath } from "~/_utils"; -import { User } from "~types/SessionUser"; +import { SessionUser } from "~dm-types/SessionUser"; -export const getUserCredentials = (user: User) => ({ +export const getUserCredentials = (user: SessionUser) => ({ "x-dm-user": user.username, "x-dm-pass": user.hashedPassword, }); -export const authenticateToken = ( - req: Request, - res: Response, - next: CallableFunction, -) => { - const authHeader = req.headers.authorization; - const token = authHeader?.split(" ")?.[1]; - - if (token == null) return res.sendStatus(401); - - jwt.verify( - token, - process.env.TOKEN_SECRET!, - (err: unknown, user: unknown) => { - if (err) { - return res.sendStatus(401); - } - req.user = user as User; - next(); - }, - ); -}; - export const checkUserIsAdminForExportOrIsEditorForSaveOrIsFirstFileForModel = ( req: Request, res: Response, - next: CallableFunction, + next: CallableFunction ) => { const { runExport, country, magazine, issuenumber } = req.body as { runExport: boolean; @@ -63,7 +40,7 @@ export const checkUserIsAdminForExportOrIsEditorForSaveOrIsFirstFileForModel = ( export const checkUserIsAdminOrEditor = ( req: Request, res: Response, - next: CallableFunction, + next: CallableFunction ) => { const user = req.user; if (!(user && ["Admin", "Edition"].includes(user.privileges.EdgeCreator))) { @@ -75,7 +52,7 @@ export const checkUserIsAdminOrEditor = ( export const injectTokenIfValid = ( req: Request, _: Response, - next: CallableFunction, + next: CallableFunction ) => { const authHeader = req.headers.authorization; const token = authHeader?.split(" ")[1]; @@ -88,12 +65,12 @@ export const injectTokenIfValid = ( process.env.TOKEN_SECRET!, (err: unknown, user: unknown) => { if (user) { - req.user = user as User; + req.user = user as SessionUser; } else { console.log(`Invalid token: ${err as string}`); } next(); - }, + } ); } }; diff --git a/api/routes/_upload_utils.ts b/api/services/_upload_utils.ts similarity index 100% rename from api/routes/_upload_utils.ts rename to api/services/_upload_utils.ts diff --git a/api/services/browse/index.ts b/api/services/browse/index.ts new file mode 100644 index 00000000..bc24ae7d --- /dev/null +++ b/api/services/browse/index.ts @@ -0,0 +1,76 @@ +import { readdirSync, statSync } from "fs"; +import path from "path"; +import type { Namespace, Server } from "socket.io"; + +import type Events from "./types"; +import { namespaceEndpoint } from "./types"; +const edgesPath = `${process.env.PWD!}/../${process.env.EDGES_PATH!}`; +const REGEX_IS_BROWSABLE_FILE = /^[-+(). _A-Za-z\d]+$/; +const REGEX_IS_SVG_FILE = /^_?.+\.svg$/; + +const findInDir = (dir: string) => { + const fileList = { + current: [] as { filename: string; mtime: string }[], + published: [] as { filename: string; mtime: string }[], + }; + try { + const files = readdirSync(dir); + const filteredFiles = files.filter((file) => + REGEX_IS_BROWSABLE_FILE.test(file), + ); + for (const file of filteredFiles) { + const filePath = path.join(dir, file); + if (!file.includes(".")) { + findInDir(filePath); + } else if (REGEX_IS_SVG_FILE.test(file)) { + const edgeStatus = file.startsWith("_") ? "current" : "published"; + fileList[edgeStatus].push({ + filename: filePath.replace(/.+\/edges\//, ""), + mtime: statSync(filePath).mtime.toISOString(), + }); + } + } + } catch (e) { + return Promise.reject(e); + } + return Promise.resolve(fileList); +}; + +export default (io: Server) => { + (io.of(namespaceEndpoint) as Namespace).on("connection", (socket) => { + console.log("connected to browse"); + + socket.on("listEdgeModels", async (callback) => { + findInDir(edgesPath) + .then((results) => callback({ results })) + .catch((errorDetails) => + callback({ + error: "Generic error", + errorDetails: errorDetails as string, + }), + ); + }); + + socket.on("listEdgeParts", async (parameters, callback) => { + const { country, imageType, magazine } = parameters; + if ( + !/^(elements)|(photos)$/.test(imageType) || + !/^[a-z]+$/.test(country) || + !/^[-A-Z0-9]+$/.test(magazine) + ) { + callback({ error: "Invalid parameters" }); + } + try { + callback({ + results: readdirSync( + `${process.env.EDGES_PATH!}/${country}/${imageType}`, + ).filter((item) => + new RegExp(`(?:^|[. ])${magazine}(?:[. ]|$)`).test(item), + ), + }); + } catch (e) { + callback({ results: [] }); + } + }); + }); +}; diff --git a/api/services/browse/types.ts b/api/services/browse/types.ts new file mode 100644 index 00000000..81f60a93 --- /dev/null +++ b/api/services/browse/types.ts @@ -0,0 +1,36 @@ +import type { Errorable } from "~socket.io-services/types"; + +export const namespaceEndpoint = "/save"; +export default abstract class { + static namespaceEndpoint = namespaceEndpoint; + + abstract listEdgeModels: ( + callback: ( + value: Errorable< + { + results: { + current: { filename: string; mtime: string }[]; + published: { filename: string; mtime: string }[]; + }; + }, + "Generic error" + >, + ) => void, + ) => void; + + abstract listEdgeParts: ( + parameters: { + imageType: "elements" | "photos"; + country: string; + magazine: string; + }, + callback: ( + value: Errorable< + { + results: string[]; + }, + "Generic error" | "Invalid parameters" + >, + ) => void, + ) => void; +} diff --git a/api/services/image-info/index.ts b/api/services/image-info/index.ts new file mode 100644 index 00000000..6817aa58 --- /dev/null +++ b/api/services/image-info/index.ts @@ -0,0 +1,37 @@ +import axios from "axios"; +import sizeOf from "image-size"; +import type { Namespace, Server } from "socket.io"; + +import type Events from "./types"; +import { namespaceEndpoint } from "./types"; +export default (io: Server) => { + (io.of(namespaceEndpoint) as Namespace).on("connection", (socket) => { + console.log("connected to text"); + + socket.on("getImageInfo", async (targetUrl, callback) => { + const url = targetUrl.startsWith("https://res.cloudinary.com") + ? targetUrl + : `${process.env.EDGES_URL!}/${targetUrl}`; + + const response = await axios.get(url); + if (response.status === 200) { + try { + const buffer = Buffer.from(response.data); + const dimensions = sizeOf(buffer) as { + width: number; + height: number; + }; + const base64 = `data:${ + response.headers["Content-Type"] + };base64,${buffer.toString()}`; + callback({ results: { dimensions, base64, url } }); + } catch (e) { + callback({ + error: "Cloudinary error", + errorDetails: `${targetUrl} : ${e as string}`, + }); + } + } + }); + }); +}; diff --git a/api/services/image-info/types.ts b/api/services/image-info/types.ts new file mode 100644 index 00000000..5ac3f5a1 --- /dev/null +++ b/api/services/image-info/types.ts @@ -0,0 +1,22 @@ +import type { Errorable } from "~socket.io-services/types"; + +export const namespaceEndpoint = "/image-info"; +export default abstract class { + static namespaceEndpoint = namespaceEndpoint; + + abstract getImageInfo: ( + targetUrl: string, + callback: ( + value: Errorable< + { + results: { + dimensions: { width: number; height: number }; + base64: string; + url: string; + }; + }, + "Cloudinary error" + >, + ) => void, + ) => void; +} diff --git a/api/services/save/index.ts b/api/services/save/index.ts new file mode 100644 index 00000000..b4bff8e1 --- /dev/null +++ b/api/services/save/index.ts @@ -0,0 +1,91 @@ +import { mkdirSync, unlinkSync, writeFileSync } from "fs"; +import path from "path"; +import type { Namespace } from "socket.io"; +import type { Server } from "socket.io"; + +import { getSvgPath } from "~/_utils"; +import EdgeCreatorServices from "~dm-services/edgecreator/types"; +import { useSocket } from "~socket.io-client-services"; +import type { ExportPaths } from "~types/ExportPaths"; + +import type Events from "./types"; +import { namespaceEndpoint } from "./types"; +import { exec } from "child_process"; + +const socket = useSocket(process.env.DM_SOCKET_URL!); +const { services: edgeCreatorServices } = + socket.addNamespace( + EdgeCreatorServices.namespaceEndpoint + ); +export default (io: Server) => { + (io.of(namespaceEndpoint) as Namespace).on("connection", (socket) => { + console.log("connected to save"); + + socket.on("saveEdge", async (parameters, callback) => { + const { + runExport, + runSubmit, + country, + magazine, + issuenumber, + contributors, + content, + } = parameters; + const svgPath = getSvgPath(runExport, country, magazine, issuenumber); + + const publicationcode = `${country}/${magazine}`; + + mkdirSync(path.dirname(svgPath), { recursive: true }); + writeFileSync(svgPath, content); + let paths: ExportPaths = { svgPath }; + if (runExport) { + const pngPath = svgPath.replace(".svg", ".png"); + + exec(`convert ${svgPath} ${pngPath}`); + + paths = { ...paths, pngPath }; + + const designers = contributors + .filter(({ contributionType }) => contributionType === "createur") + .map(({ user }) => user.username); + + const photographers = contributors + .filter(({ contributionType }) => contributionType === "photographe") + .map(({ user }) => user.username); + + const publicationResult = await edgeCreatorServices.publishEdge({ + publicationcode, + issuenumber, + designers, + photographers, + }); + if (publicationResult.error) { + callback({ + error: "Generic error", + errorDetails: publicationResult.errorDetails as string, + }); + return; + } + try { + unlinkSync(getSvgPath(false, country, magazine, issuenumber)); + } catch (errorDetails) { + if ((errorDetails as { code?: string }).code === "ENOENT") { + console.log("No temporary SVG file to delete was found"); + } else { + callback({ + error: "Generic error", + errorDetails: errorDetails as string, + }); + } + } + + callback({ results: { paths, isNew: publicationResult.isNew } }); + } else { + if (runSubmit) { + await edgeCreatorServices.submitEdge(publicationcode, issuenumber); + } + callback({ results: { paths, isNew: false } }); + } + }); + }); +}; diff --git a/api/services/save/types.ts b/api/services/save/types.ts new file mode 100644 index 00000000..0373596a --- /dev/null +++ b/api/services/save/types.ts @@ -0,0 +1,28 @@ +import type { Errorable } from "~socket.io-services/types"; +import type { ExportPaths } from "~types/ExportPaths"; +import type { ModelContributor } from "~types/ModelContributor"; + +export const namespaceEndpoint = "/save"; +export default abstract class { + static namespaceEndpoint = namespaceEndpoint; + + abstract saveEdge: ( + parameters: { + runExport: boolean; + runSubmit: boolean; + country: string; + magazine: string; + issuenumber: string; + contributors: ModelContributor[]; + content: string; + }, + callback: ( + value: Errorable< + { + results: { paths: ExportPaths; isNew: boolean }; + }, + "Generic error" + >, + ) => void, + ) => void; +} diff --git a/api/services/text/index.ts b/api/services/text/index.ts new file mode 100644 index 00000000..8007125f --- /dev/null +++ b/api/services/text/index.ts @@ -0,0 +1,123 @@ +import axios from "axios"; +import { v2 as cloudinary } from "cloudinary"; +import type { Namespace, Server } from "socket.io"; + +import type Events from "./types"; +import { namespaceEndpoint } from "./types"; + +const sessionHashes: Record = {}; + +const generateImage = (parameters: { + color: string; + colorBackground: string; + width: number; + font: string; + text: string; +}) => + axios + .get( + parameters.font.includes("/") + ? process.env.FONT_BASE_URL! + : `${process.env.FONT_PRODUCT_BASE_URL!}${parameters.font}`, + ) + .then(({ data }: { data: string }) => { + const sessionHashMatch = data.match(/(?<=font_rend.php\?id=)[a-z\d]+/); + if (sessionHashMatch) { + sessionHashes[parameters.font] = sessionHashMatch[0]; + } else { + throw new Error( + `No session ID found in URL ${process.env.FONT_BASE_URL!}${ + parameters.font + }`, + ); + } + }) + .catch((response: Error) => { + return Promise.reject(response); + }) + .then(() => + cloudinary.uploader.upload( + `${process.env.FONT_IMAGE_GEN_URL!}?${new URLSearchParams({ + id: sessionHashes[parameters.font], + rbe: "fixed", + rt: parameters.text, + fg: parameters.color, + bg: parameters.colorBackground, + }).toString()}`, + { + folder: "texts", + async: false, + tags: [parameters.font], + context: parameters, + }, + (error, result) => { + if (error) { + console.error(error); + } + const { width, height, secure_url: url } = result!; + Promise.resolve({ width, height, url }); + }, + ), + ); + +export default (io: Server) => { + (io.of(namespaceEndpoint) as Namespace).on("connection", (socket) => { + console.log("connected to text"); + + socket.on("getText", async (parameters, callback) => { + const { color, colorBackground, width, font, text } = parameters; + const context: Record = { + color, + colorBackground, + width, + text, + }; + await cloudinary.search + .expression( + `tags=${font} AND ${Object.keys(context) + .reduce( + (acc, key) => [ + ...acc, + `context.${key}="${String(context[key])}"`, + ], + [], + ) + .join(" AND ")}`, + ) + .execute() + .then( + ({ + resources, + }: { + resources: { + width: number; + height: number; + secure_url: string; + }[]; + }) => { + if (resources.length) { + console.log(`Found an existing text`); + const { width, height, secure_url: url } = resources[0]; + callback({ results: { width, height, url } }); + } else { + console.log(`Found no existing text, generating text image...`); + generateImage(parameters) + .then(({ width, height, secure_url: url }) => { + console.log(`Text image generated: url=${url}`); + callback({ results: { width, height, url } }); + }) + .catch((response: Error) => { + callback({ + error: "Image generation error", + errorDetails: response.message, + }); + }); + } + }, + ) + .catch((e) => { + console.error(e); + }); + }); + }); +}; diff --git a/api/services/text/types.ts b/api/services/text/types.ts new file mode 100644 index 00000000..c7163d77 --- /dev/null +++ b/api/services/text/types.ts @@ -0,0 +1,28 @@ +import type { Errorable } from "~socket.io-services/types"; + +export const namespaceEndpoint = "/text"; +export default abstract class { + static namespaceEndpoint = namespaceEndpoint; + + abstract getText: ( + parameters: { + color: string; + colorBackground: string; + width: number; + font: string; + text: string; + }, + callback: ( + value: Errorable< + { + results: { + width: number; + height: number; + url: string; + }; + }, + "Image generation error" + >, + ) => void, + ) => void; +} diff --git a/api/services/upload/index.ts b/api/services/upload/index.ts new file mode 100644 index 00000000..7ee9f7df --- /dev/null +++ b/api/services/upload/index.ts @@ -0,0 +1,243 @@ +import crypto from "crypto"; +import type { Request, Response } from "express"; +import fs from "fs"; +import { decode } from "node-base64-image"; +import { dirname } from "path"; +import type { Namespace, Server } from "socket.io"; + +import { getUserCredentials } from "~/services/_auth"; +import EdgeCreatorServices from "~dm-services/edgecreator/types"; +import { EventCalls, useSocket } from "~socket.io-client-services"; + +import { getNextAvailableFile } from "../_upload_utils"; +import type Events from "./types"; +import { namespaceEndpoint } from "./types"; + +const edgesPath: string = process.env.EDGES_PATH!; + +let edgeCreatorServices: EventCalls; + +export default (io: Server) => { + (io.of(namespaceEndpoint) as Namespace).on("connection", (socket) => { + const dmSocket = useSocket(process.env.DM_SOCKET_URL!); + ({ services: edgeCreatorServices } = + dmSocket.addNamespace( + EdgeCreatorServices.namespaceEndpoint + )); + console.log("connected to upload"); + + socket.on("uploadFromBase64", async (parameters, callback) => { + const { country, issuenumber, magazine, data } = parameters; + const path = `${edgesPath}/${country}/photos`; + const tentativeFileName = `${magazine}.${issuenumber}.photo`; + const fileName = getNextAvailableFile( + `${path}/${tentativeFileName}`, + "jpg" + ).match(/\/([^/]+)$/)![1]; + + await decode(data, { + fname: `${path}/${fileName.replace(/.jpg$/, "")}`, + ext: "jpg", + }); + + await edgeCreatorServices.sendNewEdgePhotoEmail( + `${country}/${magazine}`, + issuenumber + ); + + callback({ fileName }); + }); + }); +}; + +export const upload = async ( + req: Request< + Record, + { + photo: boolean; + multiple: boolean; + edge: { + country: string; + magazine: string; + issuenumber: string; + }; + } + >, + res: Response +) => { + const userCredentials = getUserCredentials(req.user!); + + let allowedMimeTypes: string[]; + + const { photo: isEdgePhoto, multiple: isMultipleEdgePhoto, edge } = req.body; + const files = req.files! as Express.Multer.File[]; + const targetFilesnames = []; + for (const { + originalname: filename, + mimetype: mimetype, + path: temporaryPath, + } of files) { + allowedMimeTypes = isEdgePhoto + ? ["image/jpg", "image/jpeg"] + : ["image/png"]; + + const targetFilename = getTargetFilename( + filename, + isMultipleEdgePhoto, + edge, + isEdgePhoto + ); + try { + const { hash } = await validateUpload( + mimetype, + targetFilename, + allowedMimeTypes, + isEdgePhoto, + userCredentials, + edge, + temporaryPath + ); + saveFile(temporaryPath, targetFilename); + await storePhotoHash(targetFilename, hash); + targetFilesnames.push( + targetFilename.replace( + process.env.EDGES_PATH!, + process.env.VITE_EDGES_URL! + ) + ); + } catch (e: unknown) { + res.writeHead(400, { + Connection: "close", + "Content-Type": "application/json", + }); + res.end((e as Error).message); + } + } + res.writeHead(200, { Connection: "close" }); + return res.json(targetFilesnames.map((fileName) => ({ fileName }))); +}; + +const getTargetFilename = ( + filename: string, + isMultipleEdgePhoto: boolean, + edge: { + country: string; + magazine: string; + issuenumber: string; + }, + isEdgePhoto: boolean +) => { + filename = filename.normalize("NFD").replace(/[\u0300-\u036F]/g, ""); + + if (isMultipleEdgePhoto) { + return getNextAvailableFile( + `${edgesPath}/tranches_multiples/photo.multiple`, + "jpg" + ); + } else { + const { country, issuenumber, magazine } = edge; + if (isEdgePhoto) { + return getNextAvailableFile( + `${edgesPath}/${country}/photos/${magazine}.${issuenumber}.photo`, + "jpg" + ); + } else { + return `${edgesPath}/${country}/elements/${ + filename.includes(magazine) ? filename : `${magazine}.${filename}` + }`; + } + } +}; + +const validateUpload = async ( + mimetype: string, + filename: string, + allowedMimeTypes: string[], + isEdgePhoto: boolean, + userCredentials: Record, + edge: { + country: string; + magazine: string; + issuenumber: string; + }, + filePath: string +): Promise<{ hash: string }> => { + if (!allowedMimeTypes.includes(mimetype)) { + throw new Error( + JSON.stringify({ + error: + "Invalid file type: {mimetype}, the following types are allowed: {allowedMimeTypes}", + placeholders: { mimetype, allowedMimeTypes }, + }) + ); + } + const { hash } = readContentsAndCalculateHash(filePath); + if (isEdgePhoto) { + if (await hasReachedDailyUploadLimit()) { + throw new Error( + JSON.stringify({ + error: "You have reached your daily upload limit", + }) + ); + } + if (await hasAlreadySentPhoto(hash)) { + throw new Error( + JSON.stringify({ error: "You have already sent this photo" }) + ); + } + } else { + // await readFile(filestream); + const otherElementUses = await getFilenameUsagesInOtherModels( + filename, + edge + ); + if (fs.existsSync(filename) && otherElementUses.length) { + throw new Error( + JSON.stringify({ + error: + "This file name is already used in other models, please rename your file", + placeholders: { + otherElementUses: JSON.stringify(otherElementUses), + }, + }) + ); + } + } + return { hash }; +}; + +const hasReachedDailyUploadLimit = async () => + (await edgeCreatorServices.checkTodayLimit()).uploadedFilesToday.length > 10; + +const hasAlreadySentPhoto = async (hash: string) => + (await edgeCreatorServices.getImageByHash(hash)) === null; + +const readContentsAndCalculateHash = ( + fileName: string +): { contents: Buffer; hash: string } => { + const fileBuffer = fs.readFileSync(fileName); + const hashSum = crypto.createHash("sha256"); + hashSum.update(fileBuffer); + + return { contents: fileBuffer, hash: hashSum.digest("hex") }; +}; + +const getFilenameUsagesInOtherModels = async ( + filename: string, + currentModel: { country: string; magazine: string; issuenumber: string } +) => + (await edgeCreatorServices.getImagesFromFilename(filename)).filter( + (otherUse) => + currentModel.country !== otherUse.country || + currentModel.magazine !== otherUse.magazine || + currentModel.issuenumber !== otherUse.issuenumberStart + ); + +const saveFile = (temporaryPath: string, finalPath: string) => { + fs.mkdirSync(dirname(finalPath), { recursive: true }); + fs.renameSync(temporaryPath, finalPath); +}; + +const storePhotoHash = async (filename: string, hash: string) => { + await edgeCreatorServices.createElementImage(hash, filename); +}; diff --git a/api/services/upload/types.ts b/api/services/upload/types.ts new file mode 100644 index 00000000..7fa97bfc --- /dev/null +++ b/api/services/upload/types.ts @@ -0,0 +1,23 @@ +import type { Errorable } from "~socket.io-services/types"; + +export const namespaceEndpoint = "/save"; +export default abstract class { + static namespaceEndpoint = namespaceEndpoint; + + abstract uploadFromBase64: ( + parameters: { + data: string; + country: string; + magazine: string; + issuenumber: string; + }, + callback: ( + value: Errorable< + { + fileName: string; + }, + "Generic error" + >, + ) => void, + ) => void; +} diff --git a/api/tsconfig.json b/api/tsconfig.json index fc48b799..504bee56 100644 --- a/api/tsconfig.json +++ b/api/tsconfig.json @@ -2,11 +2,10 @@ "compilerOptions": { "baseUrl": ".", "module": "ESNext", - "target": "es2020", - "lib": ["DOM", "ESNext"], + "target": "es2018", + "lib": ["ESNext"], "strict": true, - "jsx": "preserve", - "esModuleInterop": true, + "esModuleInterop": true, "skipLibCheck": true, "moduleResolution": "node", "resolveJsonModule": true, @@ -15,13 +14,16 @@ "allowJs": true, "forceConsistentCasingInFileNames": true, "outDir": "./dist", + "preserveWatchOutput": true, "paths": { "~/*": ["./*"], "~types/*": ["../types/*"], - "~dm_types/*": ["./node_modules/ducksmanager/types/*"], - "~prisma/*": ["./node_modules/ducksmanager/types/*"], - "~prisma_clients/*": ["node_modules/ducksmanager/api/dist/prisma/*"], - "~routes/*": ["./routes/*"] + "~dm-services/*": ["../../../packages/api/services/*"], + "~dm-types/*": ["../../../packages/types/*"], + "~prisma-clients": ["../../../packages/prisma-clients"], + "~prisma-clients/*": ["../../../packages/prisma-clients/*"], + "~socket.io-services/*": ["../../../packages/socket.io-services/*"], + "~socket.io-client-services": ["../../../packages/socket.io-client-services"] } }, "exclude": ["node_modules"], diff --git a/api/tsconfig.prod.json b/api/tsconfig.prod.json deleted file mode 100644 index 71c9fe02..00000000 --- a/api/tsconfig.prod.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "compilerOptions": { - "baseUrl": ".", - "module": "commonjs", - "target": "es2018", - "lib": [ - "DOM", - "ESNext" - ], - "strict": true, - "jsx": "preserve", - "esModuleInterop": true, - "skipLibCheck": true, - "moduleResolution": "node", - "resolveJsonModule": true, - "noUnusedLocals": true, - "strictNullChecks": true, - "allowJs": true, - "forceConsistentCasingInFileNames": true, - "outDir": "./dist", - "paths": { - "~/*": [ - "*" - ], - "~types/*": [ - "../types/*" - ], - "~dm_types/*": [ - "./dm_types/*" - ], - "~prisma/*": [ - "./dm_types/*" - ], - "~prisma_clients/*": [ - "./prisma_clients/*" - ], - "~routes/*": [ - "./routes/*" - ] - } - }, - "include": [ - "*.ts", - "routes/**/*.ts", - "dm_types/**/*.ts", - "prisma_clients/*" - ] -} \ No newline at end of file diff --git a/auto-imports.d.ts b/auto-imports.d.ts deleted file mode 100644 index 5a368798..00000000 --- a/auto-imports.d.ts +++ /dev/null @@ -1,932 +0,0 @@ -/* eslint-disable */ -/* prettier-ignore */ -// @ts-nocheck -// noinspection JSUnusedGlobalSymbols -// Generated by unplugin-auto-import -export {} -declare global { - const $: typeof import('vue/macros')['$'] - const $$: typeof import('vue/macros')['$$'] - const $computed: typeof import('vue/macros')['$computed'] - const $customRef: typeof import('vue/macros')['$customRef'] - const $ref: typeof import('vue/macros')['$ref'] - const $shallowRef: typeof import('vue/macros')['$shallowRef'] - const $toRef: typeof import('vue/macros')['$toRef'] - const EffectScope: typeof import('vue')['EffectScope'] - const GET__fs__base64: typeof import('./types/routes')['GET__fs__base64'] - const GET__fs__browseEdges: typeof import('./types/routes')['GET__fs__browseEdges'] - const GET__fs__browse__$imageType__$country__$magazine: typeof import('./types/routes')['GET__fs__browse__$imageType__$country__$magazine'] - const GET__fs__generateDefaultEdge: typeof import('./types/routes')['GET__fs__generateDefaultEdge'] - const GET__fs__text: typeof import('./types/routes')['GET__fs__text'] - const POST__fs__save: typeof import('./types/routes')['POST__fs__save'] - const POST__fs__upload: typeof import('./types/routes')['POST__fs__upload'] - const POST__fs__upload_base64: typeof import('./types/routes')['POST__fs__upload_base64'] - const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] - const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] - const availableLocales: typeof import('./src/composables/useLocales')['availableLocales'] - const computed: typeof import('vue')['computed'] - const computedAsync: typeof import('@vueuse/core')['computedAsync'] - const computedEager: typeof import('@vueuse/core')['computedEager'] - const computedInject: typeof import('@vueuse/core')['computedInject'] - const computedWithControl: typeof import('@vueuse/core')['computedWithControl'] - const controlledComputed: typeof import('@vueuse/core')['controlledComputed'] - const controlledRef: typeof import('@vueuse/core')['controlledRef'] - const createApp: typeof import('vue')['createApp'] - const createEventHook: typeof import('@vueuse/core')['createEventHook'] - const createGlobalState: typeof import('@vueuse/core')['createGlobalState'] - const createInjectionState: typeof import('@vueuse/core')['createInjectionState'] - const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn'] - const createReusableTemplate: typeof import('@vueuse/core')['createReusableTemplate'] - const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable'] - const createTemplatePromise: typeof import('@vueuse/core')['createTemplatePromise'] - const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn'] - const customRef: typeof import('vue')['customRef'] - const debouncedRef: typeof import('@vueuse/core')['debouncedRef'] - const debouncedWatch: typeof import('@vueuse/core')['debouncedWatch'] - const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] - const defineComponent: typeof import('vue')['defineComponent'] - const eagerComputed: typeof import('@vueuse/core')['eagerComputed'] - const effectScope: typeof import('vue')['effectScope'] - const extendRef: typeof import('@vueuse/core')['extendRef'] - const getCurrentInstance: typeof import('vue')['getCurrentInstance'] - const getCurrentLocaleShortKey: typeof import('./src/composables/useLocales')['getCurrentLocaleShortKey'] - const getCurrentScope: typeof import('vue')['getCurrentScope'] - const h: typeof import('vue')['h'] - const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch'] - const inject: typeof import('vue')['inject'] - const isDefined: typeof import('@vueuse/core')['isDefined'] - const isProxy: typeof import('vue')['isProxy'] - const isReactive: typeof import('vue')['isReactive'] - const isReadonly: typeof import('vue')['isReadonly'] - const isRef: typeof import('vue')['isRef'] - const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable'] - const markRaw: typeof import('vue')['markRaw'] - const nextTick: typeof import('vue')['nextTick'] - const onActivated: typeof import('vue')['onActivated'] - const onBeforeMount: typeof import('vue')['onBeforeMount'] - const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave'] - const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate'] - const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] - const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] - const onClickOutside: typeof import('@vueuse/core')['onClickOutside'] - const onDeactivated: typeof import('vue')['onDeactivated'] - const onErrorCaptured: typeof import('vue')['onErrorCaptured'] - const onKeyStroke: typeof import('@vueuse/core')['onKeyStroke'] - const onLongPress: typeof import('@vueuse/core')['onLongPress'] - const onMounted: typeof import('vue')['onMounted'] - const onRenderTracked: typeof import('vue')['onRenderTracked'] - const onRenderTriggered: typeof import('vue')['onRenderTriggered'] - const onScopeDispose: typeof import('vue')['onScopeDispose'] - const onServerPrefetch: typeof import('vue')['onServerPrefetch'] - const onStartTyping: typeof import('@vueuse/core')['onStartTyping'] - const onUnmounted: typeof import('vue')['onUnmounted'] - const onUpdated: typeof import('vue')['onUpdated'] - const pausableWatch: typeof import('@vueuse/core')['pausableWatch'] - const provide: typeof import('vue')['provide'] - const reactify: typeof import('@vueuse/core')['reactify'] - const reactifyObject: typeof import('@vueuse/core')['reactifyObject'] - const reactive: typeof import('vue')['reactive'] - const reactiveComputed: typeof import('@vueuse/core')['reactiveComputed'] - const reactiveOmit: typeof import('@vueuse/core')['reactiveOmit'] - const reactivePick: typeof import('@vueuse/core')['reactivePick'] - const readonly: typeof import('vue')['readonly'] - const ref: typeof import('vue')['ref'] - const refAutoReset: typeof import('@vueuse/core')['refAutoReset'] - const refDebounced: typeof import('@vueuse/core')['refDebounced'] - const refDefault: typeof import('@vueuse/core')['refDefault'] - const refThrottled: typeof import('@vueuse/core')['refThrottled'] - const refWithControl: typeof import('@vueuse/core')['refWithControl'] - const resolveComponent: typeof import('vue')['resolveComponent'] - const resolveRef: typeof import('@vueuse/core')['resolveRef'] - const resolveUnref: typeof import('@vueuse/core')['resolveUnref'] - const shallowReactive: typeof import('vue')['shallowReactive'] - const shallowReadonly: typeof import('vue')['shallowReadonly'] - const shallowRef: typeof import('vue')['shallowRef'] - const syncRef: typeof import('@vueuse/core')['syncRef'] - const syncRefs: typeof import('@vueuse/core')['syncRefs'] - const templateRef: typeof import('@vueuse/core')['templateRef'] - const throttledRef: typeof import('@vueuse/core')['throttledRef'] - const throttledWatch: typeof import('@vueuse/core')['throttledWatch'] - const toRaw: typeof import('vue')['toRaw'] - const toReactive: typeof import('@vueuse/core')['toReactive'] - const toRef: typeof import('vue')['toRef'] - const toRefs: typeof import('vue')['toRefs'] - const toValue: typeof import('vue')['toValue'] - const triggerRef: typeof import('vue')['triggerRef'] - const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount'] - const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount'] - const tryOnMounted: typeof import('@vueuse/core')['tryOnMounted'] - const tryOnScopeDispose: typeof import('@vueuse/core')['tryOnScopeDispose'] - const tryOnUnmounted: typeof import('@vueuse/core')['tryOnUnmounted'] - const unref: typeof import('vue')['unref'] - const unrefElement: typeof import('@vueuse/core')['unrefElement'] - const until: typeof import('@vueuse/core')['until'] - const useActiveElement: typeof import('@vueuse/core')['useActiveElement'] - const useAnimate: typeof import('@vueuse/core')['useAnimate'] - const useArrayDifference: typeof import('@vueuse/core')['useArrayDifference'] - const useArrayEvery: typeof import('@vueuse/core')['useArrayEvery'] - const useArrayFilter: typeof import('@vueuse/core')['useArrayFilter'] - const useArrayFind: typeof import('@vueuse/core')['useArrayFind'] - const useArrayFindIndex: typeof import('@vueuse/core')['useArrayFindIndex'] - const useArrayFindLast: typeof import('@vueuse/core')['useArrayFindLast'] - const useArrayIncludes: typeof import('@vueuse/core')['useArrayIncludes'] - const useArrayJoin: typeof import('@vueuse/core')['useArrayJoin'] - const useArrayMap: typeof import('@vueuse/core')['useArrayMap'] - const useArrayReduce: typeof import('@vueuse/core')['useArrayReduce'] - const useArraySome: typeof import('@vueuse/core')['useArraySome'] - const useArrayUnique: typeof import('@vueuse/core')['useArrayUnique'] - const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue'] - const useAsyncState: typeof import('@vueuse/core')['useAsyncState'] - const useAttrs: typeof import('vue')['useAttrs'] - const useBase64: typeof import('@vueuse/core')['useBase64'] - const useBase64Legacy: typeof import('./src/composables/useBase64Legacy')['default'] - const useBattery: typeof import('@vueuse/core')['useBattery'] - const useBluetooth: typeof import('@vueuse/core')['useBluetooth'] - const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints'] - const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel'] - const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation'] - const useCached: typeof import('@vueuse/core')['useCached'] - const useClipboard: typeof import('@vueuse/core')['useClipboard'] - const useCloned: typeof import('@vueuse/core')['useCloned'] - const useColorMode: typeof import('@vueuse/core')['useColorMode'] - const useCondition: typeof import('./src/composables/useCondition')['default'] - const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog'] - const useCounter: typeof import('@vueuse/core')['useCounter'] - const useCssModule: typeof import('vue')['useCssModule'] - const useCssVar: typeof import('@vueuse/core')['useCssVar'] - const useCssVars: typeof import('vue')['useCssVars'] - const useCurrentElement: typeof import('@vueuse/core')['useCurrentElement'] - const useCycleList: typeof import('@vueuse/core')['useCycleList'] - const useDark: typeof import('@vueuse/core')['useDark'] - const useDateFormat: typeof import('@vueuse/core')['useDateFormat'] - const useDebounce: typeof import('@vueuse/core')['useDebounce'] - const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn'] - const useDebouncedRefHistory: typeof import('@vueuse/core')['useDebouncedRefHistory'] - const useDeviceMotion: typeof import('@vueuse/core')['useDeviceMotion'] - const useDeviceOrientation: typeof import('@vueuse/core')['useDeviceOrientation'] - const useDevicePixelRatio: typeof import('@vueuse/core')['useDevicePixelRatio'] - const useDevicesList: typeof import('@vueuse/core')['useDevicesList'] - const useDisplayMedia: typeof import('@vueuse/core')['useDisplayMedia'] - const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility'] - const useDraggable: typeof import('@vueuse/core')['useDraggable'] - const useDropZone: typeof import('@vueuse/core')['useDropZone'] - const useElementBounding: typeof import('@vueuse/core')['useElementBounding'] - const useElementByPoint: typeof import('@vueuse/core')['useElementByPoint'] - const useElementHover: typeof import('@vueuse/core')['useElementHover'] - const useElementSize: typeof import('@vueuse/core')['useElementSize'] - const useElementVisibility: typeof import('@vueuse/core')['useElementVisibility'] - const useEventBus: typeof import('@vueuse/core')['useEventBus'] - const useEventListener: typeof import('@vueuse/core')['useEventListener'] - const useEventSource: typeof import('@vueuse/core')['useEventSource'] - const useEyeDropper: typeof import('@vueuse/core')['useEyeDropper'] - const useFavicon: typeof import('@vueuse/core')['useFavicon'] - const useFetch: typeof import('@vueuse/core')['useFetch'] - const useFileDialog: typeof import('@vueuse/core')['useFileDialog'] - const useFileSystemAccess: typeof import('@vueuse/core')['useFileSystemAccess'] - const useFocus: typeof import('@vueuse/core')['useFocus'] - const useFocusWithin: typeof import('@vueuse/core')['useFocusWithin'] - const useFps: typeof import('@vueuse/core')['useFps'] - const useFullscreen: typeof import('@vueuse/core')['useFullscreen'] - const useGamepad: typeof import('@vueuse/core')['useGamepad'] - const useGeolocation: typeof import('@vueuse/core')['useGeolocation'] - const useIdle: typeof import('@vueuse/core')['useIdle'] - const useImage: typeof import('@vueuse/core')['useImage'] - const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll'] - const useIntersectionObserver: typeof import('@vueuse/core')['useIntersectionObserver'] - const useInterval: typeof import('@vueuse/core')['useInterval'] - const useIntervalFn: typeof import('@vueuse/core')['useIntervalFn'] - const useKeyModifier: typeof import('@vueuse/core')['useKeyModifier'] - const useLastChanged: typeof import('@vueuse/core')['useLastChanged'] - const useLegacyDb: typeof import('./src/composables/useLegacyDb')['default'] - const useLink: typeof import('vue-router')['useLink'] - const useLocalStorage: typeof import('@vueuse/core')['useLocalStorage'] - const useMagicKeys: typeof import('@vueuse/core')['useMagicKeys'] - const useManualRefHistory: typeof import('@vueuse/core')['useManualRefHistory'] - const useMedal: typeof import('./src/composables/useMedal')['default'] - const useMediaControls: typeof import('@vueuse/core')['useMediaControls'] - const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery'] - const useMemoize: typeof import('@vueuse/core')['useMemoize'] - const useMemory: typeof import('@vueuse/core')['useMemory'] - const useModelLoad: typeof import('./src/composables/useModelLoad')['default'] - const useMounted: typeof import('@vueuse/core')['useMounted'] - const useMouse: typeof import('@vueuse/core')['useMouse'] - const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement'] - const useMousePressed: typeof import('@vueuse/core')['useMousePressed'] - const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver'] - const useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage'] - const useNetwork: typeof import('@vueuse/core')['useNetwork'] - const useNow: typeof import('@vueuse/core')['useNow'] - const useObjectUrl: typeof import('@vueuse/core')['useObjectUrl'] - const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination'] - const useOnline: typeof import('@vueuse/core')['useOnline'] - const usePageLeave: typeof import('@vueuse/core')['usePageLeave'] - const useParallax: typeof import('@vueuse/core')['useParallax'] - const useParentElement: typeof import('@vueuse/core')['useParentElement'] - const usePerformanceObserver: typeof import('@vueuse/core')['usePerformanceObserver'] - const usePermission: typeof import('@vueuse/core')['usePermission'] - const usePointer: typeof import('@vueuse/core')['usePointer'] - const usePointerLock: typeof import('@vueuse/core')['usePointerLock'] - const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe'] - const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme'] - const usePreferredContrast: typeof import('@vueuse/core')['usePreferredContrast'] - const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark'] - const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages'] - const usePreferredReducedMotion: typeof import('@vueuse/core')['usePreferredReducedMotion'] - const usePrevious: typeof import('@vueuse/core')['usePrevious'] - const useRafFn: typeof import('@vueuse/core')['useRafFn'] - const useRedirect: typeof import('./src/composables/useRedirect')['default'] - const useRefHistory: typeof import('@vueuse/core')['useRefHistory'] - const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver'] - const useRoute: typeof import('vue-router')['useRoute'] - const useRouter: typeof import('vue-router')['useRouter'] - const useSaveEdge: typeof import('./src/composables/useSaveEdge')['default'] - const useScreenOrientation: typeof import('@vueuse/core')['useScreenOrientation'] - const useScreenSafeArea: typeof import('@vueuse/core')['useScreenSafeArea'] - const useScriptTag: typeof import('@vueuse/core')['useScriptTag'] - const useScroll: typeof import('@vueuse/core')['useScroll'] - const useScrollLock: typeof import('@vueuse/core')['useScrollLock'] - const useSessionStorage: typeof import('@vueuse/core')['useSessionStorage'] - const useShare: typeof import('@vueuse/core')['useShare'] - const useSlots: typeof import('vue')['useSlots'] - const useSorted: typeof import('@vueuse/core')['useSorted'] - const useSpeechRecognition: typeof import('@vueuse/core')['useSpeechRecognition'] - const useSpeechSynthesis: typeof import('@vueuse/core')['useSpeechSynthesis'] - const useStepOptions: typeof import('./src/composables/useStepOptions')['useStepOptions'] - const useStepper: typeof import('@vueuse/core')['useStepper'] - const useStorage: typeof import('@vueuse/core')['useStorage'] - const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync'] - const useStyleTag: typeof import('@vueuse/core')['useStyleTag'] - const useSupported: typeof import('@vueuse/core')['useSupported'] - const useSurroundingEdge: typeof import('./src/composables/useSurroundingEdge')['default'] - const useSvgUtils: typeof import('./src/composables/useSvgUtils')['default'] - const useSwipe: typeof import('@vueuse/core')['useSwipe'] - const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList'] - const useTextDirection: typeof import('@vueuse/core')['useTextDirection'] - const useTextSelection: typeof import('@vueuse/core')['useTextSelection'] - const useTextTemplate: typeof import('./src/composables/useTextTemplate')['default'] - const useTextareaAutosize: typeof import('@vueuse/core')['useTextareaAutosize'] - const useThrottle: typeof import('@vueuse/core')['useThrottle'] - const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn'] - const useThrottledRefHistory: typeof import('@vueuse/core')['useThrottledRefHistory'] - const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo'] - const useTimeout: typeof import('@vueuse/core')['useTimeout'] - const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn'] - const useTimeoutPoll: typeof import('@vueuse/core')['useTimeoutPoll'] - const useTimestamp: typeof import('@vueuse/core')['useTimestamp'] - const useTitle: typeof import('@vueuse/core')['useTitle'] - const useToNumber: typeof import('@vueuse/core')['useToNumber'] - const useToString: typeof import('@vueuse/core')['useToString'] - const useToggle: typeof import('@vueuse/core')['useToggle'] - const useTransition: typeof import('@vueuse/core')['useTransition'] - const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams'] - const useUserMedia: typeof import('@vueuse/core')['useUserMedia'] - const useVModel: typeof import('@vueuse/core')['useVModel'] - const useVModels: typeof import('@vueuse/core')['useVModels'] - const useVibrate: typeof import('@vueuse/core')['useVibrate'] - const useVirtualList: typeof import('@vueuse/core')['useVirtualList'] - const useWakeLock: typeof import('@vueuse/core')['useWakeLock'] - const useWebNotification: typeof import('@vueuse/core')['useWebNotification'] - const useWebSocket: typeof import('@vueuse/core')['useWebSocket'] - const useWebWorker: typeof import('@vueuse/core')['useWebWorker'] - const useWebWorkerFn: typeof import('@vueuse/core')['useWebWorkerFn'] - const useWindowFocus: typeof import('@vueuse/core')['useWindowFocus'] - const useWindowScroll: typeof import('@vueuse/core')['useWindowScroll'] - const useWindowSize: typeof import('@vueuse/core')['useWindowSize'] - const watch: typeof import('vue')['watch'] - const watchArray: typeof import('@vueuse/core')['watchArray'] - const watchAtMost: typeof import('@vueuse/core')['watchAtMost'] - const watchDebounced: typeof import('@vueuse/core')['watchDebounced'] - const watchDeep: typeof import('@vueuse/core')['watchDeep'] - const watchEffect: typeof import('vue')['watchEffect'] - const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable'] - const watchImmediate: typeof import('@vueuse/core')['watchImmediate'] - const watchOnce: typeof import('@vueuse/core')['watchOnce'] - const watchPausable: typeof import('@vueuse/core')['watchPausable'] - const watchPostEffect: typeof import('vue')['watchPostEffect'] - const watchSyncEffect: typeof import('vue')['watchSyncEffect'] - const watchThrottled: typeof import('@vueuse/core')['watchThrottled'] - const watchTriggerable: typeof import('@vueuse/core')['watchTriggerable'] - const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter'] - const whenever: typeof import('@vueuse/core')['whenever'] -} -// for type re-export -declare global { - // @ts-ignore - export type { Component, ComponentPublicInstance, ComputedRef, InjectionKey, PropType, Ref, VNode } from 'vue' -} -// for vue template auto import -import { UnwrapRef } from 'vue' -declare module 'vue' { - interface ComponentCustomProperties { - readonly $$: UnwrapRef - readonly $: UnwrapRef - readonly $computed: UnwrapRef - readonly $customRef: UnwrapRef - readonly $ref: UnwrapRef - readonly $shallowRef: UnwrapRef - readonly $toRef: UnwrapRef - readonly EffectScope: UnwrapRef - readonly GET__fs__base64: UnwrapRef - readonly GET__fs__browseEdges: UnwrapRef - readonly GET__fs__browse__$imageType__$country__$magazine: UnwrapRef - readonly GET__fs__generateDefaultEdge: UnwrapRef - readonly GET__fs__text: UnwrapRef - readonly POST__fs__save: UnwrapRef - readonly POST__fs__upload: UnwrapRef - readonly POST__fs__upload_base64: UnwrapRef - readonly asyncComputed: UnwrapRef - readonly autoResetRef: UnwrapRef - readonly availableLocales: UnwrapRef - readonly computed: UnwrapRef - readonly computedAsync: UnwrapRef - readonly computedEager: UnwrapRef - readonly computedInject: UnwrapRef - readonly computedWithControl: UnwrapRef - readonly controlledComputed: UnwrapRef - readonly controlledRef: UnwrapRef - readonly createApp: UnwrapRef - readonly createEventHook: UnwrapRef - readonly createGlobalState: UnwrapRef - readonly createInjectionState: UnwrapRef - readonly createReactiveFn: UnwrapRef - readonly createReusableTemplate: UnwrapRef - readonly createSharedComposable: UnwrapRef - readonly createTemplatePromise: UnwrapRef - readonly createUnrefFn: UnwrapRef - readonly customRef: UnwrapRef - readonly debouncedRef: UnwrapRef - readonly debouncedWatch: UnwrapRef - readonly defineAsyncComponent: UnwrapRef - readonly defineComponent: UnwrapRef - readonly eagerComputed: UnwrapRef - readonly effectScope: UnwrapRef - readonly extendRef: UnwrapRef - readonly getCurrentInstance: UnwrapRef - readonly getCurrentLocaleShortKey: UnwrapRef - readonly getCurrentScope: UnwrapRef - readonly h: UnwrapRef - readonly ignorableWatch: UnwrapRef - readonly inject: UnwrapRef - readonly isDefined: UnwrapRef - readonly isProxy: UnwrapRef - readonly isReactive: UnwrapRef - readonly isReadonly: UnwrapRef - readonly isRef: UnwrapRef - readonly makeDestructurable: UnwrapRef - readonly markRaw: UnwrapRef - readonly nextTick: UnwrapRef - readonly onActivated: UnwrapRef - readonly onBeforeMount: UnwrapRef - readonly onBeforeRouteLeave: UnwrapRef - readonly onBeforeRouteUpdate: UnwrapRef - readonly onBeforeUnmount: UnwrapRef - readonly onBeforeUpdate: UnwrapRef - readonly onClickOutside: UnwrapRef - readonly onDeactivated: UnwrapRef - readonly onErrorCaptured: UnwrapRef - readonly onKeyStroke: UnwrapRef - readonly onLongPress: UnwrapRef - readonly onMounted: UnwrapRef - readonly onRenderTracked: UnwrapRef - readonly onRenderTriggered: UnwrapRef - readonly onScopeDispose: UnwrapRef - readonly onServerPrefetch: UnwrapRef - readonly onStartTyping: UnwrapRef - readonly onUnmounted: UnwrapRef - readonly onUpdated: UnwrapRef - readonly pausableWatch: UnwrapRef - readonly provide: UnwrapRef - readonly reactify: UnwrapRef - readonly reactifyObject: UnwrapRef - readonly reactive: UnwrapRef - readonly reactiveComputed: UnwrapRef - readonly reactiveOmit: UnwrapRef - readonly reactivePick: UnwrapRef - readonly readonly: UnwrapRef - readonly ref: UnwrapRef - readonly refAutoReset: UnwrapRef - readonly refDebounced: UnwrapRef - readonly refDefault: UnwrapRef - readonly refThrottled: UnwrapRef - readonly refWithControl: UnwrapRef - readonly resolveComponent: UnwrapRef - readonly resolveRef: UnwrapRef - readonly resolveUnref: UnwrapRef - readonly shallowReactive: UnwrapRef - readonly shallowReadonly: UnwrapRef - readonly shallowRef: UnwrapRef - readonly syncRef: UnwrapRef - readonly syncRefs: UnwrapRef - readonly templateRef: UnwrapRef - readonly throttledRef: UnwrapRef - readonly throttledWatch: UnwrapRef - readonly toRaw: UnwrapRef - readonly toReactive: UnwrapRef - readonly toRef: UnwrapRef - readonly toRefs: UnwrapRef - readonly toValue: UnwrapRef - readonly triggerRef: UnwrapRef - readonly tryOnBeforeMount: UnwrapRef - readonly tryOnBeforeUnmount: UnwrapRef - readonly tryOnMounted: UnwrapRef - readonly tryOnScopeDispose: UnwrapRef - readonly tryOnUnmounted: UnwrapRef - readonly unref: UnwrapRef - readonly unrefElement: UnwrapRef - readonly until: UnwrapRef - readonly useActiveElement: UnwrapRef - readonly useAnimate: UnwrapRef - readonly useArrayDifference: UnwrapRef - readonly useArrayEvery: UnwrapRef - readonly useArrayFilter: UnwrapRef - readonly useArrayFind: UnwrapRef - readonly useArrayFindIndex: UnwrapRef - readonly useArrayFindLast: UnwrapRef - readonly useArrayIncludes: UnwrapRef - readonly useArrayJoin: UnwrapRef - readonly useArrayMap: UnwrapRef - readonly useArrayReduce: UnwrapRef - readonly useArraySome: UnwrapRef - readonly useArrayUnique: UnwrapRef - readonly useAsyncQueue: UnwrapRef - readonly useAsyncState: UnwrapRef - readonly useAttrs: UnwrapRef - readonly useBase64: UnwrapRef - readonly useBase64Legacy: UnwrapRef - readonly useBattery: UnwrapRef - readonly useBluetooth: UnwrapRef - readonly useBreakpoints: UnwrapRef - readonly useBroadcastChannel: UnwrapRef - readonly useBrowserLocation: UnwrapRef - readonly useCached: UnwrapRef - readonly useClipboard: UnwrapRef - readonly useCloned: UnwrapRef - readonly useColorMode: UnwrapRef - readonly useCondition: UnwrapRef - readonly useConfirmDialog: UnwrapRef - readonly useCounter: UnwrapRef - readonly useCssModule: UnwrapRef - readonly useCssVar: UnwrapRef - readonly useCssVars: UnwrapRef - readonly useCurrentElement: UnwrapRef - readonly useCycleList: UnwrapRef - readonly useDark: UnwrapRef - readonly useDateFormat: UnwrapRef - readonly useDebounce: UnwrapRef - readonly useDebounceFn: UnwrapRef - readonly useDebouncedRefHistory: UnwrapRef - readonly useDeviceMotion: UnwrapRef - readonly useDeviceOrientation: UnwrapRef - readonly useDevicePixelRatio: UnwrapRef - readonly useDevicesList: UnwrapRef - readonly useDisplayMedia: UnwrapRef - readonly useDocumentVisibility: UnwrapRef - readonly useDraggable: UnwrapRef - readonly useDropZone: UnwrapRef - readonly useElementBounding: UnwrapRef - readonly useElementByPoint: UnwrapRef - readonly useElementHover: UnwrapRef - readonly useElementSize: UnwrapRef - readonly useElementVisibility: UnwrapRef - readonly useEventBus: UnwrapRef - readonly useEventListener: UnwrapRef - readonly useEventSource: UnwrapRef - readonly useEyeDropper: UnwrapRef - readonly useFavicon: UnwrapRef - readonly useFetch: UnwrapRef - readonly useFileDialog: UnwrapRef - readonly useFileSystemAccess: UnwrapRef - readonly useFocus: UnwrapRef - readonly useFocusWithin: UnwrapRef - readonly useFps: UnwrapRef - readonly useFullscreen: UnwrapRef - readonly useGamepad: UnwrapRef - readonly useGeolocation: UnwrapRef - readonly useIdle: UnwrapRef - readonly useImage: UnwrapRef - readonly useInfiniteScroll: UnwrapRef - readonly useIntersectionObserver: UnwrapRef - readonly useInterval: UnwrapRef - readonly useIntervalFn: UnwrapRef - readonly useKeyModifier: UnwrapRef - readonly useLastChanged: UnwrapRef - readonly useLegacyDb: UnwrapRef - readonly useLink: UnwrapRef - readonly useLocalStorage: UnwrapRef - readonly useMagicKeys: UnwrapRef - readonly useManualRefHistory: UnwrapRef - readonly useMedal: UnwrapRef - readonly useMediaControls: UnwrapRef - readonly useMediaQuery: UnwrapRef - readonly useMemoize: UnwrapRef - readonly useMemory: UnwrapRef - readonly useModelLoad: UnwrapRef - readonly useMounted: UnwrapRef - readonly useMouse: UnwrapRef - readonly useMouseInElement: UnwrapRef - readonly useMousePressed: UnwrapRef - readonly useMutationObserver: UnwrapRef - readonly useNavigatorLanguage: UnwrapRef - readonly useNetwork: UnwrapRef - readonly useNow: UnwrapRef - readonly useObjectUrl: UnwrapRef - readonly useOffsetPagination: UnwrapRef - readonly useOnline: UnwrapRef - readonly usePageLeave: UnwrapRef - readonly useParallax: UnwrapRef - readonly useParentElement: UnwrapRef - readonly usePerformanceObserver: UnwrapRef - readonly usePermission: UnwrapRef - readonly usePointer: UnwrapRef - readonly usePointerLock: UnwrapRef - readonly usePointerSwipe: UnwrapRef - readonly usePreferredColorScheme: UnwrapRef - readonly usePreferredContrast: UnwrapRef - readonly usePreferredDark: UnwrapRef - readonly usePreferredLanguages: UnwrapRef - readonly usePreferredReducedMotion: UnwrapRef - readonly usePrevious: UnwrapRef - readonly useRafFn: UnwrapRef - readonly useRedirect: UnwrapRef - readonly useRefHistory: UnwrapRef - readonly useResizeObserver: UnwrapRef - readonly useRoute: UnwrapRef - readonly useRouter: UnwrapRef - readonly useSaveEdge: UnwrapRef - readonly useScreenOrientation: UnwrapRef - readonly useScreenSafeArea: UnwrapRef - readonly useScriptTag: UnwrapRef - readonly useScroll: UnwrapRef - readonly useScrollLock: UnwrapRef - readonly useSessionStorage: UnwrapRef - readonly useShare: UnwrapRef - readonly useSlots: UnwrapRef - readonly useSorted: UnwrapRef - readonly useSpeechRecognition: UnwrapRef - readonly useSpeechSynthesis: UnwrapRef - readonly useStepOptions: UnwrapRef - readonly useStepper: UnwrapRef - readonly useStorage: UnwrapRef - readonly useStorageAsync: UnwrapRef - readonly useStyleTag: UnwrapRef - readonly useSupported: UnwrapRef - readonly useSurroundingEdge: UnwrapRef - readonly useSvgUtils: UnwrapRef - readonly useSwipe: UnwrapRef - readonly useTemplateRefsList: UnwrapRef - readonly useTextDirection: UnwrapRef - readonly useTextSelection: UnwrapRef - readonly useTextTemplate: UnwrapRef - readonly useTextareaAutosize: UnwrapRef - readonly useThrottle: UnwrapRef - readonly useThrottleFn: UnwrapRef - readonly useThrottledRefHistory: UnwrapRef - readonly useTimeAgo: UnwrapRef - readonly useTimeout: UnwrapRef - readonly useTimeoutFn: UnwrapRef - readonly useTimeoutPoll: UnwrapRef - readonly useTimestamp: UnwrapRef - readonly useTitle: UnwrapRef - readonly useToNumber: UnwrapRef - readonly useToString: UnwrapRef - readonly useToggle: UnwrapRef - readonly useTransition: UnwrapRef - readonly useUrlSearchParams: UnwrapRef - readonly useUserMedia: UnwrapRef - readonly useVModel: UnwrapRef - readonly useVModels: UnwrapRef - readonly useVibrate: UnwrapRef - readonly useVirtualList: UnwrapRef - readonly useWakeLock: UnwrapRef - readonly useWebNotification: UnwrapRef - readonly useWebSocket: UnwrapRef - readonly useWebWorker: UnwrapRef - readonly useWebWorkerFn: UnwrapRef - readonly useWindowFocus: UnwrapRef - readonly useWindowScroll: UnwrapRef - readonly useWindowSize: UnwrapRef - readonly watch: UnwrapRef - readonly watchArray: UnwrapRef - readonly watchAtMost: UnwrapRef - readonly watchDebounced: UnwrapRef - readonly watchDeep: UnwrapRef - readonly watchEffect: UnwrapRef - readonly watchIgnorable: UnwrapRef - readonly watchImmediate: UnwrapRef - readonly watchOnce: UnwrapRef - readonly watchPausable: UnwrapRef - readonly watchPostEffect: UnwrapRef - readonly watchSyncEffect: UnwrapRef - readonly watchThrottled: UnwrapRef - readonly watchTriggerable: UnwrapRef - readonly watchWithFilter: UnwrapRef - readonly whenever: UnwrapRef - } -} -declare module '@vue/runtime-core' { - interface ComponentCustomProperties { - readonly $$: UnwrapRef - readonly $: UnwrapRef - readonly $computed: UnwrapRef - readonly $customRef: UnwrapRef - readonly $ref: UnwrapRef - readonly $shallowRef: UnwrapRef - readonly $toRef: UnwrapRef - readonly EffectScope: UnwrapRef - readonly GET__fs__base64: UnwrapRef - readonly GET__fs__browseEdges: UnwrapRef - readonly GET__fs__browse__$imageType__$country__$magazine: UnwrapRef - readonly GET__fs__generateDefaultEdge: UnwrapRef - readonly GET__fs__text: UnwrapRef - readonly POST__fs__save: UnwrapRef - readonly POST__fs__upload: UnwrapRef - readonly POST__fs__upload_base64: UnwrapRef - readonly asyncComputed: UnwrapRef - readonly autoResetRef: UnwrapRef - readonly availableLocales: UnwrapRef - readonly computed: UnwrapRef - readonly computedAsync: UnwrapRef - readonly computedEager: UnwrapRef - readonly computedInject: UnwrapRef - readonly computedWithControl: UnwrapRef - readonly controlledComputed: UnwrapRef - readonly controlledRef: UnwrapRef - readonly createApp: UnwrapRef - readonly createEventHook: UnwrapRef - readonly createGlobalState: UnwrapRef - readonly createInjectionState: UnwrapRef - readonly createReactiveFn: UnwrapRef - readonly createReusableTemplate: UnwrapRef - readonly createSharedComposable: UnwrapRef - readonly createTemplatePromise: UnwrapRef - readonly createUnrefFn: UnwrapRef - readonly customRef: UnwrapRef - readonly debouncedRef: UnwrapRef - readonly debouncedWatch: UnwrapRef - readonly defineAsyncComponent: UnwrapRef - readonly defineComponent: UnwrapRef - readonly eagerComputed: UnwrapRef - readonly effectScope: UnwrapRef - readonly extendRef: UnwrapRef - readonly getCurrentInstance: UnwrapRef - readonly getCurrentLocaleShortKey: UnwrapRef - readonly getCurrentScope: UnwrapRef - readonly h: UnwrapRef - readonly ignorableWatch: UnwrapRef - readonly inject: UnwrapRef - readonly isDefined: UnwrapRef - readonly isProxy: UnwrapRef - readonly isReactive: UnwrapRef - readonly isReadonly: UnwrapRef - readonly isRef: UnwrapRef - readonly makeDestructurable: UnwrapRef - readonly markRaw: UnwrapRef - readonly nextTick: UnwrapRef - readonly onActivated: UnwrapRef - readonly onBeforeMount: UnwrapRef - readonly onBeforeRouteLeave: UnwrapRef - readonly onBeforeRouteUpdate: UnwrapRef - readonly onBeforeUnmount: UnwrapRef - readonly onBeforeUpdate: UnwrapRef - readonly onClickOutside: UnwrapRef - readonly onDeactivated: UnwrapRef - readonly onErrorCaptured: UnwrapRef - readonly onKeyStroke: UnwrapRef - readonly onLongPress: UnwrapRef - readonly onMounted: UnwrapRef - readonly onRenderTracked: UnwrapRef - readonly onRenderTriggered: UnwrapRef - readonly onScopeDispose: UnwrapRef - readonly onServerPrefetch: UnwrapRef - readonly onStartTyping: UnwrapRef - readonly onUnmounted: UnwrapRef - readonly onUpdated: UnwrapRef - readonly pausableWatch: UnwrapRef - readonly provide: UnwrapRef - readonly reactify: UnwrapRef - readonly reactifyObject: UnwrapRef - readonly reactive: UnwrapRef - readonly reactiveComputed: UnwrapRef - readonly reactiveOmit: UnwrapRef - readonly reactivePick: UnwrapRef - readonly readonly: UnwrapRef - readonly ref: UnwrapRef - readonly refAutoReset: UnwrapRef - readonly refDebounced: UnwrapRef - readonly refDefault: UnwrapRef - readonly refThrottled: UnwrapRef - readonly refWithControl: UnwrapRef - readonly resolveComponent: UnwrapRef - readonly resolveRef: UnwrapRef - readonly resolveUnref: UnwrapRef - readonly shallowReactive: UnwrapRef - readonly shallowReadonly: UnwrapRef - readonly shallowRef: UnwrapRef - readonly syncRef: UnwrapRef - readonly syncRefs: UnwrapRef - readonly templateRef: UnwrapRef - readonly throttledRef: UnwrapRef - readonly throttledWatch: UnwrapRef - readonly toRaw: UnwrapRef - readonly toReactive: UnwrapRef - readonly toRef: UnwrapRef - readonly toRefs: UnwrapRef - readonly toValue: UnwrapRef - readonly triggerRef: UnwrapRef - readonly tryOnBeforeMount: UnwrapRef - readonly tryOnBeforeUnmount: UnwrapRef - readonly tryOnMounted: UnwrapRef - readonly tryOnScopeDispose: UnwrapRef - readonly tryOnUnmounted: UnwrapRef - readonly unref: UnwrapRef - readonly unrefElement: UnwrapRef - readonly until: UnwrapRef - readonly useActiveElement: UnwrapRef - readonly useAnimate: UnwrapRef - readonly useArrayDifference: UnwrapRef - readonly useArrayEvery: UnwrapRef - readonly useArrayFilter: UnwrapRef - readonly useArrayFind: UnwrapRef - readonly useArrayFindIndex: UnwrapRef - readonly useArrayFindLast: UnwrapRef - readonly useArrayIncludes: UnwrapRef - readonly useArrayJoin: UnwrapRef - readonly useArrayMap: UnwrapRef - readonly useArrayReduce: UnwrapRef - readonly useArraySome: UnwrapRef - readonly useArrayUnique: UnwrapRef - readonly useAsyncQueue: UnwrapRef - readonly useAsyncState: UnwrapRef - readonly useAttrs: UnwrapRef - readonly useBase64: UnwrapRef - readonly useBase64Legacy: UnwrapRef - readonly useBattery: UnwrapRef - readonly useBluetooth: UnwrapRef - readonly useBreakpoints: UnwrapRef - readonly useBroadcastChannel: UnwrapRef - readonly useBrowserLocation: UnwrapRef - readonly useCached: UnwrapRef - readonly useClipboard: UnwrapRef - readonly useCloned: UnwrapRef - readonly useColorMode: UnwrapRef - readonly useCondition: UnwrapRef - readonly useConfirmDialog: UnwrapRef - readonly useCounter: UnwrapRef - readonly useCssModule: UnwrapRef - readonly useCssVar: UnwrapRef - readonly useCssVars: UnwrapRef - readonly useCurrentElement: UnwrapRef - readonly useCycleList: UnwrapRef - readonly useDark: UnwrapRef - readonly useDateFormat: UnwrapRef - readonly useDebounce: UnwrapRef - readonly useDebounceFn: UnwrapRef - readonly useDebouncedRefHistory: UnwrapRef - readonly useDeviceMotion: UnwrapRef - readonly useDeviceOrientation: UnwrapRef - readonly useDevicePixelRatio: UnwrapRef - readonly useDevicesList: UnwrapRef - readonly useDisplayMedia: UnwrapRef - readonly useDocumentVisibility: UnwrapRef - readonly useDraggable: UnwrapRef - readonly useDropZone: UnwrapRef - readonly useElementBounding: UnwrapRef - readonly useElementByPoint: UnwrapRef - readonly useElementHover: UnwrapRef - readonly useElementSize: UnwrapRef - readonly useElementVisibility: UnwrapRef - readonly useEventBus: UnwrapRef - readonly useEventListener: UnwrapRef - readonly useEventSource: UnwrapRef - readonly useEyeDropper: UnwrapRef - readonly useFavicon: UnwrapRef - readonly useFetch: UnwrapRef - readonly useFileDialog: UnwrapRef - readonly useFileSystemAccess: UnwrapRef - readonly useFocus: UnwrapRef - readonly useFocusWithin: UnwrapRef - readonly useFps: UnwrapRef - readonly useFullscreen: UnwrapRef - readonly useGamepad: UnwrapRef - readonly useGeolocation: UnwrapRef - readonly useIdle: UnwrapRef - readonly useImage: UnwrapRef - readonly useInfiniteScroll: UnwrapRef - readonly useIntersectionObserver: UnwrapRef - readonly useInterval: UnwrapRef - readonly useIntervalFn: UnwrapRef - readonly useKeyModifier: UnwrapRef - readonly useLastChanged: UnwrapRef - readonly useLegacyDb: UnwrapRef - readonly useLink: UnwrapRef - readonly useLocalStorage: UnwrapRef - readonly useMagicKeys: UnwrapRef - readonly useManualRefHistory: UnwrapRef - readonly useMedal: UnwrapRef - readonly useMediaControls: UnwrapRef - readonly useMediaQuery: UnwrapRef - readonly useMemoize: UnwrapRef - readonly useMemory: UnwrapRef - readonly useModelLoad: UnwrapRef - readonly useMounted: UnwrapRef - readonly useMouse: UnwrapRef - readonly useMouseInElement: UnwrapRef - readonly useMousePressed: UnwrapRef - readonly useMutationObserver: UnwrapRef - readonly useNavigatorLanguage: UnwrapRef - readonly useNetwork: UnwrapRef - readonly useNow: UnwrapRef - readonly useObjectUrl: UnwrapRef - readonly useOffsetPagination: UnwrapRef - readonly useOnline: UnwrapRef - readonly usePageLeave: UnwrapRef - readonly useParallax: UnwrapRef - readonly useParentElement: UnwrapRef - readonly usePerformanceObserver: UnwrapRef - readonly usePermission: UnwrapRef - readonly usePointer: UnwrapRef - readonly usePointerLock: UnwrapRef - readonly usePointerSwipe: UnwrapRef - readonly usePreferredColorScheme: UnwrapRef - readonly usePreferredContrast: UnwrapRef - readonly usePreferredDark: UnwrapRef - readonly usePreferredLanguages: UnwrapRef - readonly usePreferredReducedMotion: UnwrapRef - readonly usePrevious: UnwrapRef - readonly useRafFn: UnwrapRef - readonly useRedirect: UnwrapRef - readonly useRefHistory: UnwrapRef - readonly useResizeObserver: UnwrapRef - readonly useRoute: UnwrapRef - readonly useRouter: UnwrapRef - readonly useSaveEdge: UnwrapRef - readonly useScreenOrientation: UnwrapRef - readonly useScreenSafeArea: UnwrapRef - readonly useScriptTag: UnwrapRef - readonly useScroll: UnwrapRef - readonly useScrollLock: UnwrapRef - readonly useSessionStorage: UnwrapRef - readonly useShare: UnwrapRef - readonly useSlots: UnwrapRef - readonly useSorted: UnwrapRef - readonly useSpeechRecognition: UnwrapRef - readonly useSpeechSynthesis: UnwrapRef - readonly useStepOptions: UnwrapRef - readonly useStepper: UnwrapRef - readonly useStorage: UnwrapRef - readonly useStorageAsync: UnwrapRef - readonly useStyleTag: UnwrapRef - readonly useSupported: UnwrapRef - readonly useSurroundingEdge: UnwrapRef - readonly useSvgUtils: UnwrapRef - readonly useSwipe: UnwrapRef - readonly useTemplateRefsList: UnwrapRef - readonly useTextDirection: UnwrapRef - readonly useTextSelection: UnwrapRef - readonly useTextTemplate: UnwrapRef - readonly useTextareaAutosize: UnwrapRef - readonly useThrottle: UnwrapRef - readonly useThrottleFn: UnwrapRef - readonly useThrottledRefHistory: UnwrapRef - readonly useTimeAgo: UnwrapRef - readonly useTimeout: UnwrapRef - readonly useTimeoutFn: UnwrapRef - readonly useTimeoutPoll: UnwrapRef - readonly useTimestamp: UnwrapRef - readonly useTitle: UnwrapRef - readonly useToNumber: UnwrapRef - readonly useToString: UnwrapRef - readonly useToggle: UnwrapRef - readonly useTransition: UnwrapRef - readonly useUrlSearchParams: UnwrapRef - readonly useUserMedia: UnwrapRef - readonly useVModel: UnwrapRef - readonly useVModels: UnwrapRef - readonly useVibrate: UnwrapRef - readonly useVirtualList: UnwrapRef - readonly useWakeLock: UnwrapRef - readonly useWebNotification: UnwrapRef - readonly useWebSocket: UnwrapRef - readonly useWebWorker: UnwrapRef - readonly useWebWorkerFn: UnwrapRef - readonly useWindowFocus: UnwrapRef - readonly useWindowScroll: UnwrapRef - readonly useWindowSize: UnwrapRef - readonly watch: UnwrapRef - readonly watchArray: UnwrapRef - readonly watchAtMost: UnwrapRef - readonly watchDebounced: UnwrapRef - readonly watchDeep: UnwrapRef - readonly watchEffect: UnwrapRef - readonly watchIgnorable: UnwrapRef - readonly watchImmediate: UnwrapRef - readonly watchOnce: UnwrapRef - readonly watchPausable: UnwrapRef - readonly watchPostEffect: UnwrapRef - readonly watchSyncEffect: UnwrapRef - readonly watchThrottled: UnwrapRef - readonly watchTriggerable: UnwrapRef - readonly watchWithFilter: UnwrapRef - readonly whenever: UnwrapRef - } -} diff --git a/axios-helper.ts b/axios-helper.ts deleted file mode 100644 index 5fe4882c..00000000 --- a/axios-helper.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { useCookies } from "@vueuse/integrations/useCookies"; -import axios, { - AxiosInstance, - AxiosResponse, - InternalAxiosRequestConfig, -} from "axios"; -import { AxiosCacheInstance } from "axios-cache-interceptor"; - -import { Call, ContractWithMethodAndUrl } from "~types/Call"; - -export const addUrlParamsRequestInterceptor = < - Type extends AxiosInstance | AxiosCacheInstance, ->( - axiosInstance: Type, -) => { - axiosInstance.interceptors.request.use( - (config: InternalAxiosRequestConfig) => { - if (config.url) { - const currentUrl = new URL(config.url, config.baseURL); - currentUrl.pathname = Object.entries( - config.urlParams ?? ({} as Record), - ).reduce( - (pathname, [k, v]) => - pathname.replace(`:${k}`, encodeURIComponent(v)), - currentUrl.pathname, - ); - return { - ...config, - baseURL: `${currentUrl.protocol}//${currentUrl.host}`, - url: currentUrl.pathname, - }; - } - return config; - }, - ); - return axiosInstance; -}; - -declare module "axios" { - interface InternalAxiosRequestConfig { - urlParams?: Record | undefined; - } - - interface AxiosRequestConfig { - urlParams?: Record | undefined; - } -} - -type MyCall = Call; - -export const call = >( - instance: AxiosInstance | AxiosCacheInstance, - contract: Contract, -): Promise> => - instance.request({ - method: contract.getMethod(), - url: contract.getUrl(), - params: contract.call?.query || undefined, - urlParams: contract.call?.params ?? undefined, - data: (contract.call?.reqBody as never) || undefined, - }); - -export const getChunkedRequests = async < - Contract extends ContractWithMethodAndUrl, ->({ - callFn, - valuesToChunk, - chunkSize, -}: { - callFn: (chunk: string) => Promise>; - valuesToChunk: string[]; - chunkSize: number; - chunkOnQueryParam?: boolean; - parameterName?: string; -}): Promise => { - const slices = Array.from( - { length: Math.ceil(valuesToChunk.length / chunkSize) }, - (_, i) => valuesToChunk.slice(i * chunkSize, i * chunkSize + chunkSize), - ); - let acc: Contract["resBody"] = (await callFn(slices[0].join(","))).data; - for (const slice of slices.slice(1)) { - acc = Array.isArray(acc) - ? [ - ...(acc as never[]), - ...((await callFn(slice.join(","))).data as never[]), - ] - : { - ...(acc as Record), - ...((await callFn(slice.join(","))).data as Record), - }; - } - return acc; -}; - -export const createAxios = (baseURL: string) => { - const newInstance = axios.create({ baseURL }); - - newInstance.interceptors.request.use( - (config) => { - const token: string = useCookies().get("token"); - if (token) { - config.headers.Authorization = `Bearer ${token}`; - } - return config; - }, - (error) => Promise.reject(error), - ); - - addUrlParamsRequestInterceptor(newInstance); - - return newInstance; -}; diff --git a/components.d.ts b/components.d.ts deleted file mode 100644 index 49bad629..00000000 --- a/components.d.ts +++ /dev/null @@ -1,99 +0,0 @@ -/* eslint-disable */ -/* prettier-ignore */ -// @ts-nocheck -// Generated by unplugin-vue-components -// Read more: https://github.com/vuejs/core/pull/3399 -export {} - -declare module 'vue' { - export interface GlobalComponents { - ArcCircleRender: typeof import('./src/components/renders/ArcCircleRender.vue')['default'] - BAlert: typeof import('bootstrap-vue-next')['BAlert'] - BBadge: typeof import('bootstrap-vue-next')['BBadge'] - BButton: typeof import('bootstrap-vue-next')['BButton'] - BButtonGroup: typeof import('bootstrap-vue-next')['BButtonGroup'] - BButtonToolbar: typeof import('bootstrap-vue-next')['BButtonToolbar'] - BCard: typeof import('bootstrap-vue-next')['BCard'] - BCardGroup: typeof import('bootstrap-vue-next')['BCardGroup'] - BCardText: typeof import('bootstrap-vue-next')['BCardText'] - BCarousel: typeof import('bootstrap-vue-next')['BCarousel'] - BCarouselSlide: typeof import('bootstrap-vue-next')['BCarouselSlide'] - BCol: typeof import('bootstrap-vue-next')['BCol'] - BCollapse: typeof import('bootstrap-vue-next')['BCollapse'] - BContainer: typeof import('bootstrap-vue-next')['BContainer'] - BDropdown: typeof import('bootstrap-vue-next')['BDropdown'] - BDropdownItem: typeof import('bootstrap-vue-next')['BDropdownItem'] - BFormCheckbox: typeof import('bootstrap-vue-next')['BFormCheckbox'] - BFormGroup: typeof import('bootstrap-vue-next')['BFormGroup'] - BFormInput: typeof import('bootstrap-vue-next')['BFormInput'] - BFormRadio: typeof import('bootstrap-vue-next')['BFormRadio'] - BFormSelect: typeof import('bootstrap-vue-next')['BFormSelect'] - BFormSelectOption: typeof import('bootstrap-vue-next')['BFormSelectOption'] - BImg: typeof import('bootstrap-vue-next')['BImg'] - BLink: typeof import('bootstrap-vue-next')['BLink'] - BModal: typeof import('bootstrap-vue-next')['BModal'] - BNavbar: typeof import('bootstrap-vue-next')['BNavbar'] - BNavbarBrand: typeof import('bootstrap-vue-next')['BNavbarBrand'] - BNavbarToggle: typeof import('bootstrap-vue-next')['BNavbarToggle'] - BPopover: typeof import('bootstrap-vue-next')['BPopover'] - BProgress: typeof import('bootstrap-vue-next')['BProgress'] - BProgressBar: typeof import('bootstrap-vue-next')['BProgressBar'] - BRow: typeof import('bootstrap-vue-next')['BRow'] - BTab: typeof import('bootstrap-vue-next')['BTab'] - BTabs: typeof import('bootstrap-vue-next')['BTabs'] - ConfirmEditMultipleValues: typeof import('./src/components/ConfirmEditMultipleValues.vue')['default'] - Default: typeof import('./src/layouts/default.vue')['default'] - Dimensions: typeof import('./src/components/Dimensions.vue')['default'] - EdgeCanvas: typeof import('./src/components/EdgeCanvas.vue')['default'] - EdgeGallery: typeof import('./src/components/EdgeGallery.vue')['default'] - EdgeLink: typeof import('./src/components/EdgeLink.vue')['default'] - FillRender: typeof import('./src/components/renders/FillRender.vue')['default'] - FormColorInputRow: typeof import('./src/components/FormColorInputRow.vue')['default'] - FormInputRow: typeof import('./src/components/FormInputRow.vue')['default'] - Gallery: typeof import('./src/components/Gallery.vue')['default'] - GradientRender: typeof import('./src/components/renders/GradientRender.vue')['default'] - IBiArchive: typeof import('~icons/bi/archive')['default'] - IBiArrowDownSquareFill: typeof import('~icons/bi/arrow-down-square-fill')['default'] - IBiArrowsAngleExpand: typeof import('~icons/bi/arrows-angle-expand')['default'] - IBiArrowUpSquareFill: typeof import('~icons/bi/arrow-up-square-fill')['default'] - IBiCamera: typeof import('~icons/bi/camera')['default'] - IBiCheck: typeof import('~icons/bi/check')['default'] - IBiCloudArrowUpFill: typeof import('~icons/bi/cloud-arrow-up-fill')['default'] - IBiEmojiFrownFill: typeof import('~icons/bi/emoji-frown-fill')['default'] - IBiEmojiNeutralFill: typeof import('~icons/bi/emoji-neutral-fill')['default'] - IBiEmojiSmileFill: typeof import('~icons/bi/emoji-smile-fill')['default'] - IBiEyeFill: typeof import('~icons/bi/eye-fill')['default'] - IBiEyeSlashFill: typeof import('~icons/bi/eye-slash-fill')['default'] - IBiFront: typeof import('~icons/bi/front')['default'] - IBiHouse: typeof import('~icons/bi/house')['default'] - IBiInfoCircleFill: typeof import('~icons/bi/info-circle-fill')['default'] - IBiPencil: typeof import('~icons/bi/pencil')['default'] - IBiX: typeof import('~icons/bi/x')['default'] - IBiXSquareFill: typeof import('~icons/bi/x-square-fill')['default'] - ImageRender: typeof import('./src/components/renders/ImageRender.vue')['default'] - Issue: typeof import('./src/components/from-dm/Issue.vue')['default'] - IssueSelect: typeof import('./src/components/IssueSelect.vue')['default'] - Medal: typeof import('./src/components/from-dm/Medal.vue')['default'] - MedalProgress: typeof import('./src/components/from-dm/MedalProgress.vue')['default'] - ModelEdit: typeof import('./src/components/ModelEdit.vue')['default'] - MultipleTargetOptions: typeof import('./src/components/MultipleTargetOptions.vue')['default'] - PolygonRender: typeof import('./src/components/renders/PolygonRender.vue')['default'] - Popover: typeof import('./src/components/Popover.vue')['default'] - PositionHelper: typeof import('./src/components/PositionHelper.vue')['default'] - Publication: typeof import('./src/components/from-dm/Publication.vue')['default'] - PublishedEdge: typeof import('./src/components/PublishedEdge.vue')['default'] - RectangleRender: typeof import('./src/components/renders/RectangleRender.vue')['default'] - RouterLink: typeof import('vue-router')['RouterLink'] - RouterView: typeof import('vue-router')['RouterView'] - SaveModelButton: typeof import('./src/components/SaveModelButton.vue')['default'] - SessionInfo: typeof import('./src/components/SessionInfo.vue')['default'] - StapleRender: typeof import('./src/components/renders/StapleRender.vue')['default'] - TextRender: typeof import('./src/components/renders/TextRender.vue')['default'] - TopBar: typeof import('./src/components/TopBar.vue')['default'] - Upload: typeof import('./src/components/Upload.vue')['default'] - UploadableEdgesCarousel: typeof import('./src/components/from-dm/UploadableEdgesCarousel.vue')['default'] - } - export interface ComponentCustomProperties { - vBTooltip: typeof import('bootstrap-vue-next')['vBTooltip'] - } -} diff --git a/package.json b/package.json index d92f561b..a77a0881 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,18 @@ { - "name": "edgecreator", + "name": "~edgecreator", "type": "module", + "files": [ + "dist" + ], "engines": { "node": ">=18.0.0 <19.0.0" }, "scripts": { "build": "vite build", - "dev": "concurrently -n front,back \"pnpm run start:front\" \"pnpm run start:back\"", + "dev": "concurrently -n vite,vue-tsc \"vite --port 8002\" \"vue-tsc --noEmit --watch\"", "lint": "eslint --fix --cache .", "prepare": "husky install", "preview": "vite preview", - "start:back": "cd api && pnpm run dev", - "start:front": "concurrently -n vite,vue-tsc \"vite --port 8002\" \"vue-tsc --noEmit --watch\"", "typecheck": "vue-tsc --noEmit" }, "dependencies": { @@ -27,14 +28,15 @@ "@uppy/xhr-upload": "^1.7.5", "@vueuse/core": "^10.9.0", "@vueuse/integrations": "^10.9.0", - "axios": "^1.6.8", + "axios": "^1.7.0", "axios-cache-interceptor": "^1.5.2", "bootstrap": "^5.3.3", - "bootstrap-vue-next": "^0.17.6", + "bootstrap-vue-next": "^0.18.0", "cropperjs": "^1.6.2", "interactjs": "^1.10.27", + "js-cookie": "^3.0.5", "pinia": "^2.1.7", - "sass": "^1.77.1", + "sass": "^1.77.2", "universal-cookie": "^4.0.4", "vue": "^3.4.27", "vue-cropperjs": "^5.0.0", @@ -42,13 +44,18 @@ "vue-router": "^4.3.2", "vue3-simple-typeahead": "^1.0.11", "xmldom": "^0.6.0", - "~prisma-clients": "workspace:*" + "~edgecreator-api": "workspace:*", + "~prisma-clients": "workspace:*", + "~socket.io-client-services": "workspace:*", + "~web": "workspace:*" }, "devDependencies": { "@iconify-json/bi": "^1.1.23", - "@intlify/unplugin-vue-i18n": "^0.11.0", - "@rushstack/eslint-patch": "^1.10.2", + "@intlify/unplugin-vue-i18n": "^4.0.0", + "@rushstack/eslint-patch": "^1.10.3", + "@types/eslint": "^8.56.10", "@types/js-cookie": "^3.0.6", + "@types/node": "^18.19.33", "@types/vue-cropperjs": "^4.1.6", "@types/xmldom": "^0.1.34", "@typescript-eslint/eslint-plugin": "^6.21.0", @@ -60,7 +67,7 @@ "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier-vue": "^5.0.0", - "eslint-plugin-simple-import-sort": "^10.0.0", + "eslint-plugin-simple-import-sort": "^12.1.0", "eslint-plugin-unused-imports": "^3.2.0", "eslint-plugin-vue": "^9.26.0", "husky": "^8.0.3", @@ -72,7 +79,7 @@ "vite": "^5.2.11", "vite-plugin-pages": "^0.32.1", "vite-plugin-vue-layouts": "^0.11.0", - "vue-tsc": "^1.8.27" + "vue-tsc": "^2.0.19" }, "eslintConfig": { "extends": "@antfu" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4cc94524..a95e1872 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,31 +43,34 @@ importers: version: 10.9.0(vue@3.4.27(typescript@5.4.5)) '@vueuse/integrations': specifier: ^10.9.0 - version: 10.9.0(axios@1.6.8)(universal-cookie@4.0.4)(vue@3.4.27(typescript@5.4.5)) + version: 10.9.0(axios@1.7.0)(universal-cookie@4.0.4)(vue@3.4.27(typescript@5.4.5)) axios: - specifier: ^1.6.8 - version: 1.6.8 + specifier: ^1.7.0 + version: 1.7.0 axios-cache-interceptor: specifier: ^1.5.2 - version: 1.5.2(axios@1.6.8) + version: 1.5.2(axios@1.7.0) bootstrap: specifier: ^5.3.3 version: 5.3.3(@popperjs/core@2.11.8) bootstrap-vue-next: - specifier: ^0.17.6 - version: 0.17.6(vue@3.4.27(typescript@5.4.5)) + specifier: ^0.18.0 + version: 0.18.0(vue@3.4.27(typescript@5.4.5)) cropperjs: specifier: ^1.6.2 version: 1.6.2 interactjs: specifier: ^1.10.27 version: 1.10.27 + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 pinia: specifier: ^2.1.7 version: 2.1.7(typescript@5.4.5)(vue@3.4.27(typescript@5.4.5)) sass: - specifier: ^1.77.1 - version: 1.77.1 + specifier: ^1.77.2 + version: 1.77.2 universal-cookie: specifier: ^4.0.4 version: 4.0.4 @@ -89,22 +92,37 @@ importers: xmldom: specifier: ^0.6.0 version: 0.6.0 + ~edgecreator-api: + specifier: workspace:* + version: link:api ~prisma-clients: specifier: workspace:* version: link:../../packages/prisma-clients + ~socket.io-client-services: + specifier: workspace:* + version: link:../../packages/socket.io-client-services + ~web: + specifier: workspace:* + version: link:../web devDependencies: '@iconify-json/bi': specifier: ^1.1.23 version: 1.1.23 '@intlify/unplugin-vue-i18n': - specifier: ^0.11.0 - version: 0.11.0(rollup@4.17.2)(vue-i18n@9.13.1(vue@3.4.27(typescript@5.4.5))) + specifier: ^4.0.0 + version: 4.0.0(rollup@4.17.2)(vue-i18n@9.13.1(vue@3.4.27(typescript@5.4.5))) '@rushstack/eslint-patch': - specifier: ^1.10.2 - version: 1.10.2 + specifier: ^1.10.3 + version: 1.10.3 + '@types/eslint': + specifier: ^8.56.10 + version: 8.56.10 '@types/js-cookie': specifier: ^3.0.6 version: 3.0.6 + '@types/node': + specifier: ^18.19.33 + version: 18.19.33 '@types/vue-cropperjs': specifier: ^4.1.6 version: 4.1.6 @@ -119,7 +137,7 @@ importers: version: 6.21.0(eslint@8.57.0)(typescript@5.4.5) '@vitejs/plugin-vue': specifier: ^5.0.4 - version: 5.0.4(vite@5.2.11(sass@1.77.1))(vue@3.4.27(typescript@5.4.5)) + version: 5.0.4(vite@5.2.11(@types/node@18.19.33)(sass@1.77.2))(vue@3.4.27(typescript@5.4.5)) '@vue/eslint-config-prettier': specifier: ^7.1.0 version: 7.1.0(eslint@8.57.0)(prettier@3.2.5) @@ -139,8 +157,8 @@ importers: specifier: ^5.0.0 version: 5.0.0 eslint-plugin-simple-import-sort: - specifier: ^10.0.0 - version: 10.0.0(eslint@8.57.0) + specifier: ^12.1.0 + version: 12.1.0(eslint@8.57.0) eslint-plugin-unused-imports: specifier: ^3.2.0 version: 3.2.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) @@ -167,16 +185,16 @@ importers: version: 0.27.0(@babel/parser@7.24.5)(rollup@4.17.2)(vue@3.4.27(typescript@5.4.5)) vite: specifier: ^5.2.11 - version: 5.2.11(sass@1.77.1) + version: 5.2.11(@types/node@18.19.33)(sass@1.77.2) vite-plugin-pages: specifier: ^0.32.1 - version: 0.32.1(@vue/compiler-sfc@3.4.27)(vite@5.2.11(sass@1.77.1)) + version: 0.32.1(@vue/compiler-sfc@3.4.27)(vite@5.2.11(@types/node@18.19.33)(sass@1.77.2)) vite-plugin-vue-layouts: specifier: ^0.11.0 - version: 0.11.0(vite@5.2.11(sass@1.77.1))(vue-router@4.3.2(vue@3.4.27(typescript@5.4.5)))(vue@3.4.27(typescript@5.4.5)) + version: 0.11.0(vite@5.2.11(@types/node@18.19.33)(sass@1.77.2))(vue-router@4.3.2(vue@3.4.27(typescript@5.4.5)))(vue@3.4.27(typescript@5.4.5)) vue-tsc: - specifier: ^1.8.27 - version: 1.8.27(typescript@5.4.5) + specifier: ^2.0.19 + version: 2.0.19(typescript@5.4.5) packages: @@ -366,8 +384,8 @@ packages: resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@floating-ui/core@1.6.1': - resolution: {integrity: sha512-42UH54oPZHPdRHdw6BgoBD6cg/eVTmVrFcgeRDM3jbO7uxSoipVcmcIGFcA5jmOHO5apcyvBhkSKES3fQJnu7A==} + '@floating-ui/core@1.6.2': + resolution: {integrity: sha512-+2XpQV9LLZeanU4ZevzRnGFg2neDeKHgFLjP6YLW+tly0IvrhqT4u8enLGjLH3qeh85g19xY5rsAusfwTdn5lg==} '@floating-ui/dom@1.6.5': resolution: {integrity: sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==} @@ -401,8 +419,8 @@ packages: '@interactjs/types@1.10.27': resolution: {integrity: sha512-BUdv0cvs4H5ODuwft2Xp4eL8Vmi3LcihK42z0Ft/FbVJZoRioBsxH+LlsBdK4tAie7PqlKGy+1oyOncu1nQ6eA==} - '@intlify/bundle-utils@6.0.1': - resolution: {integrity: sha512-BkeZNKZiC0B7K3OYMwiPLoAqsZmKH3SxTL75vYAkuQ//XWR8WO0NpfjXhTxgLTVFHxMcNb2agAopC0DP6fqDrg==} + '@intlify/bundle-utils@8.0.0': + resolution: {integrity: sha512-1B++zykRnMwQ+20SpsZI1JCnV/YJt9Oq7AGlEurzkWJOFtFAVqaGc/oV36PBRYeiKnTbY9VYfjBimr2Vt42wLQ==} engines: {node: '>= 14.16'} peerDependencies: petite-vue-i18n: '*' @@ -421,20 +439,12 @@ packages: resolution: {integrity: sha512-SKsVa4ajYGBVm7sHMXd5qX70O2XXjm55zdZB3VeMFCvQyvLew/dLvq3MqnaIsTMF1VkkOb9Ttr6tHcMlyPDL9w==} engines: {node: '>= 16'} - '@intlify/message-compiler@9.3.0-beta.17': - resolution: {integrity: sha512-i7hvVIRk1Ax2uKa9xLRJCT57to08OhFMhFXXjWN07rmx5pWQYQ23MfX1xgggv9drnWTNhqEiD+u4EJeHoS5+Ww==} - engines: {node: '>= 14'} - '@intlify/shared@9.13.1': resolution: {integrity: sha512-u3b6BKGhE6j/JeRU6C/RL2FgyJfy6LakbtfeVF8fJXURpZZTzfh3e05J0bu0XPw447Q6/WUp3C4ajv4TMS4YsQ==} engines: {node: '>= 16'} - '@intlify/shared@9.3.0-beta.17': - resolution: {integrity: sha512-mscf7RQsUTOil35jTij4KGW1RC9SWQjYScwLxP53Ns6g24iEd5HN7ksbt9O6FvTmlQuX77u+MXpBdfJsGqizLQ==} - engines: {node: '>= 14'} - - '@intlify/unplugin-vue-i18n@0.11.0': - resolution: {integrity: sha512-ivcLZo08fvepHWV8o5lcKfhcKFSWqhwrqIAU6pUIbvq2ICo9fnXnIPYIZj7FeuHDLW1G3ADm44ZhQC3nYmvDlg==} + '@intlify/unplugin-vue-i18n@4.0.0': + resolution: {integrity: sha512-q2Mhqa/mLi0tulfLFO4fMXXvEbkSZpI5yGhNNsLTNJJ41icEGUuyDe+j5zRZIKSkOJRgX6YbCyibTDJdRsukmw==} engines: {node: '>= 14.16'} peerDependencies: petite-vue-i18n: '*' @@ -563,8 +573,8 @@ packages: cpu: [x64] os: [win32] - '@rushstack/eslint-patch@1.10.2': - resolution: {integrity: sha512-hw437iINopmQuxWPSUEvqE56NCPsiU8N4AYtfHmJFckclktzK9YQJieD3XkDCDH4OjL+C7zgPUh73R/nrcHrqw==} + '@rushstack/eslint-patch@1.10.3': + resolution: {integrity: sha512-qC/xYId4NMebE6w/V33Fh9gWxLgURiNYgVNObbJl2LZv0GUUItCcCqC5axQSwRaAgaxl2mELq1rMzlswaQ0Zxg==} '@transloadit/prettier-bytes@0.0.7': resolution: {integrity: sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA==} @@ -575,6 +585,9 @@ packages: '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/eslint@8.56.10': + resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==} + '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} @@ -587,6 +600,9 @@ packages: '@types/ms@0.7.34': resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + '@types/node@18.19.33': + resolution: {integrity: sha512-NR9+KrpSajr2qBVp/Yt5TU/rp+b5Mayi3+OlMlcg2cVCfRmcG5PWZ7S4+MG9PZ5gWBoc9Pd0BKSRViuBCRPu0A==} + '@types/semver@7.5.8': resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} @@ -799,14 +815,14 @@ packages: vite: ^5.0.0 vue: ^3.2.25 - '@volar/language-core@1.11.1': - resolution: {integrity: sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==} + '@volar/language-core@2.2.4': + resolution: {integrity: sha512-7As47GndxGxsqqYnbreLrfB5NDUeQioPM2LJKUuB4/34c0NpEJ2byVl3c9KYdjIdiEstWZ9JLtLKNTaPWb5jtA==} - '@volar/source-map@1.11.1': - resolution: {integrity: sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==} + '@volar/source-map@2.2.4': + resolution: {integrity: sha512-m92FLpR9vB1YEZfiZ+bfgpLrToL/DNkOrorWVep3pffHrwwI4Tx2oIQN+sqHJfKkiT5N3J1owC+8crhAEinfjg==} - '@volar/typescript@1.11.1': - resolution: {integrity: sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==} + '@volar/typescript@2.2.4': + resolution: {integrity: sha512-uAQC53tgEbHO62G8NXMfmBrJAlP2QJ9WxVEEQqqK3I6VSy8frL5LbH3hAWODxiwMWixv74wJLWlKbWXOgdIoRQ==} '@vue/compiler-core@3.4.27': resolution: {integrity: sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==} @@ -843,8 +859,8 @@ packages: typescript: optional: true - '@vue/language-core@1.8.27': - resolution: {integrity: sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==} + '@vue/language-core@2.0.19': + resolution: {integrity: sha512-A9EGOnvb51jOvnCYoRLnMP+CcoPlbZVxI9gZXE/y2GksRWM6j/PrLEIC++pnosWTN08tFpJgxhSS//E9v/Sg+Q==} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -926,11 +942,6 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@7.4.1: - resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} - engines: {node: '>=0.4.0'} - hasBin: true - acorn@8.11.3: resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} engines: {node: '>=0.4.0'} @@ -975,8 +986,8 @@ packages: peerDependencies: axios: ^1 - axios@1.6.8: - resolution: {integrity: sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==} + axios@1.7.0: + resolution: {integrity: sha512-IiB0wQeKyPRdsFVhBgIo31FbzOyf2M6wYl7/NVutFwFBRMiAbjNiydJIHKeLmPugF4kJLfA1uWZ82Is2QzqqFA==} balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -988,10 +999,10 @@ packages: boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - bootstrap-vue-next@0.17.6: - resolution: {integrity: sha512-dfZdJEVlpmzVLGJUY15+yWBqC3iMd9iItBwVQ1FRcPcGUoziU45KcdF+YdEMHmRaVuT0VKfC96wpTFTeHrA0Mw==} + bootstrap-vue-next@0.18.0: + resolution: {integrity: sha512-/j+RlrruU0X7JIhKUDleCelWTojBDzQRBUHstFYXvnso+P6TcTllGDqPpr+NJIolZnaqnOF4LoMPr0QwveBmAA==} peerDependencies: - vue: ^3.4.21 + vue: ^3.4.27 bootstrap@5.3.3: resolution: {integrity: sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==} @@ -1195,8 +1206,8 @@ packages: eslint-config-prettier: optional: true - eslint-plugin-simple-import-sort@10.0.0: - resolution: {integrity: sha512-AeTvO9UCMSNzIHRkg8S6c3RPy5YEwKWSQPx3DYghLedo2ZQxowPFLGDN1AZ2evfg6r6mjBSZSLxLFsWSu3acsw==} + eslint-plugin-simple-import-sort@12.1.0: + resolution: {integrity: sha512-Y2fqAfC11TcG/WP3TrI1Gi3p3nc8XJyEOJYHyEPEGI/UAgNx6akxxlX74p7SbAQdLcgASKhj8M0GKvH3vq/+ig==} peerDependencies: eslint: '>=5.0.0' @@ -1228,14 +1239,6 @@ packages: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint-utils@2.1.0: - resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} - engines: {node: '>=6'} - - eslint-visitor-keys@1.3.0: - resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} - engines: {node: '>=4'} - eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1245,10 +1248,6 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true - espree@6.2.1: - resolution: {integrity: sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==} - engines: {node: '>=6.0.0'} - espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1453,8 +1452,8 @@ packages: resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} - immutable@4.3.5: - resolution: {integrity: sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==} + immutable@4.3.6: + resolution: {integrity: sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==} import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} @@ -1576,6 +1575,10 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} + js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true @@ -1594,9 +1597,9 @@ packages: engines: {node: '>=6'} hasBin: true - jsonc-eslint-parser@1.4.1: - resolution: {integrity: sha512-hXBrvsR1rdjmB2kQmUjf1rEIa+TqHBGMge8pwi++C+Si1ad7EjZrJcpgwym+QGK/pqTx+K7keFAtLlVNdLRJOg==} - engines: {node: '>=8.10.0'} + jsonc-eslint-parser@2.4.0: + resolution: {integrity: sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -1681,8 +1684,8 @@ packages: ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - muggle-string@0.3.1: - resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==} + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} namespace-emitter@2.0.1: resolution: {integrity: sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g==} @@ -1779,8 +1782,8 @@ packages: pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -1898,18 +1901,14 @@ packages: rxjs@7.8.1: resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} - sass@1.77.1: - resolution: {integrity: sha512-OMEyfirt9XEfyvocduUIOlUSkWOXS/LAt6oblR/ISXCTukyavjex+zQNm51pPCOiFKY1QpWvEH1EeCkgyV3I6w==} + sass@1.77.2: + resolution: {integrity: sha512-eb4GZt1C3avsX3heBNlrc7I09nyT00IUuo4eFhAbeXWU2fvA7oXI53SxODVAA+zgZCk9aunAZgO+losjR3fAwA==} engines: {node: '>=14.0.0'} hasBin: true scule@1.3.0: resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - semver@7.6.2: resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} engines: {node: '>=10'} @@ -2052,6 +2051,9 @@ packages: ufo@1.5.3: resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + unhead@1.9.10: resolution: {integrity: sha512-Y3w+j1x1YFig2YuE+W2sER+SciRR7MQktYRHNqvZJ0iUNCCJTS8Z/SdSMUEeuFV28daXeASlR3fy7Ry3O2indg==} @@ -2199,8 +2201,8 @@ packages: vue-template-compiler@2.7.16: resolution: {integrity: sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==} - vue-tsc@1.8.27: - resolution: {integrity: sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==} + vue-tsc@2.0.19: + resolution: {integrity: sha512-JWay5Zt2/871iodGF72cELIbcAoPyhJxq56mPPh+M2K7IwI688FMrFKc/+DvB05wDWEuCPexQJ6L10zSwzzapg==} hasBin: true peerDependencies: typescript: '*' @@ -2272,12 +2274,9 @@ packages: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} - yaml-eslint-parser@0.3.2: - resolution: {integrity: sha512-32kYO6kJUuZzqte82t4M/gB6/+11WAuHiEnK7FreMo20xsCKPeFH5tDBU7iWxR7zeJpNnMXfJyXwne48D0hGrg==} - - yaml@1.10.2: - resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} - engines: {node: '>= 6'} + yaml-eslint-parser@1.2.2: + resolution: {integrity: sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg==} + engines: {node: ^14.17.0 || >=16.0.0} yaml@2.4.2: resolution: {integrity: sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==} @@ -2422,13 +2421,13 @@ snapshots: '@eslint/js@8.57.0': {} - '@floating-ui/core@1.6.1': + '@floating-ui/core@1.6.2': dependencies: '@floating-ui/utils': 0.2.2 '@floating-ui/dom@1.6.5': dependencies: - '@floating-ui/core': 1.6.1 + '@floating-ui/core': 1.6.2 '@floating-ui/utils': 0.2.2 '@floating-ui/utils@0.2.2': {} @@ -2474,18 +2473,17 @@ snapshots: '@interactjs/types@1.10.27': {} - '@intlify/bundle-utils@6.0.1(vue-i18n@9.13.1(vue@3.4.27(typescript@5.4.5)))': + '@intlify/bundle-utils@8.0.0(vue-i18n@9.13.1(vue@3.4.27(typescript@5.4.5)))': dependencies: - '@intlify/message-compiler': 9.3.0-beta.17 - '@intlify/shared': 9.3.0-beta.17 + '@intlify/message-compiler': 9.13.1 + '@intlify/shared': 9.13.1 acorn: 8.11.3 escodegen: 2.1.0 estree-walker: 2.0.2 - jsonc-eslint-parser: 1.4.1 - magic-string: 0.30.10 + jsonc-eslint-parser: 2.4.0 mlly: 1.7.0 - source-map: 0.6.1 - yaml-eslint-parser: 0.3.2 + source-map-js: 1.2.0 + yaml-eslint-parser: 1.2.2 optionalDependencies: vue-i18n: 9.13.1(vue@3.4.27(typescript@5.4.5)) @@ -2499,19 +2497,12 @@ snapshots: '@intlify/shared': 9.13.1 source-map-js: 1.2.0 - '@intlify/message-compiler@9.3.0-beta.17': - dependencies: - '@intlify/shared': 9.3.0-beta.17 - source-map: 0.6.1 - '@intlify/shared@9.13.1': {} - '@intlify/shared@9.3.0-beta.17': {} - - '@intlify/unplugin-vue-i18n@0.11.0(rollup@4.17.2)(vue-i18n@9.13.1(vue@3.4.27(typescript@5.4.5)))': + '@intlify/unplugin-vue-i18n@4.0.0(rollup@4.17.2)(vue-i18n@9.13.1(vue@3.4.27(typescript@5.4.5)))': dependencies: - '@intlify/bundle-utils': 6.0.1(vue-i18n@9.13.1(vue@3.4.27(typescript@5.4.5))) - '@intlify/shared': 9.3.0-beta.17 + '@intlify/bundle-utils': 8.0.0(vue-i18n@9.13.1(vue@3.4.27(typescript@5.4.5))) + '@intlify/shared': 9.13.1 '@rollup/pluginutils': 5.1.0(rollup@4.17.2) '@vue/compiler-sfc': 3.4.27 debug: 4.3.4 @@ -2519,8 +2510,8 @@ snapshots: js-yaml: 4.1.0 json5: 2.2.3 pathe: 1.1.2 - picocolors: 1.0.0 - source-map: 0.6.1 + picocolors: 1.0.1 + source-map-js: 1.2.0 unplugin: 1.10.1 optionalDependencies: vue-i18n: 9.13.1(vue@3.4.27(typescript@5.4.5)) @@ -2609,7 +2600,7 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.17.2': optional: true - '@rushstack/eslint-patch@1.10.2': {} + '@rushstack/eslint-patch@1.10.3': {} '@transloadit/prettier-bytes@0.0.7': {} @@ -2619,6 +2610,11 @@ snapshots: dependencies: '@types/ms': 0.7.34 + '@types/eslint@8.56.10': + dependencies: + '@types/estree': 1.0.5 + '@types/json-schema': 7.0.15 + '@types/estree@1.0.5': {} '@types/js-cookie@3.0.6': {} @@ -2627,6 +2623,10 @@ snapshots: '@types/ms@0.7.34': {} + '@types/node@18.19.33': + dependencies: + undici-types: 5.26.5 + '@types/semver@7.5.8': {} '@types/vue-cropperjs@4.1.6': @@ -2931,22 +2931,22 @@ snapshots: '@uppy/utils': 3.6.2 cuid: 2.1.8 - '@vitejs/plugin-vue@5.0.4(vite@5.2.11(sass@1.77.1))(vue@3.4.27(typescript@5.4.5))': + '@vitejs/plugin-vue@5.0.4(vite@5.2.11(@types/node@18.19.33)(sass@1.77.2))(vue@3.4.27(typescript@5.4.5))': dependencies: - vite: 5.2.11(sass@1.77.1) + vite: 5.2.11(@types/node@18.19.33)(sass@1.77.2) vue: 3.4.27(typescript@5.4.5) - '@volar/language-core@1.11.1': + '@volar/language-core@2.2.4': dependencies: - '@volar/source-map': 1.11.1 + '@volar/source-map': 2.2.4 - '@volar/source-map@1.11.1': + '@volar/source-map@2.2.4': dependencies: - muggle-string: 0.3.1 + muggle-string: 0.4.1 - '@volar/typescript@1.11.1': + '@volar/typescript@2.2.4': dependencies: - '@volar/language-core': 1.11.1 + '@volar/language-core': 2.2.4 path-browserify: 1.0.1 '@vue/compiler-core@3.4.27': @@ -3008,15 +3008,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@vue/language-core@1.8.27(typescript@5.4.5)': + '@vue/language-core@2.0.19(typescript@5.4.5)': dependencies: - '@volar/language-core': 1.11.1 - '@volar/source-map': 1.11.1 + '@volar/language-core': 2.2.4 '@vue/compiler-dom': 3.4.27 '@vue/shared': 3.4.27 computeds: 0.0.1 minimatch: 9.0.4 - muggle-string: 0.3.1 path-browserify: 1.0.1 vue-template-compiler: 2.7.16 optionalDependencies: @@ -3055,13 +3053,13 @@ snapshots: - '@vue/composition-api' - vue - '@vueuse/integrations@10.9.0(axios@1.6.8)(universal-cookie@4.0.4)(vue@3.4.27(typescript@5.4.5))': + '@vueuse/integrations@10.9.0(axios@1.7.0)(universal-cookie@4.0.4)(vue@3.4.27(typescript@5.4.5))': dependencies: '@vueuse/core': 10.9.0(vue@3.4.27(typescript@5.4.5)) '@vueuse/shared': 10.9.0(vue@3.4.27(typescript@5.4.5)) vue-demi: 0.14.7(vue@3.4.27(typescript@5.4.5)) optionalDependencies: - axios: 1.6.8 + axios: 1.7.0 universal-cookie: 4.0.4 transitivePeerDependencies: - '@vue/composition-api' @@ -3078,16 +3076,10 @@ snapshots: abortcontroller-polyfill@1.7.5: {} - acorn-jsx@5.3.2(acorn@7.4.1): - dependencies: - acorn: 7.4.1 - acorn-jsx@5.3.2(acorn@8.11.3): dependencies: acorn: 8.11.3 - acorn@7.4.1: {} - acorn@8.11.3: {} ajv@6.12.6: @@ -3123,14 +3115,14 @@ snapshots: dependencies: possible-typed-array-names: 1.0.0 - axios-cache-interceptor@1.5.2(axios@1.6.8): + axios-cache-interceptor@1.5.2(axios@1.7.0): dependencies: - axios: 1.6.8 + axios: 1.7.0 cache-parser: 1.2.4 fast-defer: 1.1.8 object-code: 1.3.3 - axios@1.6.8: + axios@1.7.0: dependencies: follow-redirects: 1.15.6 form-data: 4.0.0 @@ -3144,7 +3136,7 @@ snapshots: boolbase@1.0.0: {} - bootstrap-vue-next@0.17.6(vue@3.4.27(typescript@5.4.5)): + bootstrap-vue-next@0.18.0(vue@3.4.27(typescript@5.4.5)): dependencies: '@floating-ui/vue': 1.0.6(vue@3.4.27(typescript@5.4.5)) '@vueuse/core': 10.9.0(vue@3.4.27(typescript@5.4.5)) @@ -3380,7 +3372,7 @@ snapshots: eslint-plugin-prettier-vue@5.0.0: dependencies: '@vue/compiler-sfc': 3.4.27 - picocolors: 1.0.0 + picocolors: 1.0.1 prettier: 3.2.5 prettier-linter-helpers: 1.0.0 synckit: 0.8.8 @@ -3393,7 +3385,7 @@ snapshots: optionalDependencies: eslint-config-prettier: 8.10.0(eslint@8.57.0) - eslint-plugin-simple-import-sort@10.0.0(eslint@8.57.0): + eslint-plugin-simple-import-sort@12.1.0(eslint@8.57.0): dependencies: eslint: 8.57.0 @@ -3430,12 +3422,6 @@ snapshots: esrecurse: 4.3.0 estraverse: 5.3.0 - eslint-utils@2.1.0: - dependencies: - eslint-visitor-keys: 1.3.0 - - eslint-visitor-keys@1.3.0: {} - eslint-visitor-keys@3.4.3: {} eslint@8.57.0: @@ -3481,12 +3467,6 @@ snapshots: transitivePeerDependencies: - supports-color - espree@6.2.1: - dependencies: - acorn: 7.4.1 - acorn-jsx: 5.3.2(acorn@7.4.1) - eslint-visitor-keys: 1.3.0 - espree@9.6.1: dependencies: acorn: 8.11.3 @@ -3680,7 +3660,7 @@ snapshots: ignore@5.3.1: {} - immutable@4.3.5: {} + immutable@4.3.6: {} import-fresh@3.3.0: dependencies: @@ -3791,6 +3771,8 @@ snapshots: isexe@2.0.0: {} + js-cookie@3.0.5: {} + js-yaml@4.1.0: dependencies: argparse: 2.0.1 @@ -3803,13 +3785,12 @@ snapshots: json5@2.2.3: {} - jsonc-eslint-parser@1.4.1: + jsonc-eslint-parser@2.4.0: dependencies: - acorn: 7.4.1 - eslint-utils: 2.1.0 - eslint-visitor-keys: 1.3.0 - espree: 6.2.1 - semver: 6.3.1 + acorn: 8.11.3 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + semver: 7.6.2 keyv@4.5.4: dependencies: @@ -3889,7 +3870,7 @@ snapshots: ms@2.1.2: {} - muggle-string@0.3.1: {} + muggle-string@0.4.1: {} namespace-emitter@2.0.1: {} @@ -3972,7 +3953,7 @@ snapshots: pathe@1.1.2: {} - picocolors@1.0.0: {} + picocolors@1.0.1: {} picomatch@2.3.1: {} @@ -4000,7 +3981,7 @@ snapshots: postcss@8.4.38: dependencies: nanoid: 3.3.7 - picocolors: 1.0.0 + picocolors: 1.0.1 source-map-js: 1.2.0 preact@8.2.9: {} @@ -4089,16 +4070,14 @@ snapshots: dependencies: tslib: 2.6.2 - sass@1.77.1: + sass@1.77.2: dependencies: chokidar: 3.6.0 - immutable: 4.3.5 + immutable: 4.3.6 source-map-js: 1.2.0 scule@1.3.0: {} - semver@6.3.1: {} - semver@7.6.2: {} set-function-length@1.2.2: @@ -4216,6 +4195,8 @@ snapshots: ufo@1.5.3: {} + undici-types@5.26.5: {} + unhead@1.9.10: dependencies: '@unhead/dom': 1.9.10 @@ -4313,7 +4294,7 @@ snapshots: util-deprecate@1.0.2: {} - vite-plugin-pages@0.32.1(@vue/compiler-sfc@3.4.27)(vite@5.2.11(sass@1.77.1)): + vite-plugin-pages@0.32.1(@vue/compiler-sfc@3.4.27)(vite@5.2.11(@types/node@18.19.33)(sass@1.77.2)): dependencies: '@types/debug': 4.1.12 debug: 4.3.4 @@ -4322,32 +4303,33 @@ snapshots: fast-glob: 3.3.2 json5: 2.2.3 local-pkg: 0.5.0 - picocolors: 1.0.0 - vite: 5.2.11(sass@1.77.1) + picocolors: 1.0.1 + vite: 5.2.11(@types/node@18.19.33)(sass@1.77.2) yaml: 2.4.2 optionalDependencies: '@vue/compiler-sfc': 3.4.27 transitivePeerDependencies: - supports-color - vite-plugin-vue-layouts@0.11.0(vite@5.2.11(sass@1.77.1))(vue-router@4.3.2(vue@3.4.27(typescript@5.4.5)))(vue@3.4.27(typescript@5.4.5)): + vite-plugin-vue-layouts@0.11.0(vite@5.2.11(@types/node@18.19.33)(sass@1.77.2))(vue-router@4.3.2(vue@3.4.27(typescript@5.4.5)))(vue@3.4.27(typescript@5.4.5)): dependencies: debug: 4.3.4 fast-glob: 3.3.2 - vite: 5.2.11(sass@1.77.1) + vite: 5.2.11(@types/node@18.19.33)(sass@1.77.2) vue: 3.4.27(typescript@5.4.5) vue-router: 4.3.2(vue@3.4.27(typescript@5.4.5)) transitivePeerDependencies: - supports-color - vite@5.2.11(sass@1.77.1): + vite@5.2.11(@types/node@18.19.33)(sass@1.77.2): dependencies: esbuild: 0.20.2 postcss: 8.4.38 rollup: 4.17.2 optionalDependencies: + '@types/node': 18.19.33 fsevents: 2.3.3 - sass: 1.77.1 + sass: 1.77.2 vue-cropperjs@5.0.0(vue@3.4.27(typescript@5.4.5)): dependencies: @@ -4388,10 +4370,10 @@ snapshots: de-indent: 1.0.2 he: 1.2.0 - vue-tsc@1.8.27(typescript@5.4.5): + vue-tsc@2.0.19(typescript@5.4.5): dependencies: - '@volar/typescript': 1.11.1 - '@vue/language-core': 1.8.27(typescript@5.4.5) + '@volar/typescript': 2.2.4 + '@vue/language-core': 2.0.19(typescript@5.4.5) semver: 7.6.2 typescript: 5.4.5 @@ -4463,13 +4445,11 @@ snapshots: y18n@5.0.8: {} - yaml-eslint-parser@0.3.2: + yaml-eslint-parser@1.2.2: dependencies: - eslint-visitor-keys: 1.3.0 + eslint-visitor-keys: 3.4.3 lodash: 4.17.21 - yaml: 1.10.2 - - yaml@1.10.2: {} + yaml: 2.4.2 yaml@2.4.2: {} diff --git a/src/App.vue b/src/App.vue index 7274244b..3086de71 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,18 +1,73 @@ diff --git a/src/components/ConfirmEditMultipleValues.vue b/src/components/ConfirmEditMultipleValues.vue index 7f5e9573..7b008e63 100644 --- a/src/components/ConfirmEditMultipleValues.vue +++ b/src/components/ConfirmEditMultipleValues.vue @@ -21,7 +21,7 @@ diff --git a/src/components/EdgeCanvas.vue b/src/components/EdgeCanvas.vue index a0dbc503..0e6f63c4 100644 --- a/src/components/EdgeCanvas.vue +++ b/src/components/EdgeCanvas.vue @@ -85,10 +85,10 @@ diff --git a/src/components/FormColorInputRow.vue b/src/components/FormColorInputRow.vue index e7d77c4b..da1c629e 100644 --- a/src/components/FormColorInputRow.vue +++ b/src/components/FormColorInputRow.vue @@ -89,7 +89,8 @@ diff --git a/src/components/Popover.vue b/src/components/Popover.vue index 617fa1a0..972e6b97 100644 --- a/src/components/Popover.vue +++ b/src/components/Popover.vue @@ -23,10 +23,10 @@ - diff --git a/src/components/SessionInfo.vue b/src/components/SessionInfo.vue index c23b3fd8..a120f913 100644 --- a/src/components/SessionInfo.vue +++ b/src/components/SessionInfo.vue @@ -20,17 +20,16 @@ import { useI18n } from "vue-i18n"; import { availableLocales } from "~/composables/useLocales"; -import { coa } from "~/stores/coa"; -import { collection } from "~/stores/collection"; +import { stores as webStores } from "~web"; const { locale } = useI18n(); const locales = computed(() => availableLocales); -const collectionStore = collection(); +const collectionStore = webStores.collection(); const username = computed(() => collectionStore.user?.username as string); const reloadWithLocale = async (key: string) => { locale.value = key; - await coa().fetchCountryNames(locale.value); + await webStores.coa().fetchCountryNames(); };