@nodus-lib/nodus 0.0.1 → 0.0.3

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/README.md CHANGED
@@ -1,52 +1,51 @@
1
1
  # next-session-inspector
2
2
 
3
- Next.js **미들웨어**에서 세션 쿠키(`nodus_session`)를 발급·유지하는 경량 패키지입니다.
3
+ Next.js 미들웨어에서 `nodus_session` 쿠키를 발급하고 유지하며, 방문 이벤트를 Nodus로 전송하는 경량 패키지입니다.
4
4
 
5
5
  ## 요구 사항
6
6
 
7
7
  - Node.js `>=18.18.0`
8
- - Next.js `>=14` (peer dependency)
8
+ - Next.js `>=14`
9
9
 
10
10
  ## 설치
11
11
 
12
12
  ```bash
13
- npm install next-session-inspector
13
+ npm install @nodus-lib/nodus
14
14
  ```
15
15
 
16
16
  ## 사용법
17
17
 
18
- 루트의 `middleware.ts`에서 그대로 재보냅니다.
18
+ 프로젝트의 `middleware.ts` 파일을 만들거나 수정합니다.
19
19
 
20
20
  ```ts
21
- export { middleware, config } from "next-session-inspector";
21
+ export { middleware, config } from "@nodus-lib/nodus";
22
22
  ```
23
23
 
24
- 또는 파일에 옮겨 적어도 됩니다.
24
+ Nodus 사이트 키를 환경 변수로 설정합니다.
25
25
 
