readme-aura 0.1.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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +134 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +192 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/components/MockupPhone.d.ts +11 -0
  7. package/dist/components/MockupPhone.js +155 -0
  8. package/dist/components/MockupPhone.js.map +1 -0
  9. package/dist/components/StatsCard.d.ts +11 -0
  10. package/dist/components/StatsCard.js +91 -0
  11. package/dist/components/StatsCard.js.map +1 -0
  12. package/dist/components/index.d.ts +2 -0
  13. package/dist/components/index.js +3 -0
  14. package/dist/components/index.js.map +1 -0
  15. package/dist/fonts.d.ts +3 -0
  16. package/dist/fonts.js +58 -0
  17. package/dist/fonts.js.map +1 -0
  18. package/dist/github.d.ts +12 -0
  19. package/dist/github.js +271 -0
  20. package/dist/github.js.map +1 -0
  21. package/dist/init.d.ts +14 -0
  22. package/dist/init.js +105 -0
  23. package/dist/init.js.map +1 -0
  24. package/dist/parser.d.ts +2 -0
  25. package/dist/parser.js +49 -0
  26. package/dist/parser.js.map +1 -0
  27. package/dist/renderer.d.ts +5 -0
  28. package/dist/renderer.js +124 -0
  29. package/dist/renderer.js.map +1 -0
  30. package/dist/templates/source-profile.d.ts +5 -0
  31. package/dist/templates/source-profile.js +30 -0
  32. package/dist/templates/source-profile.js.map +1 -0
  33. package/dist/templates/source-project.d.ts +5 -0
  34. package/dist/templates/source-project.js +27 -0
  35. package/dist/templates/source-project.js.map +1 -0
  36. package/dist/templates/workflow.d.ts +1 -0
  37. package/dist/templates/workflow.js +27 -0
  38. package/dist/templates/workflow.js.map +1 -0
  39. package/dist/types.d.ts +71 -0
  40. package/dist/types.js +2 -0
  41. package/dist/types.js.map +1 -0
  42. package/package.json +57 -0
  43. package/readme.source.md +498 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatsCard.js","sourceRoot":"","sources":["../../src/components/StatsCard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { makeStatsCard } from './StatsCard.js';
