embedoc 0.10.2 → 0.11.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/README.md CHANGED
@@ -46,7 +46,26 @@ yarn add embedoc
46
46
 
47
47
  ## Quick Start
48
48
 
49
- ### 1. Create Configuration File
49
+ ### 1. Initialize Project
50
+
51
+ ```bash
52
+ npx embedoc init
53
+ ```
54
+
55
+ This creates:
56
+ - `embedoc.config.yaml` - configuration file
57
+ - `.embedoc/renderers/index.ts` - renderer registration
58
+ - `.embedoc/datasources/index.ts` - custom datasource registration
59
+ - `.embedoc/templates/` - Handlebars templates directory
60
+
61
+ If `package.json` exists, npm scripts are also added:
62
+ - `npm run embedoc:build` - build documents
63
+ - `npm run embedoc:watch` - watch mode
64
+ - `npm run embedoc:generate` - run generators
65
+
66
+ ### 2. Configure
67
+
68
+ Edit `embedoc.config.yaml` to set your targets and datasources:
50
69
 
51
70
  ```yaml
52
71
  # embedoc.config.yaml
@@ -62,15 +81,12 @@ datasources:
62
81
  metadata_db:
63
82
  type: sqlite
64
83
  path: "./data/metadata.db"
65
-
66
- embeds_dir: "./embeds"
67
- templates_dir: "./templates"
68
84
  ```
69
85
 
70
- ### 2. Create an Embed
86
+ ### 3. Create a Renderer
71
87
 
72
88
  ```typescript
73
- // embeds/table_columns.ts
89
+ // .embedoc/renderers/table_columns.ts
74
90
  import { defineEmbed } from 'embedoc';
75
91
 
76
92
  export default defineEmbed({
@@ -104,10 +120,10 @@ export default defineEmbed({
104
120
  });
105
121
  ```
106
122
 
107
- Register your embed in `embeds/index.ts`:
123
+ Register your renderer in `.embedoc/renderers/index.ts`:
108
124
 
109
125
  ```typescript
110
- // embeds/index.ts
126
+ // .embedoc/renderers/index.ts
111
127
  import tableColumns from './table_columns.ts';
112
128
 
113
129
  export const embeds = {
@@ -117,7 +133,7 @@ export const embeds = {
117
133
 
118
134
  > **Note**: embedoc can directly import TypeScript files, so **no compilation is required**.
119
135
 
120
- ### 3. Add Markers to Your Document
136
+ ### 4. Add Markers to Your Document
121
137
 
122
138
  ```markdown
123
139
  # Users Table
