dn-react-router-toolkit 0.7.6 → 0.7.7

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.
@@ -1,4 +1,11 @@
1
1
  export { createAPIHandler } from './create_handler.mjs';
2
+ export { APIHandlerOptions, apiHandler } from './create_api_handler.mjs';
3
+ export { ItemAPIHandlerOptions, itemApiHandler } from './item_api_handler.mjs';
2
4
  import 'react-router';
3
5
  import 'dn-react-toolkit/auth/server';
4
6
  import 'dn-react-toolkit/file/server';
7
+ import 'drizzle-orm';
8
+ import '../table/repository.mjs';
9
+ import 'drizzle-orm/pg-core';
10
+ import '../auth/with_auth.mjs';
11
+ import 'dn-react-toolkit/auth';
@@ -1,4 +1,11 @@
1
1
  export { createAPIHandler } from './create_handler.js';
2
+ export { APIHandlerOptions, apiHandler } from './create_api_handler.js';
3
+ export { ItemAPIHandlerOptions, itemApiHandler } from './item_api_handler.js';
2
4
  import 'react-router';
3
5
  import 'dn-react-toolkit/auth/server';
4
6
  import 'dn-react-toolkit/file/server';
7
+ import 'drizzle-orm';
8
+ import '../table/repository.js';
9
+ import 'drizzle-orm/pg-core';
10
+ import '../auth/with_auth.js';
11
+ import 'dn-react-toolkit/auth';
package/dist/api/index.js CHANGED
@@ -20,7 +20,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/api/index.ts
21
21
  var api_exports = {};
22
22
  __export(api_exports, {
23
- createAPIHandler: () => createAPIHandler
23
+ apiHandler: () => apiHandler,
24
+ createAPIHandler: () => createAPIHandler,
25
+ itemApiHandler: () => itemApiHandler
24
26
  });
25
27
  module.exports = __toCommonJS(api_exports);
26
28
 
@@ -237,7 +239,166 @@ var createAPIHandler = ({
237
239
  };
238
240
  return handler;
239
241
  };
