@mandujs/core 0.18.20 → 0.18.22
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 +3 -1
- package/src/brain/architecture/analyzer.ts +3 -5
- package/src/brain/architecture/types.ts +4 -4
- package/src/brain/doctor/analyzer.ts +1 -0
- package/src/brain/doctor/index.ts +1 -1
- package/src/brain/doctor/patcher.ts +10 -6
- package/src/brain/doctor/reporter.ts +4 -4
- package/src/brain/types.ts +14 -10
- package/src/bundler/build.ts +17 -17
- package/src/bundler/css.ts +3 -2
- package/src/bundler/dev.ts +1 -1
- package/src/client/island.ts +10 -9
- package/src/client/router.ts +1 -1
- package/src/config/mcp-ref.ts +6 -6
- package/src/config/metadata.test.ts +1 -1
- package/src/config/metadata.ts +36 -16
- package/src/config/symbols.ts +1 -1
- package/src/config/validate.ts +17 -1
- package/src/content/content.test.ts +3 -3
- package/src/content/loaders/file.ts +3 -0
- package/src/content/loaders/glob.ts +1 -0
- package/src/contract/client-safe.test.ts +1 -1
- package/src/contract/client.test.ts +2 -1
- package/src/contract/client.ts +18 -18
- package/src/contract/define.ts +32 -17
- package/src/contract/handler.ts +11 -11
- package/src/contract/index.ts +2 -5
- package/src/contract/infer.test.ts +2 -1
- package/src/contract/normalize.test.ts +1 -1
- package/src/contract/normalize.ts +17 -11
- package/src/contract/registry.test.ts +1 -1
- package/src/contract/zod-utils.ts +155 -0
- package/src/devtools/client/catchers/error-catcher.ts +3 -3
- package/src/devtools/client/catchers/network-proxy.ts +5 -1
- package/src/devtools/client/components/kitchen-root.tsx +2 -2
- package/src/devtools/client/components/panel/guard-panel.tsx +3 -3
- package/src/devtools/client/state-manager.ts +9 -9
- package/src/devtools/index.ts +8 -8
- package/src/devtools/init.ts +2 -2
- package/src/devtools/protocol.ts +4 -4
- package/src/devtools/server/source-context.ts +9 -3
- package/src/devtools/types.ts +5 -5
- package/src/devtools/worker/redaction-worker.ts +12 -5
- package/src/error/index.ts +1 -1
- package/src/error/result.ts +14 -0
- package/src/filling/deps.ts +5 -2
- package/src/filling/filling.ts +1 -1
- package/src/generator/templates.ts +2 -2
- package/src/guard/contract-guard.test.ts +1 -0
- package/src/guard/file-type.test.ts +1 -1
- package/src/guard/index.ts +1 -1
- package/src/guard/negotiation.ts +29 -1
- package/src/guard/presets/index.ts +3 -0
- package/src/guard/semantic-slots.ts +4 -4
- package/src/index.ts +10 -1
- package/src/intent/index.ts +28 -17
- package/src/island/index.ts +8 -8
- package/src/openapi/generator.ts +49 -31
- package/src/plugins/index.ts +1 -1
- package/src/plugins/registry.ts +28 -18
- package/src/plugins/types.ts +2 -2
- package/src/resource/__tests__/backward-compat.test.ts +2 -2
- package/src/resource/__tests__/edge-cases.test.ts +14 -13
- package/src/resource/__tests__/fixtures.ts +2 -2
- package/src/resource/__tests__/generator.test.ts +1 -1
- package/src/resource/__tests__/performance.test.ts +8 -6
- package/src/resource/schema.ts +1 -1
- package/src/router/fs-routes.ts +34 -40
- package/src/router/fs-types.ts +2 -2
- package/src/router/index.ts +1 -1
- package/src/runtime/boundary.tsx +4 -4
- package/src/runtime/logger.test.ts +3 -3
- package/src/runtime/logger.ts +1 -1
- package/src/runtime/server.ts +18 -16
- package/src/runtime/ssr.ts +1 -1
- package/src/runtime/stable-selector.ts +1 -2
- package/src/runtime/streaming-ssr.ts +15 -6
- package/src/seo/index.ts +5 -0
- package/src/seo/integration/ssr.ts +4 -4
- package/src/seo/render/basic.ts +12 -4
- package/src/seo/render/opengraph.ts +12 -6
- package/src/seo/render/twitter.ts +3 -2
- package/src/seo/resolve/url.ts +7 -0
- package/src/seo/types.ts +13 -0
- package/src/spec/schema.ts +89 -61
- package/src/types/branded.ts +56 -0
- package/src/types/index.ts +1 -0
- package/src/utils/hasher.test.ts +6 -6
- package/src/utils/hasher.ts +2 -2
- package/src/utils/index.ts +1 -1
- package/src/watcher/watcher.ts +2 -2
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Branded Types - Nominal typing for string identifiers
|
|
3
|
+
*
|
|
4
|
+
* Prevents accidental mixing of different ID types at compile time.
|
|
5
|
+
* All branded types are structurally compatible with plain strings at runtime.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const col = collectionId("blog");
|
|
10
|
+
* const entry = entryId("hello-world");
|
|
11
|
+
* // col and entry are both strings at runtime,
|
|
12
|
+
* // but TypeScript treats them as distinct types.
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
declare const __brand: unique symbol;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Brand utility type - creates nominal types from structural types.
|
|
20
|
+
* The brand exists only at the type level and has zero runtime cost.
|
|
21
|
+
*/
|
|
22
|
+
export type Brand<T, B extends string> = T & { readonly [__brand]: B };
|
|
23
|
+
|
|
24
|
+
/** Branded string identifying a content collection */
|
|
25
|
+
export type CollectionId = Brand<string, "CollectionId">;
|
|
26
|
+
|
|
27
|
+
/** Branded string identifying a content entry within a collection */
|
|
28
|
+
export type EntryId = Brand<string, "EntryId">;
|
|
29
|
+
|
|
30
|
+
/** Branded string containing sanitized HTML (XSS-safe) */
|
|
31
|
+
export type SafeHTML = Brand<string, "SafeHTML">;
|
|
32
|
+
|
|
33
|
+
/** Branded string identifying a route in the manifest */
|
|
34
|
+
export type RouteId = Brand<string, "RouteId">;
|
|
35
|
+
|
|
36
|
+
// -- Constructor functions --
|
|
37
|
+
|
|
38
|
+
/** Create a branded CollectionId from a plain string */
|
|
39
|
+
export function collectionId(id: string): CollectionId {
|
|
40
|
+
return id as CollectionId;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Create a branded EntryId from a plain string */
|
|
44
|
+
export function entryId(id: string): EntryId {
|
|
45
|
+
return id as EntryId;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Create a branded SafeHTML from a sanitized string */
|
|
49
|
+
export function safeHTML(html: string): SafeHTML {
|
|
50
|
+
return html as SafeHTML;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Create a branded RouteId from a plain string */
|
|
54
|
+
export function routeId(id: string): RouteId {
|
|
55
|
+
return id as RouteId;
|
|
56
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./branded";
|
package/src/utils/hasher.test.ts
CHANGED
|
@@ -146,25 +146,25 @@ describe("normalizeForHash", () => {
|
|
|
146
146
|
["a", 2],
|
|
147
147
|
["m", 3],
|
|
148
148
|
]);
|
|
149
|
-
const normalized = normalizeForHash({ data: map }) as
|
|
149
|
+
const normalized = normalizeForHash({ data: map }) as Record<string, Record<string, unknown>>;
|
|
150
150
|
|
|
151
151
|
expect(normalized.data.__type__).toBe("Map");
|
|
152
|
-
expect(normalized.data.entries[0][0]).toBe("a"); // 정렬됨
|
|
152
|
+
expect((normalized.data.entries as string[][])[0][0]).toBe("a"); // 정렬됨
|
|
153
153
|
});
|
|
154
154
|
|
|
155
155
|
it("should handle Set as sorted array", () => {
|
|
156
156
|
const set = new Set([3, 1, 2]);
|
|
157
|
-
const normalized = normalizeForHash({ data: set }) as
|
|
157
|
+
const normalized = normalizeForHash({ data: set }) as Record<string, Record<string, unknown>>;
|
|
158
158
|
|
|
159
159
|
expect(normalized.data.__type__).toBe("Set");
|
|
160
160
|
expect(normalized.data.items).toEqual([1, 2, 3]); // 정렬됨
|
|
161
161
|
});
|
|
162
162
|
|
|
163
163
|
it("should detect circular references", () => {
|
|
164
|
-
const obj:
|
|
164
|
+
const obj: Record<string, unknown> = { a: 1 };
|
|
165
165
|
obj.self = obj;
|
|
166
166
|
|
|
167
|
-
const normalized = normalizeForHash(obj) as
|
|
167
|
+
const normalized = normalizeForHash(obj) as Record<string, unknown>;
|
|
168
168
|
expect(normalized.self).toBe("__circular__");
|
|
169
169
|
});
|
|
170
170
|
|
|
@@ -184,7 +184,7 @@ describe("normalizeForHash", () => {
|
|
|
184
184
|
|
|
185
185
|
it("should normalize Error objects", () => {
|
|
186
186
|
const error = new TypeError("test error");
|
|
187
|
-
const normalized = normalizeForHash({ error }) as
|
|
187
|
+
const normalized = normalizeForHash({ error }) as Record<string, Record<string, unknown>>;
|
|
188
188
|
|
|
189
189
|
expect(normalized.error.__type__).toBe("Error");
|
|
190
190
|
expect(normalized.error.name).toBe("TypeError");
|
package/src/utils/hasher.ts
CHANGED
|
@@ -25,7 +25,7 @@ export interface HashOptions {
|
|
|
25
25
|
exclude?: string[];
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export interface
|
|
28
|
+
export interface HashNormalizeOptions {
|
|
29
29
|
/** 제외할 키 패턴 */
|
|
30
30
|
exclude?: string[];
|
|
31
31
|
/** Date를 ISO 문자열로 변환 (기본값: true) */
|
|
@@ -59,7 +59,7 @@ export interface NormalizeOptions {
|
|
|
59
59
|
*/
|
|
60
60
|
export function normalizeForHash(
|
|
61
61
|
value: unknown,
|
|
62
|
-
options:
|
|
62
|
+
options: HashNormalizeOptions = {},
|
|
63
63
|
seen: WeakSet<object> = new WeakSet()
|
|
64
64
|
): unknown {
|
|
65
65
|
const {
|
package/src/utils/index.ts
CHANGED
package/src/watcher/watcher.ts
CHANGED
|
@@ -157,8 +157,8 @@ export class FileWatcher {
|
|
|
157
157
|
this.processFileEvent("delete", filePath);
|
|
158
158
|
});
|
|
159
159
|
|
|
160
|
-
this.chokidarWatcher.on("error", (error) => {
|
|
161
|
-
console.error(`[Watch] Error:`, error.message);
|
|
160
|
+
this.chokidarWatcher.on("error", (error: unknown) => {
|
|
161
|
+
console.error(`[Watch] Error:`, error instanceof Error ? error.message : String(error));
|
|
162
162
|
});
|
|
163
163
|
|
|
164
164
|
this._active = true;
|