@mzebley/mark-down-angular 1.0.0 → 1.1.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 +31 -14
- package/dist/index.cjs +30 -59
- package/dist/index.d.cts +12 -17
- package/dist/index.d.ts +12 -17
- package/dist/index.js +22 -47
- package/package.json +18 -6
- package/src/index.ts +1 -0
- package/src/snippet-view.component.ts +7 -5
- package/src/snippet.service.ts +1 -30
- package/src/token.ts +11 -13
- package/tsconfig.json +8 -1
package/README.md
CHANGED
|
@@ -30,26 +30,38 @@ Provide a shared `SnippetClient` from your root bootstrap call or feature module
|
|
|
30
30
|
|
|
31
31
|
```ts
|
|
32
32
|
import { bootstrapApplication } from '@angular/platform-browser';
|
|
33
|
-
import {
|
|
33
|
+
import { provideSnippetClient } from '@mzebley/mark-down/angular';
|
|
34
34
|
|
|
35
35
|
bootstrapApplication(AppComponent, {
|
|
36
36
|
providers: [
|
|
37
|
-
...
|
|
38
|
-
manifest: '/snippets
|
|
37
|
+
...provideSnippetClient({
|
|
38
|
+
manifest: '/assets/content/snippets/manifest.json',
|
|
39
|
+
base: '/assets/content/snippets',
|
|
39
40
|
}),
|
|
40
41
|
],
|
|
41
42
|
});
|
|
42
43
|
```
|
|
43
44
|
|
|
44
|
-
`
|
|
45
|
+
`provideSnippetClient` wires up the client as an Angular provider using the same options supported by the core runtime (`manifest`, `base`, `fetch`, `frontMatter`, `cache`, `verbose`). Prefer the scoped `@mzebley/mark-down/angular` entry point for tree-shaking and clearer typing. For backwards compatibility this package also re-exports `provideMarkDown`, `MARK_DOWN_CLIENT`, and the legacy `SnippetService` name.
|
|
46
|
+
|
|
47
|
+
### Angular compatibility
|
|
48
|
+
|
|
49
|
+
| Angular version | Status |
|
|
50
|
+
| ---------------- | ------ |
|
|
51
|
+
| 17.x | ✅ Supported |
|
|
52
|
+
| 18.x | ✅ Supported |
|
|
53
|
+
| 19.x | ✅ Supported |
|
|
54
|
+
| 20.x | ✅ Supported |
|
|
55
|
+
|
|
56
|
+
The package declares peer dependency ranges `>=17 <21` so projects running any currently supported Angular major release can install without `--legacy-peer-deps`.
|
|
45
57
|
|
|
46
58
|
## Consuming snippets
|
|
47
59
|
|
|
48
|
-
Inject `
|
|
60
|
+
Inject `MarkdownSnippetService` into components or services to access Observables for snippets:
|
|
49
61
|
|
|
50
62
|
```ts
|
|
51
63
|
import { Component, inject } from '@angular/core';
|
|
52
|
-
import {
|
|
64
|
+
import { MarkdownSnippetService } from '@mzebley/mark-down/angular';
|
|
53
65
|
|
|
54
66
|
@Component({
|
|
55
67
|
selector: 'docs-hero',
|
|
@@ -61,12 +73,12 @@ import { SnippetService } from '@mzebley/mark-down-angular';
|
|
|
61
73
|
`,
|
|
62
74
|
})
|
|
63
75
|
export class DocsHeroComponent {
|
|
64
|
-
private readonly snippets = inject(
|
|
76
|
+
private readonly snippets = inject(MarkdownSnippetService);
|
|
65
77
|
readonly hero$ = this.snippets.get('getting-started-welcome');
|
|
66
78
|
}
|
|
67
79
|
```
|
|
68
80
|
|
|
69
|
-
The service mirrors the core client APIs (`get`, `
|
|
81
|
+
The service mirrors the core client APIs (`get`, `listAll`, `listByType`, `listByGroup`, `search`) but returns cold Observables that share cached results across subscribers.
|
|
70
82
|
|
|
71
83
|
## `<snippet-view>` component
|
|
72
84
|
|
|
@@ -80,7 +92,7 @@ Features:
|
|
|
80
92
|
|
|
81
93
|
- Uses Angular's `DomSanitizer` to render HTML safely.
|
|
82
94
|
- Emits a `loaded` event once the snippet resolves so parent components can react.
|
|
83
|
-
- Provides
|
|
95
|
+
- Provides a loading placeholder and gracefully emits `undefined` when the slug cannot be resolved.
|
|
84
96
|
- Supports `class`/`ngClass` bindings for styling since it renders a standard `<div>`.
|
|
85
97
|
|
|
86
98
|
## Server-side rendering
|
|
@@ -90,18 +102,23 @@ When running in Angular Universal, supply a server-compatible fetch implementati
|
|
|
90
102
|
```ts
|
|
91
103
|
import fetch from 'node-fetch';
|
|
92
104
|
|
|
93
|
-
|
|
105
|
+
provideSnippetClient({
|
|
94
106
|
manifest: () => import('../snippets-index.json'),
|
|
95
|
-
|
|
107
|
+
fetch: (url) => fetch(url).then((response) => {
|
|
108
|
+
if (!response.ok) {
|
|
109
|
+
throw new Error(`Request failed with status ${response.status}`);
|
|
110
|
+
}
|
|
111
|
+
return response;
|
|
112
|
+
}),
|
|
96
113
|
});
|
|
97
114
|
```
|
|
98
115
|
|
|
99
|
-
The provider forwards all options to the underlying `SnippetClient`, so SSR and preloaded manifests work exactly like the core package.
|
|
116
|
+
The provider forwards all options to the underlying `SnippetClient`, so SSR, custom cache policies, and preloaded manifests work exactly like the core package.
|
|
100
117
|
|
|
101
118
|
## Testing tips
|
|
102
119
|
|
|
103
|
-
- Provide a mock manifest array during tests: `
|
|
104
|
-
- Use `
|
|
120
|
+
- Provide a mock manifest array during tests: `provideSnippetClient({ manifest: mockManifest })`.
|
|
121
|
+
- Use `MarkdownSnippetService` with the Angular `TestBed` to assert filtering behaviour.
|
|
105
122
|
- Pair with the [example application](../../examples/basic/README.md) to see how snippets integrate with routing and feature modules.
|
|
106
123
|
|
|
107
124
|
## Roadmap
|
package/dist/index.cjs
CHANGED
|
@@ -9,14 +9,15 @@ var __export = (target, all) => {
|
|
|
9
9
|
for (var name in all)
|
|
10
10
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
11
|
};
|
|
12
|
-
var __copyProps = (to,
|
|
13
|
-
if (
|
|
14
|
-
for (let key of __getOwnPropNames(
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
15
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
-
__defProp(to, key, { get: () =>
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
17
|
}
|
|
18
18
|
return to;
|
|
19
19
|
};
|
|
20
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
20
21
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
22
|
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
23
|
// file that has been converted to a CommonJS file using a Babel-
|
|
@@ -34,80 +35,49 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
34
35
|
if (kind && result) __defProp(target, key, result);
|
|
35
36
|
return result;
|
|
36
37
|
};
|
|
37
|
-
var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
|
|
38
38
|
|
|
39
39
|
// src/index.ts
|
|
40
40
|
var index_exports = {};
|
|
41
41
|
__export(index_exports, {
|
|
42
42
|
MARK_DOWN_CLIENT: () => MARK_DOWN_CLIENT,
|
|
43
43
|
MARK_DOWN_OPTIONS: () => MARK_DOWN_OPTIONS,
|
|
44
|
-
SnippetService: () =>
|
|
44
|
+
SnippetService: () => import_angular2.MarkdownSnippetService,
|
|
45
45
|
SnippetViewComponent: () => SnippetViewComponent,
|
|
46
46
|
provideMarkDown: () => provideMarkDown
|
|
47
47
|
});
|
|
48
48
|
module.exports = __toCommonJS(index_exports);
|
|
49
|
+
__reExport(index_exports, require("@mzebley/mark-down/angular"), module.exports);
|
|
49
50
|
|
|
50
51
|
// src/token.ts
|
|
51
|
-
var
|
|
52
|
-
var
|
|
53
|
-
var
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return [
|
|
57
|
-
{ provide: MARK_DOWN_OPTIONS, useValue: options },
|
|
58
|
-
{
|
|
59
|
-
provide: MARK_DOWN_CLIENT,
|
|
60
|
-
useFactory: (opts) => client ?? new import_mark_down.SnippetClient(opts),
|
|
61
|
-
deps: [MARK_DOWN_OPTIONS]
|
|
62
|
-
}
|
|
63
|
-
];
|
|
52
|
+
var import_angular = require("@mzebley/mark-down/angular");
|
|
53
|
+
var MARK_DOWN_CLIENT = import_angular.SNIPPET_CLIENT;
|
|
54
|
+
var MARK_DOWN_OPTIONS = import_angular.SNIPPET_CLIENT_OPTIONS;
|
|
55
|
+
function provideMarkDown(options) {
|
|
56
|
+
return (0, import_angular.provideSnippetClient)(options);
|
|
64
57
|
}
|
|
65
58
|
|
|
66
59
|
// src/snippet.service.ts
|
|
67
|
-
var
|
|
68
|
-
var import_rxjs = require("rxjs");
|
|
69
|
-
var SnippetService = class {
|
|
70
|
-
constructor(client) {
|
|
71
|
-
this.client = client;
|
|
72
|
-
}
|
|
73
|
-
get(slug) {
|
|
74
|
-
return (0, import_rxjs.from)(this.client.get(slug)).pipe((0, import_rxjs.shareReplay)(1));
|
|
75
|
-
}
|
|
76
|
-
list(options) {
|
|
77
|
-
return (0, import_rxjs.from)(this.client.list(options)).pipe((0, import_rxjs.shareReplay)(1));
|
|
78
|
-
}
|
|
79
|
-
listByGroup(group, options) {
|
|
80
|
-
return (0, import_rxjs.from)(this.client.listByGroup(group, options)).pipe((0, import_rxjs.shareReplay)(1));
|
|
81
|
-
}
|
|
82
|
-
listByType(type, options) {
|
|
83
|
-
return (0, import_rxjs.from)(this.client.listByType(type, options)).pipe((0, import_rxjs.shareReplay)(1));
|
|
84
|
-
}
|
|
85
|
-
html(slug) {
|
|
86
|
-
return this.get(slug).pipe((0, import_rxjs.map)((snippet) => snippet?.html ?? null));
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
SnippetService = __decorateClass([
|
|
90
|
-
(0, import_core2.Injectable)({ providedIn: "root" }),
|
|
91
|
-
__decorateParam(0, (0, import_core2.Inject)(MARK_DOWN_CLIENT))
|
|
92
|
-
], SnippetService);
|
|
60
|
+
var import_angular2 = require("@mzebley/mark-down/angular");
|
|
93
61
|
|
|
94
62
|
// src/snippet-view.component.ts
|
|
95
63
|
var import_common = require("@angular/common");
|
|
96
|
-
var
|
|
64
|
+
var import_core = require("@angular/core");
|
|
97
65
|
var import_platform_browser = require("@angular/platform-browser");
|
|
98
|
-
var
|
|
66
|
+
var import_rxjs = require("rxjs");
|
|
99
67
|
var import_operators = require("rxjs/operators");
|
|
100
68
|
var import_dompurify = __toESM(require("dompurify"), 1);
|
|
101
69
|
var SnippetViewComponent = class {
|
|
102
70
|
constructor() {
|
|
103
|
-
this.slug$ = new
|
|
104
|
-
this.sanitizer = (0,
|
|
105
|
-
this.snippets = (0,
|
|
106
|
-
this.loaded = new
|
|
71
|
+
this.slug$ = new import_rxjs.BehaviorSubject(null);
|
|
72
|
+
this.sanitizer = (0, import_core.inject)(import_platform_browser.DomSanitizer);
|
|
73
|
+
this.snippets = (0, import_core.inject)(import_angular2.MarkdownSnippetService);
|
|
74
|
+
this.loaded = new import_core.EventEmitter();
|
|
107
75
|
this.snippet$ = this.slug$.pipe(
|
|
108
|
-
(0, import_operators.switchMap)(
|
|
109
|
-
|
|
110
|
-
|
|
76
|
+
(0, import_operators.switchMap)(
|
|
77
|
+
(slug) => slug ? this.snippets.get(slug).pipe((0, import_operators.catchError)(() => (0, import_rxjs.of)(null))) : (0, import_rxjs.of)(null)
|
|
78
|
+
),
|
|
79
|
+
(0, import_operators.tap)((snippet) => this.loaded.emit(snippet ?? void 0)),
|
|
80
|
+
(0, import_operators.shareReplay)({ bufferSize: 1, refCount: true })
|
|
111
81
|
);
|
|
112
82
|
this.content$ = this.snippet$.pipe(
|
|
113
83
|
(0, import_operators.map)((snippet) => {
|
|
@@ -124,13 +94,13 @@ var SnippetViewComponent = class {
|
|
|
124
94
|
}
|
|
125
95
|
};
|
|
126
96
|
__decorateClass([
|
|
127
|
-
(0,
|
|
97
|
+
(0, import_core.Input)()
|
|
128
98
|
], SnippetViewComponent.prototype, "slug", 2);
|
|
129
99
|
__decorateClass([
|
|
130
|
-
(0,
|
|
100
|
+
(0, import_core.Output)()
|
|
131
101
|
], SnippetViewComponent.prototype, "loaded", 2);
|
|
132
102
|
SnippetViewComponent = __decorateClass([
|
|
133
|
-
(0,
|
|
103
|
+
(0, import_core.Component)({
|
|
134
104
|
selector: "snippet-view",
|
|
135
105
|
standalone: true,
|
|
136
106
|
imports: [import_common.CommonModule],
|
|
@@ -142,7 +112,7 @@ SnippetViewComponent = __decorateClass([
|
|
|
142
112
|
<div class="mark-down-snippet--loading">Loading snippet\u2026</div>
|
|
143
113
|
</ng-template>
|
|
144
114
|
`,
|
|
145
|
-
changeDetection:
|
|
115
|
+
changeDetection: import_core.ChangeDetectionStrategy.OnPush
|
|
146
116
|
})
|
|
147
117
|
], SnippetViewComponent);
|
|
148
118
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -151,5 +121,6 @@ SnippetViewComponent = __decorateClass([
|
|
|
151
121
|
MARK_DOWN_OPTIONS,
|
|
152
122
|
SnippetService,
|
|
153
123
|
SnippetViewComponent,
|
|
154
|
-
provideMarkDown
|
|
124
|
+
provideMarkDown,
|
|
125
|
+
...require("@mzebley/mark-down/angular")
|
|
155
126
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,21 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { SnippetClientOptions } from '@mzebley/mark-down/angular';
|
|
2
|
+
export * from '@mzebley/mark-down/angular';
|
|
3
|
+
export { MarkdownSnippetService as SnippetService } from '@mzebley/mark-down/angular';
|
|
4
|
+
import * as _angular_core from '@angular/core';
|
|
5
|
+
import { Provider, OnChanges, EventEmitter } from '@angular/core';
|
|
6
|
+
import * as _mzebley_mark_down from '@mzebley/mark-down';
|
|
7
|
+
import { Snippet } from '@mzebley/mark-down';
|
|
4
8
|
import { SafeHtml } from '@angular/platform-browser';
|
|
9
|
+
import { Observable } from 'rxjs';
|
|
5
10
|
|
|
6
|
-
declare const MARK_DOWN_CLIENT: InjectionToken<SnippetClient>;
|
|
7
|
-
declare const MARK_DOWN_OPTIONS: InjectionToken<SnippetClientOptions>;
|
|
8
|
-
declare function provideMarkDown(options: SnippetClientOptions
|
|
9
|
-
|
|
10
|
-
declare class SnippetService {
|
|
11
|
-
private readonly client;
|
|
12
|
-
constructor(client: SnippetClient);
|
|
13
|
-
get(slug: string): Observable<Snippet | undefined>;
|
|
14
|
-
list(options?: ListOptions): Observable<SnippetMeta[]>;
|
|
15
|
-
listByGroup(group: string, options?: ListOptions): Observable<SnippetMeta[]>;
|
|
16
|
-
listByType(type: string, options?: ListOptions): Observable<SnippetMeta[]>;
|
|
17
|
-
html(slug: string): Observable<string | null>;
|
|
18
|
-
}
|
|
11
|
+
declare const MARK_DOWN_CLIENT: _angular_core.InjectionToken<_mzebley_mark_down.SnippetClient>;
|
|
12
|
+
declare const MARK_DOWN_OPTIONS: _angular_core.InjectionToken<SnippetClientOptions>;
|
|
13
|
+
declare function provideMarkDown(options: SnippetClientOptions): Provider[];
|
|
19
14
|
|
|
20
15
|
declare class SnippetViewComponent implements OnChanges {
|
|
21
16
|
private readonly slug$;
|
|
@@ -28,4 +23,4 @@ declare class SnippetViewComponent implements OnChanges {
|
|
|
28
23
|
ngOnChanges(): void;
|
|
29
24
|
}
|
|
30
25
|
|
|
31
|
-
export { MARK_DOWN_CLIENT, MARK_DOWN_OPTIONS,
|
|
26
|
+
export { MARK_DOWN_CLIENT, MARK_DOWN_OPTIONS, SnippetViewComponent, provideMarkDown };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,21 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { SnippetClientOptions } from '@mzebley/mark-down/angular';
|
|
2
|
+
export * from '@mzebley/mark-down/angular';
|
|
3
|
+
export { MarkdownSnippetService as SnippetService } from '@mzebley/mark-down/angular';
|
|
4
|
+
import * as _angular_core from '@angular/core';
|
|
5
|
+
import { Provider, OnChanges, EventEmitter } from '@angular/core';
|
|
6
|
+
import * as _mzebley_mark_down from '@mzebley/mark-down';
|
|
7
|
+
import { Snippet } from '@mzebley/mark-down';
|
|
4
8
|
import { SafeHtml } from '@angular/platform-browser';
|
|
9
|
+
import { Observable } from 'rxjs';
|
|
5
10
|
|
|
6
|
-
declare const MARK_DOWN_CLIENT: InjectionToken<SnippetClient>;
|
|
7
|
-
declare const MARK_DOWN_OPTIONS: InjectionToken<SnippetClientOptions>;
|
|
8
|
-
declare function provideMarkDown(options: SnippetClientOptions
|
|
9
|
-
|
|
10
|
-
declare class SnippetService {
|
|
11
|
-
private readonly client;
|
|
12
|
-
constructor(client: SnippetClient);
|
|
13
|
-
get(slug: string): Observable<Snippet | undefined>;
|
|
14
|
-
list(options?: ListOptions): Observable<SnippetMeta[]>;
|
|
15
|
-
listByGroup(group: string, options?: ListOptions): Observable<SnippetMeta[]>;
|
|
16
|
-
listByType(type: string, options?: ListOptions): Observable<SnippetMeta[]>;
|
|
17
|
-
html(slug: string): Observable<string | null>;
|
|
18
|
-
}
|
|
11
|
+
declare const MARK_DOWN_CLIENT: _angular_core.InjectionToken<_mzebley_mark_down.SnippetClient>;
|
|
12
|
+
declare const MARK_DOWN_OPTIONS: _angular_core.InjectionToken<SnippetClientOptions>;
|
|
13
|
+
declare function provideMarkDown(options: SnippetClientOptions): Provider[];
|
|
19
14
|
|
|
20
15
|
declare class SnippetViewComponent implements OnChanges {
|
|
21
16
|
private readonly slug$;
|
|
@@ -28,4 +23,4 @@ declare class SnippetViewComponent implements OnChanges {
|
|
|
28
23
|
ngOnChanges(): void;
|
|
29
24
|
}
|
|
30
25
|
|
|
31
|
-
export { MARK_DOWN_CLIENT, MARK_DOWN_OPTIONS,
|
|
26
|
+
export { MARK_DOWN_CLIENT, MARK_DOWN_OPTIONS, SnippetViewComponent, provideMarkDown };
|
package/dist/index.js
CHANGED
|
@@ -8,51 +8,24 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
8
8
|
if (kind && result) __defProp(target, key, result);
|
|
9
9
|
return result;
|
|
10
10
|
};
|
|
11
|
-
|
|
11
|
+
|
|
12
|
+
// src/index.ts
|
|
13
|
+
export * from "@mzebley/mark-down/angular";
|
|
12
14
|
|
|
13
15
|
// src/token.ts
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
useFactory: (opts) => client ?? new SnippetClient(opts),
|
|
24
|
-
deps: [MARK_DOWN_OPTIONS]
|
|
25
|
-
}
|
|
26
|
-
];
|
|
16
|
+
import {
|
|
17
|
+
SNIPPET_CLIENT,
|
|
18
|
+
SNIPPET_CLIENT_OPTIONS,
|
|
19
|
+
provideSnippetClient
|
|
20
|
+
} from "@mzebley/mark-down/angular";
|
|
21
|
+
var MARK_DOWN_CLIENT = SNIPPET_CLIENT;
|
|
22
|
+
var MARK_DOWN_OPTIONS = SNIPPET_CLIENT_OPTIONS;
|
|
23
|
+
function provideMarkDown(options) {
|
|
24
|
+
return provideSnippetClient(options);
|
|
27
25
|
}
|
|
28
26
|
|
|
29
27
|
// src/snippet.service.ts
|
|
30
|
-
import {
|
|
31
|
-
import { from, map, shareReplay } from "rxjs";
|
|
32
|
-
var SnippetService = class {
|
|
33
|
-
constructor(client) {
|
|
34
|
-
this.client = client;
|
|
35
|
-
}
|
|
36
|
-
get(slug) {
|
|
37
|
-
return from(this.client.get(slug)).pipe(shareReplay(1));
|
|
38
|
-
}
|
|
39
|
-
list(options) {
|
|
40
|
-
return from(this.client.list(options)).pipe(shareReplay(1));
|
|
41
|
-
}
|
|
42
|
-
listByGroup(group, options) {
|
|
43
|
-
return from(this.client.listByGroup(group, options)).pipe(shareReplay(1));
|
|
44
|
-
}
|
|
45
|
-
listByType(type, options) {
|
|
46
|
-
return from(this.client.listByType(type, options)).pipe(shareReplay(1));
|
|
47
|
-
}
|
|
48
|
-
html(slug) {
|
|
49
|
-
return this.get(slug).pipe(map((snippet) => snippet?.html ?? null));
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
SnippetService = __decorateClass([
|
|
53
|
-
Injectable({ providedIn: "root" }),
|
|
54
|
-
__decorateParam(0, Inject(MARK_DOWN_CLIENT))
|
|
55
|
-
], SnippetService);
|
|
28
|
+
import { MarkdownSnippetService } from "@mzebley/mark-down/angular";
|
|
56
29
|
|
|
57
30
|
// src/snippet-view.component.ts
|
|
58
31
|
import { CommonModule } from "@angular/common";
|
|
@@ -66,21 +39,23 @@ import {
|
|
|
66
39
|
} from "@angular/core";
|
|
67
40
|
import { DomSanitizer } from "@angular/platform-browser";
|
|
68
41
|
import { BehaviorSubject, of } from "rxjs";
|
|
69
|
-
import { map
|
|
42
|
+
import { catchError, map, shareReplay, switchMap, tap } from "rxjs/operators";
|
|
70
43
|
import DOMPurify from "dompurify";
|
|
71
44
|
var SnippetViewComponent = class {
|
|
72
45
|
constructor() {
|
|
73
46
|
this.slug$ = new BehaviorSubject(null);
|
|
74
47
|
this.sanitizer = inject(DomSanitizer);
|
|
75
|
-
this.snippets = inject(
|
|
48
|
+
this.snippets = inject(MarkdownSnippetService);
|
|
76
49
|
this.loaded = new EventEmitter();
|
|
77
50
|
this.snippet$ = this.slug$.pipe(
|
|
78
|
-
switchMap(
|
|
79
|
-
|
|
80
|
-
|
|
51
|
+
switchMap(
|
|
52
|
+
(slug) => slug ? this.snippets.get(slug).pipe(catchError(() => of(null))) : of(null)
|
|
53
|
+
),
|
|
54
|
+
tap((snippet) => this.loaded.emit(snippet ?? void 0)),
|
|
55
|
+
shareReplay({ bufferSize: 1, refCount: true })
|
|
81
56
|
);
|
|
82
57
|
this.content$ = this.snippet$.pipe(
|
|
83
|
-
|
|
58
|
+
map((snippet) => {
|
|
84
59
|
if (!snippet) {
|
|
85
60
|
return null;
|
|
86
61
|
}
|
|
@@ -118,7 +93,7 @@ SnippetViewComponent = __decorateClass([
|
|
|
118
93
|
export {
|
|
119
94
|
MARK_DOWN_CLIENT,
|
|
120
95
|
MARK_DOWN_OPTIONS,
|
|
121
|
-
SnippetService,
|
|
96
|
+
MarkdownSnippetService as SnippetService,
|
|
122
97
|
SnippetViewComponent,
|
|
123
98
|
provideMarkDown
|
|
124
99
|
};
|
package/package.json
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mzebley/mark-down-angular",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "mark↓ Angular Adapter",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
7
|
-
"module": "dist/index.
|
|
7
|
+
"module": "dist/index.js",
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
9
16
|
"publishConfig": {
|
|
10
17
|
"access": "public"
|
|
11
18
|
},
|
|
@@ -17,9 +24,14 @@
|
|
|
17
24
|
"dompurify": "^3.0.9"
|
|
18
25
|
},
|
|
19
26
|
"peerDependencies": {
|
|
20
|
-
"@angular/common": "
|
|
21
|
-
"@angular/core": "
|
|
22
|
-
"@angular/platform-browser": "
|
|
23
|
-
"rxjs": "
|
|
27
|
+
"@angular/common": ">=17 <21",
|
|
28
|
+
"@angular/core": ">=17 <21",
|
|
29
|
+
"@angular/platform-browser": ">=17 <21",
|
|
30
|
+
"rxjs": ">=7.8.0 <8.0.0 || >=8.0.0 <9.0.0"
|
|
31
|
+
},
|
|
32
|
+
"peerDependenciesMeta": {
|
|
33
|
+
"@angular/platform-browser": {
|
|
34
|
+
"optional": true
|
|
35
|
+
}
|
|
24
36
|
}
|
|
25
37
|
}
|
package/src/index.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "@angular/core";
|
|
11
11
|
import { DomSanitizer, SafeHtml } from "@angular/platform-browser";
|
|
12
12
|
import { BehaviorSubject, Observable, of } from "rxjs";
|
|
13
|
-
import { map, shareReplay, switchMap, tap } from "rxjs/operators";
|
|
13
|
+
import { catchError, map, shareReplay, switchMap, tap } from "rxjs/operators";
|
|
14
14
|
import type { Snippet } from "@mzebley/mark-down";
|
|
15
15
|
import { SnippetService } from "./snippet.service";
|
|
16
16
|
import DOMPurify from "dompurify";
|
|
@@ -37,10 +37,12 @@ export class SnippetViewComponent implements OnChanges {
|
|
|
37
37
|
@Input() slug?: string;
|
|
38
38
|
@Output() readonly loaded = new EventEmitter<Snippet | undefined>();
|
|
39
39
|
|
|
40
|
-
private readonly snippet$: Observable<Snippet |
|
|
41
|
-
switchMap((slug) =>
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
private readonly snippet$: Observable<Snippet | null> = this.slug$.pipe(
|
|
41
|
+
switchMap((slug) =>
|
|
42
|
+
slug ? this.snippets.get(slug).pipe(catchError(() => of(null))) : of(null)
|
|
43
|
+
),
|
|
44
|
+
tap((snippet) => this.loaded.emit(snippet ?? undefined)),
|
|
45
|
+
shareReplay({ bufferSize: 1, refCount: true })
|
|
44
46
|
);
|
|
45
47
|
|
|
46
48
|
readonly content$: Observable<SafeHtml | null> = this.snippet$.pipe(
|
package/src/snippet.service.ts
CHANGED
|
@@ -1,30 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { from, map, Observable, shareReplay } from "rxjs";
|
|
3
|
-
import type { ListOptions, Snippet, SnippetMeta } from "@mzebley/mark-down";
|
|
4
|
-
import { SnippetClient } from "@mzebley/mark-down";
|
|
5
|
-
import { MARK_DOWN_CLIENT } from "./token";
|
|
6
|
-
|
|
7
|
-
@Injectable({ providedIn: "root" })
|
|
8
|
-
export class SnippetService {
|
|
9
|
-
constructor(@Inject(MARK_DOWN_CLIENT) private readonly client: SnippetClient) {}
|
|
10
|
-
|
|
11
|
-
get(slug: string): Observable<Snippet | undefined> {
|
|
12
|
-
return from(this.client.get(slug)).pipe(shareReplay(1));
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
list(options?: ListOptions): Observable<SnippetMeta[]> {
|
|
16
|
-
return from(this.client.list(options)).pipe(shareReplay(1));
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
listByGroup(group: string, options?: ListOptions): Observable<SnippetMeta[]> {
|
|
20
|
-
return from(this.client.listByGroup(group, options)).pipe(shareReplay(1));
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
listByType(type: string, options?: ListOptions): Observable<SnippetMeta[]> {
|
|
24
|
-
return from(this.client.listByType(type, options)).pipe(shareReplay(1));
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
html(slug: string): Observable<string | null> {
|
|
28
|
-
return this.get(slug).pipe(map((snippet) => snippet?.html ?? null));
|
|
29
|
-
}
|
|
30
|
-
}
|
|
1
|
+
export { MarkdownSnippetService as SnippetService } from "@mzebley/mark-down/angular";
|
package/src/token.ts
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { Provider } from "@angular/core";
|
|
2
|
+
import {
|
|
3
|
+
SNIPPET_CLIENT,
|
|
4
|
+
SNIPPET_CLIENT_OPTIONS,
|
|
5
|
+
provideSnippetClient,
|
|
6
|
+
type SnippetClientOptions
|
|
7
|
+
} from "@mzebley/mark-down/angular";
|
|
3
8
|
|
|
4
|
-
export const MARK_DOWN_CLIENT =
|
|
5
|
-
export const MARK_DOWN_OPTIONS =
|
|
9
|
+
export const MARK_DOWN_CLIENT = SNIPPET_CLIENT;
|
|
10
|
+
export const MARK_DOWN_OPTIONS = SNIPPET_CLIENT_OPTIONS;
|
|
6
11
|
|
|
7
|
-
export function provideMarkDown(options: SnippetClientOptions
|
|
8
|
-
return
|
|
9
|
-
{ provide: MARK_DOWN_OPTIONS, useValue: options },
|
|
10
|
-
{
|
|
11
|
-
provide: MARK_DOWN_CLIENT,
|
|
12
|
-
useFactory: (opts: SnippetClientOptions) => client ?? new SnippetClient(opts),
|
|
13
|
-
deps: [MARK_DOWN_OPTIONS]
|
|
14
|
-
}
|
|
15
|
-
];
|
|
12
|
+
export function provideMarkDown(options: SnippetClientOptions): Provider[] {
|
|
13
|
+
return provideSnippetClient(options);
|
|
16
14
|
}
|
package/tsconfig.json
CHANGED
|
@@ -3,7 +3,14 @@
|
|
|
3
3
|
"compilerOptions": {
|
|
4
4
|
"outDir": "dist",
|
|
5
5
|
"experimentalDecorators": true,
|
|
6
|
-
"emitDecoratorMetadata": true
|
|
6
|
+
"emitDecoratorMetadata": true,
|
|
7
|
+
"baseUrl": ".",
|
|
8
|
+
"paths": {
|
|
9
|
+
"@mzebley/mark-down": ["../core/src/index.ts"],
|
|
10
|
+
"@mzebley/mark-down/angular": ["../core/src/angular/index.ts"],
|
|
11
|
+
"@mzebley/mark-down/browser": ["../core/src/browser.ts"],
|
|
12
|
+
"@mzebley/mark-down/slug": ["../core/src/slug.ts"]
|
|
13
|
+
}
|
|
7
14
|
},
|
|
8
15
|
"include": ["src/**/*"]
|
|
9
16
|
}
|