242
+
243
+ // src/api/create_api_handler.ts
244
+ var import_http2 = require("dn-react-toolkit/http");
245
+ var import_drizzle_orm = require("drizzle-orm");
246
+ var import_react_router2 = require("react-router");
247
+ var import_uuid2 = require("uuid");
248
+
249
+ // src/crud/serialize.ts
250
+ function deserialize(data) {
251
+ if (data === void 0) {
252
+ return void 0;
253
+ }
254
+ if (typeof data === "object" && data !== null && "type" in data && "value" in data) {
255
+ const { type, value } = data;
256
+ switch (type) {
257
+ case "null":
258
+ return null;
259
+ case "string":
260
+ return value;
261
+ case "number":
262
+ return value;
263
+ case "boolean":
264
+ return value;
265
+ case "date":
266
+ return new Date(value);
267
+ case "array":
268
+ return value.map((item) => deserialize(item));
269
+ case "object":
270
+ return Object.entries(value).reduce(
271
+ (acc, [key, value2]) => {
272
+ return {
273
+ ...acc,
274
+ [key]: deserialize(value2)
275
+ };
276
+ },
277
+ {}
278
+ );
279
+ default:
280
+ return void 0;
281
+ }
282
+ }
283
+ return void 0;
284
+ }
285
+
286
+ // src/api/create_api_handler.ts
287
+ function apiHandler({
288
+ withAuthAction,
289
+ repository,
290
+ validators,
291
+ existingConditions,
292
+ injectUserId,
293
+ roles
294
+ }) {
295
+ const loader = async ({ request }) => {
296
+ return {};
297
+ };
298
+ const action = withAuthAction((auth) => async ({ request }) => {
299
+ if (roles && roles.length > 0 && (!auth || !roles.includes(auth.role))) {
300
+ throw (0, import_http2.UNAUTHORIZED)();
301
+ }
302
+ switch (request.method) {
303
+ case "POST":
304
+ case "PUT": {
305
+ try {
306
+ const serilaizedParams = await request.json();
307
+ const params = deserialize(serilaizedParams);
308
+ if (validators) {
309
+ const paramsForValidation = Object.keys(validators).filter(
310
+ (key) => Object.prototype.hasOwnProperty.call(validators, key)
311
+ );
312
+ for (const paramKey of paramsForValidation) {
313
+ const value = params[paramKey];
314
+ const validator = validators[paramKey];
315
+ if (validator?.validate && !validator.validate(value)) {
316
+ throw (0, import_http2.BAD_REQUEST)(
317
+ validator.message ? validator.message(value) : void 0
318
+ );
319
+ }
320
+ }
321
+ }
322
+ const itemId = params.id || (0, import_uuid2.v4)();
323
+ if (!params.id && existingConditions) {
324
+ const paramsForExistenceCheck = Object.keys(
325
+ existingConditions
326
+ ).filter(
327
+ (key) => Object.prototype.hasOwnProperty.call(params, key)
328
+ );
329
+ if (paramsForExistenceCheck.length > 0) {
330
+ const where = (0, import_drizzle_orm.and)(
331
+ ...paramsForExistenceCheck.reduce((acc, key) => {
332
+ const condition = existingConditions[key];
333
+ if (condition) {
334
+ acc.push(condition(params[key]));
335
+ }
336
+ return acc;
337
+ }, [])
338
+ );
339
+ const existing = await repository.findAll({
340
+ limit: 1,
341
+ where
342
+ });
343
+ if (existing.length > 0) {
344
+ throw (0, import_http2.CONFLICT)("\uC790\uB8CC\uAC00 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4.");
345
+ }
346
+ }
347
+ }
348
+ const values = {
349
+ id: itemId,
350
+ userId: injectUserId ? auth?.userId : void 0,
351
+ ...params
352
+ };
353
+ const item = await repository.save(values);
354
+ return (0, import_http2.CREATED)(item);
355
+ } catch (error) {
356
+ if (error instanceof Error) {
357
+ throw (0, import_http2.INTERNAL_SERVER_ERROR)(error.message);
358
+ }
359
+ throw error;
360
+ }
361
+ }
362
+ default:
363
+ throw (0, import_http2.METHOD_NOT_ALLOWED)();
364
+ }
365
+ });
366
+ return {
367
+ loader,
368
+ action
369
+ };
370
+ }
371
+
372
+ // src/api/item_api_handler.ts
373
+ var import_http3 = require("dn-react-toolkit/http");
374
+ var import_react_router3 = require("react-router");
375
+ function itemApiHandler({
376
+ withAuthAction,
377
+ repository
378
+ }) {
379
+ const loader = async ({ request }) => {
380
+ return {};
381
+ };
382
+ const action = withAuthAction((auth) => async ({ params, request }) => {
383
+ if (!auth || auth.role !== "admin") {
384
+ return (0, import_http3.UNAUTHORIZED)();
385
+ }
386
+ switch (request.method) {
387
+ case "DELETE": {
388
+ const itemId = params.itemId;
389
+ await repository.delete(itemId);
390
+ return {};
391
+ }
392
+ }
393
+ });
394
+ return {
395
+ loader,
396
+ action
397
+ };
398
+ }
240
399
  // Annotate the CommonJS export names for ESM import in node:
241
400
  0 && (module.exports = {
242
- createAPIHandler
401
+ apiHandler,
402
+ createAPIHandler,
403
+ itemApiHandler
243
404
  });
@@ -225,6 +225,174 @@ var createAPIHandler = ({
225
225
  };
226
226
  return handler;
227
227
  };
