@uniai-fe/uds-templates 0.1.30 → 0.1.31

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniai-fe/uds-templates",
3
- "version": "0.1.30",
3
+ "version": "0.1.31",
4
4
  "description": "UNIAI Design System; UI Templates Package",
5
5
  "type": "module",
6
6
  "private": false,
@@ -6,7 +6,7 @@ import type {
6
6
  } from "../types";
7
7
  import { getQueryString } from "@uniai-fe/util-functions";
8
8
 
9
- export const getCctvCompanyList = async ({
9
+ export const getClientCctvCompanyList = async ({
10
10
  username,
11
11
  url,
12
12
  }: {
@@ -14,7 +14,9 @@ export const getCctvCompanyList = async ({
14
14
  url?: string;
15
15
  }) =>
16
16
  await (
17
- await fetch(`${url ?? "/api/cctv/company-list"}${getQueryString(username)}`)
17
+ await fetch(
18
+ `${url ?? "/api/cctv/company-list"}${getQueryString({ username })}`,
19
+ )
18
20
  ).json();
19
21
 
20
22
  export const useQueryCctvCompanyList = ({
@@ -26,7 +28,7 @@ export const useQueryCctvCompanyList = ({
26
28
  }): UseQueryResult<{ data: API_Res_CctvCompanyGroup[]; total_count: number }> =>
27
29
  useQuery({
28
30
  queryKey: ["cctv_company_list", username, url],
29
- queryFn: () => getCctvCompanyList({ username, url }),
31
+ queryFn: () => getClientCctvCompanyList({ username, url }),
30
32
  enabled: Boolean(username),
31
33
  });
32
34
 
@@ -1,10 +1,14 @@
1
1
  import {
2
+ fetchWithBody,
2
3
  generateBackendQueryUrl_GET,
3
4
  nextAPILog,
4
5
  } from "@uniai-fe/util-functions";
5
6
  import type {
6
7
  API_Req_GetCompanyListParams,
8
+ API_Req_GetCctvTokenParams,
9
+ API_Req_CctvRtcTokenOrigin,
7
10
  API_Res_CctvCompanyGroup,
11
+ API_Res_CctvRtcToken,
8
12
  } from "../types";
9
13
 
10
14
  export const GROUP_PRESET: API_Res_CctvCompanyGroup[] = [
@@ -125,7 +129,7 @@ export function classifyGroups(
125
129
  }
126
130
 
127
131
  /**
128
- * CCTV; API route.ts 로직
132
+ * CCTV; company-list API route.ts 로직
129
133
  * @api
130
134
  * @route /v1/users/{username}/cctvs
131
135
  * @param {API_Req_GetCompanyListParams} params
@@ -134,7 +138,7 @@ export function classifyGroups(
134
138
  * @property {string} [queryUrl] 백엔드 요청 url
135
139
  * @property {URLSearchParams | object} searchParams 요청 searchParams
136
140
  */
137
- export async function getCompanyList({
141
+ export async function getServerCompanyList({
138
142
  domain,
139
143
  routeUrl,
140
144
  queryUrl,
@@ -186,3 +190,104 @@ export async function getCompanyList({
186
190
  };
187
191
  }
188
192
  }
193
+
194
+ /**
195
+ * CCTV; token API route.ts 로직
196
+ * @api
197
+ * @route /token
198
+ * @param {API_Req_GetCctvTokenParams} params
199
+ * @property {string} domain API 요청 도메인(서버)
200
+ * @property {string} routeUrl Next.js app/api 이하 경로 url
201
+ * @property {string} [queryUrl] 백엔드 요청 url
202
+ * @property {NextRequest} req Next.js API body 데이터
203
+ */
204
+ export async function getServerCctvToken({
205
+ domain,
206
+ routeUrl,
207
+ queryUrl,
208
+ req,
209
+ headers,
210
+ }: API_Req_GetCctvTokenParams): Promise<{
211
+ res: API_Res_CctvRtcToken;
212
+ domain: string;
213
+ queryUrl: string;
214
+ options?: ResponseInit;
215
+ }> {
216
+ const query_url = queryUrl || "/token";
217
+ const reqBody = await req.json();
218
+
219
+ const API_OPTION = {
220
+ domain,
221
+ queryUrl: query_url,
222
+ };
223
+
224
+ const alternateResponse: API_Res_CctvRtcToken = {
225
+ token: "",
226
+ };
227
+
228
+ const BODY_PRESET: API_Req_CctvRtcTokenOrigin = {
229
+ site: "company_id",
230
+ username: "harim",
231
+ password: "harim",
232
+ action: "read",
233
+ path: "cam_id",
234
+ ttl_seconds: 3600,
235
+ kid: "streaming-auth-1",
236
+ };
237
+
238
+ if (!reqBody || !reqBody.username || !reqBody.company_id || !reqBody.cam_id) {
239
+ return {
240
+ res: alternateResponse,
241
+ ...API_OPTION,
242
+ options: {
243
+ status: 400,
244
+ statusText: "토큰 요청 파라미터가 올바르지 않습니다.",
245
+ },
246
+ };
247
+ }
248
+
249
+ const site = !isNaN(Number(reqBody.company_id))
250
+ ? `farm${reqBody.company_id}`
251
+ : String(reqBody.company_id);
252
+ const username = reqBody.username;
253
+ const password = reqBody.password || reqBody.username;
254
+ const path = !isNaN(Number(reqBody.cam_id))
255
+ ? `cam${reqBody.cam_id}`
256
+ : String(reqBody.cam_id);
257
+
258
+ // 토큰 요청 payload 구성
259
+ const bodyData: API_Req_CctvRtcTokenOrigin = {
260
+ ...BODY_PRESET,
261
+ site,
262
+ username,
263
+ password,
264
+ path,
265
+ };
266
+
267
+ try {
268
+ const res = await fetchWithBody<
269
+ API_Req_CctvRtcTokenOrigin,
270
+ API_Res_CctvRtcToken
271
+ >({
272
+ method: "POST",
273
+ routeUrl,
274
+ ...API_OPTION,
275
+ headers: {
276
+ accept: "application/json",
277
+ "Content-Type": "application/json",
278
+ ...(headers || {}),
279
+ },
280
+ bodyData,
281
+ alternateResponse,
282
+ });
283
+
284
+ return { res, ...API_OPTION };
285
+ } catch (error) {
286
+ nextAPILog("POST", routeUrl, query_url, { error });
287
+ return {
288
+ res: alternateResponse,
289
+ ...API_OPTION,
290
+ options: { status: 500 },
291
+ };
292
+ }
293
+ }
@@ -1,4 +1,5 @@
1
1
  import type { UtilQueryBaseParams } from "@uniai-fe/util-functions";
2
+ import type { NextRequest } from "next/server";
2
3
 
3
4
  /**
4
5
  * CCTV; api getCompanyList params
@@ -109,15 +110,72 @@ export interface API_Res_CctvCompanyGroup {
109
110
  }
110
111
 
111
112
  /**
112
- * CCTV; 실시간 스트리밍 토큰 요청
113
+ * CCTV; 실시간 스트리밍 토큰 요청 (Next.js API 요청)
113
114
  * @property {string} company_id 업체 id코드
114
115
  * @property {string} cam_id 카메라 id코드
115
- * @property {string} username 사용자명
116
+ * @property {string} username 사용자 계정 아이디
116
117
  */
117
118
  export interface API_Req_CctvRtcToken {
118
- company_id: string;
119
- cam_id: string;
119
+ /**
120
+ * 업체 id 코드
121
+ */
122
+ company_id: number | string;
123
+ /**
124
+ * 카메라 id 코드
125
+ */
126
+ cam_id: number | string;
127
+ /**
128
+ * 사용자 계정 아이디
129
+ */
120
130
  username: string;
131
+ /**
132
+ * 사용자 계정 비밀번호
133
+ */
134
+ password?: string;
135
+ }
136
+
137
+ /**
138
+ * CCTV; 실시간 스트리밍 토큰 요청 (백엔드 요청)
139
+ * @property {string} site company_id 맵핑 (ex. farm102)
140
+ * @property {string} username 사용자 계정 아이디
141
+ * @property {string} password 사용자 계정 비밀번호 (대체로 계정 아이디 맵핑)
142
+ * @property {string} action "read"
143
+ * @property {string} path cam_id 맵핑 (ex. cam3)
144
+ * @property {number} ttl_seconds 시간? (default 3600)
145
+ * @property {string} kid "streaming-auth-1"
146
+ */
147
+ export interface API_Req_CctvRtcTokenOrigin {
148
+ /**
149
+ * company_id 맵핑
150
+ * ex) farm102
151
+ */
152
+ site: string;
153
+ /**
154
+ * 사용자 계정 아이디
155
+ */
156
+ username: string;
157
+ /**
158
+ * 사용자 계정 비밀번호
159
+ * - 대체로 계정 아이디 맵핑
160
+ */
161
+ password: string;
162
+ /**
163
+ * "read"
164
+ */
165
+ action: string;
166
+ /**
167
+ * cam_id 맵핑
168
+ * ex) cam3
169
+ */
170
+ path: string;
171
+ /**
172
+ * default) 3600
173
+ */
174
+ ttl_seconds: number;
175
+ /**
176
+ * "streaming-auth-1"
177
+ */
178
+ kid: string;
121
179
  }
122
180
 
123
181
  /**
@@ -125,6 +183,10 @@ export interface API_Req_CctvRtcToken {
125
183
  * @property {string} token 인증 토큰
126
184
  */
127
185
  export interface API_Res_CctvRtcToken {
186
+ /**
187
+ * JWT 인증 토큰
188
+ * Bearer
189
+ */
128
190
  token: string;
129
191
  }
130
192
 
@@ -164,3 +226,38 @@ export interface API_Req_CctvStreamToken {
164
226
  */
165
227
  cam_id: string;
166
228
  }
229
+
230
+ /**
231
+ * CCTV; 서버 토큰 요청 파라미터
232
+ * @property {string} domain API 요청 도메인(서버)
233
+ * @property {string} routeUrl Next.js app/api 이하 경로 url
234
+ * @property {string} [queryUrl] 백엔드 요청 url
235
+ * @property {string} username 사용자 아이디
236
+ * @property {string} company_id 업체 id코드(site)
237
+ * @property {string} cam_id 카메라 id코드
238
+ * @property {string} [password] 사용자 비밀번호 (없으면 username 사용)
239
+ * @property {number} [ttl_seconds] 토큰 만료시간
240
+ * @property {string} [kid] 키 id
241
+ * @property {Record<string, string>} [headers] 추가 요청 헤더
242
+ */
243
+ export type API_Req_CctvTokenPreset = Partial<
244
+ Pick<API_Req_CctvRtcTokenOrigin, "password" | "ttl_seconds" | "kid">
245
+ >;
246
+
247
+ export interface API_Req_GetCctvTokenParams extends Omit<
248
+ UtilQueryBaseParams,
249
+ "queryUrl"
250
+ > {
251
+ /**
252
+ * 백엔드 요청 url
253
+ */
254
+ queryUrl?: string;
255
+ /**
256
+ * Next.js API 요청 body
257
+ */
258
+ req: NextRequest;
259
+ /**
260
+ * 추가 요청 헤더
261
+ */
262
+ headers?: Record<string, string>;
263
+ }