2
+ export { makeMockupPhone } from './MockupPhone.js';
@@ -0,0 +1,3 @@
1
+ export { makeStatsCard } from './StatsCard.js';
2
+ export { makeMockupPhone } from './MockupPhone.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { FontConfig } from './types.js';
2
+ export declare function loadDefaultFonts(): Promise<FontConfig[]>;
3
+ export declare function loadFontsFromDir(dirPath: string): Promise<FontConfig[]>;
package/dist/fonts.js ADDED
@@ -0,0 +1,58 @@
1
+ import { readFile, readdir } from 'node:fs/promises';
2
+ import { resolve, basename, extname } from 'node:path';
3
+ import { createRequire } from 'node:module';
4
+ const require = createRequire(import.meta.url);
5
+ const FONT_EXTENSIONS = ['.ttf', '.otf', '.woff'];
6
+ export async function loadDefaultFonts() {
7
+ try {
8
+ return await loadFontsourceInter();
9
+ }
10
+ catch {
11
+ console.log(' @fontsource/inter not found, fetching from Google Fonts CDN...');
12
+ return await loadInterFromCDN();
13
+ }
14
+ }
15
+ async function loadFontsourceInter() {
16
+ const basePath = resolve(require.resolve('@fontsource/inter/metadata.json'), '..', 'files');
17
+ const regular = await readFile(resolve(basePath, 'inter-latin-400-normal.woff'));
18
+ const bold = await readFile(resolve(basePath, 'inter-latin-700-normal.woff'));
19
+ return [
20
+ { name: 'Inter', data: regular.buffer, weight: 400, style: 'normal' },
21
+ { name: 'Inter', data: bold.buffer, weight: 700, style: 'normal' },
22
+ ];
23
+ }
24
+ async function loadInterFromCDN() {
25
+ const cssUrl = 'https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap';
26
+ const cssResponse = await fetch(cssUrl, {
27
+ headers: { 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36' },
28
+ });
29
+ const css = await cssResponse.text();
30
+ const urls = [...css.matchAll(/src:\s*url\(([^)]+\.woff)\)/g)].map((m) => m[1]);
31
+ if (urls.length === 0) {
32
+ throw new Error('Could not extract font URL from Google Fonts CSS');
33
+ }
34
+ const fonts = [];
35
+ for (const url of urls) {
36
+ const response = await fetch(url);
37
+ const data = await response.arrayBuffer();
38
+ const weight = url.includes('700') ? 700 : 400;
39
+ fonts.push({ name: 'Inter', data, weight, style: 'normal' });
40
+ }
41
+ return fonts;
42
+ }
43
+ export async function loadFontsFromDir(dirPath) {
44
+ const absDir = resolve(dirPath);
45
+ const files = await readdir(absDir);
46
+ const fontFiles = files.filter((f) => FONT_EXTENSIONS.includes(extname(f).toLowerCase()));
47
+ if (fontFiles.length === 0) {
48
+ throw new Error(`No font files (${FONT_EXTENSIONS.join(', ')}) found in ${absDir}`);
49
+ }
50
+ const fonts = [];
51
+ for (const file of fontFiles) {
52
+ const data = await readFile(resolve(absDir, file));
53
+ const name = basename(file, extname(file)).replace(/[-_](Regular|Bold|Italic|Light|Medium|SemiBold|ExtraBold|Black|\d+)/gi, '');
54
+ fonts.push({ name, data: data.buffer, weight: 400, style: 'normal' });
55
+ }
56
+ return fonts;
57
+ }
58
+ //# sourceMappingURL=fonts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fonts.js","sourceRoot":"","sources":["../src/fonts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { GitHubData, RepositoryData } from './types.js';
2
+ export interface GitHubRemote {
3
+ owner: string;
4
+ repo: string;
5
+ }
6
+ export declare function parseGitHubRemote(url: string): GitHubRemote | null;
7
+ export declare function detectGitHubRemote(): GitHubRemote | null;
8
+ export declare function detectGitHubUser(): string | null;
9
+ export declare function fetchGitHubData(username: string, token: string): Promise<GitHubData>;
10
+ export declare function createMockGitHubData(username: string): GitHubData;
11
+ export declare function fetchRepositoryData(owner: string, repo: string, token: string): Promise<RepositoryData>;
12
+ export declare function createMockRepoData(owner: string, repo: string): RepositoryData;
package/dist/github.js ADDED
@@ -0,0 +1,271 @@
1
+ import { execSync } from 'node:child_process';
2
+ // ── GraphQL Queries ──────────────────────────────────────────────
3
+ const USER_QUERY = `
4
+ query ($login: String!) {
5
+ user(login: $login) {
6
+ login
7
+ name
8
+ avatarUrl
9
+ bio
10
+ location
11
+ company
12
+ followers { totalCount }
13
+ following { totalCount }
14
+ createdAt
15
+ repositories(
16
+ first: 100
17
+ ownerAffiliations: OWNER
18
+ orderBy: { field: STARGAZERS, direction: DESC }
19
+ privacy: PUBLIC
20
+ ) {
21
+ totalCount
22
+ nodes {
23
+ name
24
+ description
25
+ url
26
+ stargazerCount
27
+ forkCount
28
+ primaryLanguage { name color }
29
+ defaultBranchRef {
30
+ target {
31
+ ... on Commit {
32
+ history { totalCount }
33
+ }
34
+ }
35
+ }
36
+ }
37
+ }
38
+ }
39
+ }
40
+ `;
41
+ const REPO_QUERY = `
42
+ query ($owner: String!, $name: String!) {
43
+ repository(owner: $owner, name: $name) {
44
+ name
45
+ description
46
+ url
47
+ stargazerCount
48
+ forkCount
49
+ primaryLanguage { name color }
50
+ defaultBranchRef {
51
+ target {
52
+ ... on Commit {
53
+ history { totalCount }
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+ `;
60
+ async function graphql(token, query, variables) {
61
+ const res = await fetch('https://api.github.com/graphql', {
62
+ method: 'POST',
63
+ headers: {
64
+ Authorization: `bearer ${token}`,
65
+ 'Content-Type': 'application/json',
66
+ 'User-Agent': 'readme-aura',
67
+ },
68
+ body: JSON.stringify({ query, variables }),
69
+ });
70
+ if (!res.ok) {
71
+ const text = await res.text();
72
+ throw new Error(`GitHub API returned ${res.status}: ${text}`);
73
+ }
74
+ return res.json();
75
+ }
76
+ export function parseGitHubRemote(url) {
77
+ // https://github.com/user/repo.git or https://github.com/user/repo
78
+ const httpsMatch = url.match(/github\.com\/([^/]+)\/([^/.]+)/);
79
+ if (httpsMatch)
80
+ return { owner: httpsMatch[1], repo: httpsMatch[2] };
81
+ // git@github.com:user/repo.git or git@github.com:user/repo
82
+ const sshMatch = url.match(/github\.com:([^/]+)\/([^/.]+)/);
83
+ if (sshMatch)
84
+ return { owner: sshMatch[1], repo: sshMatch[2] };
85
+ return null;
86
+ }
87
+ export function detectGitHubRemote() {
88
+ try {
89
+ const remote = execSync('git remote get-url origin', {
90
+ encoding: 'utf-8',
91
+ stdio: ['pipe', 'pipe', 'pipe'],
92
+ }).trim();
93
+ return parseGitHubRemote(remote);
94
+ }
95
+ catch {
96
+ return null;
97
+ }
98
+ }
99
+ export function detectGitHubUser() {
100
+ return detectGitHubRemote()?.owner ?? null;
101
+ }
102
+ // ── Data Transformation ──────────────────────────────────────────
103
+ function transformUser(raw) {
104
+ return {
105
+ login: raw.login,
106
+ name: raw.name,
107
+ avatarUrl: raw.avatarUrl,
108
+ bio: raw.bio,
109
+ location: raw.location,
110
+ company: raw.company,
111
+ followers: raw.followers.totalCount,
112
+ following: raw.following.totalCount,
113
+ createdAt: raw.createdAt,
114
+ };
115
+ }
116
+ function transformStats(raw) {
117
+ const repos = raw.repositories.nodes;
118
+ return {
119
+ totalStars: repos.reduce((sum, r) => sum + r.stargazerCount, 0),
120
+ totalForks: repos.reduce((sum, r) => sum + r.forkCount, 0),
121
+ totalRepos: raw.repositories.totalCount,
122
+ totalCommits: repos.reduce((sum, r) => {
123
+ return sum + (r.defaultBranchRef?.target?.history?.totalCount ?? 0);
124
+ }, 0),
125
+ };
126
+ }
127
+ function transformLanguages(raw) {
128
+ const counts = new Map();
129
+ for (const repo of raw.repositories.nodes) {
130
+ if (!repo.primaryLanguage)
131
+ continue;
132
+ const { name, color } = repo.primaryLanguage;
133
+ const existing = counts.get(name);
134
+ if (existing) {
135
+ existing.count++;
136
+ }
137
+ else {
138
+ counts.set(name, { count: 1, color });
139
+ }
140
+ }
141
+ const total = [...counts.values()].reduce((s, v) => s + v.count, 0);
142
+ if (total === 0)
143
+ return [];
144
+ return [...counts.entries()]
145
+ .map(([name, { count, color }]) => ({
146
+ name,
147
+ percentage: Math.round((count / total) * 100),
148
+ color,
149
+ }))
150
+ .sort((a, b) => b.percentage - a.percentage)
151
+ .slice(0, 10);
152
+ }
153
+ function transformRepos(raw) {
154
+ return raw.repositories.nodes.slice(0, 10).map((r) => ({
155
+ name: r.name,
156
+ description: r.description,
157
+ url: r.url,
158
+ stars: r.stargazerCount,
159
+ forks: r.forkCount,
160
+ language: r.primaryLanguage?.name ?? null,
161
+ }));
162
+ }
163
+ // ── Public API ───────────────────────────────────────────────────
164
+ export async function fetchGitHubData(username, token) {
165
+ const response = await graphql(token, USER_QUERY, { login: username });
166
+ if (response.errors?.length) {
167
+ throw new Error(`GitHub GraphQL error: ${response.errors.map((e) => e.message).join(', ')}`);
168
+ }
169
+ if (!response.data?.user) {
170
+ throw new Error(`GitHub user "${username}" not found.`);
171
+ }
172
+ const raw = response.data.user;
173
+ return {
174
+ user: transformUser(raw),
175
+ stats: transformStats(raw),
176
+ languages: transformLanguages(raw),
177
+ repos: transformRepos(raw),
178
+ };
179
+ }
180
+ // ── Mock data for testing without token ──────────────────────────
181
+ export function createMockGitHubData(username) {
182
+ return {
183
+ user: {
184
+ login: username,
185
+ name: username,
186
+ avatarUrl: `https://github.com/${username}.png`,
187
+ bio: 'A passionate developer',
188
+ location: null,
189
+ company: null,
190
+ followers: 42,
191
+ following: 10,
192
+ createdAt: '2020-01-01T00:00:00Z',
193
+ },
194
+ stats: {
195
+ totalStars: 128,
196
+ totalForks: 34,
197
+ totalRepos: 25,
198
+ totalCommits: 1547,
199
+ },
200
+ languages: [
201
+ { name: 'TypeScript', percentage: 45, color: '#3178c6' },
202
+ { name: 'JavaScript', percentage: 25, color: '#f1e05a' },
203
+ { name: 'Python', percentage: 15, color: '#3572A5' },
204
+ { name: 'Rust', percentage: 10, color: '#dea584' },
205
+ { name: 'Go', percentage: 5, color: '#00ADD8' },
206
+ ],
207
+ repos: [
208
+ {
209
+ name: 'awesome-project',
210
+ description: 'My best project',
211
+ url: `https://github.com/${username}/awesome-project`,
212
+ stars: 64,
213
+ forks: 12,
214
+ language: 'TypeScript',
215
+ },
216
+ {
217
+ name: 'cool-lib',
218
+ description: 'A cool library',
219
+ url: `https://github.com/${username}/cool-lib`,
220
+ stars: 32,
221
+ forks: 8,
222
+ language: 'JavaScript',
223
+ },
224
+ {
225
+ name: 'rust-tool',
226
+ description: 'Fast CLI tool',
227
+ url: `https://github.com/${username}/rust-tool`,
228
+ stars: 18,
229
+ forks: 5,
230
+ language: 'Rust',
231
+ },
232
+ ],
233
+ };
234
+ }
235
+ // ── Repository API ───────────────────────────────────────────────
236
+ export async function fetchRepositoryData(owner, repo, token) {
237
+ const response = await graphql(token, REPO_QUERY, {
238
+ owner,
239
+ name: repo,
240
+ });
241
+ if (response.errors?.length) {
242
+ throw new Error(`GitHub GraphQL error: ${response.errors.map((e) => e.message).join(', ')}`);
243
+ }
244
+ const r = response.data?.repository;
245
+ if (!r) {
246
+ throw new Error(`Repository "${owner}/${repo}" not found.`);
247
+ }
248
+ return {
249
+ name: r.name,
250
+ description: r.description,
251
+ url: r.url,
252
+ stars: r.stargazerCount,
253
+ forks: r.forkCount,
254
+ language: r.primaryLanguage?.name ?? null,
255
+ languageColor: r.primaryLanguage?.color ?? null,
256
+ commits: r.defaultBranchRef?.target?.history?.totalCount ?? 0,
257
+ };
258
+ }
259
+ export function createMockRepoData(owner, repo) {
260
+ return {
261
+ name: repo,
262
+ description: 'A great project',
263
+ url: `https://github.com/${owner}/${repo}`,
264
+ stars: 42,
265
+ forks: 8,
266
+ language: 'TypeScript',
267
+ languageColor: '#3178c6',
268
+ commits: 256,
269
+ };
270
+ }
271
+ //# sourceMappingURL=github.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.js","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"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"}
package/dist/init.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { type GitHubRemote } from './github.js';
2
+ export interface InitOptions {
3
+ cwd?: string;
4
+ template?: 'profile' | 'project';
5
+ force?: boolean;
6
+ }
7
+ export interface InitResult {
8
+ created: string[];
9
+ skipped: string[];
10
+ gitignoreFixed: string[];
11
+ template: 'profile' | 'project';
12
+ remote: GitHubRemote | null;
13
+ }
14
+ export declare function initProject(opts?: InitOptions): Promise<InitResult>;
package/dist/init.js ADDED
@@ -0,0 +1,105 @@
1
+ import { writeFile, readFile, mkdir, access } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { execSync } from 'node:child_process';
4
+ import { parseGitHubRemote } from './github.js';
5
+ import { generateWorkflow } from './templates/workflow.js';
6
+ import { generateSourceProfile } from './templates/source-profile.js';
7
+ import { generateSourceProject } from './templates/source-project.js';
8
+ async function fileExists(path) {
9
+ try {
10
+ await access(path);
11
+ return true;
12
+ }
13
+ catch {
14
+ return false;
15
+ }
16
+ }
17
+ function isIgnored(filePath, cwd) {
18
+ try {
19
+ execSync(`git check-ignore -q "${filePath}"`, { cwd, stdio: 'ignore' });
20
+ return true;
21
+ }
22
+ catch {
23
+ return false;
24
+ }
25
+ }
26
+ function detectRemote(cwd) {
27
+ try {
28
+ const remote = execSync('git remote get-url origin', {
29
+ cwd,
30
+ encoding: 'utf-8',
31
+ stdio: ['pipe', 'pipe', 'pipe'],
32
+ }).trim();
33
+ return parseGitHubRemote(remote);
34
+ }
35
+ catch {
36
+ return null;
37
+ }
38
+ }
39
+ function resolveTemplate(remote, override) {
40
+ if (override)
41
+ return override;
42
+ if (remote && remote.owner === remote.repo)
43
+ return 'profile';
44
+ return 'project';
45
+ }
46
+ async function auditGitignore(cwd) {
47
+ const checks = [
48
+ { path: '.github/assets/placeholder', rule: '!.github/assets/' },
49
+ { path: '.github/workflows/readme-aura.yml', rule: '!.github/workflows/' },
50
+ { path: 'README.md', rule: '!README.md' },
51
+ { path: 'readme.source.md', rule: '!readme.source.md' },
52
+ ];
53
+ const fixes = [];
54
+ for (const check of checks) {
55
+ if (isIgnored(check.path, cwd)) {
56
+ fixes.push(check.rule);
57
+ }
58
+ }
59
+ if (fixes.length > 0) {
60
+ const gitignorePath = join(cwd, '.gitignore');
61
+ let content = '';
62
+ try {
63
+ content = await readFile(gitignorePath, 'utf-8');
64
+ }
65
+ catch {
66
+ /* no .gitignore */
67
+ }
68
+ const suffix = '\n# readme-aura: ensure generated files are tracked\n' + fixes.join('\n') + '\n';
69
+ await writeFile(gitignorePath, content + suffix, 'utf-8');
70
+ }
71
+ return fixes;
72
+ }
73
+ export async function initProject(opts = {}) {
74
+ const cwd = opts.cwd ?? process.cwd();
75
+ const remote = detectRemote(cwd);
76
+ const template = resolveTemplate(remote, opts.template);
77
+ const created = [];
78
+ const skipped = [];
79
+ const workflowRelPath = '.github/workflows/readme-aura.yml';
80
+ const workflowPath = join(cwd, workflowRelPath);
81
+ const workflowExists = await fileExists(workflowPath);
82
+ if (!workflowExists || opts.force) {
83
+ await mkdir(join(cwd, '.github/workflows'), { recursive: true });
84
+ await writeFile(workflowPath, generateWorkflow(), 'utf-8');
85
+ created.push(workflowRelPath);
86
+ }
87
+ else {
88
+ skipped.push(workflowRelPath);
89
+ }
90
+ const sourceRelPath = 'readme.source.md';
91
+ const sourcePath = join(cwd, sourceRelPath);
92
+ const sourceExists = await fileExists(sourcePath);
93
+ if (!sourceExists || opts.force) {
94
+ const ctx = { owner: remote?.owner ?? 'your-username', repo: remote?.repo ?? 'your-repo' };
95
+ const content = template === 'profile' ? generateSourceProfile(ctx) : generateSourceProject(ctx);
96
+ await writeFile(sourcePath, content, 'utf-8');
97
+ created.push(sourceRelPath);
98
+ }
99
+ else {
100
+ skipped.push(sourceRelPath);
101
+ }
102
+ const gitignoreFixed = await auditGitignore(cwd);
103
+ return { created, skipped, gitignoreFixed, template, remote };
104
+ }
105
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { ParseResult } from './types.js';
2
+ export declare function parseSource(sourcePath: string, assetsDir?: string, outputPath?: string): Promise<ParseResult>;
package/dist/parser.js ADDED
@@ -0,0 +1,49 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { resolve, relative, dirname } from 'node:path';
3
+ import { unified } from 'unified';
4
+ import remarkParse from 'remark-parse';
5
+ import remarkStringify from 'remark-stringify';
6
+ import { visit } from 'unist-util-visit';
7
+ const AURA_LANG = 'aura';
8
+ export async function parseSource(sourcePath, assetsDir = '.github/assets', outputPath = 'README.md') {
9
+ const source = await readFile(sourcePath, 'utf-8');
10
+ const blocks = [];
11
+ let blockIndex = 0;
12
+ // Compute asset path relative to the output file
13
+ const absAssets = resolve(assetsDir);
14
+ const absOutput = resolve(outputPath);
15
+ const relAssets = './' + relative(dirname(absOutput), absAssets).replace(/\\/g, '/');
16
+ const file = await unified()
17
+ .use(remarkParse)
18
+ .use(() => (tree) => {
19
+ visit(tree, 'code', (node, index, parent) => {
20
+ const codeNode = node;
21
+ if (codeNode.lang !== AURA_LANG || index === undefined || !parent)
22
+ return;
23
+ blocks.push({
24
+ index: blockIndex,
25
+ content: codeNode.value,
26
+ meta: codeNode.meta ?? undefined,
27
+ });
28
+ const imageNode = {
29
+ type: 'image',
30
+ url: `${relAssets}/readme-aura-component-${blockIndex}.svg`,
31
+ alt: `readme-aura-component-${blockIndex}`,
32
+ title: 'Generated by readme-aura',
33
+ };
34
+ const paragraphNode = {
35
+ type: 'paragraph',
36
+ children: [imageNode],
37
+ };
38
+ parent.children[index] = paragraphNode;
39
+ blockIndex++;
40
+ });
41
+ })
42
+ .use(remarkStringify)
43
+ .process(source);
44
+ return {
45
+ markdown: String(file),
46
+ blocks,
47
+ };
48
+ }
49
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,WAAW,MAAM,cAAc,CAAC;AACvC,OAAO,eAAe,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAKzC,MAAM,SAAS,GAAG,MAAM,CAAC;AAEzB,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,UAAkB,EAClB,SAAS,GAAG,gBAAgB,EAC5B,UAAU,GAAG,WAAW;IAExB,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,iDAAiD;IACjD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAErF,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE;SACzB,GAAG,CAAC,WAAW,CAAC;SAChB,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,IAAU,EAAE,EAAE;QACxB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,MAA0B,EAAE,EAAE;YAC9D,MAAM,QAAQ,GAAG,IAAY,CAAC;YAC9B,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,MAAM;gBAAE,OAAO;YAE1E,MAAM,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,UAAU;gBACjB,OAAO,EAAE,QAAQ,CAAC,KAAK;gBACvB,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,SAAS;aACjC,CAAC,CAAC;YAEH,MAAM,SAAS,GAAU;gBACvB,IAAI,EAAE,OAAO;gBACb,GAAG,EAAE,GAAG,SAAS,0BAA0B,UAAU,MAAM;gBAC3D,GAAG,EAAE,yBAAyB,UAAU,EAAE;gBAC1C,KAAK,EAAE,0BAA0B;aAClC,CAAC;YAEF,MAAM,aAAa,GAAc;gBAC/B,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,CAAC,SAAS,CAAC;aACtB,CAAC;YAED,MAAM,CAAC,QAAsB,CAAC,KAAK,CAAC,GAAG,aAAa,CAAC;YACtD,UAAU,EAAE,CAAC;QACf,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;SACD,GAAG,CAAC,eAAe,CAAC;SACpB,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnB,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC;QACtB,MAAM;KACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { ExtractedBlock, FontConfig, RenderOptions } from './types.js';
2
+ export declare function parseMeta(meta?: string): RenderOptions;
3
+ export declare function createElement(type: unknown, props: Record<string, unknown> | null, ...children: unknown[]): unknown;
4
+ export declare function transpileJsx(jsxString: string, context?: Record<string, unknown>): unknown;
5
+ export declare function renderBlock(block: ExtractedBlock, fonts: FontConfig[], context?: Record<string, unknown>): Promise<string>;