@interware/content-generator 0.4.2 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{App-8EiV8xw6.mjs → App-BQr5_g5u.mjs} +64 -34
- package/dist/_chunks/{App-CsarVpQf.js → App-CfwvfmvL.js} +63 -33
- package/dist/_chunks/{Settings-DXyz9jmT.js → Settings-BrqTzJp-.js} +2 -2
- package/dist/_chunks/{Settings-Be27Xer1.mjs → Settings-CdZnYLLK.mjs} +2 -2
- package/dist/_chunks/{getTranslation-YJf3i4B7.mjs → getTranslation-B9ND5RaH.mjs} +1 -1
- package/dist/_chunks/{getTranslation-BODOQcEi.js → getTranslation-DNhP1INv.js} +1 -1
- package/dist/_chunks/{index-DIbmEmw5.js → index-DGPqyrzz.js} +2 -2
- package/dist/_chunks/{index-DL56cMMt.mjs → index-Dyq8dxMX.mjs} +2 -2
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/src/hooks/generate-images/useImages.d.ts +1 -0
- package/dist/server/index.js +45 -0
- package/dist/server/index.mjs +45 -0
- package/dist/server/src/controllers/controller.d.ts +1 -0
- package/dist/server/src/controllers/index.d.ts +1 -0
- package/dist/server/src/index.d.ts +2 -0
- package/dist/server/src/services/index.d.ts +1 -0
- package/dist/server/src/services/service.d.ts +1 -0
- package/package.json +1 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useRBAC, useFetchClient, useNotification, Page } from "@strapi/strapi/admin";
|
|
3
|
-
import { SubNav, SubNavHeader, SubNavSections, SubNavSection, SubNavLink, Box, Table, Thead, Tr, Th, Typography, Flex, Tbody, Td, Button, LinkButton, Dialog, Grid, Field, Textarea, TextInput, Combobox, ComboboxOption, Modal, Card, CardHeader, CardCheckbox, CardAsset, CardBody, CardContent, CardTitle, CardSubtitle, CardBadge, CardAction, IconButton, DesignSystemProvider } from "@strapi/design-system";
|
|
3
|
+
import { SubNav, SubNavHeader, SubNavSections, SubNavSection, SubNavLink, Box, Table, Thead, Tr, Th, Typography, Flex, Tbody, Td, Button, LinkButton, Dialog, Grid, Field, Textarea, TextInput, Combobox, ComboboxOption, Modal, Card, CardHeader, CardCheckbox, CardAsset, CardBody, CardContent, CardTitle, CardSubtitle, CardBadge, CardAction, IconButton, Loader, DesignSystemProvider } from "@strapi/design-system";
|
|
4
4
|
import { useLocation, useNavigate, Routes, Route } from "react-router-dom";
|
|
5
|
-
import { p as pluginPermissions, c as closeDialog, o as openDialog, P as PLUGIN_ID } from "./index-
|
|
5
|
+
import { p as pluginPermissions, c as closeDialog, o as openDialog, P as PLUGIN_ID } from "./index-Dyq8dxMX.mjs";
|
|
6
6
|
import { useIntl } from "react-intl";
|
|
7
7
|
import { useCallback, memo, useMemo, useState, useRef, useEffect, createContext, useContext } from "react";
|
|
8
8
|
import { useDispatch, useSelector } from "react-redux";
|
|
9
9
|
import { Play, ExternalLink, Image as Image$1, Download, Trash, PlusCircle } from "@strapi/icons";
|
|
10
|
-
import { g as getTranslation } from "./getTranslation-
|
|
10
|
+
import { g as getTranslation } from "./getTranslation-B9ND5RaH.mjs";
|
|
11
11
|
import { useFormik } from "formik";
|
|
12
12
|
import * as Yup from "yup";
|
|
13
13
|
const links = [
|
|
@@ -1000,8 +1000,9 @@ const ImagesProvider = ({ children }) => {
|
|
|
1000
1000
|
const { openDialog: openDialog2, closeDialog: closeDialog2 } = useDialog("dialog-delete-image");
|
|
1001
1001
|
const { formatMessage } = useIntl();
|
|
1002
1002
|
const { toggleNotification } = useNotification();
|
|
1003
|
+
const { post } = useFetchClient();
|
|
1003
1004
|
const [images, setImages] = useState([]);
|
|
1004
|
-
const [
|
|
1005
|
+
const [downloadingId, setDownloadingId] = useState(null);
|
|
1005
1006
|
const [open, setOpen] = useState(false);
|
|
1006
1007
|
const currentImageRef = useRef();
|
|
1007
1008
|
const fetchImages = useCallback(async () => {
|
|
@@ -1067,41 +1068,68 @@ const ImagesProvider = ({ children }) => {
|
|
|
1067
1068
|
return;
|
|
1068
1069
|
}
|
|
1069
1070
|
}, [openDialog2, setOpen]);
|
|
1070
|
-
const downloadImage = (url, filename) => {
|
|
1071
|
-
|
|
1072
|
-
const
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1071
|
+
const downloadImage = async (url, filename) => {
|
|
1072
|
+
if (!url) return;
|
|
1073
|
+
const absoluteUrl = url.startsWith("/uploads") ? `${window.location.origin}${url}` : url;
|
|
1074
|
+
try {
|
|
1075
|
+
const { data } = await post(
|
|
1076
|
+
"/strapi-content-generator-gemini/download-file",
|
|
1077
|
+
{ url: absoluteUrl }
|
|
1078
|
+
);
|
|
1079
|
+
const { base64, contentType } = data;
|
|
1080
|
+
const binary = atob(base64);
|
|
1081
|
+
const bytes = new Uint8Array(binary.length);
|
|
1082
|
+
for (let i = 0; i < binary.length; i++) {
|
|
1083
|
+
bytes[i] = binary.charCodeAt(i);
|
|
1084
|
+
}
|
|
1085
|
+
const blob = new Blob([bytes], { type: contentType });
|
|
1086
|
+
const blobUrl = window.URL.createObjectURL(blob);
|
|
1087
|
+
const link = document.createElement("a");
|
|
1088
|
+
link.href = blobUrl;
|
|
1089
|
+
link.download = filename;
|
|
1090
|
+
document.body.appendChild(link);
|
|
1091
|
+
link.click();
|
|
1092
|
+
document.body.removeChild(link);
|
|
1093
|
+
window.URL.revokeObjectURL(blobUrl);
|
|
1094
|
+
} catch (error) {
|
|
1095
|
+
console.error("Download error:", error);
|
|
1096
|
+
const link = document.createElement("a");
|
|
1097
|
+
link.href = absoluteUrl;
|
|
1098
|
+
link.target = "_blank";
|
|
1099
|
+
link.rel = "noopener noreferrer";
|
|
1100
|
+
document.body.appendChild(link);
|
|
1101
|
+
link.click();
|
|
1102
|
+
document.body.removeChild(link);
|
|
1103
|
+
}
|
|
1081
1104
|
};
|
|
1082
1105
|
const handleDownload = async (selectedKeys) => {
|
|
1083
1106
|
const image = currentImageRef.current;
|
|
1084
1107
|
if (!image) return;
|
|
1085
1108
|
setOpen(false);
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1109
|
+
setDownloadingId(image.documentId);
|
|
1110
|
+
try {
|
|
1111
|
+
const keys = Array.isArray(selectedKeys) ? selectedKeys : Array.from(selectedKeys);
|
|
1112
|
+
const extension = image.ext?.replace(".", "") ?? "jpg";
|
|
1113
|
+
const formats = image.formats;
|
|
1114
|
+
const items = keys.map((key) => {
|
|
1115
|
+
if (key === "principal") {
|
|
1116
|
+
return {
|
|
1117
|
+
url: image.url,
|
|
1118
|
+
filename: `image-principal-${image.documentId}.${extension}`
|
|
1119
|
+
};
|
|
1120
|
+
}
|
|
1121
|
+
const formatImage = formats?.[key];
|
|
1122
|
+
if (!formatImage) return null;
|
|
1091
1123
|
return {
|
|
1092
|
-
url:
|
|
1093
|
-
filename: `image
|
|
1124
|
+
url: formatImage.url,
|
|
1125
|
+
filename: `image-${key}-${image.documentId}.${extension}`
|
|
1094
1126
|
};
|
|
1127
|
+
}).filter(Boolean);
|
|
1128
|
+
for (const item of items) {
|
|
1129
|
+
await downloadImage(item.url, item.filename);
|
|
1095
1130
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
return {
|
|
1099
|
-
url: formatImage.url,
|
|
1100
|
-
filename: `image-${key}-${image.documentId}.${extension}`
|
|
1101
|
-
};
|
|
1102
|
-
}).filter(Boolean);
|
|
1103
|
-
for (const item of items) {
|
|
1104
|
-
await downloadImage(item.url, item.filename);
|
|
1131
|
+
} finally {
|
|
1132
|
+
setDownloadingId(null);
|
|
1105
1133
|
}
|
|
1106
1134
|
};
|
|
1107
1135
|
useEffect(() => {
|
|
@@ -1130,7 +1158,7 @@ const ImagesProvider = ({ children }) => {
|
|
|
1130
1158
|
] })
|
|
1131
1159
|
}
|
|
1132
1160
|
),
|
|
1133
|
-
/* @__PURE__ */ jsx(ImagesContext.Provider, { value: { images, onClickAction }, children })
|
|
1161
|
+
/* @__PURE__ */ jsx(ImagesContext.Provider, { value: { images, downloadingId, onClickAction }, children })
|
|
1134
1162
|
] });
|
|
1135
1163
|
};
|
|
1136
1164
|
const useImages = () => {
|
|
@@ -1141,7 +1169,8 @@ const useImages = () => {
|
|
|
1141
1169
|
return context;
|
|
1142
1170
|
};
|
|
1143
1171
|
const Image = ({ image }) => {
|
|
1144
|
-
const { onClickAction } = useImages();
|
|
1172
|
+
const { onClickAction, downloadingId } = useImages();
|
|
1173
|
+
const isDownloading = downloadingId === image.documentId;
|
|
1145
1174
|
return /* @__PURE__ */ jsxs(Card, { id: image.id, children: [
|
|
1146
1175
|
/* @__PURE__ */ jsxs(CardHeader, { children: [
|
|
1147
1176
|
/* @__PURE__ */ jsxs(CardAction, { position: "end", children: [
|
|
@@ -1149,10 +1178,11 @@ const Image = ({ image }) => {
|
|
|
1149
1178
|
IconButton,
|
|
1150
1179
|
{
|
|
1151
1180
|
label: "Descargar",
|
|
1181
|
+
disabled: isDownloading,
|
|
1152
1182
|
onClick: () => {
|
|
1153
1183
|
onClickAction(image, "download");
|
|
1154
1184
|
},
|
|
1155
|
-
children: /* @__PURE__ */ jsx(Download, {})
|
|
1185
|
+
children: isDownloading ? /* @__PURE__ */ jsx(Loader, { small: true }) : /* @__PURE__ */ jsx(Download, {})
|
|
1156
1186
|
}
|
|
1157
1187
|
),
|
|
1158
1188
|
/* @__PURE__ */ jsx(
|
|
@@ -4,12 +4,12 @@ const jsxRuntime = require("react/jsx-runtime");
|
|
|
4
4
|
const admin = require("@strapi/strapi/admin");
|
|
5
5
|
const designSystem = require("@strapi/design-system");
|
|
6
6
|
const reactRouterDom = require("react-router-dom");
|
|
7
|
-
const index = require("./index-
|
|
7
|
+
const index = require("./index-DGPqyrzz.js");
|
|
8
8
|
const reactIntl = require("react-intl");
|
|
9
9
|
const react = require("react");
|
|
10
10
|
const reactRedux = require("react-redux");
|
|
11
11
|
const icons = require("@strapi/icons");
|
|
12
|
-
const getTranslation = require("./getTranslation-
|
|
12
|
+
const getTranslation = require("./getTranslation-DNhP1INv.js");
|
|
13
13
|
const formik = require("formik");
|
|
14
14
|
const Yup = require("yup");
|
|
15
15
|
function _interopNamespace(e) {
|
|
@@ -1020,8 +1020,9 @@ const ImagesProvider = ({ children }) => {
|
|
|
1020
1020
|
const { openDialog, closeDialog } = useDialog("dialog-delete-image");
|
|
1021
1021
|
const { formatMessage } = reactIntl.useIntl();
|
|
1022
1022
|
const { toggleNotification } = admin.useNotification();
|
|
1023
|
+
const { post } = admin.useFetchClient();
|
|
1023
1024
|
const [images, setImages] = react.useState([]);
|
|
1024
|
-
const [
|
|
1025
|
+
const [downloadingId, setDownloadingId] = react.useState(null);
|
|
1025
1026
|
const [open, setOpen] = react.useState(false);
|
|
1026
1027
|
const currentImageRef = react.useRef();
|
|
1027
1028
|
const fetchImages = react.useCallback(async () => {
|
|
@@ -1087,41 +1088,68 @@ const ImagesProvider = ({ children }) => {
|
|
|
1087
1088
|
return;
|
|
1088
1089
|
}
|
|
1089
1090
|
}, [openDialog, setOpen]);
|
|
1090
|
-
const downloadImage = (url, filename) => {
|
|
1091
|
-
|
|
1092
|
-
const
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1091
|
+
const downloadImage = async (url, filename) => {
|
|
1092
|
+
if (!url) return;
|
|
1093
|
+
const absoluteUrl = url.startsWith("/uploads") ? `${window.location.origin}${url}` : url;
|
|
1094
|
+
try {
|
|
1095
|
+
const { data } = await post(
|
|
1096
|
+
"/strapi-content-generator-gemini/download-file",
|
|
1097
|
+
{ url: absoluteUrl }
|
|
1098
|
+
);
|
|
1099
|
+
const { base64, contentType } = data;
|
|
1100
|
+
const binary = atob(base64);
|
|
1101
|
+
const bytes = new Uint8Array(binary.length);
|
|
1102
|
+
for (let i = 0; i < binary.length; i++) {
|
|
1103
|
+
bytes[i] = binary.charCodeAt(i);
|
|
1104
|
+
}
|
|
1105
|
+
const blob = new Blob([bytes], { type: contentType });
|
|
1106
|
+
const blobUrl = window.URL.createObjectURL(blob);
|
|
1107
|
+
const link = document.createElement("a");
|
|
1108
|
+
link.href = blobUrl;
|
|
1109
|
+
link.download = filename;
|
|
1110
|
+
document.body.appendChild(link);
|
|
1111
|
+
link.click();
|
|
1112
|
+
document.body.removeChild(link);
|
|
1113
|
+
window.URL.revokeObjectURL(blobUrl);
|
|
1114
|
+
} catch (error) {
|
|
1115
|
+
console.error("Download error:", error);
|
|
1116
|
+
const link = document.createElement("a");
|
|
1117
|
+
link.href = absoluteUrl;
|
|
1118
|
+
link.target = "_blank";
|
|
1119
|
+
link.rel = "noopener noreferrer";
|
|
1120
|
+
document.body.appendChild(link);
|
|
1121
|
+
link.click();
|
|
1122
|
+
document.body.removeChild(link);
|
|
1123
|
+
}
|
|
1101
1124
|
};
|
|
1102
1125
|
const handleDownload = async (selectedKeys) => {
|
|
1103
1126
|
const image = currentImageRef.current;
|
|
1104
1127
|
if (!image) return;
|
|
1105
1128
|
setOpen(false);
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1129
|
+
setDownloadingId(image.documentId);
|
|
1130
|
+
try {
|
|
1131
|
+
const keys = Array.isArray(selectedKeys) ? selectedKeys : Array.from(selectedKeys);
|
|
1132
|
+
const extension = image.ext?.replace(".", "") ?? "jpg";
|
|
1133
|
+
const formats = image.formats;
|
|
1134
|
+
const items = keys.map((key) => {
|
|
1135
|
+
if (key === "principal") {
|
|
1136
|
+
return {
|
|
1137
|
+
url: image.url,
|
|
1138
|
+
filename: `image-principal-${image.documentId}.${extension}`
|
|
1139
|
+
};
|
|
1140
|
+
}
|
|
1141
|
+
const formatImage = formats?.[key];
|
|
1142
|
+
if (!formatImage) return null;
|
|
1111
1143
|
return {
|
|
1112
|
-
url:
|
|
1113
|
-
filename: `image
|
|
1144
|
+
url: formatImage.url,
|
|
1145
|
+
filename: `image-${key}-${image.documentId}.${extension}`
|
|
1114
1146
|
};
|
|
1147
|
+
}).filter(Boolean);
|
|
1148
|
+
for (const item of items) {
|
|
1149
|
+
await downloadImage(item.url, item.filename);
|
|
1115
1150
|
}
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
return {
|
|
1119
|
-
url: formatImage.url,
|
|
1120
|
-
filename: `image-${key}-${image.documentId}.${extension}`
|
|
1121
|
-
};
|
|
1122
|
-
}).filter(Boolean);
|
|
1123
|
-
for (const item of items) {
|
|
1124
|
-
await downloadImage(item.url, item.filename);
|
|
1151
|
+
} finally {
|
|
1152
|
+
setDownloadingId(null);
|
|
1125
1153
|
}
|
|
1126
1154
|
};
|
|
1127
1155
|
react.useEffect(() => {
|
|
@@ -1150,7 +1178,7 @@ const ImagesProvider = ({ children }) => {
|
|
|
1150
1178
|
] })
|
|
1151
1179
|
}
|
|
1152
1180
|
),
|
|
1153
|
-
/* @__PURE__ */ jsxRuntime.jsx(ImagesContext.Provider, { value: { images, onClickAction }, children })
|
|
1181
|
+
/* @__PURE__ */ jsxRuntime.jsx(ImagesContext.Provider, { value: { images, downloadingId, onClickAction }, children })
|
|
1154
1182
|
] });
|
|
1155
1183
|
};
|
|
1156
1184
|
const useImages = () => {
|
|
@@ -1161,7 +1189,8 @@ const useImages = () => {
|
|
|
1161
1189
|
return context;
|
|
1162
1190
|
};
|
|
1163
1191
|
const Image = ({ image }) => {
|
|
1164
|
-
const { onClickAction } = useImages();
|
|
1192
|
+
const { onClickAction, downloadingId } = useImages();
|
|
1193
|
+
const isDownloading = downloadingId === image.documentId;
|
|
1165
1194
|
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Card, { id: image.id, children: [
|
|
1166
1195
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.CardHeader, { children: [
|
|
1167
1196
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.CardAction, { position: "end", children: [
|
|
@@ -1169,10 +1198,11 @@ const Image = ({ image }) => {
|
|
|
1169
1198
|
designSystem.IconButton,
|
|
1170
1199
|
{
|
|
1171
1200
|
label: "Descargar",
|
|
1201
|
+
disabled: isDownloading,
|
|
1172
1202
|
onClick: () => {
|
|
1173
1203
|
onClickAction(image, "download");
|
|
1174
1204
|
},
|
|
1175
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(icons.Download, {})
|
|
1205
|
+
children: isDownloading ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { small: true }) : /* @__PURE__ */ jsxRuntime.jsx(icons.Download, {})
|
|
1176
1206
|
}
|
|
1177
1207
|
),
|
|
1178
1208
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -7,8 +7,8 @@ const react = require("react");
|
|
|
7
7
|
const designSystem = require("@strapi/design-system");
|
|
8
8
|
const formik = require("formik");
|
|
9
9
|
const Yup = require("yup");
|
|
10
|
-
const index = require("./index-
|
|
11
|
-
const getTranslation = require("./getTranslation-
|
|
10
|
+
const index = require("./index-DGPqyrzz.js");
|
|
11
|
+
const getTranslation = require("./getTranslation-DNhP1INv.js");
|
|
12
12
|
function _interopNamespace(e) {
|
|
13
13
|
if (e && e.__esModule) return e;
|
|
14
14
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
@@ -5,8 +5,8 @@ import { useCallback, useState, useEffect } from "react";
|
|
|
5
5
|
import { Box, Grid, Field, Flex, Button, DesignSystemProvider, Typography } from "@strapi/design-system";
|
|
6
6
|
import { Formik } from "formik";
|
|
7
7
|
import * as Yup from "yup";
|
|
8
|
-
import { P as PLUGIN_ID } from "./index-
|
|
9
|
-
import { g as getTranslation } from "./getTranslation-
|
|
8
|
+
import { P as PLUGIN_ID } from "./index-Dyq8dxMX.mjs";
|
|
9
|
+
import { g as getTranslation } from "./getTranslation-B9ND5RaH.mjs";
|
|
10
10
|
const useSettings = () => {
|
|
11
11
|
const { get, post } = useFetchClient();
|
|
12
12
|
const getSettings = useCallback(
|
|
@@ -77,7 +77,7 @@ const index = {
|
|
|
77
77
|
defaultMessage: PLUGIN_ID
|
|
78
78
|
},
|
|
79
79
|
Component: async () => {
|
|
80
|
-
const { App } = await Promise.resolve().then(() => require("./App-
|
|
80
|
+
const { App } = await Promise.resolve().then(() => require("./App-CfwvfmvL.js"));
|
|
81
81
|
return App;
|
|
82
82
|
},
|
|
83
83
|
permissions: [
|
|
@@ -98,7 +98,7 @@ const index = {
|
|
|
98
98
|
defaultMessage: PLUGIN_ID
|
|
99
99
|
},
|
|
100
100
|
Component: async () => {
|
|
101
|
-
const component = await Promise.resolve().then(() => require("./Settings-
|
|
101
|
+
const component = await Promise.resolve().then(() => require("./Settings-BrqTzJp-.js"));
|
|
102
102
|
return component.default;
|
|
103
103
|
},
|
|
104
104
|
to: `plugins/${PLUGIN_ID}/settings`,
|
|
@@ -76,7 +76,7 @@ const index = {
|
|
|
76
76
|
defaultMessage: PLUGIN_ID
|
|
77
77
|
},
|
|
78
78
|
Component: async () => {
|
|
79
|
-
const { App } = await import("./App-
|
|
79
|
+
const { App } = await import("./App-BQr5_g5u.mjs");
|
|
80
80
|
return App;
|
|
81
81
|
},
|
|
82
82
|
permissions: [
|
|
@@ -97,7 +97,7 @@ const index = {
|
|
|
97
97
|
defaultMessage: PLUGIN_ID
|
|
98
98
|
},
|
|
99
99
|
Component: async () => {
|
|
100
|
-
const component = await import("./Settings-
|
|
100
|
+
const component = await import("./Settings-CdZnYLLK.mjs");
|
|
101
101
|
return component.default;
|
|
102
102
|
},
|
|
103
103
|
to: `plugins/${PLUGIN_ID}/settings`,
|
package/dist/admin/index.js
CHANGED
package/dist/admin/index.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { ReactNode } from 'react';
|
|
|
2
2
|
import type { Data } from '@strapi/strapi';
|
|
3
3
|
interface ImagesContextType {
|
|
4
4
|
images: Data.ContentType<"plugin::upload.file">[];
|
|
5
|
+
downloadingId: string | null;
|
|
5
6
|
onClickAction: (image: Data.ContentType<"plugin::upload.file">, action: "delete" | "download") => void;
|
|
6
7
|
}
|
|
7
8
|
export declare const ImagesProvider: ({ children }: {
|
package/dist/server/index.js
CHANGED
|
@@ -127,6 +127,9 @@ const controller = ({ strapi }) => {
|
|
|
127
127
|
async generateImage(ctx) {
|
|
128
128
|
ctx.body = await pluginService().generateImage(ctx);
|
|
129
129
|
},
|
|
130
|
+
async downloadFile(ctx) {
|
|
131
|
+
await pluginService().downloadFile(ctx);
|
|
132
|
+
},
|
|
130
133
|
async generateVideo(ctx) {
|
|
131
134
|
ctx.body = await pluginService().generateVideo(ctx);
|
|
132
135
|
},
|
|
@@ -240,6 +243,15 @@ const admin = [
|
|
|
240
243
|
auth: false
|
|
241
244
|
}
|
|
242
245
|
},
|
|
246
|
+
{
|
|
247
|
+
method: "POST",
|
|
248
|
+
path: "/download-file",
|
|
249
|
+
handler: "controller.downloadFile",
|
|
250
|
+
config: {
|
|
251
|
+
policies: [],
|
|
252
|
+
auth: false
|
|
253
|
+
}
|
|
254
|
+
},
|
|
243
255
|
{
|
|
244
256
|
method: "POST",
|
|
245
257
|
path: "/generate-article",
|
|
@@ -2841,6 +2853,39 @@ const service = ({ strapi }) => {
|
|
|
2841
2853
|
return await strapi.documents("plugin::upload.file").delete(sanitizedQueryParams);
|
|
2842
2854
|
},
|
|
2843
2855
|
// ───────────────────────────────
|
|
2856
|
+
// 📥 Proxy File Download (bypasses browser CORS)
|
|
2857
|
+
// ───────────────────────────────
|
|
2858
|
+
async downloadFile(ctx) {
|
|
2859
|
+
const { url } = ctx.request.body;
|
|
2860
|
+
if (!url) {
|
|
2861
|
+
ctx.status = 400;
|
|
2862
|
+
ctx.body = { error: "Se requiere el parámetro 'url'." };
|
|
2863
|
+
return;
|
|
2864
|
+
}
|
|
2865
|
+
let parsedUrl;
|
|
2866
|
+
try {
|
|
2867
|
+
parsedUrl = new URL(url);
|
|
2868
|
+
const allowedHosts = [
|
|
2869
|
+
"web-cms-interware.s3.us-east-1.amazonaws.com",
|
|
2870
|
+
"api.interware.com.mx",
|
|
2871
|
+
...process.env.NODE_ENV === "development" ? ["localhost"] : []
|
|
2872
|
+
];
|
|
2873
|
+
if (!allowedHosts.includes(parsedUrl.hostname)) {
|
|
2874
|
+
ctx.status = 403;
|
|
2875
|
+
ctx.body = { error: "URL no permitida." };
|
|
2876
|
+
return;
|
|
2877
|
+
}
|
|
2878
|
+
} catch {
|
|
2879
|
+
ctx.status = 400;
|
|
2880
|
+
ctx.body = { error: "URL inválida." };
|
|
2881
|
+
return;
|
|
2882
|
+
}
|
|
2883
|
+
const response = await axios.get(url, { responseType: "arraybuffer" });
|
|
2884
|
+
const base64 = Buffer.from(response.data).toString("base64");
|
|
2885
|
+
const contentType = response.headers["content-type"] || "application/octet-stream";
|
|
2886
|
+
ctx.body = { base64, contentType };
|
|
2887
|
+
},
|
|
2888
|
+
// ───────────────────────────────
|
|
2844
2889
|
// 🏞️ Internal File Upload Helper
|
|
2845
2890
|
// ───────────────────────────────
|
|
2846
2891
|
async _uploadGeneratedFile(file, filename, mimeType, folderName = "Generated") {
|
package/dist/server/index.mjs
CHANGED
|
@@ -108,6 +108,9 @@ const controller = ({ strapi }) => {
|
|
|
108
108
|
async generateImage(ctx) {
|
|
109
109
|
ctx.body = await pluginService().generateImage(ctx);
|
|
110
110
|
},
|
|
111
|
+
async downloadFile(ctx) {
|
|
112
|
+
await pluginService().downloadFile(ctx);
|
|
113
|
+
},
|
|
111
114
|
async generateVideo(ctx) {
|
|
112
115
|
ctx.body = await pluginService().generateVideo(ctx);
|
|
113
116
|
},
|
|
@@ -221,6 +224,15 @@ const admin = [
|
|
|
221
224
|
auth: false
|
|
222
225
|
}
|
|
223
226
|
},
|
|
227
|
+
{
|
|
228
|
+
method: "POST",
|
|
229
|
+
path: "/download-file",
|
|
230
|
+
handler: "controller.downloadFile",
|
|
231
|
+
config: {
|
|
232
|
+
policies: [],
|
|
233
|
+
auth: false
|
|
234
|
+
}
|
|
235
|
+
},
|
|
224
236
|
{
|
|
225
237
|
method: "POST",
|
|
226
238
|
path: "/generate-article",
|
|
@@ -2822,6 +2834,39 @@ const service = ({ strapi }) => {
|
|
|
2822
2834
|
return await strapi.documents("plugin::upload.file").delete(sanitizedQueryParams);
|
|
2823
2835
|
},
|
|
2824
2836
|
// ───────────────────────────────
|
|
2837
|
+
// 📥 Proxy File Download (bypasses browser CORS)
|
|
2838
|
+
// ───────────────────────────────
|
|
2839
|
+
async downloadFile(ctx) {
|
|
2840
|
+
const { url } = ctx.request.body;
|
|
2841
|
+
if (!url) {
|
|
2842
|
+
ctx.status = 400;
|
|
2843
|
+
ctx.body = { error: "Se requiere el parámetro 'url'." };
|
|
2844
|
+
return;
|
|
2845
|
+
}
|
|
2846
|
+
let parsedUrl;
|
|
2847
|
+
try {
|
|
2848
|
+
parsedUrl = new URL(url);
|
|
2849
|
+
const allowedHosts = [
|
|
2850
|
+
"web-cms-interware.s3.us-east-1.amazonaws.com",
|
|
2851
|
+
"api.interware.com.mx",
|
|
2852
|
+
...process.env.NODE_ENV === "development" ? ["localhost"] : []
|
|
2853
|
+
];
|
|
2854
|
+
if (!allowedHosts.includes(parsedUrl.hostname)) {
|
|
2855
|
+
ctx.status = 403;
|
|
2856
|
+
ctx.body = { error: "URL no permitida." };
|
|
2857
|
+
return;
|
|
2858
|
+
}
|
|
2859
|
+
} catch {
|
|
2860
|
+
ctx.status = 400;
|
|
2861
|
+
ctx.body = { error: "URL inválida." };
|
|
2862
|
+
return;
|
|
2863
|
+
}
|
|
2864
|
+
const response = await axios.get(url, { responseType: "arraybuffer" });
|
|
2865
|
+
const base64 = Buffer.from(response.data).toString("base64");
|
|
2866
|
+
const contentType = response.headers["content-type"] || "application/octet-stream";
|
|
2867
|
+
ctx.body = { base64, contentType };
|
|
2868
|
+
},
|
|
2869
|
+
// ───────────────────────────────
|
|
2825
2870
|
// 🏞️ Internal File Upload Helper
|
|
2826
2871
|
// ───────────────────────────────
|
|
2827
2872
|
async _uploadGeneratedFile(file, filename, mimeType, folderName = "Generated") {
|
|
@@ -10,6 +10,7 @@ declare const controller: ({ strapi }: {
|
|
|
10
10
|
generateArticle(ctx: any): Promise<void>;
|
|
11
11
|
generateImageForArticle(ctx: any): Promise<void>;
|
|
12
12
|
generateImage(ctx: any): Promise<void>;
|
|
13
|
+
downloadFile(ctx: any): Promise<void>;
|
|
13
14
|
generateVideo(ctx: any): Promise<void>;
|
|
14
15
|
publishToLinkedIn(ctx: any): Promise<void>;
|
|
15
16
|
publishToFacebook(ctx: any): Promise<void>;
|
|
@@ -10,6 +10,7 @@ declare const _default: {
|
|
|
10
10
|
generateArticle(ctx: any): Promise<void>;
|
|
11
11
|
generateImageForArticle(ctx: any): Promise<void>;
|
|
12
12
|
generateImage(ctx: any): Promise<void>;
|
|
13
|
+
downloadFile(ctx: any): Promise<void>;
|
|
13
14
|
generateVideo(ctx: any): Promise<void>;
|
|
14
15
|
publishToLinkedIn(ctx: any): Promise<void>;
|
|
15
16
|
publishToFacebook(ctx: any): Promise<void>;
|
|
@@ -26,6 +26,7 @@ declare const _default: {
|
|
|
26
26
|
generateArticle(ctx: any): Promise<void>;
|
|
27
27
|
generateImageForArticle(ctx: any): Promise<void>;
|
|
28
28
|
generateImage(ctx: any): Promise<void>;
|
|
29
|
+
downloadFile(ctx: any): Promise<void>;
|
|
29
30
|
generateVideo(ctx: any): Promise<void>;
|
|
30
31
|
publishToLinkedIn(ctx: any): Promise<void>;
|
|
31
32
|
publishToFacebook(ctx: any): Promise<void>;
|
|
@@ -170,6 +171,7 @@ declare const _default: {
|
|
|
170
171
|
width?: number;
|
|
171
172
|
}[];
|
|
172
173
|
}>;
|
|
174
|
+
downloadFile(ctx: any): Promise<void>;
|
|
173
175
|
_uploadGeneratedFile(file: string | Buffer, filename: string, mimeType: string, folderName?: string): Promise<any>;
|
|
174
176
|
generateArticle(ctx: any): Promise<{
|
|
175
177
|
id: import("@strapi/types/dist/data").ID;
|
|
@@ -105,6 +105,7 @@ declare const _default: {
|
|
|
105
105
|
width?: number;
|
|
106
106
|
}[];
|
|
107
107
|
}>;
|
|
108
|
+
downloadFile(ctx: any): Promise<void>;
|
|
108
109
|
_uploadGeneratedFile(file: string | Buffer, filename: string, mimeType: string, folderName?: string): Promise<any>;
|
|
109
110
|
generateArticle(ctx: any): Promise<{
|
|
110
111
|
id: import("@strapi/types/dist/data").ID;
|
|
@@ -106,6 +106,7 @@ declare const service: ({ strapi }: {
|
|
|
106
106
|
width?: number;
|
|
107
107
|
}[];
|
|
108
108
|
}>;
|
|
109
|
+
downloadFile(ctx: any): Promise<void>;
|
|
109
110
|
_uploadGeneratedFile(file: Buffer | string, filename: string, mimeType: string, folderName?: string): Promise<any>;
|
|
110
111
|
generateArticle(ctx: any): Promise<{
|
|
111
112
|
id: import("@strapi/types/dist/data").ID;
|
package/package.json
CHANGED