@xyd-js/uniform 0.1.0-xyd.4 → 0.1.0-xyd.56
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 +418 -0
- package/LICENSE +21 -0
- package/dist/index.cjs +141 -79
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +26 -8
- package/dist/index.d.ts +26 -8
- package/dist/index.js +138 -78
- package/dist/index.js.map +1 -1
- package/dist/markdown.cjs +42 -10
- package/dist/markdown.cjs.map +1 -1
- package/dist/markdown.d.cts +3 -1
- package/dist/markdown.d.ts +3 -1
- package/dist/markdown.js +42 -10
- package/dist/markdown.js.map +1 -1
- package/dist/types-BiglsETJ.d.cts +180 -0
- package/dist/types-BiglsETJ.d.ts +180 -0
- package/index.ts +10 -4
- package/package.json +9 -5
- package/src/index.ts +35 -17
- package/src/markdown/index.ts +5 -2
- package/src/markdown/utils.ts +45 -10
- package/src/plugins/__tests__/pluginJsonView.test.ts +132 -0
- package/src/plugins/index.ts +2 -0
- package/src/plugins/pluginJsonView.ts +54 -0
- package/src/plugins/pluginNavigation.ts +135 -0
- package/src/types.ts +230 -70
- package/tsconfig.json +4 -1
- package/vitest.config.ts +15 -0
- package/dist/types-C8Pm_zQH.d.cts +0 -80
- package/dist/types-C8Pm_zQH.d.ts +0 -80
- package/src/utils.ts +0 -123
package/src/markdown/utils.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { fromMarkdown } from "mdast-util-from-markdown";
|
|
1
2
|
import {u} from "unist-builder";
|
|
2
3
|
|
|
3
4
|
import {
|
|
@@ -41,13 +42,12 @@ export function heading(
|
|
|
41
42
|
let uDesc = [
|
|
42
43
|
u(
|
|
43
44
|
'heading',
|
|
44
|
-
{depth:
|
|
45
|
+
{depth: uTitle.depth + 1},
|
|
45
46
|
[u('text', `!description`),]
|
|
46
47
|
),
|
|
47
48
|
u('paragraph', [u('text', description)])
|
|
48
49
|
]
|
|
49
50
|
|
|
50
|
-
|
|
51
51
|
let uRefCategory
|
|
52
52
|
if (refCategory) {
|
|
53
53
|
uRefCategory = u(
|
|
@@ -79,12 +79,24 @@ export function heading(
|
|
|
79
79
|
|
|
80
80
|
|
|
81
81
|
for (const [key, value] of Object.entries(refContext)) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
82
|
+
if (typeof value === "object") {
|
|
83
|
+
// TODO: support ```<lang> ??
|
|
84
|
+
if (value.code) {
|
|
85
|
+
uContext.push(
|
|
86
|
+
u('heading', {depth: uContext[0].depth + 1}, [u('text', `!${key}`)])
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
uContext.push(
|
|
90
|
+
u('code', {lang: value.lang}, value.code)
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
uContext.push(
|
|
98
|
+
u('heading', {depth: uContext[0].depth + 1}, [u('text', `!${key} ${value.toString()}`)])
|
|
99
|
+
);
|
|
88
100
|
}
|
|
89
101
|
}
|
|
90
102
|
|
|
@@ -191,6 +203,7 @@ export function definitions(definitions: Definition[]) {
|
|
|
191
203
|
name: prop.name,
|
|
192
204
|
type: prop.type,
|
|
193
205
|
description: prop.description,
|
|
206
|
+
context: prop.context,
|
|
194
207
|
properties: prop.properties // TODO: fix ts
|
|
195
208
|
},
|
|
196
209
|
md,
|
|
@@ -213,13 +226,35 @@ export function properties(
|
|
|
213
226
|
const uPropTitle = u('heading', {depth}, [u('text', propTitle)]);
|
|
214
227
|
const uPropName = u('paragraph', {depth}, [u('text', `!name ${paramName}`)]);
|
|
215
228
|
const uPropType = u('paragraph', {depth}, [u('text', `!type ${props.type}`)]);
|
|
216
|
-
const
|
|
229
|
+
const markdownAst = fromMarkdown(props.description || '');
|
|
230
|
+
const uPropDesc = u("paragraph", { depth }, markdownAst.children);
|
|
231
|
+
const uContext = []
|
|
232
|
+
|
|
233
|
+
if (props.context && Object.keys(props.context)) {
|
|
234
|
+
uContext.push(u(
|
|
235
|
+
'heading',
|
|
236
|
+
{depth: depth + 1},
|
|
237
|
+
[
|
|
238
|
+
u('text', `!context`),
|
|
239
|
+
]
|
|
240
|
+
))
|
|
241
|
+
|
|
242
|
+
for (const [key, value] of Object.entries(props.context)) {
|
|
243
|
+
uContext.push(u(
|
|
244
|
+
'heading',
|
|
245
|
+
{depth: uContext[0].depth + 1},
|
|
246
|
+
[u('text', `!${key} ${value}`)]
|
|
247
|
+
)
|
|
248
|
+
)
|
|
249
|
+
}
|
|
250
|
+
}
|
|
217
251
|
|
|
218
252
|
output.push(
|
|
219
253
|
uPropTitle,
|
|
220
254
|
uPropName,
|
|
221
255
|
uPropType,
|
|
222
|
-
uPropDesc
|
|
256
|
+
uPropDesc,
|
|
257
|
+
...uContext
|
|
223
258
|
);
|
|
224
259
|
|
|
225
260
|
if (props.properties) {
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import { pluginJsonView } from '../pluginJsonView';
|
|
4
|
+
import type { Reference } from '../../types';
|
|
5
|
+
import uniform from '../../index'
|
|
6
|
+
|
|
7
|
+
describe('pluginJsonView', () => {
|
|
8
|
+
it('should handle properties without examples', () => {
|
|
9
|
+
const plugin = pluginJsonView();
|
|
10
|
+
|
|
11
|
+
const inputs: Reference[] = [
|
|
12
|
+
{
|
|
13
|
+
title: 'Test title',
|
|
14
|
+
description: 'Test description',
|
|
15
|
+
canonical: 'test-canonical',
|
|
16
|
+
examples: {
|
|
17
|
+
groups: []
|
|
18
|
+
},
|
|
19
|
+
"definitions": [
|
|
20
|
+
{
|
|
21
|
+
"title": "Properties",
|
|
22
|
+
"properties": [
|
|
23
|
+
{
|
|
24
|
+
"name": "charset",
|
|
25
|
+
"type": "string",
|
|
26
|
+
"description": "Character encoding for the document\n",
|
|
27
|
+
"examples": [
|
|
28
|
+
"\"UTF-8\""
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "robots",
|
|
33
|
+
"type": "string",
|
|
34
|
+
"description": "Standard meta tag for controlling search engine crawling and indexing\n",
|
|
35
|
+
"examples": [
|
|
36
|
+
"\"index, follow\"",
|
|
37
|
+
"\"noindex, nofollow\""
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
title: 'Test title',
|
|
46
|
+
description: 'Test description',
|
|
47
|
+
canonical: 'test-canonical',
|
|
48
|
+
examples: {
|
|
49
|
+
groups: []
|
|
50
|
+
},
|
|
51
|
+
"definitions": [
|
|
52
|
+
{
|
|
53
|
+
"title": "Properties",
|
|
54
|
+
"properties": [
|
|
55
|
+
{
|
|
56
|
+
"name": "charset",
|
|
57
|
+
"type": "string",
|
|
58
|
+
"description": "Character encoding for the document\n",
|
|
59
|
+
"examples": [
|
|
60
|
+
"UTF-8"
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"name": "robots",
|
|
65
|
+
"type": "string",
|
|
66
|
+
"description": "Standard meta tag for controlling search engine crawling and indexing\n",
|
|
67
|
+
"examples": [
|
|
68
|
+
"index, follow",
|
|
69
|
+
"noindex, nofollow"
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
title: 'Test title',
|
|
78
|
+
description: 'Test description',
|
|
79
|
+
canonical: 'test-canonical',
|
|
80
|
+
examples: {
|
|
81
|
+
groups: []
|
|
82
|
+
},
|
|
83
|
+
"definitions": [
|
|
84
|
+
{
|
|
85
|
+
"title": "Properties",
|
|
86
|
+
"properties": [
|
|
87
|
+
{
|
|
88
|
+
"name": "robots",
|
|
89
|
+
"type": "string",
|
|
90
|
+
"description": "Standard meta tag for controlling search engine crawling and indexing\n",
|
|
91
|
+
"examples": [
|
|
92
|
+
"index, follow",
|
|
93
|
+
"noindex, nofollow"
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"name": "charset",
|
|
98
|
+
"type": "string",
|
|
99
|
+
"description": "Character encoding for the document\n",
|
|
100
|
+
"examples": [
|
|
101
|
+
"UTF-8"
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
];
|
|
109
|
+
|
|
110
|
+
const outputs: string[] = [
|
|
111
|
+
'{\n' +
|
|
112
|
+
' "charset": "UTF-8",\n' +
|
|
113
|
+
' "robots": "index, follow" // or "noindex, nofollow"\n' +
|
|
114
|
+
'}',
|
|
115
|
+
|
|
116
|
+
'{\n' +
|
|
117
|
+
' "charset": "UTF-8",\n' +
|
|
118
|
+
' "robots": "index, follow" // or "noindex, nofollow"\n' +
|
|
119
|
+
'}',
|
|
120
|
+
|
|
121
|
+
'{\n' +
|
|
122
|
+
' "robots": "index, follow", // or "noindex, nofollow"\n' +
|
|
123
|
+
' "charset": "UTF-8"\n' +
|
|
124
|
+
'}',
|
|
125
|
+
]
|
|
126
|
+
const result = uniform(inputs, {
|
|
127
|
+
plugins: [plugin]
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
expect(result.out.jsonViews).toStrictEqual(outputs);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { UniformPluginArgs, UniformPlugin } from "../index";
|
|
2
|
+
import { Reference } from "../types";
|
|
3
|
+
|
|
4
|
+
export interface pluginJsonViewOptions {
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
type pluginJsonViewOutput = {
|
|
8
|
+
jsonViews: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function pluginJsonView(
|
|
12
|
+
options?: pluginJsonViewOptions
|
|
13
|
+
): UniformPlugin<pluginJsonViewOutput> {
|
|
14
|
+
|
|
15
|
+
return function pluginJsonViewInner({
|
|
16
|
+
defer,
|
|
17
|
+
}: UniformPluginArgs) {
|
|
18
|
+
const jsonViews: string[] = [];
|
|
19
|
+
|
|
20
|
+
defer(() => ({
|
|
21
|
+
jsonViews
|
|
22
|
+
}))
|
|
23
|
+
|
|
24
|
+
return (ref: Reference) => {
|
|
25
|
+
// Build the output string manually to ensure exact format
|
|
26
|
+
const lines: string[] = [];
|
|
27
|
+
lines.push('{');
|
|
28
|
+
|
|
29
|
+
ref.definitions.forEach(def => {
|
|
30
|
+
def.properties.forEach((prop, index) => {
|
|
31
|
+
// Remove any quotes and trailing characters from the value
|
|
32
|
+
const value = (prop.examples?.[0] || '').replace(/^"|"$|[^a-zA-Z0-9\s\-_.,:/@#=;+()]/g, '');
|
|
33
|
+
const comment = prop.examples && prop.examples.length > 1
|
|
34
|
+
? ` // or "${(prop.examples as string[])[1].replace(/^"|"$|[^a-zA-Z0-9\s\-_.,:/@#=;+()]/g, '')}"`
|
|
35
|
+
: '';
|
|
36
|
+
const isLast = index === def.properties.length - 1;
|
|
37
|
+
// Add comma after the value but before the comment
|
|
38
|
+
lines.push(` "${prop.name}": "${value}"${isLast ? '' : ','}${comment}`);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
lines.push('}');
|
|
43
|
+
|
|
44
|
+
jsonViews.push(lines.join('\n'));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// example usage:
|
|
50
|
+
// const response = uniform([/* references */], {
|
|
51
|
+
// plugins: [pluginJsonView({
|
|
52
|
+
//
|
|
53
|
+
// })],
|
|
54
|
+
// });
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
|
|
3
|
+
import type { Sidebar, Metadata, MetadataMap, Settings, PageURL } from "@xyd-js/core";
|
|
4
|
+
|
|
5
|
+
import type { UniformPluginArgs, UniformPlugin } from "../index";
|
|
6
|
+
import { CodeBlockTab, Example, ExampleGroup, Reference } from "../types";
|
|
7
|
+
|
|
8
|
+
const DEFAULT_VIRTUAL_FOLDER = ".xyd/.cache/.content" // TODO: share this + .xyd/.build/.content for build
|
|
9
|
+
|
|
10
|
+
const DEFAULT_GROUP_NAME = "API Reference" // TODO: configurable
|
|
11
|
+
|
|
12
|
+
type GroupMap = {
|
|
13
|
+
[key: string]: {
|
|
14
|
+
__groups: GroupMap
|
|
15
|
+
pages: Set<string>
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface pluginNavigationOptions {
|
|
20
|
+
urlPrefix: string
|
|
21
|
+
defaultGroup?: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type pluginNavigationOutput = {
|
|
25
|
+
pageFrontMatter: MetadataMap;
|
|
26
|
+
sidebar: Sidebar[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function pluginNavigation(
|
|
30
|
+
settings: Settings,
|
|
31
|
+
options: pluginNavigationOptions
|
|
32
|
+
): UniformPlugin<pluginNavigationOutput> {
|
|
33
|
+
if (!options.urlPrefix) {
|
|
34
|
+
throw new Error("urlPrefix is required")
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return function pluginNavigationInner({
|
|
38
|
+
defer,
|
|
39
|
+
}: UniformPluginArgs) {
|
|
40
|
+
const pageFrontMatter: MetadataMap = {}
|
|
41
|
+
const groupMaps: GroupMap = {}
|
|
42
|
+
|
|
43
|
+
defer(() => ({
|
|
44
|
+
pageFrontMatter,
|
|
45
|
+
sidebar: convertGroupMapsToSidebar(settings, groupMaps) as Sidebar[]
|
|
46
|
+
}))
|
|
47
|
+
|
|
48
|
+
return (ref: Reference) => {
|
|
49
|
+
const dataCtx = ref.context
|
|
50
|
+
const pagePath = path.join(options.urlPrefix, ref.canonical)
|
|
51
|
+
|
|
52
|
+
let group = dataCtx?.group || []
|
|
53
|
+
let title = ref.title
|
|
54
|
+
|
|
55
|
+
if (pageFrontMatter[pagePath]) {
|
|
56
|
+
console.error("(pluginNavigation): pageFrontMatter[pagePath] already exists", pagePath)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (!group) {
|
|
60
|
+
group = [options.defaultGroup || DEFAULT_GROUP_NAME]
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
pageFrontMatter[pagePath] = {
|
|
64
|
+
title,
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (typeof group === "string") {
|
|
68
|
+
// TODO: seek nested group (it's not always from 0)
|
|
69
|
+
throw new Error("group as string is not supported yet")
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
group.reduce((groups: GroupMap, groupName: string, i: number) => {
|
|
73
|
+
if (!groups[groupName]) {
|
|
74
|
+
groups[groupName] = {
|
|
75
|
+
__groups: {},
|
|
76
|
+
pages: new Set()
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (i === group.length - 1) {
|
|
81
|
+
groups[groupName].pages.add(pagePath)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return groups[groupName].__groups
|
|
85
|
+
}, groupMaps)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function convertGroupMapsToSidebar(settings: Settings, groupMaps: GroupMap): Sidebar[] {
|
|
91
|
+
const nav: Sidebar[] = []
|
|
92
|
+
|
|
93
|
+
Object.keys(groupMaps).map((groupName) => {
|
|
94
|
+
const current = groupMaps[groupName]
|
|
95
|
+
|
|
96
|
+
const pages: PageURL[] = []
|
|
97
|
+
|
|
98
|
+
current.pages.forEach((page: string) => {
|
|
99
|
+
if (settings?.engine?.uniform?.store) {
|
|
100
|
+
pages.push(page)
|
|
101
|
+
return
|
|
102
|
+
}
|
|
103
|
+
pages.push({
|
|
104
|
+
virtual: path.join(DEFAULT_VIRTUAL_FOLDER, page),
|
|
105
|
+
page: page,
|
|
106
|
+
})
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
if (Object.keys(current.__groups).length) {
|
|
110
|
+
const subNav: Sidebar = {
|
|
111
|
+
group: groupName,
|
|
112
|
+
pages: convertGroupMapsToSidebar(settings, current.__groups)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
nav.push(subNav)
|
|
116
|
+
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
nav.push({
|
|
121
|
+
group: groupName,
|
|
122
|
+
pages,
|
|
123
|
+
})
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
return nav
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// TODO: in the future xyd settings must be removed cuz uniform will be part of opendocs
|
|
130
|
+
// example usage:
|
|
131
|
+
// const response = uniform([/* references */], {
|
|
132
|
+
// plugins: [pluginNavigation({}, {
|
|
133
|
+
// urlPrefix: "/docs"
|
|
134
|
+
// })],
|
|
135
|
+
// });
|