@gaonjs/vue 0.1.2 → 0.1.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/index.d.ts +2 -0
- package/dist/index.js +7 -1
- package/dist/pageProps.d.ts +15 -0
- package/dist/pageProps.js +23 -0
- package/dist/serialize.d.ts +17 -0
- package/dist/serialize.js +51 -0
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @gaonjs/vue — Gaon 프론트엔드 어댑터 첫 구현 (Vue 3 · Inertia 브리지 · SSR).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* 전체 어댑터(Inertia 브리지·SSR)는 후속 마일스톤이다. M3 에서는 타입
|
|
5
|
+
* 브리지의 Vue 쪽 끝인 pageProps 를 제공한다(§6.2) — 스키마→.vue 타입
|
|
6
|
+
* 체인의 마지막 고리.
|
|
5
7
|
*/
|
|
6
8
|
import { VERSION } from "@gaonjs/core";
|
|
7
9
|
export const version = VERSION;
|
|
8
10
|
export const status = "planned";
|
|
11
|
+
// 타입 브리지 (M3) — GaonRouteMap[K] → 페이지 props 타입
|
|
12
|
+
export { pageProps } from "./pageProps.js";
|
|
13
|
+
// 직렬화 경계 (M4) — Rec → JSON-safe 페이지 props (Date/bigint→string, hidden 제외)
|
|
14
|
+
export { serializeProps } from "./serialize.js";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Rendered } from '@gaonjs/web';
|
|
2
|
+
import type { Serialized } from './serialize.js';
|
|
3
|
+
declare global {
|
|
4
|
+
interface GaonRouteMap {
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
type PropsOf<F> = F extends (...args: never[]) => infer R ? Awaited<R> extends Rendered<infer P> ? P : never : never;
|
|
8
|
+
/**
|
|
9
|
+
* 페이지의 props 타입을 라우트 이름으로 가져온다.
|
|
10
|
+
* `const { posts } = pageProps<'posts#index'>()`
|
|
11
|
+
* 런타임 값은 Inertia 가 주입한 실제 페이지 props 로 대체된다(M4 브리지 —
|
|
12
|
+
* serializeProps 를 통과한 JSON-safe 값).
|
|
13
|
+
*/
|
|
14
|
+
export declare function pageProps<K extends keyof GaonRouteMap>(): Serialized<PropsOf<GaonRouteMap[K]>>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// @gaonjs/vue · pageProps — 라우트 이름 문자열 → 컨트롤러 반환 props 타입.
|
|
2
|
+
//
|
|
3
|
+
// 타입 브리지의 Vue 쪽 끝(§6.2). `.gaon/routes.d.ts` 가 declaration
|
|
4
|
+
// merging 으로 GaonRouteMap 을 채우면(라우트 이름 → 컨트롤러 액션 타입),
|
|
5
|
+
// pageProps<'posts#index'>() 가 그 액션의 render props 타입을 돌려준다.
|
|
6
|
+
//
|
|
7
|
+
// 스키마→모델→컨트롤러→(생성된 라우트 지도)→페이지로 이어지는 타입
|
|
8
|
+
// 체인의 마지막 고리다. 스키마에서 컬럼을 지우면 .vue 템플릿의 사용
|
|
9
|
+
// 지점에서 vue-tsc 가 에러를 낸다(완료 기준).
|
|
10
|
+
//
|
|
11
|
+
// 반환 타입은 깊은 직렬화 경계 Serialized<P> 로 승격된다(M4). 컨트롤러가
|
|
12
|
+
// 넘긴 raw props(Date·bigint·모델 메서드·hidden 포함)가 아니라, 페이지가
|
|
13
|
+
// 실제로 받는 JSON-safe 모양이다 — Date/bigint 는 문자열, hidden 컬럼은
|
|
14
|
+
// 존재하지 않으므로 접근 시 컴파일 에러가 난다(§4.2 완료 기준).
|
|
15
|
+
/**
|
|
16
|
+
* 페이지의 props 타입을 라우트 이름으로 가져온다.
|
|
17
|
+
* `const { posts } = pageProps<'posts#index'>()`
|
|
18
|
+
* 런타임 값은 Inertia 가 주입한 실제 페이지 props 로 대체된다(M4 브리지 —
|
|
19
|
+
* serializeProps 를 통과한 JSON-safe 값).
|
|
20
|
+
*/
|
|
21
|
+
export function pageProps() {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IsHidden } from '@gaonjs/core';
|
|
2
|
+
/**
|
|
3
|
+
* 서버 타입 `T`(Date·bigint·메서드·hidden 포함) → 페이지가 받는 JSON-safe 타입.
|
|
4
|
+
*
|
|
5
|
+
* 규칙: Date→string, bigint→string, 함수→제외, 배열·객체는 재귀.
|
|
6
|
+
* 객체에서 hidden 브랜드가 붙은 키와 함수 값 키는 결과에서 빠진다.
|
|
7
|
+
*/
|
|
8
|
+
export type Serialized<T> = T extends Date ? string : T extends bigint ? string : T extends (...args: never[]) => unknown ? never : T extends ReadonlyArray<infer U> ? Array<Serialized<U>> : T extends object ? SerializedObject<T> : T;
|
|
9
|
+
type SerializedObject<T> = {
|
|
10
|
+
[K in keyof T as IsHidden<T[K]> extends true ? never : T[K] extends (...args: never[]) => unknown ? never : K]: Serialized<T[K]>;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* 컨트롤러 props 를 JSON-safe 페이지 props 로 변환한다(Inertia 브리지).
|
|
14
|
+
* Date→ISO 문자열, bigint→문자열, 함수 제거, hidden 컬럼 제외, 중첩 재귀.
|
|
15
|
+
*/
|
|
16
|
+
export declare function serializeProps<T>(value: T): Serialized<T>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// @gaonjs/vue · 직렬화 경계 (M4 — Rec → Serialized 깊은 매핑 + 런타임)
|
|
2
|
+
//
|
|
3
|
+
// 서버의 레코드는 그대로 JSON 이 아니다(§4.4). 모델 메서드·관계 함수가
|
|
4
|
+
// 붙어 있고, Date·bigint 는 JSON 위에서 문자열이 되며(bigint 는 애초에
|
|
5
|
+
// JSON.stringify 가 던진다), hidden 컬럼은 노출되면 안 된다(§4.2).
|
|
6
|
+
//
|
|
7
|
+
// 이 경계에서 두 가지가 맞물린다:
|
|
8
|
+
// · 타입: Serialized<P> 가 페이지가 실제로 받는 JSON-safe 모양을 계산한다
|
|
9
|
+
// (Date/bigint → string, 함수·hidden 제외, 중첩·배열 재귀). pageProps<K>()
|
|
10
|
+
// 의 반환 타입을 이 매핑으로 승격한다.
|
|
11
|
+
// · 런타임: serializeProps() 가 컨트롤러 props 를 같은 규칙으로 변환한다.
|
|
12
|
+
// Inertia 브리지가 페이지에 넘기기 직전 이 함수를 통과시킨다.
|
|
13
|
+
//
|
|
14
|
+
// hidden 지식의 출처는 @gaonjs/data 다(RowOf 브랜딩 + 레코드의 HIDDEN_COLUMNS
|
|
15
|
+
// 마커). 여기서는 그 브랜드/마커를 감지해 떨구기만 한다 — 책임 분리(§13.5 M4).
|
|
16
|
+
import { HIDDEN_COLUMNS } from '@gaonjs/core';
|
|
17
|
+
// ── 런타임 ────────────────────────────────────────────────────
|
|
18
|
+
/**
|
|
19
|
+
* 컨트롤러 props 를 JSON-safe 페이지 props 로 변환한다(Inertia 브리지).
|
|
20
|
+
* Date→ISO 문자열, bigint→문자열, 함수 제거, hidden 컬럼 제외, 중첩 재귀.
|
|
21
|
+
*/
|
|
22
|
+
export function serializeProps(value) {
|
|
23
|
+
return serialize(value);
|
|
24
|
+
}
|
|
25
|
+
function serialize(value) {
|
|
26
|
+
if (value === null || value === undefined)
|
|
27
|
+
return value;
|
|
28
|
+
if (typeof value === 'bigint')
|
|
29
|
+
return value.toString();
|
|
30
|
+
if (value instanceof Date)
|
|
31
|
+
return value.toISOString();
|
|
32
|
+
if (Array.isArray(value))
|
|
33
|
+
return value.map(serialize);
|
|
34
|
+
if (typeof value === 'object') {
|
|
35
|
+
// 모델 레코드는 HIDDEN_COLUMNS 마커(비열거)로 제외할 컬럼명을 싣는다.
|
|
36
|
+
const hidden = value[HIDDEN_COLUMNS];
|
|
37
|
+
const out = {};
|
|
38
|
+
for (const key of Object.keys(value)) {
|
|
39
|
+
if (hidden && hidden.includes(key))
|
|
40
|
+
continue;
|
|
41
|
+
const v = value[key];
|
|
42
|
+
if (typeof v === 'function')
|
|
43
|
+
continue; // 메서드·관계 함수는 직렬화하지 않는다
|
|
44
|
+
out[key] = serialize(v);
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
if (typeof value === 'function')
|
|
49
|
+
return undefined;
|
|
50
|
+
return value;
|
|
51
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gaonjs/vue",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Gaon 프론트엔드 어댑터: Vue 3 · Inertia 브리지 · 타입 전파 · SSR (구현 예정)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"README.md"
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@gaonjs/core": "0.1.
|
|
27
|
+
"@gaonjs/core": "0.1.3",
|
|
28
|
+
"@gaonjs/web": "0.2.0"
|
|
28
29
|
},
|
|
29
30
|
"scripts": {
|
|
30
31
|
"build": "node ../../node_modules/typescript/bin/tsc -p tsconfig.json"
|