@mzebley/mark-down-angular 1.2.1 → 1.2.3

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
@@ -1,5 +1,6 @@
1
1
  # mark↓ Angular Adapter
2
- *(published as `@mzebley/mark-down-angular`)*
2
+
3
+ _(published as `@mzebley/mark-down-angular`)_
3
4
 
4
5
  Angular bindings for the [mark↓ core runtime](../core/README.md). This package wraps `SnippetClient` with Angular-friendly providers, services, and components so you can render Markdown snippets safely inside your application. For background on the monorepo, see the [root README](../../README.md).
5
6
 
@@ -29,14 +30,14 @@ You will also need a manifest generated by the [CLI](../cli/README.md).
29
30
  Provide a shared `SnippetClient` from your root bootstrap call or feature module:
30
31
 
31
32
  ```ts
32
- import { bootstrapApplication } from '@angular/platform-browser';
33
- import { provideSnippetClient } from '@mzebley/mark-down/angular';
33
+ import { bootstrapApplication } from "@angular/platform-browser";
34
+ import { provideSnippetClient } from "@mzebley/mark-down/angular";
34
35
 
35
36
  bootstrapApplication(AppComponent, {
36
37
  providers: [
37
38
  ...provideSnippetClient({
38
- manifest: '/assets/content/snippets/manifest.json',
39
- base: '/assets/content/snippets',
39
+ manifest: "/assets/content/snippets/manifest.json",
40
+ base: "/assets/content/snippets",
40
41
  }),
41
42
  ],
42
43
  });
@@ -46,12 +47,12 @@ bootstrapApplication(AppComponent, {
46
47
 
47
48
  ### Angular compatibility
48
49
 
49
- | Angular version | Status |
50
- | ---------------- | ------ |
51
- | 17.x | ✅ Supported |
52
- | 18.x | ✅ Supported |
53
- | 19.x | ✅ Supported |
54
- | 20.x | ✅ Supported |
50
+ | Angular version | Status |
51
+ | --------------- | ------------ |
52
+ | 17.x | ✅ Supported |
53
+ | 18.x | ✅ Supported |
54
+ | 19.x | ✅ Supported |
55
+ | 20.x | ✅ Supported |
55
56
 
56
57
  The package declares peer dependency ranges `>=17 <21` so projects running any currently supported Angular major release can install without `--legacy-peer-deps`.
57
58
 
@@ -60,11 +61,11 @@ The package declares peer dependency ranges `>=17 <21` so projects running any c
60
61
  Inject `MarkdownSnippetService` into components or services to access Observables for snippets:
61
62
 
62
63
  ```ts
63
- import { Component, inject } from '@angular/core';
64
- import { MarkdownSnippetService } from '@mzebley/mark-down/angular';
64
+ import { Component, inject } from "@angular/core";
65
+ import { MarkdownSnippetService } from "@mzebley/mark-down/angular";
65
66
 