26
- ```ts
27
- import type { NextRequest } from "next/server";
28
- import { NextResponse } from "next/server";
29
- import { middleware as baseMiddleware } from "next-session-inspector";
30
-
31
- export function middleware(request: NextRequest) {
32
- const res = baseMiddleware(request);
33
- // 추가 로직
34
- return res;
35
- }
26
+ ```env
27
+ NODUS_SITE_KEY=site_xxx
36
28
  ```
37
29
 
38
- (패키지가보내는 `middleware` 시그니처에 맞춰 호출하세요.)
30
+ ## 동작 방식
31
+
32
+ 미들웨어는 페이지 요청에서 실행되며, 기존 `nodus_session` 쿠키가 있으면 재사용하고 없으면 새로 발급합니다.
39
33
 
40
- ## 동작
34
+ 기본 matcher는 다음 요청을 제외합니다.
41
35
 
42
- - 쿠키 이름: `nodus_session`
43
- - 없으면 `crypto.randomUUID()`로 생성 후 설정
44
- - `httpOnly`, `sameSite: "lax"`, `secure: true`, `path: "/"`, 최대 수명 1년
36
+ - `/api`
37
+ - `/_next/static`
38
+ - `/_next/image`
39
+ - `/favicon.ico`
40
+ - `/sitemap.xml`
41
+ - `/robots.txt`
45
42
 
46
- ## `config.matcher`
43
+ 사이트 키가 설정되어 있으면 방문 이벤트를 전송합니다.
47
44
 
48
- 기본 matcher는 정적 자산·`api`·favicon 등을 제외한 페이지 위주 경로입니다. 필요하면 앱 쪽 `middleware.ts`에서 `config`만 덮어쓰면 됩니다.
45
+ - `session_id`
46
+ - `last_page`
47
+ - `current_page`
49
48
 
50
49
  ## 라이선스
51
50
 
52
- MIT — `LICENSE` 파일 참고.
51
+ MIT
@@ -0,0 +1 @@
1
+ export { config, middleware } from "./next/middleware";
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.middleware = exports.config = void 0;
4
+ var middleware_1 = require("./next/middleware");
5
+ Object.defineProperty(exports, "config", { enumerable: true, get: function () { return middleware_1.config; } });
6
+ Object.defineProperty(exports, "middleware", { enumerable: true, get: function () { return middleware_1.middleware; } });
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,10 @@
1
+ export interface NodusBaseRequest {
2
+ session_id: string;
3
+ }
4
+ interface Prop<T extends NodusBaseRequest> {
5
+ data: T;
6
+ url: string;
7
+ key: string;
8
+ }
9
+ export declare function nodus_server_caller<T extends NodusBaseRequest>({ data, url, key }: Prop<T>): void;
10
+ export {};
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.nodus_server_caller = nodus_server_caller;
4
+ function nodus_server_caller({ data, url, key }) {
5
+ void fetch(`https://api.ministudiolab.com/sdk/${url}?key=${key}`, {
6
+ method: "POST",
7
+ headers: {
8
+ "Content-Type": "application/json",
9
+ },
10
+ body: JSON.stringify(data),
11
+ });
12
+ }
@@ -0,0 +1,6 @@
1
+ import { NodusBaseRequest } from "./nodus-server-caller";
2
+ export interface NodusVisitEventProp extends NodusBaseRequest {
3
+ last_page: string;
4
+ current_page: string;
5
+ }
6
+ export declare function nodus_visit_event(NodusVisitEventProp: NodusVisitEventProp, key: string): void;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.nodus_visit_event = nodus_visit_event;
4
+ const nodus_server_caller_1 = require("./nodus-server-caller");
5
+ function nodus_visit_event(NodusVisitEventProp, key) {
6
+ (0, nodus_server_caller_1.nodus_server_caller)({
7
+ data: NodusVisitEventProp,
8
+ url: "visit",
9
+ key: key
10
+ });
11
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.config = void 0;
4
+ exports.middleware = middleware;
5
+ const server_1 = require("next/server");
6
+ const nodus_server_manager_1 = require("../logger/nodus-server-manager");
7
+ const nodus_session_1 = require("../session/nodus-session");
8
+ function middleware(request) {
9
+ const response = server_1.NextResponse.next();
10
+ const sessionId = (0, nodus_session_1.nodus_cookie_manager)(request, response);
11
+ const key = process.env.NODUS_SITE_KEY ?? process.env.NEXT_PUBLIC_NODUS_SITE_KEY;
12
+ if (key) {
13
+ (0, nodus_server_manager_1.nodus_visit_event)({
14
+ session_id: sessionId,
15
+ last_page: request.headers.get("referer") || "",
16
+ current_page: request.url,
17
+ }, key);
18
+ }
19
+ return response;
20
+ }
21
+ exports.config = {
22
+ matcher: [
23
+ "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)",
24
+ ],
25
+ };
@@ -0,0 +1,2 @@
1
+ import type { NextRequest, NextResponse } from "next/server";
2
+ export declare function nodus_cookie_manager(request: NextRequest, response: NextResponse): string;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.nodus_cookie_manager = nodus_cookie_manager;
4
+ const COOKIE_NAME = "nodus_session";
5
+ const COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
6
+ function nodus_cookie_manager(request, response) {
7
+ const existingSession = request.cookies.get(COOKIE_NAME)?.value;
8
+ if (existingSession) {
9
+ return existingSession;
10
+ }
11
+ const sessionId = crypto.randomUUID();
12
+ response.cookies.set(COOKIE_NAME, sessionId, {
13
+ httpOnly: true,
14
+ sameSite: "lax",
15
+ secure: true,
16
+ path: "/",
17
+ maxAge: COOKIE_MAX_AGE_SECONDS,
18
+ });
19
+ return sessionId;
20
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodus-lib/nodus",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -15,12 +15,12 @@
15
15
  "middleware"
16
16
  ],
17
17
  "sideEffects": false,
18
- "main": "dist/nodus-config.js",
19
- "types": "dist/nodus-config.d.ts",
18
+ "main": "dist/index.js",
19
+ "types": "dist/index.d.ts",
20
20
  "exports": {
21
21
  ".": {
22
- "types": "./dist/nodus-config.d.ts",
23
- "default": "./dist/nodus-config.js"
22
+ "types": "./dist/index.d.ts",
23
+ "default": "./dist/index.js"
24
24
  }
25
25
  },
26
26
  "files": [
@@ -32,9 +32,12 @@
32
32
  "node": ">=18.18.0"
33
33
  },
34
34
  "scripts": {
35
+ "prebuild": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
35
36
  "build": "tsc -p tsconfig.json",
36
37
  "check": "tsc --noEmit -p tsconfig.json",
37
- "prepublishOnly": "npm run build"
38
+ "prepublishOnly": "npm run build",
39
+ "test": "vitest run --config vitest.config.ts",
40
+ "test:watch": "vitest"
38
41
  },
39
42
  "peerDependencies": {
40
43
  "next": ">=14.0.0"
@@ -47,9 +50,11 @@
47
50
  "devDependencies": {
48
51
  "@types/node": "^24.7.2",
49
52
  "@types/react": "^18.3.12",
50
- "next": "^14.2.18",
53
+ "jsdom": "^29.1.1",
54
+ "next": "^16.2.6",
51
55
  "react": "^18.3.1",
52
56
  "react-dom": "^18.3.1",
53
- "typescript": "^5.9.3"
57
+ "typescript": "^5.9.3",
58
+ "vitest": "^4.1.6"
54
59
  }
55
60
  }
@@ -1,25 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.config = void 0;
4
- exports.middleware = middleware;
5
- const server_1 = require("next/server");
6
- const COOKIE_NAME = "nodus_session";
7
- const COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
8
- function middleware(request) {
9
- const response = server_1.NextResponse.next();
10
- const existingSession = request.cookies.get(COOKIE_NAME)?.value;
11
- const cookieValue = existingSession ?? crypto.randomUUID();
12
- response.cookies.set(COOKIE_NAME, cookieValue, {
13
- httpOnly: true,
14
- sameSite: "lax",
15
- secure: true,
16
- path: "/",
17
- maxAge: COOKIE_MAX_AGE_SECONDS,
18
- });
19
- return response;
20
- }
21
- exports.config = {
22
- matcher: [
23
- "/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)",
24
- ],
25
- };