for-humanity 0.13.1 → 0.14.1
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/CHANGELOG.md +27 -2
- package/README.md +41 -66
- package/dist/browser.js +4 -4
- package/dist/cli.css +1 -1
- package/dist/cli.js +7 -7
- package/dist/config.js +1 -1
- package/dist/constant/site.d.ts +8 -0
- package/dist/{load-site-B-u5-jv0.js → load-site-BpLDY-YA.js} +636 -383
- package/dist/{logger-Dv1i9xSV.js → logger-CLH67K3L.js} +1 -1
- package/dist/{run-site-command-cqCjpIlc.js → run-site-command--qSrkFie.js} +41 -18
- package/dist/{site-config-bllORGpm.js → site-config-FmStUQ2W.js} +44 -0
- package/dist/site.js +1 -1
- package/dist/{start-dev-server-x7Ja5uwv.js → start-dev-server-BL2HA7v6.js} +1 -2
- package/dist/type/content-config.d.ts +9 -0
- package/dist/type/site-config.d.ts +9 -0
- package/package.json +4 -3
- package/src/asset/font/architects-daughter/architects-daughter.css +1 -1
- package/src/asset/font/ibm-plex-sans-kr/ibm-plex-sans-kr.css +3 -3
- package/src/asset/font/monoplex-kr/monoplex-kr.css +2 -2
- package/template/content/README.md +5 -0
- package/template/content/asset/.gitkeep +0 -0
- package/template/content/private/.gitkeep +0 -0
- package/template/content/public/getting-started.md +26 -0
- package/template/for-humanity.config.ts +8 -0
|
@@ -2,7 +2,7 @@ import { p as copy_error_prefix } from "./copy-C1uzvEnr.js";
|
|
|
2
2
|
import { createConsola } from "consola";
|
|
3
3
|
//#region src/util/logger/logger.ts
|
|
4
4
|
/**
|
|
5
|
-
* CLI와 문서 처리의 공통 로그. Vite
|
|
5
|
+
* CLI와 문서 처리의 공통 로그. Vite, 브라우저 콘솔과 분리
|
|
6
6
|
*/
|
|
7
7
|
var logger = createConsola({ formatOptions: { date: false } }).withTag(copy_error_prefix);
|
|
8
8
|
//#endregion
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { d as copy_error_missing_build, n as copy_error_config } from "./copy-C1uzvEnr.js";
|
|
2
|
-
import { t as logger } from "./logger-
|
|
3
|
-
import { n as site_config_absent, t as siteConfigSchema } from "./site-config-
|
|
4
|
-
import { n as font_cache_control, r as asset_font_dir, t as loadSite } from "./load-site-
|
|
2
|
+
import { t as logger } from "./logger-CLH67K3L.js";
|
|
3
|
+
import { n as site_config_absent, t as siteConfigSchema } from "./site-config-FmStUQ2W.js";
|
|
4
|
+
import { n as font_cache_control, r as asset_font_dir, t as loadSite } from "./load-site-BpLDY-YA.js";
|
|
5
5
|
import { n as config_file_names, t as toErrorMessage } from "./to-error-message-pF6_7wGK.js";
|
|
6
6
|
import { copyFile, mkdir, rm, writeFile } from "node:fs/promises";
|
|
7
7
|
import { z } from "zod";
|
|
8
|
-
import { existsSync } from "node:fs";
|
|
9
|
-
import { dirname, join, relative, resolve } from "node:path";
|
|
8
|
+
import { existsSync, realpathSync } from "node:fs";
|
|
9
|
+
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
10
10
|
import { toSSG } from "hono/ssg";
|
|
11
11
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
12
12
|
import { createJiti } from "jiti";
|
|
13
13
|
//#region src/app/_function/read-site-config.ts
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* 프로젝트 루트의 설정 조회, TypeScript 실행과 스키마 검증
|
|
16
16
|
*
|
|
17
17
|
* - 중복 파일 거부, 실제 적용되는 설정의 모호성 방지
|
|
18
18
|
* - Node의 기본 TypeScript 지원 여부와 무관하게 같은 설정 실행
|
|
@@ -31,6 +31,29 @@ var readSiteConfig = async (root) => {
|
|
|
31
31
|
return parsed.data.default;
|
|
32
32
|
};
|
|
33
33
|
//#endregion
|
|
34
|
+
//#region src/app/_function/read-project.ts
|
|
35
|
+
/**
|
|
36
|
+
* 프로젝트 설정과 문서 루트 해소, 외부와 시스템 폴더 symlink 거부
|
|
37
|
+
*/
|
|
38
|
+
var readProject = async (directory) => {
|
|
39
|
+
const projectRoot = realpathSync(resolve(directory));
|
|
40
|
+
const site = await readSiteConfig(projectRoot);
|
|
41
|
+
const root = resolve(projectRoot, site.content.root);
|
|
42
|
+
if (existsSync(root)) {
|
|
43
|
+
const location = relative(projectRoot, realpathSync(root));
|
|
44
|
+
if (location === ".." || location.startsWith(`..${sep}`) || isAbsolute(location)) throw new Error(`content 루트는 프로젝트 내부여야 합니다: ${root}`);
|
|
45
|
+
if (location.split(sep).some((part) => [
|
|
46
|
+
"dist",
|
|
47
|
+
".git",
|
|
48
|
+
"node_modules"
|
|
49
|
+
].includes(part.toLowerCase()))) throw new Error(`content 루트는 dist, .git, node_modules 내부일 수 없습니다: ${root}`);
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
root,
|
|
53
|
+
site
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
//#endregion
|
|
34
57
|
//#region src/entry/preview/to-preview-config.ts
|
|
35
58
|
/**
|
|
36
59
|
* 빌드된 사이트 전용 Vite 설정. 소비 프로젝트의 설정과 환경 파일 자동 로드 제외
|
|
@@ -75,31 +98,31 @@ var toPreviewConfig = (params) => {
|
|
|
75
98
|
*/
|
|
76
99
|
var runSiteCommand = async (params) => {
|
|
77
100
|
try {
|
|
78
|
-
if (params.args._.length > 1) throw new Error("
|
|
101
|
+
if (params.args._.length > 1) throw new Error("프로젝트 폴더는 하나만 지정하세요");
|
|
79
102
|
const kitRoot = fileURLToPath(new URL("../", import.meta.url));
|
|
80
|
-
const
|
|
81
|
-
const outDir = join(
|
|
82
|
-
const siteConfig = await readSiteConfig(docsRoot);
|
|
103
|
+
const project = await readProject(params.args.dir);
|
|
104
|
+
const outDir = join(project.root, "dist");
|
|
83
105
|
if (params.command === "preview") {
|
|
84
106
|
(await (await import("vite")).preview(toPreviewConfig({
|
|
85
|
-
root:
|
|
86
|
-
port:
|
|
107
|
+
root: project.root,
|
|
108
|
+
port: project.site.port
|
|
87
109
|
}))).printUrls();
|
|
88
110
|
return;
|
|
89
111
|
}
|
|
90
112
|
if (params.command === "dev") {
|
|
91
|
-
await (await import("./start-dev-server-
|
|
92
|
-
root:
|
|
113
|
+
await (await import("./start-dev-server-BL2HA7v6.js")).startDevServer({
|
|
114
|
+
root: project.root,
|
|
93
115
|
kitRoot,
|
|
94
|
-
site:
|
|
95
|
-
source: false
|
|
116
|
+
site: project.site,
|
|
117
|
+
source: false,
|
|
118
|
+
includePrivate: true
|
|
96
119
|
});
|
|
97
120
|
return;
|
|
98
121
|
}
|
|
99
122
|
const snapshot = await loadSite({
|
|
100
|
-
root:
|
|
123
|
+
root: project.root,
|
|
101
124
|
kitRoot,
|
|
102
|
-
site:
|
|
125
|
+
site: project.site
|
|
103
126
|
});
|
|
104
127
|
await rm(outDir, {
|
|
105
128
|
recursive: true,
|
|
@@ -18,6 +18,14 @@ var site_port_default = 4321;
|
|
|
18
18
|
* 포트 번호 상한. TCP
|
|
19
19
|
*/
|
|
20
20
|
var site_port_max = 65535;
|
|
21
|
+
/**
|
|
22
|
+
* 기본 문서 루트와 공개 범위 폴더
|
|
23
|
+
*/
|
|
24
|
+
var content_default = {
|
|
25
|
+
root: "content",
|
|
26
|
+
public: "public",
|
|
27
|
+
private: "private"
|
|
28
|
+
};
|
|
21
29
|
//#endregion
|
|
22
30
|
//#region src/constant/status.ts
|
|
23
31
|
/**
|
|
@@ -39,11 +47,47 @@ var status_default_phrases = [{
|
|
|
39
47
|
kind: status_kind.unverified
|
|
40
48
|
}];
|
|
41
49
|
//#endregion
|
|
50
|
+
//#region src/type/content-config.ts
|
|
51
|
+
/**
|
|
52
|
+
* 프로젝트 내부의 상대 경로, 출력 폴더와 시스템 폴더 제외
|
|
53
|
+
*/
|
|
54
|
+
var contentPathSchema = z.string().trim().min(1).refine((value) => !/^[\\/]|[:?#%*\p{Cc}]/u.test(value) && !value.split(/[\\/]/).some((part) => [
|
|
55
|
+
"..",
|
|
56
|
+
"dist",
|
|
57
|
+
"node_modules",
|
|
58
|
+
".git"
|
|
59
|
+
].includes(part.toLowerCase())), "프로젝트 내부 상대 경로만 사용하세요. dist, node_modules, .git 경로는 사용할 수 없습니다").transform((value) => value.replaceAll("\\", "/").split("/").filter((part) => part !== "" && part !== ".").join("/"));
|
|
60
|
+
/**
|
|
61
|
+
* 공개와 내부 문서 폴더의 상대 경로 계약
|
|
62
|
+
*/
|
|
63
|
+
var contentConfigSchema = z.object({
|
|
64
|
+
/**
|
|
65
|
+
* 프로젝트 루트 기준 문서 폴더, 점 하나는 프로젝트 루트
|
|
66
|
+
*/
|
|
67
|
+
root: contentPathSchema.transform((value) => value === "" ? "." : value).default(content_default.root),
|
|
68
|
+
/**
|
|
69
|
+
* 문서 루트 아래 공개 문서 폴더
|
|
70
|
+
*/
|
|
71
|
+
public: contentPathSchema.refine((value) => value !== "", "공개 문서는 별도 하위 폴더가 필요합니다").default(content_default.public),
|
|
72
|
+
/**
|
|
73
|
+
* 문서 루트 아래 로컬 전용 문서 폴더
|
|
74
|
+
*/
|
|
75
|
+
private: contentPathSchema.refine((value) => value !== "", "내부 문서는 별도 하위 폴더가 필요합니다").default(content_default.private)
|
|
76
|
+
}).refine((value) => {
|
|
77
|
+
const published = value.public.toLowerCase();
|
|
78
|
+
const internal = value.private.toLowerCase();
|
|
79
|
+
return published !== internal && !published.startsWith(`${internal}/`) && !internal.startsWith(`${published}/`);
|
|
80
|
+
}, "공개 문서와 내부 문서 폴더는 같거나 중첩될 수 없습니다");
|
|
81
|
+
//#endregion
|
|
42
82
|
//#region src/type/site-config.ts
|
|
43
83
|
/**
|
|
44
84
|
* 사이트 설정의 입력 검증과 기본값 적용
|
|
45
85
|
*/
|
|
46
86
|
var siteConfigSchema = z.object({
|
|
87
|
+
/**
|
|
88
|
+
* 프로젝트 기준 문서 루트와 공개 범위
|
|
89
|
+
*/
|
|
90
|
+
content: contentConfigSchema.default(content_default),
|
|
47
91
|
/**
|
|
48
92
|
* 사이드바 이름과 탭 제목
|
|
49
93
|
*/
|
package/dist/site.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as loadSite } from "./load-site-
|
|
1
|
+
export { t as loadSite } from "./load-site-BpLDY-YA.js";
|
|
@@ -106,8 +106,7 @@ var toDevConfig = (params) => {
|
|
|
106
106
|
*/
|
|
107
107
|
const handleChange = (event, file) => {
|
|
108
108
|
const documentPath = relative(root, file);
|
|
109
|
-
const
|
|
110
|
-
const isDocument = documentPath !== ".." && !isAbsolute(documentPath) && !documentPath.startsWith(`..${sep}`) && !segments.some((part) => [
|
|
109
|
+
const isDocument = documentPath !== ".." && !isAbsolute(documentPath) && !documentPath.startsWith(`..${sep}`) && !documentPath.split(sep).some((part) => [
|
|
111
110
|
"dist",
|
|
112
111
|
"node_modules",
|
|
113
112
|
".git",
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* 공개와 내부 문서 폴더의 상대 경로 계약
|
|
4
|
+
*/
|
|
5
|
+
export declare const contentConfigSchema: z.ZodObject<{
|
|
6
|
+
root: z.ZodDefault<z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodTransform<string, string>>>;
|
|
7
|
+
public: z.ZodDefault<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
8
|
+
private: z.ZodDefault<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
9
|
+
}, z.core.$strip>;
|
|
@@ -3,6 +3,11 @@ import { z } from "zod";
|
|
|
3
3
|
* 사이트 설정의 입력 검증과 기본값 적용
|
|
4
4
|
*/
|
|
5
5
|
export declare const siteConfigSchema: z.ZodObject<{
|
|
6
|
+
content: z.ZodDefault<z.ZodObject<{
|
|
7
|
+
root: z.ZodDefault<z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodTransform<string, string>>>;
|
|
8
|
+
public: z.ZodDefault<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
9
|
+
private: z.ZodDefault<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
10
|
+
}, z.core.$strip>>;
|
|
6
11
|
title: z.ZodDefault<z.ZodString>;
|
|
7
12
|
description: z.ZodOptional<z.ZodString>;
|
|
8
13
|
url: z.ZodOptional<z.ZodPipe<z.ZodPipe<z.ZodURL, z.ZodTransform<URL, string>>, z.ZodTransform<string, URL>>>;
|
|
@@ -26,6 +31,10 @@ export type ResolvedSiteConfig = z.infer<typeof siteConfigSchema>;
|
|
|
26
31
|
* 작성자가 지정하는 사이트 설정, 기본값 적용 전 입력
|
|
27
32
|
*/
|
|
28
33
|
export interface SiteConfig {
|
|
34
|
+
/**
|
|
35
|
+
* 기본 content/public, content/private 구조의 경로 변경
|
|
36
|
+
*/
|
|
37
|
+
content?: z.input<typeof siteConfigSchema>["content"];
|
|
29
38
|
/**
|
|
30
39
|
* 사이드바 이름과 탭 제목, 생략 시 for humanity
|
|
31
40
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "for-humanity",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.1",
|
|
4
4
|
"description": "Documents written for humans to read: a docs kit with a sidebar, parts, sections and Mermaid diagrams, built on Hono JSX",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"docs",
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"files": [
|
|
28
28
|
"dist",
|
|
29
29
|
"src/asset",
|
|
30
|
+
"template",
|
|
30
31
|
"CHANGELOG.md"
|
|
31
32
|
],
|
|
32
33
|
"engines": {
|
|
@@ -37,9 +38,9 @@
|
|
|
37
38
|
"sync:readme": "tsx util/sync-readme.ts",
|
|
38
39
|
"sync:docs": "pnpm sync:readme && tsx util/sync-changelog.ts",
|
|
39
40
|
"dev": "pnpm sync:docs && pnpm build:kit && tsx src/entry/dev/dev.ts",
|
|
40
|
-
"build": "pnpm sync:docs && pnpm build:kit && node dist/cli.js build
|
|
41
|
+
"build": "pnpm sync:docs && pnpm build:kit && node dist/cli.js build .",
|
|
41
42
|
"build:pages": "pnpm build && tsx util/prepare-pages.ts",
|
|
42
|
-
"preview": "node dist/cli.js preview
|
|
43
|
+
"preview": "node dist/cli.js preview .",
|
|
43
44
|
"test": "pnpm build:kit && vitest run",
|
|
44
45
|
"test:watch": "pnpm build:kit && vitest",
|
|
45
46
|
"test:browser": "pnpm build:kit && playwright test",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* IBM Plex Sans KR 1.003
|
|
3
|
-
* 배포 WOFF2(fonts/complete/woff2/hinted) 원본
|
|
4
|
-
* 본문의 한글
|
|
2
|
+
* IBM Plex Sans KR 1.003, npm @ibm/plex-sans-kr 1.1.0, https://github.com/IBM/plex
|
|
3
|
+
* 배포 WOFF2(fonts/complete/woff2/hinted) 원본 그대로, 라이선스는 옆의 LICENSE.txt
|
|
4
|
+
* 본문의 한글 음절과 호환 자모만 담당, Monoplex KR 한글과 같은 글자의 원래 폭
|
|
5
5
|
*/
|
|
6
6
|
@font-face {
|
|
7
7
|
font-family: "IBM Plex Sans KR";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Monoplex KR 1.1.0
|
|
3
|
-
* 릴리스 TTF를 서브셋 없이 WOFF2로만
|
|
2
|
+
* Monoplex KR 1.1.0, https://github.com/y-kim/monoplex/releases/tag/monoplex-kr-1.1.0
|
|
3
|
+
* 릴리스 TTF를 서브셋 없이 WOFF2로만 압축, OFL FAQ의 이름 유지 조건, 라이선스는 옆의 LICENSE.md
|
|
4
4
|
* fonttools ttLib.woff2 compress MonoplexKR-Regular.ttf
|
|
5
5
|
*/
|
|
6
6
|
@font-face {
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Getting started
|
|
3
|
+
label: 문서 작성과 공개 범위
|
|
4
|
+
group: Guide
|
|
5
|
+
order: 10
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Getting started
|
|
9
|
+
|
|
10
|
+
`content/public`은 공개 문서, `content/private`는 로컬 전용 문서입니다.
|
|
11
|
+
공용 이미지와 첨부는 `content/asset`, 내부 자료는 `content/private/asset`에 보관합니다.
|
|
12
|
+
|
|
13
|
+
프로젝트 루트에서 실행합니다.
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
pnpm exec for-humanity dev
|
|
17
|
+
pnpm exec for-humanity build
|
|
18
|
+
pnpm exec for-humanity preview
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`dev`는 전체 문서, `build`와 `preview`는 공개 결과를 제공합니다.
|
|
22
|
+
배포할 폴더는 `content/dist`입니다. `content` 전체를 업로드하지 않습니다.
|
|
23
|
+
`private`는 사이트 배포 제외이며 Git 저장소 접근 제어가 아닙니다.
|
|
24
|
+
|
|
25
|
+
설정은 프로젝트 루트의 `for-humanity.config.ts`, 홈은 `content/README.md`입니다.
|
|
26
|
+
공개 문서의 URL에는 `public`이 붙지 않습니다. 이 문서는 `/getting-started/`에서 확인할 수 있습니다.
|