@@ -126,18 +142,27 @@ export const embeds = {
126
142
  <!--@embedoc:end-->
127
143
  ```
128
144
 
129
- ### 4. Run Build
145
+ ### 5. Run Build
130
146
 
131
147
  ```bash
132
148
  npx embedoc build
149
+ # or, if scripts were added to package.json:
150
+ npm run embedoc:build
133
151
  ```
134
152
 
135
153
  ---
136
154
 
137
155
  ## CLI Commands
138
156
 
157
+ > **Full CLI reference:** [docs/cli-reference.md](./docs/cli-reference.md) | **Machine-readable contract:** [cli-contract.yaml](./cli-contract.yaml)
158
+
139
159
  ```bash
160
+ # Initialize project (creates config, .embedoc/ directory, updates package.json)
161
+ embedoc init
162
+ embedoc init --force # overwrite existing files
163
+
140
164
  # Build all files
165
+ embedoc build
141
166
  embedoc build --config embedoc.config.yaml
142
167
 
143
168
  # Build specific files only
@@ -146,10 +171,14 @@ embedoc build ./path/to/file.md
146
171
  # Generate new files (specific datasource)
147
172
  embedoc generate --datasource tables
148
173
 
174
+ # Generate with specific template
175
+ embedoc generate --datasource tables --generator table_doc.hbs
176
+
149
177
  # Run all datasource generators
150
178
  embedoc generate --all
151
179
 
152
180
  # Watch mode (incremental build)
181
+ embedoc watch
153
182
  embedoc watch --config embedoc.config.yaml
154
183
 
155
184
  # Debug dependency graph
@@ -162,6 +191,8 @@ embedoc build --dry-run
162
191
  embedoc build --verbose
163
192
  ```
164
193
 
194
+ All commands can be run directly with `npx embedoc <command>` or via package.json scripts after `embedoc init`.
195
+
165
196
  ---
166
197
 
167
198
  ## Configuration File
@@ -246,11 +277,14 @@ datasources:
246
277
  type: glob
247
278
  pattern: "./docs/**/*.md"
248
279
 
249
- # Embed directory (TypeScript)
250
- embeds_dir: "./embeds"
280
+ # Renderer directory (TypeScript) - default: ".embedoc/renderers"
281
+ renderers_dir: ".embedoc/renderers"
251
282
 
252
- # Template directory (Handlebars)
253
- templates_dir: "./templates"
283
+ # Custom datasource types directory - default: ".embedoc/datasources"
284
+ datasources_dir: ".embedoc/datasources"
285
+
286
+ # Template directory (Handlebars) - default: ".embedoc/templates"
287
+ templates_dir: ".embedoc/templates"
254
288
 
255
289
  # Output settings
256
290
  output:
@@ -713,6 +747,97 @@ inline_datasource:
713
747
 
714
748
  ---
715
749
 
750
+ ## Custom Datasources
751
+
752
+ Define custom datasource types in TypeScript to connect to any data source (APIs, databases, custom file formats, etc.).
753
+
754
+ ### Defining a Custom Datasource Type
755
+
756
+ ```typescript
757
+ // .embedoc/datasources/github.ts
758
+ import { defineDatasource } from 'embedoc';
759
+
760
+ export default defineDatasource({
761
+ async create(config) {
762
+ const owner = config['owner'] as string;
763
+ const repo = config['repo'] as string;
764
+ const response = await fetch(
765
+ `https://api.github.com/repos/${owner}/${repo}/issues`
766
+ );
767
+ const issues = await response.json();
768
+
769
+ return {
770
+ async query() { return issues; },
771
+ async getAll() { return issues; },
772
+ async close() {},
773
+ };
774
+ }
775
+ });
776
+ ```
777
+
778
+ ### Registering Custom Datasource Types
779
+
780
+ ```typescript
781
+ // .embedoc/datasources/index.ts
782
+ import github from './github.ts';
783
+
784
+ export const datasourceTypes = {
785
+ github,
786
+ };
787
+ ```
788
+
789
+ ### Using in Configuration
790
+
791
+ ```yaml
792
+ # embedoc.config.yaml
793
+ datasources:
794
+ my_issues:
795
+ type: github # matches key in datasourceTypes
796
+ owner: "myorg"
797
+ repo: "myrepo"
798
+ ```
799
+
800
+ All config properties are passed to the `create()` method, so custom datasources can accept any configuration.
801
+
802
+ ### Custom Inline Format Parsers
803
+
804
+ Register custom format parsers for `@embedoc-data` inline markers by exporting `inlineFormats` alongside `datasourceTypes`:
805
+
806
+ ```typescript
807
+ // .embedoc/datasources/index.ts
808
+ import github from './github.ts';
809
+
810
+ export const datasourceTypes = {
811
+ github,
812
+ };
813
+
814
+ export const inlineFormats = {
815
+ toml: (content: string) => parseToml(content),
816
+ ini: (content: string) => {
817
+ const result: Record<string, string> = {};
818
+ for (const line of content.split('\n')) {
819
+ const [key, ...rest] = line.split('=');
820
+ if (key && rest.length > 0) {
821
+ result[key.trim()] = rest.join('=').trim();
822
+ }
823
+ }
824
+ return result;
825
+ },
826
+ };
827
+ ```
828
+
829
+ Custom formats can then be used in documents:
830
+
831
+ ```markdown
832
+ <!--@embedoc-data:config format="ini"-->
833
+ host=localhost
834
+ port=5432
835
+ database=myapp
836
+ <!--@embedoc-data:end-->
837
+ ```
838
+
839
+ ---
840
+
716
841
  ## File Generation
717
842
 
718
843
  Generate new files in bulk using Handlebars templates based on datasource records.
@@ -734,7 +859,7 @@ datasources:
734
859
  ### Template (Handlebars)
735
860
 
736
861
  ```handlebars
737
- {{!-- templates/table_doc.hbs --}}
862
+ {{!-- .embedoc/templates/table_doc.hbs --}}
738
863
  ---
739
864
  doc_id: "{{table_name}}"
740
865
  embeds:
@@ -851,26 +976,31 @@ Frontmatter values can be referenced in marker attributes using `${...}` syntax.
851
976
 
852
977
  ```
853
978
  your-project/
854
- ├── embedoc.config.yaml # Configuration file
855
- ├── embeds/ # Embed definitions (TypeScript)
856
- │ ├── table_columns.ts
857
- │ ├── table_relations.ts
858
- └── index.ts # Export all embeds
859
- ├── templates/ # File generation templates (Handlebars)
860
- │ ├── table_doc.hbs
861
- └── view_doc.hbs
862
- ├── data/ # Datasources
979
+ ├── embedoc.config.yaml # Configuration file
980
+ ├── .embedoc/ # All embedoc custom code
981
+ │ ├── renderers/ # Renderer definitions (TypeScript)
982
+ ├── index.ts # Export all renderers
983
+ │ ├── table_columns.ts
984
+ │ │ └── table_relations.ts
985
+ │ ├── datasources/ # Custom datasource types (TypeScript)
986
+ │ ├── index.ts # Export datasourceTypes and inlineFormats
987
+ │ │ └── github.ts
988
+ │ ├── templates/ # File generation templates (Handlebars)
989
+ │ │ ├── table_doc.hbs
990
+ │ │ └── view_doc.hbs
991
+ │ └── package.json # Optional: dependencies for custom code
992
+ ├── data/ # Datasource files
863
993
  │ ├── metadata.db
864
994
  │ └── endpoints.csv
865
- └── docs/ # Target documents
995
+ └── docs/ # Target documents
866
996
  └── tables/
867
997
  └── users.md
868
998
  ```
869
999
 
870
- ### Embed Registration
1000
+ ### Renderer Registration
871
1001
 
872
1002
  ```typescript
873
- // embeds/index.ts
1003
+ // .embedoc/renderers/index.ts
874
1004
  import tableColumns from './table_columns.ts';
875
1005
  import tableRelations from './table_relations.ts';
876
1006
  import customEmbed from './custom_embed.ts';
@@ -923,6 +1053,7 @@ npm test
923
1053
  import {
924
1054
  // Core
925
1055
  defineEmbed,
1056
+ defineDatasource,
926
1057
  build,
927
1058
  processFile,
928
1059
 
@@ -1002,6 +1133,12 @@ interface InlineDatasourceConfig {
1002
1133
  stripCodeFences?: boolean;
1003
1134
  stripPatterns?: string[];
1004
1135
  }
1136
+
1137
+ interface CustomDatasourceDefinition {
1138
+ create(config: DatasourceConfig): Promise<Datasource>;
1139
+ }
1140
+
1141
+ type InlineFormatParser = (content: string) => unknown;
1005
1142
  ```
1006
1143
 
1007
1144
  ---
@@ -0,0 +1,327 @@
1
+ # yaml-language-server: $schema=./node_modules/cli-contracts/schemas/cli-contract.schema.json
2
+ cliContracts: 0.1.0
3
+
4
+ info:
5
+ title: embedoc CLI
6
+ version: 0.11.1
7
+ description: >-
8
+ In-place document generator that auto-updates marker blocks in documents
9
+ and source code while preserving manually edited sections. Supports
10
+ multiple datasources (SQLite, CSV, JSON, YAML, glob), programmable
11
+ TypeScript renderers, Handlebars file generation, and incremental builds
12
+ with dependency tracking.
13
+ license:
14
+ name: MIT
15
+ contact:
16
+ name: foo-ogawa
17
+ url: https://github.com/foo-ogawa/embedoc
18
+
19
+ commandSets:
20
+ embedoc:
21
+ summary: In-place document generator with marker-based embedding.
22
+ executable: embedoc
23
+
24
+ globalOptions:
25
+ - name: version
26
+ aliases: [V]
27
+ description: Print version and exit.
28
+ schema:
29
+ type: boolean
30
+
31
+ - name: help
32
+ aliases: [h]
33
+ description: Show help and exit.
34
+ schema:
35
+ type: boolean
36
+
37
+ commands:
38
+ # ── init ──────────────────────────────────────────
39
+ init:
40
+ summary: Initialize embedoc in the current project.
41
+ description: >-
42
+ Creates starter configuration and directory structure:
43
+ embedoc.config.yaml, .embedoc/renderers/index.ts,
44
+ .embedoc/datasources/index.ts, and .embedoc/templates/.
45
+ If package.json exists, adds embedoc:build, embedoc:watch,
46
+ and embedoc:generate npm scripts.
47
+ usage:
48
+ - embedoc init
49
+ - embedoc init --force
50
+
51
+ options:
52
+ - name: force
53
+ aliases: [f]
54
+ description: Overwrite existing files.
55
+ schema:
56
+ type: boolean
57
+ default: false
58
+
59
+ exits:
60
+ '0':
61
+ description: Initialization succeeded.
62
+ stdout:
63
+ format: text
64
+ files:
65
+ - path: embedoc.config.yaml
66
+ required: false
67
+ mediaType: application/yaml
68
+ encoding: utf-8
69
+ description: Configuration file.
70
+ - path: .embedoc/renderers/index.ts
71
+ required: false
72
+ mediaType: text/x-typescript
73
+ encoding: utf-8
74
+ description: Renderer registration file.
75
+ - path: .embedoc/datasources/index.ts
76
+ required: false
77
+ mediaType: text/x-typescript
78
+ encoding: utf-8
79
+ description: Custom datasource registration file.
80
+ - path: .embedoc/templates/.gitkeep
81
+ required: false
82
+ description: Templates directory placeholder.
83
+
84
+ '1':
85
+ description: Initialization failed (write error).
86
+ stderr:
87
+ format: text
88
+
89
+ x-agent:
90
+ riskLevel: low
91
+ requiresConfirmation: false
92
+ idempotent: true
93
+ sideEffects:
94
+ - file_write
95
+ - directory_create
96
+
97
+ # ── build ─────────────────────────────────────────
98
+ build:
99
+ summary: Build documents by replacing markers with rendered content.
100
+ description: >-
101
+ Loads configuration, initializes datasources, loads TypeScript
102
+ renderers, and processes all target files (or specific files if
103
+ provided). Each @embedoc marker block is re-rendered and the
104
+ content between start/end markers is replaced in-place.
105
+ usage:
106
+ - embedoc build
107
+ - embedoc build --config embedoc.config.yaml
108
+ - embedoc build ./docs/tables/users.md
109
+ - embedoc build --dry-run --verbose
110
+
111
+ arguments:
112
+ - name: files
113
+ description: Specific file paths to process. If omitted, processes all targets from config.
114
+ schema:
115
+ type: array
116
+ items:
117
+ type: string
118
+ variadic: true
119
+ file:
120
+ mode: readWrite
121
+ exists: true
122
+
123
+ options:
124
+ - name: config
125
+ aliases: [c]
126
+ description: Path to config file (YAML or JSON).
127
+ valueName: path
128
+ schema:
129
+ type: string
130
+ default: embedoc.config.yaml
131
+ file:
132
+ mode: read
133
+ exists: true
134
+ mediaType: application/yaml
135
+ encoding: utf-8
136
+
137
+ - name: dry-run
138
+ aliases: [d]
139
+ description: Preview changes without writing files.
140
+ schema:
141
+ type: boolean
142
+ default: false
143
+
144
+ - name: verbose
145
+ aliases: [v]
146
+ description: Enable verbose output.
147
+ schema:
148
+ type: boolean
149
+ default: false
150
+
151
+ exits:
152
+ '0':
153
+ description: Build succeeded. All markers were processed without errors.
154
+ stdout:
155
+ format: text
156
+
157
+ '1':
158
+ description: Build failed (config not found, datasource error, or marker processing error).
159
+ stderr:
160
+ format: text
161
+
162
+ x-agent:
163
+ riskLevel: medium
164
+ requiresConfirmation: false
165
+ idempotent: true
166
+ sideEffects:
167
+ - file_write
168
+ safeDryRunOption: --dry-run
169
+ recommendedBeforeUse:
170
+ - Ensure embedoc.config.yaml exists (run init if needed).
171
+ - Verify datasource files are accessible.
172
+
173
+ # ── generate ──────────────────────────────────────
174
+ generate:
175
+ summary: Generate new files from datasource records using Handlebars templates.
176
+ description: >-
177
+ Reads datasource records and generates new files using Handlebars
178
+ templates defined in the generators config. Requires either
179
+ --datasource to process a specific datasource or --all to process
180
+ all datasources that have generators configured. Optionally filter
181
+ by generator template name with --generator.
182
+ usage:
183
+ - embedoc generate --datasource tables
184
+ - embedoc generate --all
185
+ - embedoc generate --datasource tables --generator table_doc.hbs
186
+ - embedoc generate --all --dry-run --verbose
187
+
188
+ options:
189
+ - name: config
190
+ aliases: [c]
191
+ description: Path to config file (YAML or JSON).
192
+ valueName: path
193
+ schema:
194
+ type: string
195
+ default: embedoc.config.yaml
196
+ file:
197
+ mode: read
198
+ exists: true
199
+ mediaType: application/yaml
200
+ encoding: utf-8
201
+
202
+ - name: datasource
203
+ aliases: [s]
204
+ description: Specific datasource to process.
205
+ valueName: name
206
+ schema:
207
+ type: string
208
+
209
+ - name: generator
210
+ aliases: [g]
211
+ description: Specific generator template to use.
212
+ valueName: name
213
+ schema:
214
+ type: string
215
+
216
+ - name: all
217
+ aliases: [a]
218
+ description: Process all datasources that have generators configured.
219
+ schema:
220
+ type: boolean
221
+ default: false
222
+
223
+ - name: dry-run
224
+ aliases: [d]
225
+ description: Preview generation without writing files.
226
+ schema:
227
+ type: boolean
228
+ default: false
229
+
230
+ - name: verbose
231
+ aliases: [v]
232
+ description: Enable verbose output.
233
+ schema:
234
+ type: boolean
235
+ default: false
236
+
237
+ exits:
238
+ '0':
239
+ description: Generation succeeded.
240
+ stdout:
241
+ format: text
242
+
243
+ '1':
244
+ description: >-
245
+ Generation failed (missing --datasource/--all, config not found,
246
+ datasource error, or template error).
247
+ stderr:
248
+ format: text
249
+
250
+ x-agent:
251
+ riskLevel: medium
252
+ requiresConfirmation: false
253
+ idempotent: true
254
+ sideEffects:
255
+ - file_write
256
+ safeDryRunOption: --dry-run
257
+ recommendedBeforeUse:
258
+ - Ensure embedoc.config.yaml exists with generators configured.
259
+ - Verify datasource files are accessible.
260
+ - Ensure Handlebars templates exist in templates_dir.
261
+
262
+ # ── watch ─────────────────────────────────────────
263
+ watch:
264
+ summary: Watch files and rebuild on changes with dependency tracking.
265
+ description: >-
266
+ Monitors target files, renderers, and datasource files for changes.
267
+ When a change is detected, rebuilds only affected documents using
268
+ the dependency graph. Renderer changes trigger a full renderer
269
+ reload and dependency graph rebuild. Runs until interrupted with
270
+ SIGINT (Ctrl+C).
271
+ usage:
272
+ - embedoc watch
273
+ - embedoc watch --config embedoc.config.yaml
274
+ - embedoc watch --verbose
275
+ - embedoc watch --debug-deps
276
+
277
+ options:
278
+ - name: config
279
+ aliases: [c]
280
+ description: Path to config file (YAML or JSON).
281
+ valueName: path
282
+ schema:
283
+ type: string
284
+ default: embedoc.config.yaml
285
+ file:
286
+ mode: read
287
+ exists: true
288
+ mediaType: application/yaml
289
+ encoding: utf-8
290
+
291
+ - name: verbose
292
+ aliases: [v]
293
+ description: Enable verbose rebuild output.
294
+ schema:
295
+ type: boolean
296
+ default: false
297
+
298
+ - name: debug-deps
299
+ description: Print dependency graph at startup for debugging.
300
+ schema:
301
+ type: boolean
302
+ default: false
303
+
304
+ signals:
305
+ SIGINT:
306
+ description: Gracefully stops the watcher, closes datasources, and exits.
307
+
308
+ exits:
309
+ '0':
310
+ description: Watcher stopped gracefully (via SIGINT).
311
+ stdout:
312
+ format: text
313
+
314
+ '1':
315
+ description: Watch failed (config not found or initialization error).
316
+ stderr:
317
+ format: text
318
+
319
+ x-agent:
320
+ riskLevel: medium
321
+ requiresConfirmation: false
322
+ idempotent: true
323
+ sideEffects:
324
+ - file_write
325
+ recommendedBeforeUse:
326
+ - Ensure embedoc.config.yaml exists (run init if needed).
327
+ - Verify datasource files are accessible.