dn-react-router-toolkit 0.1.0 → 0.1.1
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/cjs/auth-kit/apple_auth.js +1 -0
- package/dist/cjs/auth-kit/auth_service.js +6 -6
- package/dist/cjs/auth-kit/client/google_login_button.js +2 -8
- package/dist/cjs/auth-kit/client/redirect_page.js +4 -7
- package/dist/cjs/auth-kit/google_auth.js +4 -0
- package/dist/cjs/auth-kit/jwt.js +1 -0
- package/dist/cjs/auth-kit/kakao_auth.js +6 -1
- package/dist/cjs/components/modal/fullscreen_container.js +9 -24
- package/dist/cjs/components/modal/hooks.js +4 -6
- package/dist/cjs/components/modal/modal.js +7 -19
- package/dist/cjs/file-kit/client/drop_file_input.js +24 -71
- package/dist/cjs/file-kit/client/file_uploader.js +21 -11
- package/dist/cjs/file-kit/file_service.js +3 -0
- package/dist/cjs/file-kit/object_storage.js +4 -3
- package/dist/cjs/file-kit/responsive_image.js +4 -19
- package/dist/cjs/http-kit/response.js +5 -2
- package/dist/cjs/route/api/auth/refresh/route.js +1 -2
- package/dist/cjs/route/api/files/[fileId]/route.js +1 -1
- package/dist/cjs/route/api/files/route.js +1 -1
- package/dist/cjs/route/auth/callback/[provider]/route.js +4 -1
- package/dist/cjs/seo-kit/seo.js +33 -41
- package/dist/cjs/seo-kit/seo_loader.js +8 -12
- package/dist/esm/auth-kit/apple_auth.js +1 -0
- package/dist/esm/auth-kit/auth_service.js +6 -6
- package/dist/esm/auth-kit/client/google_login_button.d.ts +1 -2
- package/dist/esm/auth-kit/client/google_login_button.js +2 -5
- package/dist/esm/auth-kit/client/redirect_page.d.ts +1 -2
- package/dist/esm/auth-kit/client/redirect_page.js +2 -2
- package/dist/esm/auth-kit/google_auth.js +4 -0
- package/dist/esm/auth-kit/jwt.js +1 -0
- package/dist/esm/auth-kit/kakao_auth.js +6 -1
- package/dist/esm/components/modal/fullscreen_container.d.ts +1 -1
- package/dist/esm/components/modal/fullscreen_container.js +6 -18
- package/dist/esm/components/modal/hooks.d.ts +1 -1
- package/dist/esm/components/modal/hooks.js +4 -6
- package/dist/esm/components/modal/modal.d.ts +1 -1
- package/dist/esm/components/modal/modal.js +7 -19
- package/dist/esm/file-kit/client/drop_file_input.d.ts +2 -2
- package/dist/esm/file-kit/client/drop_file_input.js +24 -38
- package/dist/esm/file-kit/client/file_uploader.js +21 -11
- package/dist/esm/file-kit/file_service.js +3 -0
- package/dist/esm/file-kit/object_storage.js +4 -3
- package/dist/esm/file-kit/responsive_image.js +4 -16
- package/dist/esm/http-kit/response.js +5 -2
- package/dist/esm/route/api/auth/refresh/route.js +1 -2
- package/dist/esm/route/api/files/[fileId]/route.js +1 -1
- package/dist/esm/route/api/files/route.js +1 -1
- package/dist/esm/route/auth/callback/[provider]/route.js +4 -1
- package/dist/esm/seo-kit/seo.d.ts +1 -2
- package/dist/esm/seo-kit/seo.js +33 -38
- package/dist/esm/seo-kit/seo_loader.d.ts +1 -1
- package/dist/esm/seo-kit/seo_loader.js +8 -9
- package/package.json +1 -1
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
export class FileUploader {
|
|
2
|
+
endpoint;
|
|
2
3
|
constructor(endpoint = "/api/files") {
|
|
3
|
-
this.formatSize = (size) => {
|
|
4
|
-
if (size < 1024) {
|
|
5
|
-
return `${size} B`;
|
|
6
|
-
}
|
|
7
|
-
if (size < 1024 * 1024) {
|
|
8
|
-
return `${(size / 1024).toFixed(2)} KB`;
|
|
9
|
-
}
|
|
10
|
-
return `${(size / (1024 * 1024)).toFixed(2)} MB`;
|
|
11
|
-
};
|
|
12
4
|
this.endpoint = endpoint;
|
|
13
5
|
}
|
|
6
|
+
formatSize = (size) => {
|
|
7
|
+
if (size < 1024) {
|
|
8
|
+
return `${size} B`;
|
|
9
|
+
}
|
|
10
|
+
if (size < 1024 * 1024) {
|
|
11
|
+
return `${(size / 1024).toFixed(2)} KB`;
|
|
12
|
+
}
|
|
13
|
+
return `${(size / (1024 * 1024)).toFixed(2)} MB`;
|
|
14
|
+
};
|
|
14
15
|
uploadFile(file, options = {}) {
|
|
15
16
|
return this.uploadBlob(file, file.name, options);
|
|
16
17
|
}
|
|
@@ -21,7 +22,11 @@ export class FileUploader {
|
|
|
21
22
|
const img = new Image();
|
|
22
23
|
img.src = URL.createObjectURL(blob);
|
|
23
24
|
img.onload = () => {
|
|
24
|
-
resolve(
|
|
25
|
+
resolve({
|
|
26
|
+
...options.metadata,
|
|
27
|
+
width: img.width,
|
|
28
|
+
height: img.height,
|
|
29
|
+
});
|
|
25
30
|
};
|
|
26
31
|
img.onerror = reject;
|
|
27
32
|
return;
|
|
@@ -30,7 +35,12 @@ export class FileUploader {
|
|
|
30
35
|
const video = document.createElement("video");
|
|
31
36
|
video.src = URL.createObjectURL(blob);
|
|
32
37
|
video.onloadedmetadata = () => {
|
|
33
|
-
resolve(
|
|
38
|
+
resolve({
|
|
39
|
+
...options.metadata,
|
|
40
|
+
width: video.videoWidth,
|
|
41
|
+
height: video.videoHeight,
|
|
42
|
+
duration: video.duration,
|
|
43
|
+
});
|
|
34
44
|
};
|
|
35
45
|
video.onerror = reject;
|
|
36
46
|
return;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { GetObjectCommand, PutObjectCommand, S3Client, } from "@aws-sdk/client-s3";
|
|
2
2
|
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
|
3
3
|
export class ObjectStorage {
|
|
4
|
+
client = new S3Client({
|
|
5
|
+
region: "ap-northeast-2",
|
|
6
|
+
});
|
|
7
|
+
bucketName;
|
|
4
8
|
constructor(bucketName) {
|
|
5
|
-
this.client = new S3Client({
|
|
6
|
-
region: "ap-northeast-2",
|
|
7
|
-
});
|
|
8
9
|
this.bucketName = bucketName;
|
|
9
10
|
}
|
|
10
11
|
async generateSignedUrl(key, { contentType, expiresIn = 3600, } = {}) {
|
|
@@ -1,23 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
var t = {};
|
|
3
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
-
t[p] = s[p];
|
|
5
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
-
t[p[i]] = s[p[i]];
|
|
9
|
-
}
|
|
10
|
-
return t;
|
|
11
|
-
};
|
|
12
|
-
import React from "react";
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
2
|
const sizes = [
|
|
14
3
|
64, 128, 256, 320, 480, 640, 768, 1080, 1200, 1536, 1920, 2560, 3840,
|
|
15
4
|
];
|
|
16
5
|
export const createResponsiveImage = (cdn) => {
|
|
17
|
-
const Component = (
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return (React.createElement("img", Object.assign({}, props, { src: src, alt: alt, srcSet: generateSrcSet(src, ratio, props) })));
|
|
6
|
+
const Component = ({ alt, file, ratio, ...props }) => {
|
|
7
|
+
const src = cdn(file?.key) || props.src || "#";
|
|
8
|
+
return (_jsx("img", { ...props, src: src, alt: alt, srcSet: generateSrcSet(src, ratio, props) }));
|
|
21
9
|
};
|
|
22
10
|
return Component;
|
|
23
11
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const createJsonResponse = (status) => {
|
|
2
2
|
return (data = {}, init) => {
|
|
3
|
-
return Response.json(data,
|
|
3
|
+
return Response.json(data, { status, ...init });
|
|
4
4
|
};
|
|
5
5
|
};
|
|
6
6
|
Response;
|
|
@@ -8,7 +8,10 @@ export const OK = createJsonResponse(200);
|
|
|
8
8
|
export const CREATED = createJsonResponse(201);
|
|
9
9
|
export const ACCEPTED = createJsonResponse(202);
|
|
10
10
|
export const NO_CONTENT = (init) => {
|
|
11
|
-
return new Response(null,
|
|
11
|
+
return new Response(null, {
|
|
12
|
+
...init,
|
|
13
|
+
status: 204,
|
|
14
|
+
});
|
|
12
15
|
};
|
|
13
16
|
export const createException = (status, defaultMessage = "오류가 발생했습니다.") => {
|
|
14
17
|
return (message = defaultMessage, init) => {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { BAD_REQUEST, CREATED, UNAUTHORIZED } from "../../../../http-kit";
|
|
2
2
|
export const authRefreshHandler = async (request, { AUTH, }) => {
|
|
3
|
-
|
|
4
|
-
const refreshToken = ((_a = request === null || request === void 0 ? void 0 : request.headers.get("Authorization")) === null || _a === void 0 ? void 0 : _a.replace("Bearer ", "")) ||
|
|
3
|
+
const refreshToken = request?.headers.get("Authorization")?.replace("Bearer ", "") ||
|
|
5
4
|
(await AUTH.getRefreshTokenFromCookies(request));
|
|
6
5
|
if (!refreshToken) {
|
|
7
6
|
return BAD_REQUEST();
|
|
@@ -8,7 +8,7 @@ export const fileDeleteHandler = async (request, { fileId }, { AUTH, repository,
|
|
|
8
8
|
if (!file) {
|
|
9
9
|
return NOT_FOUND("파일을 찾을 수 없습니다.", { headers });
|
|
10
10
|
}
|
|
11
|
-
if (!repository.hasPermission(file, auth
|
|
11
|
+
if (!repository.hasPermission(file, auth?.userId)) {
|
|
12
12
|
return FORBIDDEN("파일을 삭제할 권한이 없습니다.", { headers });
|
|
13
13
|
}
|
|
14
14
|
await repository.deleteFile(fileId);
|
|
@@ -13,7 +13,7 @@ export const fileUploadHandler = async (request, { AUTH, FILE_SERVICE, }) => {
|
|
|
13
13
|
}
|
|
14
14
|
try {
|
|
15
15
|
const result = await FILE_SERVICE.generateSignedUrl({
|
|
16
|
-
userId: auth
|
|
16
|
+
userId: auth?.userId,
|
|
17
17
|
name,
|
|
18
18
|
type,
|
|
19
19
|
size,
|
|
@@ -26,6 +26,9 @@ export const thirdPartyAuthCallbackHandler = async (request, { provider, }, { AU
|
|
|
26
26
|
const redirectUrl = url.searchParams.get("state") || SITE_ORIGIN;
|
|
27
27
|
return new Response("Temporary Redirect", {
|
|
28
28
|
status: 307,
|
|
29
|
-
headers:
|
|
29
|
+
headers: {
|
|
30
|
+
...headers,
|
|
31
|
+
Location: new URL(`/r?redirectUrl=${encodeURIComponent(redirectUrl)}`, request.url).toString(),
|
|
32
|
+
},
|
|
30
33
|
});
|
|
31
34
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as Schema from "schema-dts";
|
|
2
|
-
import React from "react";
|
|
3
2
|
import type { MetaFunction } from "react-router";
|
|
4
3
|
export type SEOImage = {
|
|
5
4
|
id?: string;
|
|
@@ -95,6 +94,6 @@ export declare function configSEO(config: {
|
|
|
95
94
|
}[];
|
|
96
95
|
};
|
|
97
96
|
meta: MetaFunction<unknown, Record<string, unknown>>;
|
|
98
|
-
generateJSONLD: () =>
|
|
97
|
+
generateJSONLD: () => import("react/jsx-runtime").JSX.Element;
|
|
99
98
|
}>;
|
|
100
99
|
};
|
package/dist/esm/seo-kit/seo.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
export function configSEO(config) {
|
|
3
3
|
return {
|
|
4
4
|
config,
|
|
5
5
|
async init(props = {}) {
|
|
6
|
-
var _a;
|
|
7
6
|
const canonicalPath = props.canonicalPath;
|
|
8
7
|
const url = canonicalPath
|
|
9
8
|
? `${config.origin}${canonicalPath}`
|
|
@@ -28,7 +27,7 @@ export function configSEO(config) {
|
|
|
28
27
|
(typeof config.thumbnail === "function"
|
|
29
28
|
? await config.thumbnail()
|
|
30
29
|
: config.thumbnail);
|
|
31
|
-
const thumbnailUrl = thumbnail
|
|
30
|
+
const thumbnailUrl = thumbnail?.url;
|
|
32
31
|
const socialImage = thumbnail
|
|
33
32
|
? [
|
|
34
33
|
typeof thumbnail === "string"
|
|
@@ -50,7 +49,7 @@ export function configSEO(config) {
|
|
|
50
49
|
]
|
|
51
50
|
: []),
|
|
52
51
|
...(props.images || []),
|
|
53
|
-
...(
|
|
52
|
+
...(props.collection?.map((portfolio) => portfolio.thumbnail) || []),
|
|
54
53
|
].filter(Boolean);
|
|
55
54
|
const image = images
|
|
56
55
|
.filter((file) => file.id)
|
|
@@ -65,7 +64,7 @@ export function configSEO(config) {
|
|
|
65
64
|
return [
|
|
66
65
|
{ title: pageTitle },
|
|
67
66
|
{ name: "description", content: description },
|
|
68
|
-
{ name: "keywords", content:
|
|
67
|
+
{ name: "keywords", content: keywords?.join(", ") || "" },
|
|
69
68
|
{
|
|
70
69
|
tagName: "link",
|
|
71
70
|
rel: "canonical",
|
|
@@ -105,24 +104,21 @@ export function configSEO(config) {
|
|
|
105
104
|
? {
|
|
106
105
|
"@type": "ItemList",
|
|
107
106
|
numberOfItems: props.collection.length,
|
|
108
|
-
itemListElement: props.collection.map((item, index) => {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
107
|
+
itemListElement: props.collection.map((item, index) => ({
|
|
108
|
+
"@type": "ListItem",
|
|
109
|
+
position: index + 1,
|
|
110
|
+
url: item.url,
|
|
111
|
+
item: {
|
|
112
|
+
"@type": "WebPage",
|
|
113
|
+
"@id": `${item.url}#webpage`,
|
|
113
114
|
url: item.url,
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
dateCreated: (_c = item.createdAt) === null || _c === void 0 ? void 0 : _c.toISOString(),
|
|
122
|
-
datePublished: (_d = item.createdAt) === null || _d === void 0 ? void 0 : _d.toISOString(),
|
|
123
|
-
},
|
|
124
|
-
});
|
|
125
|
-
}),
|
|
115
|
+
name: item.title,
|
|
116
|
+
thumbnailUrl: item.thumbnail?.url,
|
|
117
|
+
dateModified: item.updatedAt?.toISOString(),
|
|
118
|
+
dateCreated: item.createdAt?.toISOString(),
|
|
119
|
+
datePublished: item.createdAt?.toISOString(),
|
|
120
|
+
},
|
|
121
|
+
})),
|
|
126
122
|
}
|
|
127
123
|
: undefined;
|
|
128
124
|
return {
|
|
@@ -135,9 +131,9 @@ export function configSEO(config) {
|
|
|
135
131
|
name: pageTitle,
|
|
136
132
|
description,
|
|
137
133
|
keywords: keywords,
|
|
138
|
-
dateModified: updatedAt
|
|
139
|
-
datePublished: createdAt
|
|
140
|
-
dateCreated: createdAt
|
|
134
|
+
dateModified: updatedAt?.toISOString(),
|
|
135
|
+
datePublished: createdAt?.toISOString(),
|
|
136
|
+
dateCreated: createdAt?.toISOString(),
|
|
141
137
|
primaryImageOfPage: thumbnail
|
|
142
138
|
? {
|
|
143
139
|
"@id": thumbnailSchemaId,
|
|
@@ -164,9 +160,9 @@ export function configSEO(config) {
|
|
|
164
160
|
description,
|
|
165
161
|
keywords: keywords,
|
|
166
162
|
headline: pageTitle,
|
|
167
|
-
dateModified: updatedAt
|
|
168
|
-
datePublished: createdAt
|
|
169
|
-
dateCreated: createdAt
|
|
163
|
+
dateModified: updatedAt?.toISOString(),
|
|
164
|
+
datePublished: createdAt?.toISOString(),
|
|
165
|
+
dateCreated: createdAt?.toISOString(),
|
|
170
166
|
isPartOf: {
|
|
171
167
|
"@id": websiteSchemaId,
|
|
172
168
|
},
|
|
@@ -181,8 +177,8 @@ export function configSEO(config) {
|
|
|
181
177
|
headline: pageTitle,
|
|
182
178
|
description: description,
|
|
183
179
|
thumbnailUrl,
|
|
184
|
-
datePublished: createdAt
|
|
185
|
-
dateModified: updatedAt
|
|
180
|
+
datePublished: createdAt?.toISOString(),
|
|
181
|
+
dateModified: updatedAt?.toISOString(),
|
|
186
182
|
isPartOf: { "@id": websiteSchemaId },
|
|
187
183
|
image,
|
|
188
184
|
},
|
|
@@ -193,8 +189,8 @@ export function configSEO(config) {
|
|
|
193
189
|
url,
|
|
194
190
|
name: pageTitle,
|
|
195
191
|
description: description,
|
|
196
|
-
datePublished: createdAt
|
|
197
|
-
dateModified: updatedAt
|
|
192
|
+
datePublished: createdAt?.toISOString(),
|
|
193
|
+
dateModified: updatedAt?.toISOString(),
|
|
198
194
|
isPartOf: { "@id": websiteSchemaId },
|
|
199
195
|
thumbnailUrl,
|
|
200
196
|
image,
|
|
@@ -206,8 +202,8 @@ export function configSEO(config) {
|
|
|
206
202
|
url,
|
|
207
203
|
name: pageTitle,
|
|
208
204
|
description: description,
|
|
209
|
-
datePublished: createdAt
|
|
210
|
-
dateModified: updatedAt
|
|
205
|
+
datePublished: createdAt?.toISOString(),
|
|
206
|
+
dateModified: updatedAt?.toISOString(),
|
|
211
207
|
isPartOf: { "@id": websiteSchemaId },
|
|
212
208
|
thumbnailUrl,
|
|
213
209
|
image,
|
|
@@ -244,7 +240,6 @@ export function configSEO(config) {
|
|
|
244
240
|
},
|
|
245
241
|
...additionalStructedData,
|
|
246
242
|
...images.map((file) => {
|
|
247
|
-
var _a, _b;
|
|
248
243
|
return {
|
|
249
244
|
"@type": "ImageObject",
|
|
250
245
|
"@id": `${url}/#${file.id}`,
|
|
@@ -252,8 +247,8 @@ export function configSEO(config) {
|
|
|
252
247
|
contentUrl: file.url,
|
|
253
248
|
name: file.alt,
|
|
254
249
|
description: file.alt,
|
|
255
|
-
width:
|
|
256
|
-
height:
|
|
250
|
+
width: file?.width?.toString(),
|
|
251
|
+
height: file?.height?.toString(),
|
|
257
252
|
creditText: config.copyright,
|
|
258
253
|
license: `${config.origin}/terms`,
|
|
259
254
|
copyrightNotice: config.copyright,
|
|
@@ -265,7 +260,7 @@ export function configSEO(config) {
|
|
|
265
260
|
}
|
|
266
261
|
function generateJSONLD() {
|
|
267
262
|
const structedData = getStructedData();
|
|
268
|
-
return (
|
|
263
|
+
return (_jsx("script", { type: "application/ld+json", dangerouslySetInnerHTML: {
|
|
269
264
|
__html: JSON.stringify(structedData).replace(/</g, "\\u003c"),
|
|
270
265
|
} }));
|
|
271
266
|
}
|
|
@@ -6,7 +6,7 @@ export declare function createSEOLoader<T, U extends JSX.IntrinsicAttributes & {
|
|
|
6
6
|
seo: SEO;
|
|
7
7
|
}>(fn?: LoaderFn<T, U>): {
|
|
8
8
|
meta: (props: T) => Promise<import("react-router").MetaFunction<unknown, Record<string, unknown>>>;
|
|
9
|
-
Page(Fc: React.FC<U>): (props: T) => Promise<JSX.Element>;
|
|
9
|
+
Page(Fc: React.FC<U>): (props: T) => Promise<import("react/jsx-runtime").JSX.Element>;
|
|
10
10
|
getData(): U;
|
|
11
11
|
wrap<V>(mapper: (props: U) => V | Promise<V>): (props: T) => Promise<V>;
|
|
12
12
|
};
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
2
|
import { createLoader } from "./loader";
|
|
2
|
-
import React from "react";
|
|
3
3
|
export function createSEOLoader(fn = () => ({})) {
|
|
4
4
|
const loader = createLoader(fn);
|
|
5
|
-
return
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} });
|
|
5
|
+
return {
|
|
6
|
+
...loader,
|
|
7
|
+
meta: loader.wrap((data) => data.seo.meta),
|
|
8
|
+
Page(Fc) {
|
|
9
|
+
return loader.wrap((data) => (_jsxs(_Fragment, { children: [data.seo?.generateJSONLD(), _jsx(Fc, { ...data })] })));
|
|
10
|
+
},
|
|
11
|
+
};
|
|
13
12
|
}
|