@fuzdev/fuz_ui 0.181.1 → 0.182.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/dist/DeclarationDetail.svelte +4 -8
- package/dist/DeclarationDetail.svelte.d.ts.map +1 -1
- package/dist/GithubLink.svelte +12 -3
- package/dist/GithubLink.svelte.d.ts +12 -3
- package/dist/GithubLink.svelte.d.ts.map +1 -1
- package/dist/Mdz.svelte +1 -1
- package/dist/MdzPrecompiled.svelte +30 -0
- package/dist/MdzPrecompiled.svelte.d.ts +11 -0
- package/dist/MdzPrecompiled.svelte.d.ts.map +1 -0
- package/dist/declaration.svelte.d.ts +1 -1
- package/dist/library.svelte.d.ts +1 -1
- package/dist/mdz_to_svelte.d.ts +38 -0
- package/dist/mdz_to_svelte.d.ts.map +1 -0
- package/dist/mdz_to_svelte.js +89 -0
- package/dist/module_helpers.d.ts +48 -5
- package/dist/module_helpers.d.ts.map +1 -1
- package/dist/module_helpers.js +22 -0
- package/dist/package_helpers.d.ts +24 -0
- package/dist/package_helpers.d.ts.map +1 -1
- package/dist/package_helpers.js +24 -0
- package/dist/svelte_preprocess_mdz.d.ts +65 -0
- package/dist/svelte_preprocess_mdz.d.ts.map +1 -0
- package/dist/svelte_preprocess_mdz.js +513 -0
- package/dist/tsdoc_mdz.d.ts +1 -1
- package/dist/tsdoc_mdz.js +1 -1
- package/package.json +27 -10
- package/src/lib/mdz_to_svelte.ts +127 -0
- package/src/lib/module_helpers.ts +48 -5
- package/src/lib/package_helpers.ts +24 -0
- package/src/lib/svelte_preprocess_mdz.ts +726 -0
- package/src/lib/tsdoc_mdz.ts +1 -1
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts parsed `MdzNode` arrays to Svelte markup strings.
|
|
3
|
+
*
|
|
4
|
+
* Used by the `svelte_preprocess_mdz` preprocessor to expand static `<Mdz content="...">` usages
|
|
5
|
+
* into pre-rendered Svelte markup at build time. The output for each node type matches what
|
|
6
|
+
* `MdzNodeView.svelte` renders at runtime, so precompiled and runtime rendering are identical.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import {UnreachableError} from '@fuzdev/fuz_util/error.js';
|
|
12
|
+
import {escape_svelte_text} from '@fuzdev/fuz_util/svelte_preprocess_helpers.js';
|
|
13
|
+
import {escape_js_string} from '@fuzdev/fuz_util/string.js';
|
|
14
|
+
|
|
15
|
+
import type {MdzNode} from './mdz.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Result of converting `MdzNode` arrays to Svelte markup.
|
|
19
|
+
*/
|
|
20
|
+
export interface MdzToSvelteResult {
|
|
21
|
+
/** Generated Svelte markup string. */
|
|
22
|
+
markup: string;
|
|
23
|
+
|
|
24
|
+
/** Required imports: `Map<local_name, {path, kind}>`. */
|
|
25
|
+
imports: Map<string, {path: string; kind: 'default' | 'named'}>;
|
|
26
|
+
|
|
27
|
+
/** Whether content references unconfigured Component or Element tags. */
|
|
28
|
+
has_unconfigured_tags: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Converts an array of `MdzNode` to a Svelte markup string.
|
|
33
|
+
*
|
|
34
|
+
* Each node type produces output matching what `MdzNodeView.svelte` renders at runtime.
|
|
35
|
+
* Collects required imports and flags unconfigured component/element references.
|
|
36
|
+
*
|
|
37
|
+
* @param nodes Parsed mdz nodes to render.
|
|
38
|
+
* @param components Component name to import path mapping (e.g., `{Alert: '$lib/Alert.svelte'}`).
|
|
39
|
+
* If content references a component not in this map, `has_unconfigured_tags` is set.
|
|
40
|
+
* @param elements Allowed HTML element names (e.g., `new Set(['aside', 'details'])`).
|
|
41
|
+
* If content references an element not in this set, `has_unconfigured_tags` is set.
|
|
42
|
+
*/
|
|
43
|
+
export const mdz_to_svelte = (
|
|
44
|
+
nodes: Array<MdzNode>,
|
|
45
|
+
components: Record<string, string>,
|
|
46
|
+
elements: ReadonlySet<string>,
|
|
47
|
+
): MdzToSvelteResult => {
|
|
48
|
+
const imports: Map<string, {path: string; kind: 'default' | 'named'}> = new Map();
|
|
49
|
+
let has_unconfigured_tags = false;
|
|
50
|
+
|
|
51
|
+
const render_nodes = (children: Array<MdzNode>): string => {
|
|
52
|
+
return children.map((child) => render_node(child)).join('');
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const render_node = (node: MdzNode): string => {
|
|
56
|
+
switch (node.type) {
|
|
57
|
+
case 'Text':
|
|
58
|
+
return escape_svelte_text(node.content);
|
|
59
|
+
|
|
60
|
+
case 'Code':
|
|
61
|
+
imports.set('DocsLink', {path: '@fuzdev/fuz_ui/DocsLink.svelte', kind: 'default'});
|
|
62
|
+
return `<DocsLink reference={'${escape_js_string(node.content)}'} />`;
|
|
63
|
+
|
|
64
|
+
case 'Codeblock': {
|
|
65
|
+
imports.set('Code', {path: '@fuzdev/fuz_code/Code.svelte', kind: 'default'});
|
|
66
|
+
const lang_attr =
|
|
67
|
+
node.lang === null ? 'lang={null}' : `lang={'${escape_js_string(node.lang)}'}`;
|
|
68
|
+
return `<Code ${lang_attr} content={'${escape_js_string(node.content)}'} />`;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
case 'Bold':
|
|
72
|
+
return `<strong>${render_nodes(node.children)}</strong>`;
|
|
73
|
+
|
|
74
|
+
case 'Italic':
|
|
75
|
+
return `<em>${render_nodes(node.children)}</em>`;
|
|
76
|
+
|
|
77
|
+
case 'Strikethrough':
|
|
78
|
+
return `<s>${render_nodes(node.children)}</s>`;
|
|
79
|
+
|
|
80
|
+
case 'Link': {
|
|
81
|
+
const children_markup = render_nodes(node.children);
|
|
82
|
+
if (node.link_type === 'internal') {
|
|
83
|
+
if (node.reference.startsWith('#') || node.reference.startsWith('?')) {
|
|
84
|
+
return `<a href={'${escape_js_string(node.reference)}'}>${children_markup}</a>`;
|
|
85
|
+
}
|
|
86
|
+
imports.set('resolve', {path: '$app/paths', kind: 'named'});
|
|
87
|
+
return `<a href={resolve('${escape_js_string(node.reference)}')}>${children_markup}</a>`;
|
|
88
|
+
}
|
|
89
|
+
// External link — matches MdzNodeView: target="_blank" rel="noopener"
|
|
90
|
+
return `<a href={'${escape_js_string(node.reference)}'} target="_blank" rel="noopener">${children_markup}</a>`;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
case 'Paragraph':
|
|
94
|
+
return `<p>${render_nodes(node.children)}</p>`;
|
|
95
|
+
|
|
96
|
+
case 'Hr':
|
|
97
|
+
return '<hr />';
|
|
98
|
+
|
|
99
|
+
case 'Heading':
|
|
100
|
+
return `<h${node.level}>${render_nodes(node.children)}</h${node.level}>`;
|
|
101
|
+
|
|
102
|
+
case 'Element': {
|
|
103
|
+
if (!elements.has(node.name)) {
|
|
104
|
+
has_unconfigured_tags = true;
|
|
105
|
+
return '';
|
|
106
|
+
}
|
|
107
|
+
return `<${node.name}>${render_nodes(node.children)}</${node.name}>`;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
case 'Component': {
|
|
111
|
+
const import_path = components[node.name];
|
|
112
|
+
if (!import_path) {
|
|
113
|
+
has_unconfigured_tags = true;
|
|
114
|
+
return '';
|
|
115
|
+
}
|
|
116
|
+
imports.set(node.name, {path: import_path, kind: 'default'});
|
|
117
|
+
return `<${node.name}>${render_nodes(node.children)}</${node.name}>`;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
default:
|
|
121
|
+
throw new UnreachableError(node);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const markup = render_nodes(nodes);
|
|
126
|
+
return {markup, imports, has_unconfigured_tags};
|
|
127
|
+
};
|
|
@@ -52,10 +52,12 @@ export interface SourceFileInfo {
|
|
|
52
52
|
* handles nested directories without special heuristics.
|
|
53
53
|
*
|
|
54
54
|
* @example
|
|
55
|
+
* ```ts
|
|
55
56
|
* const options = module_create_source_options(process.cwd(), {
|
|
56
57
|
* source_paths: ['src/lib', 'src/routes'],
|
|
57
58
|
* source_root: 'src',
|
|
58
59
|
* });
|
|
60
|
+
* ```
|
|
59
61
|
*/
|
|
60
62
|
export interface ModuleSourceOptions {
|
|
61
63
|
/**
|
|
@@ -64,7 +66,10 @@ export interface ModuleSourceOptions {
|
|
|
64
66
|
* All `source_paths` are relative to this. Typically `process.cwd()` when
|
|
65
67
|
* running from the project root via Gro, Vite, or other build tools.
|
|
66
68
|
*
|
|
67
|
-
* @example
|
|
69
|
+
* @example
|
|
70
|
+
* ```ts
|
|
71
|
+
* '/home/user/my-project'
|
|
72
|
+
* ```
|
|
68
73
|
*/
|
|
69
74
|
project_root: string;
|
|
70
75
|
/**
|
|
@@ -73,8 +78,14 @@ export interface ModuleSourceOptions {
|
|
|
73
78
|
* Paths should not have leading or trailing slashes - they are added
|
|
74
79
|
* internally for correct matching.
|
|
75
80
|
*
|
|
76
|
-
* @example
|
|
77
|
-
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```ts
|
|
83
|
+
* ['src/lib'] // single source directory
|
|
84
|
+
* ```
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* ['src/lib', 'src/routes'] // multiple directories
|
|
88
|
+
* ```
|
|
78
89
|
*/
|
|
79
90
|
source_paths: Array<string>;
|
|
80
91
|
/**
|
|
@@ -84,8 +95,14 @@ export interface ModuleSourceOptions {
|
|
|
84
95
|
* - Single `source_path`: defaults to that path
|
|
85
96
|
* - Multiple `source_paths`: required (no auto-derivation)
|
|
86
97
|
*
|
|
87
|
-
* @example
|
|
88
|
-
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```ts
|
|
100
|
+
* 'src/lib' // module paths like 'foo.ts', 'utils/bar.ts'
|
|
101
|
+
* ```
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* 'src' // module paths like 'lib/foo.ts', 'routes/page.svelte'
|
|
105
|
+
* ```
|
|
89
106
|
*/
|
|
90
107
|
source_root?: string;
|
|
91
108
|
/** Patterns to exclude (matched against full path). */
|
|
@@ -100,20 +117,24 @@ export interface ModuleSourceOptions {
|
|
|
100
117
|
* @default Uses file extension: `.svelte` → svelte, `.ts`/`.js` → typescript
|
|
101
118
|
*
|
|
102
119
|
* @example
|
|
120
|
+
* ```ts
|
|
103
121
|
* // Add MDsveX support
|
|
104
122
|
* get_analyzer: (path) => {
|
|
105
123
|
* if (path.endsWith('.svelte') || path.endsWith('.svx')) return 'svelte';
|
|
106
124
|
* if (path.endsWith('.ts') || path.endsWith('.js')) return 'typescript';
|
|
107
125
|
* return null;
|
|
108
126
|
* }
|
|
127
|
+
* ```
|
|
109
128
|
*
|
|
110
129
|
* @example
|
|
130
|
+
* ```ts
|
|
111
131
|
* // Include .d.ts files
|
|
112
132
|
* get_analyzer: (path) => {
|
|
113
133
|
* if (path.endsWith('.svelte')) return 'svelte';
|
|
114
134
|
* if (path.endsWith('.ts') || path.endsWith('.d.ts') || path.endsWith('.js')) return 'typescript';
|
|
115
135
|
* return null;
|
|
116
136
|
* }
|
|
137
|
+
* ```
|
|
117
138
|
*/
|
|
118
139
|
get_analyzer: (path: string) => AnalyzerType | null;
|
|
119
140
|
}
|
|
@@ -157,21 +178,27 @@ export const MODULE_SOURCE_PARTIAL: ModuleSourcePartial = {
|
|
|
157
178
|
* @param overrides Optional overrides for default options
|
|
158
179
|
*
|
|
159
180
|
* @example
|
|
181
|
+
* ```ts
|
|
160
182
|
* // Standard SvelteKit library
|
|
161
183
|
* const options = module_create_source_options(process.cwd());
|
|
184
|
+
* ```
|
|
162
185
|
*
|
|
163
186
|
* @example
|
|
187
|
+
* ```ts
|
|
164
188
|
* // Multiple source directories
|
|
165
189
|
* const options = module_create_source_options(process.cwd(), {
|
|
166
190
|
* source_paths: ['src/lib', 'src/routes'],
|
|
167
191
|
* source_root: 'src',
|
|
168
192
|
* });
|
|
193
|
+
* ```
|
|
169
194
|
*
|
|
170
195
|
* @example
|
|
196
|
+
* ```ts
|
|
171
197
|
* // Custom exclusions
|
|
172
198
|
* const options = module_create_source_options(process.cwd(), {
|
|
173
199
|
* exclude_patterns: [/\.test\.ts$/, /\.internal\.ts$/],
|
|
174
200
|
* });
|
|
201
|
+
* ```
|
|
175
202
|
*/
|
|
176
203
|
export const module_create_source_options = (
|
|
177
204
|
project_root: string,
|
|
@@ -195,14 +222,17 @@ export const module_create_source_options = (
|
|
|
195
222
|
* @throws Error if validation fails
|
|
196
223
|
*
|
|
197
224
|
* @example
|
|
225
|
+
* ```ts
|
|
198
226
|
* // Valid - single source path (source_root auto-derived)
|
|
199
227
|
* module_validate_source_options({
|
|
200
228
|
* project_root: '/home/user/project',
|
|
201
229
|
* source_paths: ['src/lib'],
|
|
202
230
|
* ...
|
|
203
231
|
* });
|
|
232
|
+
* ```
|
|
204
233
|
*
|
|
205
234
|
* @example
|
|
235
|
+
* ```ts
|
|
206
236
|
* // Valid - multiple source paths with explicit source_root
|
|
207
237
|
* module_validate_source_options({
|
|
208
238
|
* project_root: '/home/user/project',
|
|
@@ -210,14 +240,17 @@ export const module_create_source_options = (
|
|
|
210
240
|
* source_root: 'src',
|
|
211
241
|
* ...
|
|
212
242
|
* });
|
|
243
|
+
* ```
|
|
213
244
|
*
|
|
214
245
|
* @example
|
|
246
|
+
* ```ts
|
|
215
247
|
* // Invalid - multiple source paths without source_root
|
|
216
248
|
* module_validate_source_options({
|
|
217
249
|
* project_root: '/home/user/project',
|
|
218
250
|
* source_paths: ['src/lib', 'src/routes'], // throws
|
|
219
251
|
* ...
|
|
220
252
|
* });
|
|
253
|
+
* ```
|
|
221
254
|
*/
|
|
222
255
|
export const module_validate_source_options = (options: ModuleSourceOptions): void => {
|
|
223
256
|
const {project_root, source_paths, source_root} = options;
|
|
@@ -319,17 +352,21 @@ export const module_get_source_root = (options: ModuleSourceOptions): string =>
|
|
|
319
352
|
* @param options Module source options for path extraction
|
|
320
353
|
*
|
|
321
354
|
* @example
|
|
355
|
+
* ```ts
|
|
322
356
|
* const options = module_create_source_options('/home/user/project');
|
|
323
357
|
* module_extract_path('/home/user/project/src/lib/foo.ts', options) // => 'foo.ts'
|
|
324
358
|
* module_extract_path('/home/user/project/src/lib/nested/bar.svelte', options) // => 'nested/bar.svelte'
|
|
359
|
+
* ```
|
|
325
360
|
*
|
|
326
361
|
* @example
|
|
362
|
+
* ```ts
|
|
327
363
|
* const options = module_create_source_options('/home/user/project', {
|
|
328
364
|
* source_paths: ['src/lib', 'src/routes'],
|
|
329
365
|
* source_root: 'src',
|
|
330
366
|
* });
|
|
331
367
|
* module_extract_path('/home/user/project/src/lib/foo.ts', options) // => 'lib/foo.ts'
|
|
332
368
|
* module_extract_path('/home/user/project/src/routes/page.svelte', options) // => 'routes/page.svelte'
|
|
369
|
+
* ```
|
|
333
370
|
*/
|
|
334
371
|
export const module_extract_path = (source_id: string, options: ModuleSourceOptions): string => {
|
|
335
372
|
const effective_root = module_get_source_root(options);
|
|
@@ -347,8 +384,10 @@ export const module_extract_path = (source_id: string, options: ModuleSourceOpti
|
|
|
347
384
|
* Extract component name from a Svelte module path.
|
|
348
385
|
*
|
|
349
386
|
* @example
|
|
387
|
+
* ```ts
|
|
350
388
|
* module_get_component_name('Alert.svelte') // => 'Alert'
|
|
351
389
|
* module_get_component_name('components/Button.svelte') // => 'Button'
|
|
390
|
+
* ```
|
|
352
391
|
*/
|
|
353
392
|
export const module_get_component_name = (module_path: string): string =>
|
|
354
393
|
module_path.replace(/^.*\//, '').replace(/\.svelte$/, '');
|
|
@@ -357,7 +396,9 @@ export const module_get_component_name = (module_path: string): string =>
|
|
|
357
396
|
* Convert module path to module key format (with ./ prefix).
|
|
358
397
|
*
|
|
359
398
|
* @example
|
|
399
|
+
* ```ts
|
|
360
400
|
* module_get_key('foo.ts') // => './foo.ts'
|
|
401
|
+
* ```
|
|
361
402
|
*/
|
|
362
403
|
export const module_get_key = (module_path: string): string => `./${module_path}`;
|
|
363
404
|
|
|
@@ -394,10 +435,12 @@ export const module_is_test = (path: string): boolean => path.endsWith('.test.ts
|
|
|
394
435
|
* @returns True if the path is an analyzable source file
|
|
395
436
|
*
|
|
396
437
|
* @example
|
|
438
|
+
* ```ts
|
|
397
439
|
* const options = module_create_source_options('/home/user/project');
|
|
398
440
|
* module_is_source('/home/user/project/src/lib/foo.ts', options) // => true
|
|
399
441
|
* module_is_source('/home/user/project/src/lib/foo.test.ts', options) // => false (excluded)
|
|
400
442
|
* module_is_source('/home/user/project/src/fixtures/mini/src/lib/bar.ts', options) // => false (wrong prefix)
|
|
443
|
+
* ```
|
|
401
444
|
*/
|
|
402
445
|
export const module_is_source = (path: string, options: ModuleSourceOptions): boolean => {
|
|
403
446
|
// Check exclusion patterns first (fast regex check)
|
|
@@ -33,12 +33,16 @@ import type {PackageJson} from '@fuzdev/fuz_util/package_json.js';
|
|
|
33
33
|
* @returns Full GitHub URL to the file on the main branch
|
|
34
34
|
*
|
|
35
35
|
* @example
|
|
36
|
+
* ```ts
|
|
36
37
|
* url_github_file('https://github.com/foo/bar', 'src/index.ts')
|
|
37
38
|
* // => 'https://github.com/foo/bar/blob/main/src/index.ts'
|
|
39
|
+
* ```
|
|
38
40
|
*
|
|
39
41
|
* @example
|
|
42
|
+
* ```ts
|
|
40
43
|
* url_github_file('https://github.com/foo/bar', './src/index.ts', 42)
|
|
41
44
|
* // => 'https://github.com/foo/bar/blob/main/src/index.ts#L42'
|
|
45
|
+
* ```
|
|
42
46
|
*/
|
|
43
47
|
export const url_github_file = (repo_url: string, file_path: string, line?: number): string => {
|
|
44
48
|
const clean_path = file_path.replace(/^\.\//, '');
|
|
@@ -54,8 +58,10 @@ export const url_github_file = (repo_url: string, file_path: string, line?: numb
|
|
|
54
58
|
* @returns Organization URL, or null if repo_url doesn't end with repo_name
|
|
55
59
|
*
|
|
56
60
|
* @example
|
|
61
|
+
* ```ts
|
|
57
62
|
* url_github_org('https://github.com/fuzdev/fuz_ui', 'fuz_ui')
|
|
58
63
|
* // => 'https://github.com/fuzdev'
|
|
64
|
+
* ```
|
|
59
65
|
*/
|
|
60
66
|
export const url_github_org = (repo_url: string, repo_name: string): string | null => {
|
|
61
67
|
return repo_url.endsWith('/' + repo_name) ? strip_end(repo_url, '/' + repo_name) : null;
|
|
@@ -68,12 +74,16 @@ export const url_github_org = (repo_url: string, repo_name: string): string | nu
|
|
|
68
74
|
* @returns Owner name, or null if not a valid GitHub URL
|
|
69
75
|
*
|
|
70
76
|
* @example
|
|
77
|
+
* ```ts
|
|
71
78
|
* repo_url_github_owner('https://github.com/fuzdev/fuz_ui')
|
|
72
79
|
* // => 'fuzdev'
|
|
80
|
+
* ```
|
|
73
81
|
*
|
|
74
82
|
* @example
|
|
83
|
+
* ```ts
|
|
75
84
|
* repo_url_github_owner('https://gitlab.com/foo/bar')
|
|
76
85
|
* // => null (not a GitHub URL)
|
|
86
|
+
* ```
|
|
77
87
|
*/
|
|
78
88
|
export const repo_url_github_owner = (repo_url: string): string | null => {
|
|
79
89
|
const stripped = strip_start(repo_url, 'https://github.com/');
|
|
@@ -89,8 +99,10 @@ export const repo_url_github_owner = (repo_url: string): string | null => {
|
|
|
89
99
|
* @returns Full npm package page URL
|
|
90
100
|
*
|
|
91
101
|
* @example
|
|
102
|
+
* ```ts
|
|
92
103
|
* url_npm_package('@fuzdev/fuz_ui')
|
|
93
104
|
* // => 'https://www.npmjs.com/package/@fuzdev/fuz_ui'
|
|
105
|
+
* ```
|
|
94
106
|
*/
|
|
95
107
|
export const url_npm_package = (package_name: string): string =>
|
|
96
108
|
'https://www.npmjs.com/package/' + package_name;
|
|
@@ -118,12 +130,16 @@ export const package_is_published = (package_json: PackageJson): boolean => {
|
|
|
118
130
|
* @throws Error if scoped package name is malformed
|
|
119
131
|
*
|
|
120
132
|
* @example
|
|
133
|
+
* ```ts
|
|
121
134
|
* repo_name_parse('@fuzdev/fuz_ui')
|
|
122
135
|
* // => 'fuz_ui'
|
|
136
|
+
* ```
|
|
123
137
|
*
|
|
124
138
|
* @example
|
|
139
|
+
* ```ts
|
|
125
140
|
* repo_name_parse('lodash')
|
|
126
141
|
* // => 'lodash'
|
|
142
|
+
* ```
|
|
127
143
|
*/
|
|
128
144
|
export const repo_name_parse = (name: string): string => {
|
|
129
145
|
if (name[0] === '@') {
|
|
@@ -146,16 +162,22 @@ export const repo_name_parse = (name: string): string => {
|
|
|
146
162
|
* @returns Clean repository URL, or null if not provided
|
|
147
163
|
*
|
|
148
164
|
* @example
|
|
165
|
+
* ```ts
|
|
149
166
|
* repo_url_parse('https://github.com/foo/bar')
|
|
150
167
|
* // => 'https://github.com/foo/bar'
|
|
168
|
+
* ```
|
|
151
169
|
*
|
|
152
170
|
* @example
|
|
171
|
+
* ```ts
|
|
153
172
|
* repo_url_parse({url: 'git+https://github.com/foo/bar.git'})
|
|
154
173
|
* // => 'https://github.com/foo/bar'
|
|
174
|
+
* ```
|
|
155
175
|
*
|
|
156
176
|
* @example
|
|
177
|
+
* ```ts
|
|
157
178
|
* repo_url_parse(undefined)
|
|
158
179
|
* // => null
|
|
180
|
+
* ```
|
|
159
181
|
*/
|
|
160
182
|
export const repo_url_parse = (repository: PackageJson['repository']): string | null => {
|
|
161
183
|
if (!repository) return null;
|
|
@@ -172,8 +194,10 @@ export const repo_url_parse = (repository: PackageJson['repository']): string |
|
|
|
172
194
|
* @returns Full URL to the .well-known file
|
|
173
195
|
*
|
|
174
196
|
* @example
|
|
197
|
+
* ```ts
|
|
175
198
|
* url_well_known('https://fuz.dev', 'package.json')
|
|
176
199
|
* // => 'https://fuz.dev/.well-known/package.json'
|
|
200
|
+
* ```
|
|
177
201
|
*/
|
|
178
202
|
export const url_well_known = (homepage_url: string, filename: string): string => {
|
|
179
203
|
return `${ensure_end(homepage_url, '/')}.well-known/${filename}`;
|