@o2b/meta 1.0.0-dev.0

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/cli.js ADDED
@@ -0,0 +1,241 @@
1
+ #!/usr/bin/env node
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (let key of __getOwnPropNames(from))
11
+ if (!__hasOwnProp.call(to, key) && key !== except)
12
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
+ }
14
+ return to;
15
+ };
16
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
+ // If the importer is in node compatibility mode or this is not an ESM
18
+ // file that has been converted to a CommonJS file using a Babel-
19
+ // compatible transform (i.e. "__esModule" has not been set), then set
20
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+
25
+ // src/cli.ts
26
+ var import_cac = __toESM(require("cac"));
27
+
28
+ // package.json
29
+ var package_default = {
30
+ name: "@o2b/meta",
31
+ version: "1.0.0-alpha.0",
32
+ description: "filetree generator for o2b",
33
+ main: "./dist/index.js",
34
+ module: "./dist/index.mjs",
35
+ types: "./dist/index.d.ts",
36
+ exports: {
37
+ ".": {
38
+ types: "./dist/index.d.ts",
39
+ import: "./dist/index.mjs",
40
+ require: "./dist/index.js"
41
+ }
42
+ },
43
+ bin: {
44
+ "o2b-meta": "./dist/cli.js"
45
+ },
46
+ scripts: {
47
+ build: "tsup",
48
+ test: "vitest",
49
+ "test:run": "vitest run"
50
+ },
51
+ keywords: [],
52
+ author: "goonco",
53
+ license: "ISC",
54
+ type: "commonjs",
55
+ files: [
56
+ "dist"
57
+ ],
58
+ devDependencies: {
59
+ "@biomejs/biome": "2.3.10",
60
+ "@types/node": "^25.0.3",
61
+ "@vitest/ui": "^4.0.16",
62
+ tsup: "^8.5.1",
63
+ typescript: "^5.9.3",
64
+ vitest: "^4.0.16"
65
+ },
66
+ dependencies: {
67
+ cac: "^6.7.14",
68
+ "gray-matter": "^4.0.3",
69
+ ignore: "^7.0.5",
70
+ lilconfig: "^3.1.3"
71
+ }
72
+ };
73
+
74
+ // src/core/sync/mirror.ts
75
+ var import_node_fs = require("fs");
76
+ var import_node_path = require("path");
77
+ function mirror(filetree, srcPath, destPath) {
78
+ function aux(filetree2) {
79
+ const from = (0, import_node_path.join)(srcPath, filetree2.path);
80
+ const to = (0, import_node_path.join)(destPath, filetree2.path);
81
+ if (filetree2.type === "dir") {
82
+ if (!(0, import_node_fs.existsSync)(to)) (0, import_node_fs.mkdirSync)(to, { recursive: true });
83
+ filetree2.files.forEach((file) => {
84
+ aux(file);
85
+ });
86
+ filetree2.dirs.forEach((dir) => {
87
+ aux(dir);
88
+ });
89
+ }
90
+ if (filetree2.type === "file") {
91
+ (0, import_node_fs.copyFileSync)(from, to);
92
+ }
93
+ }
94
+ aux(filetree);
95
+ generateFileTree(filetree, destPath);
96
+ }
97
+ function generateFileTree(filetree, destPath) {
98
+ const jsonFilePath = (0, import_node_path.join)(destPath, "o2bFileTree.json");
99
+ (0, import_node_fs.writeFileSync)(jsonFilePath, JSON.stringify(filetree, null, 2), "utf-8");
100
+ }
101
+
102
+ // src/core/sync/scan.ts
103
+ var import_node_fs4 = require("fs");
104
+ var import_node_path4 = require("path");
105
+ var import_gray_matter = __toESM(require("gray-matter"));
106
+
107
+ // src/utils/ignore.ts
108
+ var import_node_fs3 = require("fs");
109
+ var import_node_path3 = require("path");
110
+ var import_ignore = __toESM(require("ignore"));
111
+
112
+ // src/utils/path.ts
113
+ var import_node_fs2 = require("fs");
114
+ var import_node_path2 = require("path");
115
+ function toAbsPath(path) {
116
+ if (!(0, import_node_path2.isAbsolute)(path)) path = (0, import_node_path2.resolve)(path);
117
+ return path;
118
+ }
119
+ function toRelPath(from, to) {
120
+ return (0, import_node_path2.relative)(from, to);
121
+ }
122
+ function isObsidianDirectory(path) {
123
+ const stat = (0, import_node_fs2.lstatSync)(path);
124
+ if (!stat.isDirectory()) return false;
125
+ const obsMetaDir = (0, import_node_fs2.readdirSync)(path, { withFileTypes: true }).filter((node) => node.isDirectory()).filter((node) => node.name === ".obsidian");
126
+ if (obsMetaDir.length !== 1) return false;
127
+ return true;
128
+ }
129
+
130
+ // src/utils/ignore.ts
131
+ var VaultIgnorer = class {
132
+ ign;
133
+ rootPath;
134
+ constructor(rootPath) {
135
+ this.rootPath = rootPath;
136
+ this.ign = (0, import_ignore.default)();
137
+ this.ign.add([".*"]);
138
+ }
139
+ load() {
140
+ const ignorePath = (0, import_node_path3.join)(this.rootPath, ".o2bignore");
141
+ if ((0, import_node_fs3.existsSync)(ignorePath))
142
+ this.ign.add((0, import_node_fs3.readFileSync)(ignorePath).toString());
143
+ }
144
+ ignore(path) {
145
+ if (path === this.rootPath) return false;
146
+ if (!(0, import_node_fs3.existsSync)(path)) throw new Error("somethings wrong!");
147
+ const stat = (0, import_node_fs3.lstatSync)(path);
148
+ const relPath = toRelPath(this.rootPath, path) + (stat.isDirectory() ? "/" : "");
149
+ return this.ign.ignores(relPath);
150
+ }
151
+ };
152
+
153
+ // src/core/sync/scan.ts
154
+ function scan(rootPath, ign) {
155
+ function aux(path) {
156
+ if (ign == null ? void 0 : ign.ignore(path)) return null;
157
+ const stat = (0, import_node_fs4.lstatSync)(path);
158
+ const name = (0, import_node_path4.basename)(path);
159
+ if (stat.isDirectory()) {
160
+ const { dirs, files } = (0, import_node_fs4.readdirSync)(path).reduce(
161
+ (acc, entry) => {
162
+ const node = aux(toAbsPath((0, import_node_path4.join)(path, entry)));
163
+ if ((node == null ? void 0 : node.type) === "dir") acc.dirs.push(node);
164
+ if ((node == null ? void 0 : node.type) === "file") acc.files.push(node);
165
+ return acc;
166
+ },
167
+ {
168
+ dirs: [],
169
+ files: []
170
+ }
171
+ );
172
+ return {
173
+ path: toRelPath(rootPath, path),
174
+ name,
175
+ type: "dir",
176
+ dirs,
177
+ files
178
+ };
179
+ }
180
+ if (stat.isFile() && name.endsWith(".md")) {
181
+ return {
182
+ path: toRelPath(rootPath, path),
183
+ name,
184
+ type: "file",
185
+ frontmatter: getFrontmatter(path)
186
+ };
187
+ }
188
+ return null;
189
+ }
190
+ return aux(rootPath);
191
+ }
192
+ function getFrontmatter(path) {
193
+ const { data: srcFrontmatter } = (0, import_gray_matter.default)((0, import_node_fs4.readFileSync)(path, "utf-8"));
194
+ return {
195
+ title: (0, import_node_path4.basename)(path).replace(/\.md$/, ""),
196
+ description: "No description provided.",
197
+ last_modified: (0, import_node_fs4.lstatSync)(path).mtime.toLocaleDateString("sv-SE"),
198
+ // "sv-SE" (스웨덴어)는 YYYY-MM-DD 형식으로 출력되는 유명한 트릭입니다.
199
+ ...srcFrontmatter
200
+ };
201
+ }
202
+
203
+ // src/index.ts
204
+ function main(config) {
205
+ const { srcPath, destPath, ignore: ignore2 } = config;
206
+ if (!isObsidianDirectory(srcPath)) throw new Error("Not a obsidian vault");
207
+ const ign = new VaultIgnorer(srcPath);
208
+ if (ignore2) ign.load();
209
+ const fileTree = scan(srcPath, ign);
210
+ if (fileTree === null) throw new Error("No content in vault");
211
+ mirror(fileTree, srcPath, destPath);
212
+ }
213
+
214
+ // src/cli.ts
215
+ var cli = (0, import_cac.default)("o2b-meta");
216
+ cli.command("<srcPath>", "target vault file").option("--destPath [destPath]", "dist", {
217
+ default: "./o2b"
218
+ }).option("--ignore", "read the .o2bIgnore if exists", {
219
+ default: true
220
+ }).option("--sync", "synchro", {
221
+ default: true
222
+ }).action((srcPath, option) => {
223
+ const { destPath, ignore: ignore2, sync } = option;
224
+ const startTime = performance.now();
225
+ if (sync) {
226
+ main({
227
+ srcPath: toAbsPath(srcPath),
228
+ destPath: toAbsPath(destPath),
229
+ ignore: ignore2
230
+ });
231
+ }
232
+ const endTime = performance.now();
233
+ const duration = (endTime - startTime).toFixed(2);
234
+ console.log(`
235
+ \u2705 Build Success!`);
236
+ console.log(` Time: ${duration}ms`);
237
+ });
238
+ cli.help();
239
+ cli.version(package_default.version);
240
+ cli.parse();
241
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli.ts","../package.json","../src/core/sync/mirror.ts","../src/core/sync/scan.ts","../src/utils/ignore.ts","../src/utils/path.ts","../src/index.ts"],"sourcesContent":["import cac from \"cac\";\nimport pkg from \"../package.json\";\nimport main from \".\";\nimport { toAbsPath } from \"./utils\";\n\nconst cli = cac(\"o2b-meta\");\n\ncli\n\t.command(\"<srcPath>\", \"target vault file\")\n\t.option(\"--destPath [destPath]\", \"dist\", {\n\t\tdefault: \"./o2b\",\n\t})\n\t.option(\"--ignore\", \"read the .o2bIgnore if exists\", {\n\t\tdefault: true,\n\t})\n\t.option(\"--sync\", \"synchro\", {\n\t\tdefault: true,\n\t})\n\t.action((srcPath, option) => {\n\t\tconst { destPath, ignore, sync } = option;\n\n\t\tconst startTime = performance.now();\n\n\t\tif (sync) {\n\t\t\tmain({\n\t\t\t\tsrcPath: toAbsPath(srcPath),\n\t\t\t\tdestPath: toAbsPath(destPath),\n\t\t\t\tignore,\n\t\t\t});\n\t\t}\n\n\t\tconst endTime = performance.now();\n\t\tconst duration = (endTime - startTime).toFixed(2); // 소수점 2자리까지\n\n\t\tconsole.log(`\\n✅ Build Success!`);\n\t\tconsole.log(` Time: ${duration}ms`);\n\t\t// console.log(` Dest: ${config.destPath}\\n`);\n\t});\n\ncli.help();\ncli.version(pkg.version);\n\n// production에 대한 에러처리\ncli.parse();\n","{\n \"name\": \"@o2b/meta\",\n \"version\": \"1.0.0-alpha.0\",\n \"description\": \"filetree generator for o2b\",\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.js\"\n }\n },\n \"bin\": {\n \"o2b-meta\": \"./dist/cli.js\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"test\": \"vitest\",\n \"test:run\": \"vitest run\"\n },\n \"keywords\": [],\n \"author\": \"goonco\",\n \"license\": \"ISC\",\n \"type\": \"commonjs\",\n \"files\": [\n \"dist\"\n ],\n \"devDependencies\": {\n \"@biomejs/biome\": \"2.3.10\",\n \"@types/node\": \"^25.0.3\",\n \"@vitest/ui\": \"^4.0.16\",\n \"tsup\": \"^8.5.1\",\n \"typescript\": \"^5.9.3\",\n \"vitest\": \"^4.0.16\"\n },\n \"dependencies\": {\n \"cac\": \"^6.7.14\",\n \"gray-matter\": \"^4.0.3\",\n \"ignore\": \"^7.0.5\",\n \"lilconfig\": \"^3.1.3\"\n }\n}\n","import { copyFileSync, existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { AbsPath, FileTree } from \"../../types\";\n\nexport function mirror(\n\tfiletree: FileTree,\n\tsrcPath: AbsPath,\n\tdestPath: AbsPath,\n) {\n\tfunction aux(filetree: FileTree) {\n\t\tconst from = join(srcPath, filetree.path);\n\t\tconst to = join(destPath, filetree.path);\n\n\t\tif (filetree.type === \"dir\") {\n\t\t\tif (!existsSync(to)) mkdirSync(to, { recursive: true });\n\n\t\t\tfiletree.files.forEach((file) => {\n\t\t\t\taux(file);\n\t\t\t});\n\n\t\t\tfiletree.dirs.forEach((dir) => {\n\t\t\t\taux(dir);\n\t\t\t});\n\t\t}\n\n\t\tif (filetree.type === \"file\") {\n\t\t\tcopyFileSync(from, to);\n\t\t}\n\t}\n\n\taux(filetree);\n\tgenerateFileTree(filetree, destPath);\n}\n\nfunction generateFileTree(filetree: FileTree, destPath: AbsPath) {\n\tconst jsonFilePath = join(destPath, \"o2bFileTree.json\");\n\twriteFileSync(jsonFilePath, JSON.stringify(filetree, null, 2), \"utf-8\");\n}\n","import { lstatSync, readdirSync, readFileSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\nimport matter from \"gray-matter\";\nimport type {\n\tAbsPath,\n\tDirNode,\n\tFileNode,\n\tFileTree,\n\tFrontmatter,\n} from \"../../types\";\nimport { toAbsPath, toRelPath, type VaultIgnorer } from \"../../utils\";\n\nexport function scan(rootPath: AbsPath, ign: VaultIgnorer): FileTree | null {\n\tfunction aux(path: AbsPath): FileTree | null {\n\t\tif (ign?.ignore(path)) return null;\n\n\t\tconst stat = lstatSync(path);\n\t\tconst name = basename(path);\n\n\t\tif (stat.isDirectory()) {\n\t\t\tconst { dirs, files } = readdirSync(path).reduce(\n\t\t\t\t(acc, entry) => {\n\t\t\t\t\tconst node = aux(toAbsPath(join(path, entry)));\n\n\t\t\t\t\tif (node?.type === \"dir\") acc.dirs.push(node);\n\t\t\t\t\tif (node?.type === \"file\") acc.files.push(node);\n\n\t\t\t\t\treturn acc;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdirs: [] as DirNode[],\n\t\t\t\t\tfiles: [] as FileNode[],\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\tpath: toRelPath(rootPath, path),\n\t\t\t\tname,\n\t\t\t\ttype: \"dir\",\n\t\t\t\tdirs,\n\t\t\t\tfiles,\n\t\t\t};\n\t\t}\n\n\t\tif (stat.isFile() && name.endsWith(\".md\")) {\n\t\t\treturn {\n\t\t\t\tpath: toRelPath(rootPath, path),\n\t\t\t\tname,\n\t\t\t\ttype: \"file\",\n\t\t\t\tfrontmatter: getFrontmatter(path),\n\t\t\t};\n\t\t}\n\n\t\treturn null;\n\t}\n\n\treturn aux(rootPath);\n}\n\nfunction getFrontmatter(path: AbsPath): Frontmatter {\n\tconst { data: srcFrontmatter } = matter(readFileSync(path, \"utf-8\"));\n\treturn {\n\t\ttitle: basename(path).replace(/\\.md$/, \"\"),\n\t\tdescription: \"No description provided.\",\n\t\tlast_modified: lstatSync(path).mtime.toLocaleDateString(\"sv-SE\"), // \"sv-SE\" (스웨덴어)는 YYYY-MM-DD 형식으로 출력되는 유명한 트릭입니다.\n\t\t...srcFrontmatter,\n\t};\n}\n","import { existsSync, lstatSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport ignore, { type Ignore } from \"ignore\";\nimport type { AbsPath } from \"../types\";\nimport { toRelPath } from \"./path\";\n\nexport class VaultIgnorer {\n\tprivate ign: Ignore;\n\tprivate rootPath: AbsPath;\n\n\tconstructor(rootPath: AbsPath) {\n\t\tthis.rootPath = rootPath;\n\t\tthis.ign = ignore();\n\n\t\tthis.ign.add([\".*\"]);\n\t}\n\n\tpublic load() {\n\t\tconst ignorePath = join(this.rootPath, \".o2bignore\");\n\t\tif (existsSync(ignorePath))\n\t\t\tthis.ign.add(readFileSync(ignorePath).toString());\n\t}\n\n\tpublic ignore(path: AbsPath): boolean {\n\t\tif (path === this.rootPath) return false;\n\n\t\tif (!existsSync(path)) throw new Error(\"somethings wrong!\");\n\n\t\tconst stat = lstatSync(path);\n\n\t\tconst relPath =\n\t\t\ttoRelPath(this.rootPath, path) + (stat.isDirectory() ? \"/\" : \"\");\n\n\t\treturn this.ign.ignores(relPath);\n\t}\n}\n","import { lstatSync, readdirSync } from \"node:fs\";\nimport { isAbsolute, relative, resolve } from \"node:path\";\nimport type { AbsPath, RelPath } from \"../types\";\n\nfunction toAbsPath(path: string): AbsPath {\n\tif (!isAbsolute(path)) path = resolve(path);\n\treturn path as AbsPath;\n}\n\nfunction toRelPath(from: AbsPath, to: AbsPath): RelPath {\n\treturn relative(from, to) as RelPath;\n}\n\nfunction isObsidianDirectory(path: AbsPath) {\n\tconst stat = lstatSync(path);\n\n\tif (!stat.isDirectory()) return false;\n\n\tconst obsMetaDir = readdirSync(path, { withFileTypes: true })\n\t\t.filter((node) => node.isDirectory())\n\t\t.filter((node) => node.name === \".obsidian\");\n\n\tif (obsMetaDir.length !== 1) return false;\n\n\treturn true;\n}\n\nexport { toAbsPath, toRelPath, isObsidianDirectory };\n","import { mirror, scan } from \"./core/sync\";\nimport type { Config } from \"./types\";\nimport { isObsidianDirectory, VaultIgnorer } from \"./utils\";\n\nexport default function main(config: Config) {\n const { srcPath, destPath, ignore } = config;\n if (!isObsidianDirectory(srcPath)) throw new Error(\"Not a obsidian vault\");\n\n const ign = new VaultIgnorer(srcPath);\n if (ignore) ign.load();\n\n const fileTree = scan(srcPath, ign);\n if (fileTree === null) throw new Error(\"No content in vault\");\n\n mirror(fileTree, srcPath, destPath);\n}\n"],"mappings":"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","names":["filetree","import_node_fs","import_node_path","import_node_fs","import_node_path","import_node_fs","import_node_path","ignore","matter","ignore","cac","ignore"]}
@@ -0,0 +1,16 @@
1
+ declare const __brand: unique symbol;
2
+ type Branded<K, T> = K & {
3
+ [__brand]: T;
4
+ };
5
+
6
+ type AbsPath = Branded<string, "abspath">;
7
+
8
+ type Config = {
9
+ srcPath: AbsPath;
10
+ destPath: AbsPath;
11
+ ignore: boolean;
12
+ };
13
+
14
+ declare function main(config: Config): void;
15
+
16
+ export { main as default };
@@ -0,0 +1,16 @@
1
+ declare const __brand: unique symbol;
2
+ type Branded<K, T> = K & {
3
+ [__brand]: T;
4
+ };
5
+
6
+ type AbsPath = Branded<string, "abspath">;
7
+
8
+ type Config = {
9
+ srcPath: AbsPath;
10
+ destPath: AbsPath;
11
+ ignore: boolean;
12
+ };
13
+
14
+ declare function main(config: Config): void;
15
+
16
+ export { main as default };
package/dist/index.js ADDED
@@ -0,0 +1,175 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+
29
+ // src/index.ts
30
+ var index_exports = {};
31
+ __export(index_exports, {
32
+ default: () => main
33
+ });
34
+ module.exports = __toCommonJS(index_exports);
35
+
36
+ // src/core/sync/mirror.ts
37
+ var import_node_fs = require("fs");
38
+ var import_node_path = require("path");
39
+ function mirror(filetree, srcPath, destPath) {
40
+ function aux(filetree2) {
41
+ const from = (0, import_node_path.join)(srcPath, filetree2.path);
42
+ const to = (0, import_node_path.join)(destPath, filetree2.path);
43
+ if (filetree2.type === "dir") {
44
+ if (!(0, import_node_fs.existsSync)(to)) (0, import_node_fs.mkdirSync)(to, { recursive: true });
45
+ filetree2.files.forEach((file) => {
46
+ aux(file);
47
+ });
48
+ filetree2.dirs.forEach((dir) => {
49
+ aux(dir);
50
+ });
51
+ }
52
+ if (filetree2.type === "file") {
53
+ (0, import_node_fs.copyFileSync)(from, to);
54
+ }
55
+ }
56
+ aux(filetree);
57
+ generateFileTree(filetree, destPath);
58
+ }
59
+ function generateFileTree(filetree, destPath) {
60
+ const jsonFilePath = (0, import_node_path.join)(destPath, "o2bFileTree.json");
61
+ (0, import_node_fs.writeFileSync)(jsonFilePath, JSON.stringify(filetree, null, 2), "utf-8");
62
+ }
63
+
64
+ // src/core/sync/scan.ts
65
+ var import_node_fs4 = require("fs");
66
+ var import_node_path4 = require("path");
67
+ var import_gray_matter = __toESM(require("gray-matter"));
68
+
69
+ // src/utils/ignore.ts
70
+ var import_node_fs3 = require("fs");
71
+ var import_node_path3 = require("path");
72
+ var import_ignore = __toESM(require("ignore"));
73
+
74
+ // src/utils/path.ts
75
+ var import_node_fs2 = require("fs");
76
+ var import_node_path2 = require("path");
77
+ function toAbsPath(path) {
78
+ if (!(0, import_node_path2.isAbsolute)(path)) path = (0, import_node_path2.resolve)(path);
79
+ return path;
80
+ }
81
+ function toRelPath(from, to) {
82
+ return (0, import_node_path2.relative)(from, to);
83
+ }
84
+ function isObsidianDirectory(path) {
85
+ const stat = (0, import_node_fs2.lstatSync)(path);
86
+ if (!stat.isDirectory()) return false;
87
+ const obsMetaDir = (0, import_node_fs2.readdirSync)(path, { withFileTypes: true }).filter((node) => node.isDirectory()).filter((node) => node.name === ".obsidian");
88
+ if (obsMetaDir.length !== 1) return false;
89
+ return true;
90
+ }
91
+
92
+ // src/utils/ignore.ts
93
+ var VaultIgnorer = class {
94
+ ign;
95
+ rootPath;
96
+ constructor(rootPath) {
97
+ this.rootPath = rootPath;
98
+ this.ign = (0, import_ignore.default)();
99
+ this.ign.add([".*"]);
100
+ }
101
+ load() {
102
+ const ignorePath = (0, import_node_path3.join)(this.rootPath, ".o2bignore");
103
+ if ((0, import_node_fs3.existsSync)(ignorePath))
104
+ this.ign.add((0, import_node_fs3.readFileSync)(ignorePath).toString());
105
+ }
106
+ ignore(path) {
107
+ if (path === this.rootPath) return false;
108
+ if (!(0, import_node_fs3.existsSync)(path)) throw new Error("somethings wrong!");
109
+ const stat = (0, import_node_fs3.lstatSync)(path);
110
+ const relPath = toRelPath(this.rootPath, path) + (stat.isDirectory() ? "/" : "");
111
+ return this.ign.ignores(relPath);
112
+ }
113
+ };
114
+
115
+ // src/core/sync/scan.ts
116
+ function scan(rootPath, ign) {
117
+ function aux(path) {
118
+ if (ign == null ? void 0 : ign.ignore(path)) return null;
119
+ const stat = (0, import_node_fs4.lstatSync)(path);
120
+ const name = (0, import_node_path4.basename)(path);
121
+ if (stat.isDirectory()) {
122
+ const { dirs, files } = (0, import_node_fs4.readdirSync)(path).reduce(
123
+ (acc, entry) => {
124
+ const node = aux(toAbsPath((0, import_node_path4.join)(path, entry)));
125
+ if ((node == null ? void 0 : node.type) === "dir") acc.dirs.push(node);
126
+ if ((node == null ? void 0 : node.type) === "file") acc.files.push(node);
127
+ return acc;
128
+ },
129
+ {
130
+ dirs: [],
131
+ files: []
132
+ }
133
+ );
134
+ return {
135
+ path: toRelPath(rootPath, path),
136
+ name,
137
+ type: "dir",
138
+ dirs,
139
+ files
140
+ };
141
+ }
142
+ if (stat.isFile() && name.endsWith(".md")) {
143
+ return {
144
+ path: toRelPath(rootPath, path),
145
+ name,
146
+ type: "file",
147
+ frontmatter: getFrontmatter(path)
148
+ };
149
+ }
150
+ return null;
151
+ }
152
+ return aux(rootPath);
153
+ }
154
+ function getFrontmatter(path) {
155
+ const { data: srcFrontmatter } = (0, import_gray_matter.default)((0, import_node_fs4.readFileSync)(path, "utf-8"));
156
+ return {
157
+ title: (0, import_node_path4.basename)(path).replace(/\.md$/, ""),
158
+ description: "No description provided.",
159
+ last_modified: (0, import_node_fs4.lstatSync)(path).mtime.toLocaleDateString("sv-SE"),
160
+ // "sv-SE" (스웨덴어)는 YYYY-MM-DD 형식으로 출력되는 유명한 트릭입니다.
161
+ ...srcFrontmatter
162
+ };
163
+ }
164
+
165
+ // src/index.ts
166
+ function main(config) {
167
+ const { srcPath, destPath, ignore: ignore2 } = config;
168
+ if (!isObsidianDirectory(srcPath)) throw new Error("Not a obsidian vault");
169
+ const ign = new VaultIgnorer(srcPath);
170
+ if (ignore2) ign.load();
171
+ const fileTree = scan(srcPath, ign);
172
+ if (fileTree === null) throw new Error("No content in vault");
173
+ mirror(fileTree, srcPath, destPath);
174
+ }
175
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/core/sync/mirror.ts","../src/core/sync/scan.ts","../src/utils/ignore.ts","../src/utils/path.ts"],"sourcesContent":["import { mirror, scan } from \"./core/sync\";\nimport type { Config } from \"./types\";\nimport { isObsidianDirectory, VaultIgnorer } from \"./utils\";\n\nexport default function main(config: Config) {\n const { srcPath, destPath, ignore } = config;\n if (!isObsidianDirectory(srcPath)) throw new Error(\"Not a obsidian vault\");\n\n const ign = new VaultIgnorer(srcPath);\n if (ignore) ign.load();\n\n const fileTree = scan(srcPath, ign);\n if (fileTree === null) throw new Error(\"No content in vault\");\n\n mirror(fileTree, srcPath, destPath);\n}\n","import { copyFileSync, existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { AbsPath, FileTree } from \"../../types\";\n\nexport function mirror(\n\tfiletree: FileTree,\n\tsrcPath: AbsPath,\n\tdestPath: AbsPath,\n) {\n\tfunction aux(filetree: FileTree) {\n\t\tconst from = join(srcPath, filetree.path);\n\t\tconst to = join(destPath, filetree.path);\n\n\t\tif (filetree.type === \"dir\") {\n\t\t\tif (!existsSync(to)) mkdirSync(to, { recursive: true });\n\n\t\t\tfiletree.files.forEach((file) => {\n\t\t\t\taux(file);\n\t\t\t});\n\n\t\t\tfiletree.dirs.forEach((dir) => {\n\t\t\t\taux(dir);\n\t\t\t});\n\t\t}\n\n\t\tif (filetree.type === \"file\") {\n\t\t\tcopyFileSync(from, to);\n\t\t}\n\t}\n\n\taux(filetree);\n\tgenerateFileTree(filetree, destPath);\n}\n\nfunction generateFileTree(filetree: FileTree, destPath: AbsPath) {\n\tconst jsonFilePath = join(destPath, \"o2bFileTree.json\");\n\twriteFileSync(jsonFilePath, JSON.stringify(filetree, null, 2), \"utf-8\");\n}\n","import { lstatSync, readdirSync, readFileSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\nimport matter from \"gray-matter\";\nimport type {\n\tAbsPath,\n\tDirNode,\n\tFileNode,\n\tFileTree,\n\tFrontmatter,\n} from \"../../types\";\nimport { toAbsPath, toRelPath, type VaultIgnorer } from \"../../utils\";\n\nexport function scan(rootPath: AbsPath, ign: VaultIgnorer): FileTree | null {\n\tfunction aux(path: AbsPath): FileTree | null {\n\t\tif (ign?.ignore(path)) return null;\n\n\t\tconst stat = lstatSync(path);\n\t\tconst name = basename(path);\n\n\t\tif (stat.isDirectory()) {\n\t\t\tconst { dirs, files } = readdirSync(path).reduce(\n\t\t\t\t(acc, entry) => {\n\t\t\t\t\tconst node = aux(toAbsPath(join(path, entry)));\n\n\t\t\t\t\tif (node?.type === \"dir\") acc.dirs.push(node);\n\t\t\t\t\tif (node?.type === \"file\") acc.files.push(node);\n\n\t\t\t\t\treturn acc;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdirs: [] as DirNode[],\n\t\t\t\t\tfiles: [] as FileNode[],\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\tpath: toRelPath(rootPath, path),\n\t\t\t\tname,\n\t\t\t\ttype: \"dir\",\n\t\t\t\tdirs,\n\t\t\t\tfiles,\n\t\t\t};\n\t\t}\n\n\t\tif (stat.isFile() && name.endsWith(\".md\")) {\n\t\t\treturn {\n\t\t\t\tpath: toRelPath(rootPath, path),\n\t\t\t\tname,\n\t\t\t\ttype: \"file\",\n\t\t\t\tfrontmatter: getFrontmatter(path),\n\t\t\t};\n\t\t}\n\n\t\treturn null;\n\t}\n\n\treturn aux(rootPath);\n}\n\nfunction getFrontmatter(path: AbsPath): Frontmatter {\n\tconst { data: srcFrontmatter } = matter(readFileSync(path, \"utf-8\"));\n\treturn {\n\t\ttitle: basename(path).replace(/\\.md$/, \"\"),\n\t\tdescription: \"No description provided.\",\n\t\tlast_modified: lstatSync(path).mtime.toLocaleDateString(\"sv-SE\"), // \"sv-SE\" (스웨덴어)는 YYYY-MM-DD 형식으로 출력되는 유명한 트릭입니다.\n\t\t...srcFrontmatter,\n\t};\n}\n","import { existsSync, lstatSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport ignore, { type Ignore } from \"ignore\";\nimport type { AbsPath } from \"../types\";\nimport { toRelPath } from \"./path\";\n\nexport class VaultIgnorer {\n\tprivate ign: Ignore;\n\tprivate rootPath: AbsPath;\n\n\tconstructor(rootPath: AbsPath) {\n\t\tthis.rootPath = rootPath;\n\t\tthis.ign = ignore();\n\n\t\tthis.ign.add([\".*\"]);\n\t}\n\n\tpublic load() {\n\t\tconst ignorePath = join(this.rootPath, \".o2bignore\");\n\t\tif (existsSync(ignorePath))\n\t\t\tthis.ign.add(readFileSync(ignorePath).toString());\n\t}\n\n\tpublic ignore(path: AbsPath): boolean {\n\t\tif (path === this.rootPath) return false;\n\n\t\tif (!existsSync(path)) throw new Error(\"somethings wrong!\");\n\n\t\tconst stat = lstatSync(path);\n\n\t\tconst relPath =\n\t\t\ttoRelPath(this.rootPath, path) + (stat.isDirectory() ? \"/\" : \"\");\n\n\t\treturn this.ign.ignores(relPath);\n\t}\n}\n","import { lstatSync, readdirSync } from \"node:fs\";\nimport { isAbsolute, relative, resolve } from \"node:path\";\nimport type { AbsPath, RelPath } from \"../types\";\n\nfunction toAbsPath(path: string): AbsPath {\n\tif (!isAbsolute(path)) path = resolve(path);\n\treturn path as AbsPath;\n}\n\nfunction toRelPath(from: AbsPath, to: AbsPath): RelPath {\n\treturn relative(from, to) as RelPath;\n}\n\nfunction isObsidianDirectory(path: AbsPath) {\n\tconst stat = lstatSync(path);\n\n\tif (!stat.isDirectory()) return false;\n\n\tconst obsMetaDir = readdirSync(path, { withFileTypes: true })\n\t\t.filter((node) => node.isDirectory())\n\t\t.filter((node) => node.name === \".obsidian\");\n\n\tif (obsMetaDir.length !== 1) return false;\n\n\treturn true;\n}\n\nexport { toAbsPath, toRelPath, isObsidianDirectory };\n"],"mappings":"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","names":["filetree","import_node_fs","import_node_path","import_node_fs","import_node_path","import_node_fs","import_node_path","ignore","matter","ignore"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,143 @@
1
+ // src/core/sync/mirror.ts
2
+ import { copyFileSync, existsSync, mkdirSync, writeFileSync } from "fs";
3
+ import { join } from "path";
4
+ function mirror(filetree, srcPath, destPath) {
5
+ function aux(filetree2) {
6
+ const from = join(srcPath, filetree2.path);
7
+ const to = join(destPath, filetree2.path);
8
+ if (filetree2.type === "dir") {
9
+ if (!existsSync(to)) mkdirSync(to, { recursive: true });
10
+ filetree2.files.forEach((file) => {
11
+ aux(file);
12
+ });
13
+ filetree2.dirs.forEach((dir) => {
14
+ aux(dir);
15
+ });
16
+ }
17
+ if (filetree2.type === "file") {
18
+ copyFileSync(from, to);
19
+ }
20
+ }
21
+ aux(filetree);
22
+ generateFileTree(filetree, destPath);
23
+ }
24
+ function generateFileTree(filetree, destPath) {
25
+ const jsonFilePath = join(destPath, "o2bFileTree.json");
26
+ writeFileSync(jsonFilePath, JSON.stringify(filetree, null, 2), "utf-8");
27
+ }
28
+
29
+ // src/core/sync/scan.ts
30
+ import { lstatSync as lstatSync3, readdirSync as readdirSync2, readFileSync as readFileSync2 } from "fs";
31
+ import { basename, join as join3 } from "path";
32
+ import matter from "gray-matter";
33
+
34
+ // src/utils/ignore.ts
35
+ import { existsSync as existsSync2, lstatSync as lstatSync2, readFileSync } from "fs";
36
+ import { join as join2 } from "path";
37
+ import ignore from "ignore";
38
+
39
+ // src/utils/path.ts
40
+ import { lstatSync, readdirSync } from "fs";
41
+ import { isAbsolute, relative, resolve } from "path";
42
+ function toAbsPath(path) {
43
+ if (!isAbsolute(path)) path = resolve(path);
44
+ return path;
45
+ }
46
+ function toRelPath(from, to) {
47
+ return relative(from, to);
48
+ }
49
+ function isObsidianDirectory(path) {
50
+ const stat = lstatSync(path);
51
+ if (!stat.isDirectory()) return false;
52
+ const obsMetaDir = readdirSync(path, { withFileTypes: true }).filter((node) => node.isDirectory()).filter((node) => node.name === ".obsidian");
53
+ if (obsMetaDir.length !== 1) return false;
54
+ return true;
55
+ }
56
+
57
+ // src/utils/ignore.ts
58
+ var VaultIgnorer = class {
59
+ ign;
60
+ rootPath;
61
+ constructor(rootPath) {
62
+ this.rootPath = rootPath;
63
+ this.ign = ignore();
64
+ this.ign.add([".*"]);
65
+ }
66
+ load() {
67
+ const ignorePath = join2(this.rootPath, ".o2bignore");
68
+ if (existsSync2(ignorePath))
69
+ this.ign.add(readFileSync(ignorePath).toString());
70
+ }
71
+ ignore(path) {
72
+ if (path === this.rootPath) return false;
73
+ if (!existsSync2(path)) throw new Error("somethings wrong!");
74
+ const stat = lstatSync2(path);
75
+ const relPath = toRelPath(this.rootPath, path) + (stat.isDirectory() ? "/" : "");
76
+ return this.ign.ignores(relPath);
77
+ }
78
+ };
79
+
80
+ // src/core/sync/scan.ts
81
+ function scan(rootPath, ign) {
82
+ function aux(path) {
83
+ if (ign == null ? void 0 : ign.ignore(path)) return null;
84
+ const stat = lstatSync3(path);
85
+ const name = basename(path);
86
+ if (stat.isDirectory()) {
87
+ const { dirs, files } = readdirSync2(path).reduce(
88
+ (acc, entry) => {
89
+ const node = aux(toAbsPath(join3(path, entry)));
90
+ if ((node == null ? void 0 : node.type) === "dir") acc.dirs.push(node);
91
+ if ((node == null ? void 0 : node.type) === "file") acc.files.push(node);
92
+ return acc;
93
+ },
94
+ {
95
+ dirs: [],
96
+ files: []
97
+ }
98
+ );
99
+ return {
100
+ path: toRelPath(rootPath, path),
101
+ name,
102
+ type: "dir",
103
+ dirs,
104
+ files
105
+ };
106
+ }
107
+ if (stat.isFile() && name.endsWith(".md")) {
108
+ return {
109
+ path: toRelPath(rootPath, path),
110
+ name,
111
+ type: "file",
112
+ frontmatter: getFrontmatter(path)
113
+ };
114
+ }
115
+ return null;
116
+ }
117
+ return aux(rootPath);
118
+ }
119
+ function getFrontmatter(path) {
120
+ const { data: srcFrontmatter } = matter(readFileSync2(path, "utf-8"));
121
+ return {
122
+ title: basename(path).replace(/\.md$/, ""),
123
+ description: "No description provided.",
124
+ last_modified: lstatSync3(path).mtime.toLocaleDateString("sv-SE"),
125
+ // "sv-SE" (스웨덴어)는 YYYY-MM-DD 형식으로 출력되는 유명한 트릭입니다.
126
+ ...srcFrontmatter
127
+ };
128
+ }
129
+
130
+ // src/index.ts
131
+ function main(config) {
132
+ const { srcPath, destPath, ignore: ignore2 } = config;
133
+ if (!isObsidianDirectory(srcPath)) throw new Error("Not a obsidian vault");
134
+ const ign = new VaultIgnorer(srcPath);
135
+ if (ignore2) ign.load();
136
+ const fileTree = scan(srcPath, ign);
137
+ if (fileTree === null) throw new Error("No content in vault");
138
+ mirror(fileTree, srcPath, destPath);
139
+ }
140
+ export {
141
+ main as default
142
+ };
143
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/sync/mirror.ts","../src/core/sync/scan.ts","../src/utils/ignore.ts","../src/utils/path.ts","../src/index.ts"],"sourcesContent":["import { copyFileSync, existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { AbsPath, FileTree } from \"../../types\";\n\nexport function mirror(\n\tfiletree: FileTree,\n\tsrcPath: AbsPath,\n\tdestPath: AbsPath,\n) {\n\tfunction aux(filetree: FileTree) {\n\t\tconst from = join(srcPath, filetree.path);\n\t\tconst to = join(destPath, filetree.path);\n\n\t\tif (filetree.type === \"dir\") {\n\t\t\tif (!existsSync(to)) mkdirSync(to, { recursive: true });\n\n\t\t\tfiletree.files.forEach((file) => {\n\t\t\t\taux(file);\n\t\t\t});\n\n\t\t\tfiletree.dirs.forEach((dir) => {\n\t\t\t\taux(dir);\n\t\t\t});\n\t\t}\n\n\t\tif (filetree.type === \"file\") {\n\t\t\tcopyFileSync(from, to);\n\t\t}\n\t}\n\n\taux(filetree);\n\tgenerateFileTree(filetree, destPath);\n}\n\nfunction generateFileTree(filetree: FileTree, destPath: AbsPath) {\n\tconst jsonFilePath = join(destPath, \"o2bFileTree.json\");\n\twriteFileSync(jsonFilePath, JSON.stringify(filetree, null, 2), \"utf-8\");\n}\n","import { lstatSync, readdirSync, readFileSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\nimport matter from \"gray-matter\";\nimport type {\n\tAbsPath,\n\tDirNode,\n\tFileNode,\n\tFileTree,\n\tFrontmatter,\n} from \"../../types\";\nimport { toAbsPath, toRelPath, type VaultIgnorer } from \"../../utils\";\n\nexport function scan(rootPath: AbsPath, ign: VaultIgnorer): FileTree | null {\n\tfunction aux(path: AbsPath): FileTree | null {\n\t\tif (ign?.ignore(path)) return null;\n\n\t\tconst stat = lstatSync(path);\n\t\tconst name = basename(path);\n\n\t\tif (stat.isDirectory()) {\n\t\t\tconst { dirs, files } = readdirSync(path).reduce(\n\t\t\t\t(acc, entry) => {\n\t\t\t\t\tconst node = aux(toAbsPath(join(path, entry)));\n\n\t\t\t\t\tif (node?.type === \"dir\") acc.dirs.push(node);\n\t\t\t\t\tif (node?.type === \"file\") acc.files.push(node);\n\n\t\t\t\t\treturn acc;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdirs: [] as DirNode[],\n\t\t\t\t\tfiles: [] as FileNode[],\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\tpath: toRelPath(rootPath, path),\n\t\t\t\tname,\n\t\t\t\ttype: \"dir\",\n\t\t\t\tdirs,\n\t\t\t\tfiles,\n\t\t\t};\n\t\t}\n\n\t\tif (stat.isFile() && name.endsWith(\".md\")) {\n\t\t\treturn {\n\t\t\t\tpath: toRelPath(rootPath, path),\n\t\t\t\tname,\n\t\t\t\ttype: \"file\",\n\t\t\t\tfrontmatter: getFrontmatter(path),\n\t\t\t};\n\t\t}\n\n\t\treturn null;\n\t}\n\n\treturn aux(rootPath);\n}\n\nfunction getFrontmatter(path: AbsPath): Frontmatter {\n\tconst { data: srcFrontmatter } = matter(readFileSync(path, \"utf-8\"));\n\treturn {\n\t\ttitle: basename(path).replace(/\\.md$/, \"\"),\n\t\tdescription: \"No description provided.\",\n\t\tlast_modified: lstatSync(path).mtime.toLocaleDateString(\"sv-SE\"), // \"sv-SE\" (스웨덴어)는 YYYY-MM-DD 형식으로 출력되는 유명한 트릭입니다.\n\t\t...srcFrontmatter,\n\t};\n}\n","import { existsSync, lstatSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport ignore, { type Ignore } from \"ignore\";\nimport type { AbsPath } from \"../types\";\nimport { toRelPath } from \"./path\";\n\nexport class VaultIgnorer {\n\tprivate ign: Ignore;\n\tprivate rootPath: AbsPath;\n\n\tconstructor(rootPath: AbsPath) {\n\t\tthis.rootPath = rootPath;\n\t\tthis.ign = ignore();\n\n\t\tthis.ign.add([\".*\"]);\n\t}\n\n\tpublic load() {\n\t\tconst ignorePath = join(this.rootPath, \".o2bignore\");\n\t\tif (existsSync(ignorePath))\n\t\t\tthis.ign.add(readFileSync(ignorePath).toString());\n\t}\n\n\tpublic ignore(path: AbsPath): boolean {\n\t\tif (path === this.rootPath) return false;\n\n\t\tif (!existsSync(path)) throw new Error(\"somethings wrong!\");\n\n\t\tconst stat = lstatSync(path);\n\n\t\tconst relPath =\n\t\t\ttoRelPath(this.rootPath, path) + (stat.isDirectory() ? \"/\" : \"\");\n\n\t\treturn this.ign.ignores(relPath);\n\t}\n}\n","import { lstatSync, readdirSync } from \"node:fs\";\nimport { isAbsolute, relative, resolve } from \"node:path\";\nimport type { AbsPath, RelPath } from \"../types\";\n\nfunction toAbsPath(path: string): AbsPath {\n\tif (!isAbsolute(path)) path = resolve(path);\n\treturn path as AbsPath;\n}\n\nfunction toRelPath(from: AbsPath, to: AbsPath): RelPath {\n\treturn relative(from, to) as RelPath;\n}\n\nfunction isObsidianDirectory(path: AbsPath) {\n\tconst stat = lstatSync(path);\n\n\tif (!stat.isDirectory()) return false;\n\n\tconst obsMetaDir = readdirSync(path, { withFileTypes: true })\n\t\t.filter((node) => node.isDirectory())\n\t\t.filter((node) => node.name === \".obsidian\");\n\n\tif (obsMetaDir.length !== 1) return false;\n\n\treturn true;\n}\n\nexport { toAbsPath, toRelPath, isObsidianDirectory };\n","import { mirror, scan } from \"./core/sync\";\nimport type { Config } from \"./types\";\nimport { isObsidianDirectory, VaultIgnorer } from \"./utils\";\n\nexport default function main(config: Config) {\n const { srcPath, destPath, ignore } = config;\n if (!isObsidianDirectory(srcPath)) throw new Error(\"Not a obsidian vault\");\n\n const ign = new VaultIgnorer(srcPath);\n if (ignore) ign.load();\n\n const fileTree = scan(srcPath, ign);\n if (fileTree === null) throw new Error(\"No content in vault\");\n\n mirror(fileTree, srcPath, destPath);\n}\n"],"mappings":"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","names":["filetree","lstatSync","readdirSync","readFileSync","join","existsSync","lstatSync","join","join","existsSync","lstatSync","lstatSync","readdirSync","join","readFileSync","ignore"]}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@o2b/meta",
3
+ "version": "1.0.0-dev.0",
4
+ "description": "filetree generator for o2b",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "bin": {
16
+ "o2b-meta": "./dist/cli.js"
17
+ },
18
+ "scripts": {
19
+ "build": "tsup",
20
+ "test": "vitest",
21
+ "test:run": "vitest run"
22
+ },
23
+ "keywords": [],
24
+ "author": "goonco",
25
+ "license": "ISC",
26
+ "type": "commonjs",
27
+ "files": [
28
+ "dist"
29
+ ],
30
+ "devDependencies": {
31
+ "@biomejs/biome": "2.3.10",
32
+ "@types/node": "^25.0.3",
33
+ "@vitest/ui": "^4.0.16",
34
+ "tsup": "^8.5.1",
35
+ "typescript": "^5.9.3",
36
+ "vitest": "^4.0.16"
37
+ },
38
+ "dependencies": {
39
+ "cac": "^6.7.14",
40
+ "gray-matter": "^4.0.3",
41
+ "ignore": "^7.0.5",
42
+ "lilconfig": "^3.1.3"
43
+ }
44
+ }