228
+
229
+ // src/api/create_api_handler.ts
230
+ import {
231
+ BAD_REQUEST,
232
+ CONFLICT,
233
+ CREATED,
234
+ INTERNAL_SERVER_ERROR,
235
+ METHOD_NOT_ALLOWED,
236
+ UNAUTHORIZED
237
+ } from "dn-react-toolkit/http";
238
+ import {
239
+ and
240
+ } from "drizzle-orm";
241
+ import "react-router";
242
+ import { v4 as v42 } from "uuid";
243
+
244
+ // src/crud/serialize.ts
245
+ function deserialize(data) {
246
+ if (data === void 0) {
247
+ return void 0;
248
+ }
249
+ if (typeof data === "object" && data !== null && "type" in data && "value" in data) {
250
+ const { type, value } = data;
251
+ switch (type) {
252
+ case "null":
253
+ return null;
254
+ case "string":
255
+ return value;
256
+ case "number":
257
+ return value;
258
+ case "boolean":
259
+ return value;
260
+ case "date":
261
+ return new Date(value);
262
+ case "array":
263
+ return value.map((item) => deserialize(item));
264
+ case "object":
265
+ return Object.entries(value).reduce(
266
+ (acc, [key, value2]) => {
267
+ return {
268
+ ...acc,
269
+ [key]: deserialize(value2)
270
+ };
271
+ },
272
+ {}
273
+ );
274
+ default:
275
+ return void 0;
276
+ }
277
+ }
278
+ return void 0;
279
+ }
280
+
281
+ // src/api/create_api_handler.ts
282
+ function apiHandler({
283
+ withAuthAction,
284
+ repository,
285
+ validators,
286
+ existingConditions,
287
+ injectUserId,
288
+ roles
289
+ }) {
290
+ const loader = async ({ request }) => {
291
+ return {};
292
+ };
293
+ const action = withAuthAction((auth) => async ({ request }) => {
294
+ if (roles && roles.length > 0 && (!auth || !roles.includes(auth.role))) {
295
+ throw UNAUTHORIZED();
296
+ }
297
+ switch (request.method) {
298
+ case "POST":
299
+ case "PUT": {
300
+ try {
301
+ const serilaizedParams = await request.json();
302
+ const params = deserialize(serilaizedParams);
303
+ if (validators) {
304
+ const paramsForValidation = Object.keys(validators).filter(
305
+ (key) => Object.prototype.hasOwnProperty.call(validators, key)
306
+ );
307
+ for (const paramKey of paramsForValidation) {
308
+ const value = params[paramKey];
309
+ const validator = validators[paramKey];
310
+ if (validator?.validate && !validator.validate(value)) {
311
+ throw BAD_REQUEST(
312
+ validator.message ? validator.message(value) : void 0
313
+ );
314
+ }
315
+ }
316
+ }
317
+ const itemId = params.id || v42();
318
+ if (!params.id && existingConditions) {
319
+ const paramsForExistenceCheck = Object.keys(
320
+ existingConditions
321
+ ).filter(
322
+ (key) => Object.prototype.hasOwnProperty.call(params, key)
323
+ );
324
+ if (paramsForExistenceCheck.length > 0) {
325
+ const where = and(
326
+ ...paramsForExistenceCheck.reduce((acc, key) => {
327
+ const condition = existingConditions[key];
328
+ if (condition) {
329
+ acc.push(condition(params[key]));
330
+ }
331
+ return acc;
332
+ }, [])
333
+ );
334
+ const existing = await repository.findAll({
335
+ limit: 1,
336
+ where
337
+ });
338
+ if (existing.length > 0) {
339
+ throw CONFLICT("\uC790\uB8CC\uAC00 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4.");
340
+ }
341
+ }
342
+ }
343
+ const values = {
344
+ id: itemId,
345
+ userId: injectUserId ? auth?.userId : void 0,
346
+ ...params
347
+ };
348
+ const item = await repository.save(values);
349
+ return CREATED(item);
350
+ } catch (error) {
351
+ if (error instanceof Error) {
352
+ throw INTERNAL_SERVER_ERROR(error.message);
353
+ }
354
+ throw error;
355
+ }
356
+ }
357
+ default:
358
+ throw METHOD_NOT_ALLOWED();
359
+ }
360
+ });
361
+ return {
362
+ loader,
363
+ action
364
+ };
365
+ }
366
+
367
+ // src/api/item_api_handler.ts
368
+ import { UNAUTHORIZED as UNAUTHORIZED2 } from "dn-react-toolkit/http";
369
+ import "react-router";
370
+ function itemApiHandler({
371
+ withAuthAction,
372
+ repository
373
+ }) {
374
+ const loader = async ({ request }) => {
375
+ return {};
376
+ };
377
+ const action = withAuthAction((auth) => async ({ params, request }) => {
378
+ if (!auth || auth.role !== "admin") {
379
+ return UNAUTHORIZED2();
380
+ }
381
+ switch (request.method) {
382
+ case "DELETE": {
383
+ const itemId = params.itemId;
384
+ await repository.delete(itemId);
385
+ return {};
386
+ }
387
+ }
388
+ });
389
+ return {
390
+ loader,
391
+ action
392
+ };
393
+ }
228
394
  export {
229
- createAPIHandler
395
+ apiHandler,
396
+ createAPIHandler,
397
+ itemApiHandler
230
398
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dn-react-router-toolkit",
3
- "version": "0.7.6",
3
+ "version": "0.7.7",
4
4
  "types": "./dist/index.d.ts",
5
5
  "main": "./dist/index.mjs",
6
6
  "module": "./dist/index.js",