66
67
  @Component({
67
- selector: 'docs-hero',
68
+ selector: "docs-hero",
68
69
  template: `
69
70
  <ng-container *ngIf="hero$ | async as hero">
70
71
  <h1>{{ hero.title }}</h1>
@@ -74,7 +75,7 @@ import { MarkdownSnippetService } from '@mzebley/mark-down/angular';
74
75
  })
75
76
  export class DocsHeroComponent {
76
77
  private readonly snippets = inject(MarkdownSnippetService);
77
- readonly hero$ = this.snippets.get('getting-started-welcome');
78
+ readonly hero$ = this.snippets.get("getting-started-welcome");
78
79
  }
79
80
  ```
80
81
 
@@ -85,7 +86,10 @@ The service mirrors the core client APIs (`get`, `listAll`, `listByType`, `listB
85
86
  Render snippets declaratively with the bundled standalone component:
86
87
 
87
88
  ```html
88
- <snippet-view [slug]="'components-button'" (loaded)="onSnippetLoaded($event)"></snippet-view>
89
+ <snippet-view
90
+ [slug]="'components-button'"
91
+ (loaded)="onSnippetLoaded($event)"
92
+ ></snippet-view>
89
93
  ```
90
94
 
91
95
  Features:
@@ -100,16 +104,17 @@ Features:
100
104
  When running in Angular Universal, supply a server-compatible fetch implementation:
101
105
 
102
106
  ```ts
103
- import fetch from 'node-fetch';
107
+ import fetch from "node-fetch";
104
108
 
105
109
  provideSnippetClient({
106
- manifest: () => import('../snippets-index.json'),
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
- }),
110
+ manifest: () => import("../snippets-index.json"),
111
+ fetch: (url) =>
112
+ fetch(url).then((response) => {
113
+ if (!response.ok) {
114
+ throw new Error(`Request failed with status ${response.status}`);
115
+ }
116
+ return response;
117
+ }),
113
118
  });
114
119
  ```
115
120
 
package/dist/index.cjs CHANGED
@@ -84,6 +84,9 @@ var SnippetViewComponent = class {
84
84
  if (!snippet) {
85
85
  return null;
86
86
  }
87
+ if (typeof window === "undefined") {
88
+ return this.sanitizer.bypassSecurityTrustHtml(snippet.html);
89
+ }
87
90
  const sanitized = import_dompurify.default.sanitize(snippet.html);
88
91
  return this.sanitizer.bypassSecurityTrustHtml(sanitized);
89
92
  })
package/dist/index.js CHANGED
@@ -59,6 +59,9 @@ var SnippetViewComponent = class {
59
59
  if (!snippet) {
60
60
  return null;
61
61
  }
62
+ if (typeof window === "undefined") {
63
+ return this.sanitizer.bypassSecurityTrustHtml(snippet.html);
64
+ }
62
65
  const sanitized = DOMPurify.sanitize(snippet.html);
63
66
  return this.sanitizer.bypassSecurityTrustHtml(sanitized);
64
67
  })
package/package.json CHANGED
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "@mzebley/mark-down-angular",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "mark↓ Angular Adapter",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
7
7
  "module": "dist/index.js",
8
8
  "types": "dist/index.d.ts",
9
+ "files": [
10
+ "dist"
11
+ ],
9
12
  "exports": {
10
13
  ".": {
11
14
  "types": "./dist/index.d.ts",
@@ -20,9 +23,12 @@
20
23
  "build": "tsup src/index.ts --dts --format esm,cjs"
21
24
  },
22
25
  "dependencies": {
23
- "@mzebley/mark-down": "^1.2.1",
26
+ "@mzebley/mark-down": "^1.2.2",
24
27
  "dompurify": "^3.0.9"
25
28
  },
29
+ "devDependencies": {
30
+ "@angular/platform-browser": ">=17 <21"
31
+ },
26
32
  "peerDependencies": {
27
33
  "@angular/common": ">=17 <21",
28
34
  "@angular/core": ">=17 <21",
package/src/index.ts DELETED
@@ -1,4 +0,0 @@
1
- export * from "@mzebley/mark-down/angular";
2
- export * from "./token";
3
- export * from "./snippet.service";
4
- export * from "./snippet-view.component";
@@ -1,61 +0,0 @@
1
- import { CommonModule } from "@angular/common";
2
- import {
3
- ChangeDetectionStrategy,
4
- Component,
5
- EventEmitter,
6
- Input,
7
- OnChanges,
8
- Output,
9
- inject
10
- } from "@angular/core";
11
- import { DomSanitizer, SafeHtml } from "@angular/platform-browser";
12
- import { BehaviorSubject, Observable, of } from "rxjs";
13
- import { catchError, map, shareReplay, switchMap, tap } from "rxjs/operators";
14
- import type { Snippet } from "@mzebley/mark-down";
15
- import { SnippetService } from "./snippet.service";
16
- import DOMPurify from "dompurify";
17
-
18
- @Component({
19
- selector: "snippet-view",
20
- standalone: true,
21
- imports: [CommonModule],
22
- template: `
23
- <ng-container *ngIf="content$ | async as html; else loading">
24
- <div class="mark-down-snippet" [innerHTML]="html"></div>
25
- </ng-container>
26
- <ng-template #loading>
27
- <div class="mark-down-snippet--loading">Loading snippet…</div>
28
- </ng-template>
29
- `,
30
- changeDetection: ChangeDetectionStrategy.OnPush
31
- })
32
- export class SnippetViewComponent implements OnChanges {
33
- private readonly slug$ = new BehaviorSubject<string | null>(null);
34
- private readonly sanitizer = inject(DomSanitizer);
35
- private readonly snippets = inject(SnippetService);
36
-
37
- @Input() slug?: string;
38
- @Output() readonly loaded = new EventEmitter<Snippet | undefined>();
39
-
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 })
46
- );
47
-
48
- readonly content$: Observable<SafeHtml | null> = this.snippet$.pipe(
49
- map((snippet) => {
50
- if (!snippet) {
51
- return null;
52
- }
53
- const sanitized = DOMPurify.sanitize(snippet.html);
54
- return this.sanitizer.bypassSecurityTrustHtml(sanitized);
55
- })
56
- );
57
-
58
- ngOnChanges(): void {
59
- this.slug$.next(this.slug ?? null);
60
- }
61
- }
@@ -1 +0,0 @@
1
- export { MarkdownSnippetService as SnippetService } from "@mzebley/mark-down/angular";
package/src/token.ts DELETED
@@ -1,14 +0,0 @@
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";
8
-
9
- export const MARK_DOWN_CLIENT = SNIPPET_CLIENT;
10
- export const MARK_DOWN_OPTIONS = SNIPPET_CLIENT_OPTIONS;
11
-
12
- export function provideMarkDown(options: SnippetClientOptions): Provider[] {
13
- return provideSnippetClient(options);
14
- }
package/tsconfig.json DELETED
@@ -1,16 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "experimentalDecorators": 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
- }
14
- },
15
- "include": ["src/**/*"]
16
- }