@analogjs/content 3.0.0-alpha.5 → 3.0.0-alpha.51

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 (63) hide show
  1. package/devtools/package.json +4 -0
  2. package/fesm2022/analogjs-content-devtools.mjs +162 -0
  3. package/fesm2022/analogjs-content-devtools.mjs.map +1 -0
  4. package/fesm2022/analogjs-content-md4x.mjs +291 -0
  5. package/fesm2022/analogjs-content-md4x.mjs.map +1 -0
  6. package/fesm2022/analogjs-content-mdc.mjs +170 -0
  7. package/fesm2022/analogjs-content-mdc.mjs.map +1 -0
  8. package/fesm2022/analogjs-content-og.mjs.map +1 -0
  9. package/fesm2022/analogjs-content-prism-highlighter.mjs +5 -4
  10. package/fesm2022/analogjs-content-prism-highlighter.mjs.map +1 -0
  11. package/fesm2022/analogjs-content-resources.mjs +39 -25
  12. package/fesm2022/analogjs-content-resources.mjs.map +1 -0
  13. package/fesm2022/analogjs-content-shiki-highlighter.mjs +1 -1
  14. package/fesm2022/analogjs-content-shiki-highlighter.mjs.map +1 -0
  15. package/fesm2022/analogjs-content.mjs +42 -354
  16. package/fesm2022/analogjs-content.mjs.map +1 -0
  17. package/fesm2022/content-list-loader.mjs +260 -0
  18. package/fesm2022/content-list-loader.mjs.map +1 -0
  19. package/fesm2022/content-renderer.mjs +128 -0
  20. package/fesm2022/content-renderer.mjs.map +1 -0
  21. package/fesm2022/marked-content-highlighter.mjs +40 -0
  22. package/fesm2022/marked-content-highlighter.mjs.map +1 -0
  23. package/fesm2022/parse-raw-content-file.mjs +45 -0
  24. package/fesm2022/parse-raw-content-file.mjs.map +1 -0
  25. package/md4x/package.json +4 -0
  26. package/mdc/package.json +4 -0
  27. package/package.json +71 -36
  28. package/plugin/migrations.json +1 -1
  29. package/plugin/package.json +2 -21
  30. package/plugin/src/index.d.ts +3 -1
  31. package/plugin/src/index.d.ts.map +1 -0
  32. package/plugin/src/index.js +5 -4
  33. package/plugin/src/index.js.map +1 -0
  34. package/plugin/src/migrations/update-markdown-version/compat.d.ts +5 -2
  35. package/plugin/src/migrations/update-markdown-version/compat.d.ts.map +1 -0
  36. package/plugin/src/migrations/update-markdown-version/compat.js +8 -7
  37. package/plugin/src/migrations/update-markdown-version/compat.js.map +1 -0
  38. package/plugin/src/migrations/update-markdown-version/update-markdown-version.d.ts +6 -2
  39. package/plugin/src/migrations/update-markdown-version/update-markdown-version.d.ts.map +1 -0
  40. package/plugin/src/migrations/update-markdown-version/update-markdown-version.js +18 -20
  41. package/plugin/src/migrations/update-markdown-version/update-markdown-version.js.map +1 -0
  42. package/src/lib/devtools/content-devtools-client.ts +215 -0
  43. package/src/lib/devtools/content-devtools.styles.css +194 -0
  44. package/types/devtools/src/index.d.ts +1 -0
  45. package/types/md4x/src/index.d.ts +5 -0
  46. package/types/md4x/src/lib/md4x-content-renderer.service.d.ts +33 -0
  47. package/types/md4x/src/lib/md4x-wasm-content-renderer.service.d.ts +16 -0
  48. package/types/md4x/src/lib/provide-md4x.d.ts +26 -0
  49. package/types/md4x/src/lib/streaming-markdown-renderer.d.ts +21 -0
  50. package/types/mdc/src/index.d.ts +2 -0
  51. package/types/mdc/src/lib/mdc-component-registry.d.ts +25 -0
  52. package/types/mdc/src/lib/mdc-renderer.directive.d.ts +33 -0
  53. package/types/prism-highlighter/src/lib/prism-highlighter.d.ts +1 -1
  54. package/types/resources/src/content-file-resource.d.ts +32 -7
  55. package/types/resources/src/content-files-resource.d.ts +2 -1
  56. package/types/src/index.d.ts +6 -3
  57. package/types/src/lib/content-locale.d.ts +68 -0
  58. package/types/src/lib/devtools/content-devtools-plugin.d.ts +23 -0
  59. package/types/src/lib/devtools/content-devtools-renderer.d.ts +23 -0
  60. package/types/src/lib/devtools/index.d.ts +23 -0
  61. package/types/src/lib/get-content-files.d.ts +19 -4
  62. package/types/src/lib/parse-raw-content-file.d.ts +15 -1
  63. package/plugin/README.md +0 -11
@@ -1,10 +1,13 @@
1
+ import { n as NoopContentRenderer, t as ContentRenderer } from "./content-renderer.mjs";
2
+ import { a as injectContentFileLoader, c as injectContentFilesMap, d as CONTENT_LOCALE, f as filterByLocale, h as withLocaleCandidates, i as CONTENT_FILE_LOADER, l as RenderTaskService, m as withLocale, n as injectContentListLoader, o as withContentFileLoader, p as injectContentLocale, r as withContentListLoader, s as injectContentFiles, t as CONTENT_LIST_LOADER, u as CONTENT_FILES_TOKEN } from "./content-list-loader.mjs";
3
+ import { n as parseRawContentFile, r as parseRawContentFileAsync, t as FrontmatterValidationError } from "./parse-raw-content-file.mjs";
4
+ import { n as withHighlighter, t as MarkedContentHighlighter } from "./marked-content-highlighter.mjs";
1
5
  import * as i0 from "@angular/core";
2
- import { Component, Directive, HostListener, Injectable, InjectionToken, Input, NgZone, PLATFORM_ID, TransferState, ViewEncapsulation, computed, inject, input, makeStateKey, signal, ɵPendingTasksInternal } from "@angular/core";
3
- import { AsyncPipe, DOCUMENT, Location, isPlatformBrowser } from "@angular/common";
6
+ import { Component, Directive, HostListener, Injectable, InjectionToken, Input, NgZone, PLATFORM_ID, ViewEncapsulation, computed, inject, input } from "@angular/core";
7
+ import { DOCUMENT, Location, isPlatformBrowser } from "@angular/common";
4
8
  import { ActivatedRoute, Router } from "@angular/router";
5
- import { Observable, from, of } from "rxjs";
9
+ import { Observable, firstValueFrom, from, isObservable, of } from "rxjs";
6
10
  import { catchError, map, switchMap, tap } from "rxjs/operators";
7
- import fm from "front-matter";
8
11
  import { getHeadingList, gfmHeadingId } from "marked-gfm-heading-id";
9
12
  import { marked } from "marked";
10
13
  import { mangle } from "marked-mangle";
@@ -29,7 +32,7 @@ var AnchorNavigationDirective = class AnchorNavigationDirective {
29
32
  static {
30
33
  this.ɵfac = i0.ɵɵngDeclareFactory({
31
34
  minVersion: "12.0.0",
32
- version: "21.1.1",
35
+ version: "21.2.8",
33
36
  ngImport: i0,
34
37
  type: AnchorNavigationDirective,
35
38
  deps: [],
@@ -39,7 +42,7 @@ var AnchorNavigationDirective = class AnchorNavigationDirective {
39
42
  static {
40
43
  this.ɵdir = i0.ɵɵngDeclareDirective({
41
44
  minVersion: "14.0.0",
42
- version: "21.1.1",
45
+ version: "21.2.8",
43
46
  type: AnchorNavigationDirective,
44
47
  isStandalone: true,
45
48
  selector: "[analogAnchorNavigation]",
@@ -50,7 +53,7 @@ var AnchorNavigationDirective = class AnchorNavigationDirective {
50
53
  };
51
54
  i0.ɵɵngDeclareClassMetadata({
52
55
  minVersion: "12.0.0",
53
- version: "21.1.1",
56
+ version: "21.2.8",
54
57
  ngImport: i0,
55
58
  type: AnchorNavigationDirective,
56
59
  decorators: [{
@@ -75,269 +78,28 @@ function isInternalUrl(anchorElement, document) {
75
78
  return anchorElement.host === document.location.host && anchorElement.protocol === document.location.protocol;
76
79
  }
77
80
  //#endregion
78
- //#region packages/content/src/lib/content-renderer.ts
79
- var ContentRenderer = class ContentRenderer {
80
- async render(content) {
81
- return {
82
- content,
83
- toc: []
84
- };
85
- }
86
- getContentHeadings(_content) {
87
- return [];
88
- }
89
- enhance() {}
90
- static {
91
- this.ɵfac = i0.ɵɵngDeclareFactory({
92
- minVersion: "12.0.0",
93
- version: "21.1.1",
94
- ngImport: i0,
95
- type: ContentRenderer,
96
- deps: [],
97
- target: i0.ɵɵFactoryTarget.Injectable
98
- });
99
- }
100
- static {
101
- this.ɵprov = i0.ɵɵngDeclareInjectable({
102
- minVersion: "12.0.0",
103
- version: "21.1.1",
104
- ngImport: i0,
105
- type: ContentRenderer
106
- });
107
- }
108
- };
109
- i0.ɵɵngDeclareClassMetadata({
110
- minVersion: "12.0.0",
111
- version: "21.1.1",
112
- ngImport: i0,
113
- type: ContentRenderer,
114
- decorators: [{ type: Injectable }]
115
- });
116
- var NoopContentRenderer = class {
117
- constructor() {
118
- this.transferState = inject(TransferState);
119
- this.contentId = 0;
120
- }
121
- /**
122
- * Generates a hash from the content string
123
- * to be used with the transfer state
124
- */
125
- generateHash(str) {
126
- let hash = 0;
127
- for (let i = 0, len = str.length; i < len; i++) {
128
- const chr = str.charCodeAt(i);
129
- hash = (hash << 5) - hash + chr;
130
- hash |= 0;
131
- }
132
- return hash;
133
- }
134
- async render(content) {
135
- this.contentId = this.generateHash(content);
136
- const toc = this.getContentHeadings(content);
137
- const key = makeStateKey(`content-headings-${this.contentId}`);
138
- return {
139
- content,
140
- toc: this.transferState.get(key, toc)
141
- };
142
- }
143
- enhance() {}
144
- getContentHeadings(content) {
145
- return this.extractHeadings(content);
146
- }
147
- extractHeadings(content) {
148
- const markdownHeadings = this.extractHeadingsFromMarkdown(content);
149
- if (markdownHeadings.length > 0) return markdownHeadings;
150
- return this.extractHeadingsFromHtml(content);
151
- }
152
- extractHeadingsFromMarkdown(content) {
153
- const lines = content.split("\n");
154
- const toc = [];
155
- const slugCounts = /* @__PURE__ */ new Map();
156
- for (const line of lines) {
157
- const match = /^(#{1,6})\s+(.+?)\s*$/.exec(line);
158
- if (!match) continue;
159
- const level = match[1].length;
160
- const text = match[2].trim();
161
- if (!text) continue;
162
- const baseSlug = text.toLowerCase().replace(/[^\w\s-]/g, "").trim().replace(/\s+/g, "-");
163
- const count = slugCounts.get(baseSlug) ?? 0;
164
- slugCounts.set(baseSlug, count + 1);
165
- const id = count === 0 ? baseSlug : `${baseSlug}-${count}`;
166
- toc.push({
167
- id,
168
- level,
169
- text
170
- });
171
- }
172
- return toc;
173
- }
174
- extractHeadingsFromHtml(content) {
175
- const toc = [];
176
- const slugCounts = /* @__PURE__ */ new Map();
177
- for (const match of content.matchAll(/<h([1-6])([^>]*)>([\s\S]*?)<\/h\1>/gi)) {
178
- const level = Number(match[1]);
179
- const attrs = match[2] ?? "";
180
- const text = (match[3] ?? "").replace(/<[^>]+>/g, "").trim();
181
- if (!text) continue;
182
- const idMatch = /\sid=(['"])(.*?)\1/i.exec(attrs) ?? /\sid=([^\s>]+)/i.exec(attrs);
183
- let id = idMatch?.[2] ?? idMatch?.[1] ?? "";
184
- if (!id) id = this.makeSlug(text, slugCounts);
185
- toc.push({
186
- id,
187
- level,
188
- text
189
- });
190
- }
191
- return toc;
192
- }
193
- makeSlug(text, slugCounts) {
194
- const baseSlug = text.toLowerCase().replace(/[^\w\s-]/g, "").trim().replace(/\s+/g, "-");
195
- const count = slugCounts.get(baseSlug) ?? 0;
196
- slugCounts.set(baseSlug, count + 1);
197
- return count === 0 ? baseSlug : `${baseSlug}-${count}`;
198
- }
199
- };
200
- //#endregion
201
- //#region packages/content/src/lib/get-content-files.ts
202
- /**
203
- * Returns the list of content files by filename with ?analog-content-list=true.
204
- * We use the query param to transform the return into an array of
205
- * just front matter attributes.
206
- *
207
- * @returns
208
- */
209
- var getContentFilesList = () => {
210
- return {};
211
- };
212
- /**
213
- * Returns the lazy loaded content files for lookups.
214
- *
215
- * @returns
216
- */
217
- var getContentFiles = () => {
218
- return {};
219
- };
220
- //#endregion
221
- //#region packages/content/src/lib/content-files-list-token.ts
222
- function getSlug(filename) {
223
- const base = (filename.split(/[/\\]/).pop() || "").trim().replace(/\.[^./\\]+$/, "");
224
- return base === "index" ? "" : base;
225
- }
226
- var CONTENT_FILES_LIST_TOKEN = new InjectionToken("@analogjs/content Content Files List", {
227
- providedIn: "root",
228
- factory() {
229
- const contentFiles = getContentFilesList();
230
- return Object.keys(contentFiles).map((filename) => {
231
- const attributes = contentFiles[filename];
232
- const slug = attributes["slug"];
233
- return {
234
- filename,
235
- attributes,
236
- slug: slug ? encodeURI(slug) : encodeURI(getSlug(filename))
237
- };
238
- });
239
- }
240
- });
241
- //#endregion
242
- //#region packages/content/src/lib/content-files-token.ts
243
- var CONTENT_FILES_TOKEN = new InjectionToken("@analogjs/content Content Files", {
244
- providedIn: "root",
245
- factory() {
246
- const allFiles = { ...getContentFiles() };
247
- const contentFilesList = inject(CONTENT_FILES_LIST_TOKEN);
248
- const lookup = {};
249
- contentFilesList.forEach((item) => {
250
- const contentFilename = item.filename.replace(/(.*?)\/content/, "/src/content");
251
- const fileParts = contentFilename.split("/");
252
- const filePath = fileParts.slice(0, fileParts.length - 1).join("/");
253
- const fileNameParts = fileParts[fileParts.length - 1].split(".");
254
- const ext = fileNameParts[fileNameParts.length - 1];
255
- let slug = item.slug ?? "";
256
- if (slug === "") slug = "index";
257
- lookup[contentFilename] = `${slug.includes("/") ? `/src/content/${slug}` : `${filePath}/${slug}`}.${ext}`.replace(/\/{2,}/g, "/");
258
- });
259
- const objectUsingSlugAttribute = {};
260
- Object.entries(allFiles).forEach((entry) => {
261
- const filename = entry[0];
262
- const value = entry[1];
263
- const newFilename = lookup[filename.replace(/^\/(.*?)\/content/, "/src/content")];
264
- if (newFilename !== void 0) {
265
- const objectFilename = newFilename.replace(/^\/(.*?)\/content/, "/src/content");
266
- objectUsingSlugAttribute[objectFilename] = value;
267
- }
268
- });
269
- return objectUsingSlugAttribute;
270
- }
271
- });
272
- new InjectionToken("@analogjs/content Content Files", {
273
- providedIn: "root",
274
- factory() {
275
- return signal(inject(CONTENT_FILES_TOKEN));
276
- }
277
- });
278
- //#endregion
279
- //#region packages/content/src/lib/parse-raw-content-file.ts
280
- function parseRawContentFile(rawContentFile) {
281
- const { body, attributes } = fm(rawContentFile);
282
- return {
283
- content: body,
284
- attributes
285
- };
81
+ //#region packages/content/src/lib/utils/zone-wait-for.ts
82
+ async function waitFor(prom) {
83
+ if (isObservable(prom)) prom = firstValueFrom(prom);
84
+ if (typeof Zone === "undefined") return prom;
85
+ const macroTask = Zone.current.scheduleMacroTask(`AnalogContentResolve-${Math.random()}`, () => {}, {}, () => {});
86
+ return prom.then((p) => {
87
+ macroTask.invoke();
88
+ return p;
89
+ });
286
90
  }
287
91
  //#endregion
288
- //#region packages/content/src/lib/render-task.service.ts
289
- var RenderTaskService = class RenderTaskService {
290
- #pendingTasks = inject(ɵPendingTasksInternal);
291
- addRenderTask() {
292
- return this.#pendingTasks.add();
293
- }
294
- clearRenderTask(clear) {
295
- if (typeof clear === "function") clear();
296
- else if (typeof this.#pendingTasks.remove === "function") this.#pendingTasks.remove(clear);
297
- }
298
- static {
299
- this.ɵfac = i0.ɵɵngDeclareFactory({
300
- minVersion: "12.0.0",
301
- version: "21.1.1",
302
- ngImport: i0,
303
- type: RenderTaskService,
304
- deps: [],
305
- target: i0.ɵɵFactoryTarget.Injectable
306
- });
307
- }
308
- static {
309
- this.ɵprov = i0.ɵɵngDeclareInjectable({
310
- minVersion: "12.0.0",
311
- version: "21.1.1",
312
- ngImport: i0,
313
- type: RenderTaskService
314
- });
315
- }
316
- };
317
- i0.ɵɵngDeclareClassMetadata({
318
- minVersion: "12.0.0",
319
- version: "21.1.1",
320
- ngImport: i0,
321
- type: RenderTaskService,
322
- decorators: [{ type: Injectable }]
323
- });
324
- //#endregion
325
92
  //#region packages/content/src/lib/content.ts
326
- function getContentFile(contentFiles, prefix, slug, fallback, renderTaskService, contentRenderer) {
93
+ function getContentFile(contentFiles, prefix, slug, fallback, renderTaskService, contentRenderer, locale) {
327
94
  const normalizedFiles = {};
328
95
  for (const [key, resolver] of Object.entries(contentFiles)) {
329
96
  const normalizedKey = key.replace(/^(?:.*)\/content/, "/src/content").replace(/\/{2,}/g, "/");
330
97
  normalizedFiles[normalizedKey] = resolver;
331
98
  }
332
99
  const base = `/src/content/${prefix}${slug}`.replace(/\/{2,}/g, "/");
333
- const matchKey = [
334
- `${base}.md`,
335
- `${base}.agx`,
336
- `${base}/index.md`,
337
- `${base}/index.agx`
338
- ].find((k) => k in normalizedFiles);
100
+ const matchKey = withLocaleCandidates([`${base}.md`, `${base}/index.md`], locale).find((k) => k in normalizedFiles);
339
101
  const contentFile = matchKey ? normalizedFiles[matchKey] : void 0;
340
- const resolvedBase = (matchKey || `${base}.md`).replace(/\.(md|agx)$/, "");
102
+ const resolvedBase = (matchKey || `${base}.md`).replace(/\.md$/, "");
341
103
  if (!contentFile) return of({
342
104
  filename: resolvedBase,
343
105
  attributes: {},
@@ -345,11 +107,12 @@ function getContentFile(contentFiles, prefix, slug, fallback, renderTaskService,
345
107
  content: fallback,
346
108
  toc: []
347
109
  });
348
- renderTaskService.addRenderTask();
110
+ const contentTask = renderTaskService.addRenderTask();
349
111
  return new Observable((observer) => {
350
- contentFile().then((content) => {
112
+ waitFor(contentFile()).then((content) => {
351
113
  observer.next(content);
352
114
  observer.complete();
115
+ setTimeout(() => renderTaskService.clearRenderTask(contentTask), 10);
353
116
  });
354
117
  }).pipe(switchMap((contentFile) => {
355
118
  if (typeof contentFile === "string") {
@@ -381,13 +144,14 @@ function injectContent(param = "slug", fallback = "No Content Found") {
381
144
  const contentFiles = inject(CONTENT_FILES_TOKEN);
382
145
  const contentRenderer = inject(ContentRenderer);
383
146
  const renderTaskService = inject(RenderTaskService);
147
+ const locale = inject(CONTENT_LOCALE, { optional: true });
384
148
  const task = renderTaskService.addRenderTask();
385
149
  if (typeof param === "string" || "param" in param) {
386
150
  const prefix = typeof param === "string" ? "" : `${param.subdirectory}/`;
387
151
  const route = inject(ActivatedRoute);
388
152
  const paramKey = typeof param === "string" ? param : param.param;
389
153
  return route.paramMap.pipe(map((params) => params.get(paramKey)), switchMap((slug) => {
390
- if (slug) return getContentFile(contentFiles, prefix, slug, fallback, renderTaskService, contentRenderer);
154
+ if (slug) return getContentFile(contentFiles, prefix, slug, fallback, renderTaskService, contentRenderer, locale);
391
155
  return of({
392
156
  filename: "",
393
157
  slug: "",
@@ -396,55 +160,7 @@ function injectContent(param = "slug", fallback = "No Content Found") {
396
160
  toc: []
397
161
  });
398
162
  }), tap(() => renderTaskService.clearRenderTask(task)));
399
- } else return getContentFile(contentFiles, "", param.customFilename, fallback, renderTaskService, contentRenderer).pipe(tap(() => renderTaskService.clearRenderTask(task)));
400
- }
401
- //#endregion
402
- //#region packages/content/src/lib/inject-content-files.ts
403
- function injectContentFiles(filterFn) {
404
- const renderTaskService = inject(RenderTaskService);
405
- const task = renderTaskService.addRenderTask();
406
- const allContentFiles = inject(CONTENT_FILES_LIST_TOKEN);
407
- renderTaskService.clearRenderTask(task);
408
- if (filterFn) return allContentFiles.filter(filterFn);
409
- return allContentFiles;
410
- }
411
- function injectContentFilesMap() {
412
- return inject(CONTENT_FILES_TOKEN);
413
- }
414
- //#endregion
415
- //#region packages/content/src/lib/marked-content-highlighter.ts
416
- var MarkedContentHighlighter = class MarkedContentHighlighter {
417
- static {
418
- this.ɵfac = i0.ɵɵngDeclareFactory({
419
- minVersion: "12.0.0",
420
- version: "21.1.1",
421
- ngImport: i0,
422
- type: MarkedContentHighlighter,
423
- deps: [],
424
- target: i0.ɵɵFactoryTarget.Injectable
425
- });
426
- }
427
- static {
428
- this.ɵprov = i0.ɵɵngDeclareInjectable({
429
- minVersion: "12.0.0",
430
- version: "21.1.1",
431
- ngImport: i0,
432
- type: MarkedContentHighlighter
433
- });
434
- }
435
- };
436
- i0.ɵɵngDeclareClassMetadata({
437
- minVersion: "12.0.0",
438
- version: "21.1.1",
439
- ngImport: i0,
440
- type: MarkedContentHighlighter,
441
- decorators: [{ type: Injectable }]
442
- });
443
- function withHighlighter(provider) {
444
- return {
445
- provide: MarkedContentHighlighter,
446
- ...provider
447
- };
163
+ } else return getContentFile(contentFiles, "", param.customFilename, fallback, renderTaskService, contentRenderer, locale).pipe(tap(() => renderTaskService.clearRenderTask(task)));
448
164
  }
449
165
  //#endregion
450
166
  //#region packages/content/src/lib/marked-setup.service.ts
@@ -478,7 +194,7 @@ var MarkedSetupService = class MarkedSetupService {
478
194
  static {
479
195
  this.ɵfac = i0.ɵɵngDeclareFactory({
480
196
  minVersion: "12.0.0",
481
- version: "21.1.1",
197
+ version: "21.2.8",
482
198
  ngImport: i0,
483
199
  type: MarkedSetupService,
484
200
  deps: [],
@@ -488,7 +204,7 @@ var MarkedSetupService = class MarkedSetupService {
488
204
  static {
489
205
  this.ɵprov = i0.ɵɵngDeclareInjectable({
490
206
  minVersion: "12.0.0",
491
- version: "21.1.1",
207
+ version: "21.2.8",
492
208
  ngImport: i0,
493
209
  type: MarkedSetupService
494
210
  });
@@ -496,7 +212,7 @@ var MarkedSetupService = class MarkedSetupService {
496
212
  };
497
213
  i0.ɵɵngDeclareClassMetadata({
498
214
  minVersion: "12.0.0",
499
- version: "21.1.1",
215
+ version: "21.2.8",
500
216
  ngImport: i0,
501
217
  type: MarkedSetupService,
502
218
  decorators: [{ type: Injectable }],
@@ -523,7 +239,7 @@ var MarkdownContentRendererService = class MarkdownContentRendererService {
523
239
  static {
524
240
  this.ɵfac = i0.ɵɵngDeclareFactory({
525
241
  minVersion: "12.0.0",
526
- version: "21.1.1",
242
+ version: "21.2.8",
527
243
  ngImport: i0,
528
244
  type: MarkdownContentRendererService,
529
245
  deps: [],
@@ -533,7 +249,7 @@ var MarkdownContentRendererService = class MarkdownContentRendererService {
533
249
  static {
534
250
  this.ɵprov = i0.ɵɵngDeclareInjectable({
535
251
  minVersion: "12.0.0",
536
- version: "21.1.1",
252
+ version: "21.2.8",
537
253
  ngImport: i0,
538
254
  type: MarkdownContentRendererService
539
255
  });
@@ -541,40 +257,12 @@ var MarkdownContentRendererService = class MarkdownContentRendererService {
541
257
  };
542
258
  i0.ɵɵngDeclareClassMetadata({
543
259
  minVersion: "12.0.0",
544
- version: "21.1.1",
260
+ version: "21.2.8",
545
261
  ngImport: i0,
546
262
  type: MarkdownContentRendererService,
547
263
  decorators: [{ type: Injectable }]
548
264
  });
549
265
  //#endregion
550
- //#region packages/content/src/lib/content-file-loader.ts
551
- var CONTENT_FILE_LOADER = new InjectionToken("@analogjs/content/resource File Loader");
552
- function injectContentFileLoader() {
553
- return inject(CONTENT_FILE_LOADER);
554
- }
555
- function withContentFileLoader() {
556
- return {
557
- provide: CONTENT_FILE_LOADER,
558
- useFactory() {
559
- return async () => injectContentFilesMap();
560
- }
561
- };
562
- }
563
- //#endregion
564
- //#region packages/content/src/lib/content-list-loader.ts
565
- var CONTENT_LIST_LOADER = new InjectionToken("@analogjs/content/resource List Loader");
566
- function injectContentListLoader() {
567
- return inject(CONTENT_LIST_LOADER);
568
- }
569
- function withContentListLoader() {
570
- return {
571
- provide: CONTENT_LIST_LOADER,
572
- useFactory() {
573
- return async () => injectContentFiles();
574
- }
575
- };
576
- }
577
- //#endregion
578
266
  //#region packages/content/src/lib/provide-content.ts
579
267
  var CONTENT_RENDERER_PROVIDERS = [
580
268
  {
@@ -613,7 +301,7 @@ var AnalogMarkdownRouteComponent = class AnalogMarkdownRouteComponent {
613
301
  static {
614
302
  this.ɵfac = i0.ɵɵngDeclareFactory({
615
303
  minVersion: "12.0.0",
616
- version: "21.1.1",
304
+ version: "21.2.8",
617
305
  ngImport: i0,
618
306
  type: AnalogMarkdownRouteComponent,
619
307
  deps: [],
@@ -623,7 +311,7 @@ var AnalogMarkdownRouteComponent = class AnalogMarkdownRouteComponent {
623
311
  static {
624
312
  this.ɵcmp = i0.ɵɵngDeclareComponent({
625
313
  minVersion: "14.0.0",
626
- version: "21.1.1",
314
+ version: "21.2.8",
627
315
  type: AnalogMarkdownRouteComponent,
628
316
  isStandalone: true,
629
317
  selector: "analog-markdown-route",
@@ -639,7 +327,7 @@ var AnalogMarkdownRouteComponent = class AnalogMarkdownRouteComponent {
639
327
  };
640
328
  i0.ɵɵngDeclareClassMetadata({
641
329
  minVersion: "12.0.0",
642
- version: "21.1.1",
330
+ version: "21.2.8",
643
331
  ngImport: i0,
644
332
  type: AnalogMarkdownRouteComponent,
645
333
  decorators: [{
@@ -647,7 +335,7 @@ i0.ɵɵngDeclareClassMetadata({
647
335
  args: [{
648
336
  selector: "analog-markdown-route",
649
337
  standalone: true,
650
- imports: [AsyncPipe],
338
+ imports: [],
651
339
  hostDirectives: [AnchorNavigationDirective],
652
340
  preserveWhitespaces: true,
653
341
  encapsulation: ViewEncapsulation.None,
@@ -696,7 +384,7 @@ var AnalogMarkdownComponent = class AnalogMarkdownComponent {
696
384
  static {
697
385
  this.ɵfac = i0.ɵɵngDeclareFactory({
698
386
  minVersion: "12.0.0",
699
- version: "21.1.1",
387
+ version: "21.2.8",
700
388
  ngImport: i0,
701
389
  type: AnalogMarkdownComponent,
702
390
  deps: [],
@@ -706,7 +394,7 @@ var AnalogMarkdownComponent = class AnalogMarkdownComponent {
706
394
  static {
707
395
  this.ɵcmp = i0.ɵɵngDeclareComponent({
708
396
  minVersion: "17.1.0",
709
- version: "21.1.1",
397
+ version: "21.2.8",
710
398
  type: AnalogMarkdownComponent,
711
399
  isStandalone: true,
712
400
  selector: "analog-markdown",
@@ -737,7 +425,7 @@ var AnalogMarkdownComponent = class AnalogMarkdownComponent {
737
425
  };
738
426
  i0.ɵɵngDeclareClassMetadata({
739
427
  minVersion: "12.0.0",
740
- version: "21.1.1",
428
+ version: "21.2.8",
741
429
  ngImport: i0,
742
430
  type: AnalogMarkdownComponent,
743
431
  decorators: [{
@@ -772,6 +460,6 @@ i0.ɵɵngDeclareClassMetadata({
772
460
  }
773
461
  });
774
462
  //#endregion
775
- export { AnchorNavigationDirective, CONTENT_FILE_LOADER, CONTENT_LIST_LOADER, ContentRenderer, MERMAID_IMPORT_TOKEN, AnalogMarkdownComponent as MarkdownComponent, MarkdownContentRendererService, AnalogMarkdownRouteComponent as MarkdownRouteComponent, MarkedContentHighlighter, MarkedSetupService, NoopContentRenderer, injectContent, injectContentFileLoader, injectContentFiles, injectContentFilesMap, injectContentListLoader, parseRawContentFile, provideContent, withContentFileLoader, withContentListLoader, withHighlighter, withMarkdownRenderer };
463
+ export { AnchorNavigationDirective, CONTENT_FILE_LOADER, CONTENT_LIST_LOADER, CONTENT_LOCALE, ContentRenderer, FrontmatterValidationError, MERMAID_IMPORT_TOKEN, AnalogMarkdownComponent as MarkdownComponent, MarkdownContentRendererService, AnalogMarkdownRouteComponent as MarkdownRouteComponent, MarkedContentHighlighter, MarkedSetupService, NoopContentRenderer, filterByLocale, injectContent, injectContentFileLoader, injectContentFiles, injectContentFilesMap, injectContentListLoader, injectContentLocale, parseRawContentFile, parseRawContentFileAsync, provideContent, withContentFileLoader, withContentListLoader, withHighlighter, withLocale, withLocaleCandidates, withMarkdownRenderer };
776
464
 
777
465
  //# sourceMappingURL=analogjs-content.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analogjs-content.mjs","names":["#marked"],"sources":["../../src/lib/anchor-navigation.directive.ts","../../src/lib/utils/zone-wait-for.ts","../../src/lib/content.ts","../../src/lib/marked-setup.service.ts","../../src/lib/markdown-content-renderer.service.ts","../../src/lib/provide-content.ts","../../src/lib/markdown-route.component.ts","../../src/lib/markdown.component.ts"],"sourcesContent":["import { Directive, HostListener, inject } from '@angular/core';\nimport { DOCUMENT, Location } from '@angular/common';\nimport { Router } from '@angular/router';\n\n@Directive({\n selector: '[analogAnchorNavigation]',\n standalone: true,\n})\nexport class AnchorNavigationDirective {\n private readonly document = inject(DOCUMENT);\n private readonly location = inject(Location);\n private readonly router = inject(Router);\n\n @HostListener('click', ['$event.target'])\n handleNavigation(element: EventTarget | null): boolean {\n if (\n element instanceof HTMLAnchorElement &&\n isInternalUrl(element, this.document) &&\n hasTargetSelf(element) &&\n !hasDownloadAttribute(element)\n ) {\n const { pathname, search, hash } = element;\n const url = this.location.normalize(`${pathname}${search}${hash}`);\n this.router.navigateByUrl(url);\n\n return false;\n }\n\n return true;\n }\n}\n\nfunction hasDownloadAttribute(anchorElement: HTMLAnchorElement): boolean {\n return anchorElement.getAttribute('download') !== null;\n}\n\nfunction hasTargetSelf(anchorElement: HTMLAnchorElement): boolean {\n return !anchorElement.target || anchorElement.target === '_self';\n}\n\nfunction isInternalUrl(\n anchorElement: HTMLAnchorElement,\n document: Document,\n): boolean {\n return (\n anchorElement.host === document.location.host &&\n anchorElement.protocol === document.location.protocol\n );\n}\n","import { firstValueFrom, isObservable, Observable } from 'rxjs';\n\ndeclare const Zone: any;\n\nexport async function waitFor<T>(prom: Promise<T> | Observable<T>): Promise<T> {\n if (isObservable(prom)) {\n prom = firstValueFrom(prom);\n }\n\n if (typeof Zone === 'undefined') {\n return prom;\n }\n\n const macroTask = Zone.current.scheduleMacroTask(\n `AnalogContentResolve-${Math.random()}`,\n () => {\n /* noop */\n },\n {},\n () => {\n /* noop */\n },\n );\n return prom.then((p: T) => {\n macroTask.invoke();\n return p;\n });\n}\n","/// <reference types=\"vite/client\" />\n\nimport { inject } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\nimport { from, Observable, of } from 'rxjs';\nimport { map, switchMap, tap } from 'rxjs/operators';\n\nimport { ContentFile } from './content-file';\nimport { ContentRenderer } from './content-renderer';\nimport { CONTENT_LOCALE, withLocaleCandidates } from './content-locale';\nimport { CONTENT_FILES_TOKEN } from './content-files-token';\nimport { parseRawContentFile } from './parse-raw-content-file';\nimport { waitFor } from './utils/zone-wait-for';\nimport { RenderTaskService } from './render-task.service';\n\nfunction getContentFile<\n Attributes extends Record<string, any> = Record<string, any>,\n>(\n contentFiles: Record<string, () => Promise<string>>,\n prefix: string,\n slug: string,\n fallback: string,\n renderTaskService: RenderTaskService,\n contentRenderer: ContentRenderer,\n locale?: string | null,\n): Observable<ContentFile<Attributes | Record<string, never>>> {\n // Normalize file keys so both \"/src/content/...\" and \"/<project>/src/content/...\" resolve.\n const normalizedFiles: Record<string, () => Promise<string>> = {};\n for (const [key, resolver] of Object.entries(contentFiles)) {\n const normalizedKey = key\n .replace(/^(?:.*)\\/content/, '/src/content')\n .replace(/\\/{2,}/g, '/');\n normalizedFiles[normalizedKey] = resolver as () => Promise<string>;\n }\n\n const base = `/src/content/${prefix}${slug}`.replace(/\\/{2,}/g, '/');\n const candidates = [`${base}.md`, `${base}/index.md`];\n\n const allCandidates = withLocaleCandidates(candidates, locale);\n const matchKey = allCandidates.find((k) => k in normalizedFiles);\n const contentFile = matchKey ? normalizedFiles[matchKey] : undefined;\n const resolvedBase = (matchKey || `${base}.md`).replace(/\\.md$/, '');\n\n if (!contentFile) {\n return of({\n filename: resolvedBase,\n attributes: {},\n slug: '',\n content: fallback,\n toc: [],\n });\n }\n\n const contentTask = renderTaskService.addRenderTask();\n return new Observable<string | { default: string; metadata: Attributes }>(\n (observer) => {\n // `waitFor` is a no-op in non-Zone environments (browser without zone.js),\n // so this branch works for both SSR and client. Keeping a single path also\n // avoids Rolldown evaluating `import.meta.env.SSR` at library-build time\n // and eliminating the task-clearing branch, which caused SSR to hang once\n // the content map resolved a real lazy import.\n waitFor(contentFile()).then((content) => {\n observer.next(content);\n observer.complete();\n\n setTimeout(() => renderTaskService.clearRenderTask(contentTask), 10);\n });\n },\n ).pipe(\n switchMap((contentFile) => {\n if (typeof contentFile === 'string') {\n const { content, attributes } =\n parseRawContentFile<Attributes>(contentFile);\n return from(contentRenderer.render(content)).pipe(\n map((rendered) => ({\n filename: resolvedBase,\n slug,\n attributes,\n content,\n toc: rendered.toc ?? [],\n })),\n );\n }\n return of({\n filename: resolvedBase,\n slug,\n attributes: contentFile.metadata,\n content: contentFile.default,\n toc: [],\n });\n }),\n );\n}\n\n/**\n * Retrieves the static content using the provided param and/or prefix.\n *\n * @param param route parameter (default: 'slug')\n * @param fallback fallback text if content file is not found (default: 'No Content Found')\n */\nexport function injectContent<\n Attributes extends Record<string, any> = Record<string, any>,\n>(\n param:\n | string\n | {\n param: string;\n subdirectory: string;\n }\n | {\n customFilename: string;\n } = 'slug',\n fallback = 'No Content Found',\n): Observable<ContentFile<Attributes | Record<string, never>>> {\n const contentFiles = inject(CONTENT_FILES_TOKEN);\n const contentRenderer = inject(ContentRenderer);\n const renderTaskService = inject(RenderTaskService);\n const locale = inject(CONTENT_LOCALE, { optional: true });\n const task = renderTaskService.addRenderTask();\n\n if (typeof param === 'string' || 'param' in param) {\n const prefix = typeof param === 'string' ? '' : `${param.subdirectory}/`;\n const route = inject(ActivatedRoute);\n const paramKey = typeof param === 'string' ? param : param.param;\n return route.paramMap.pipe(\n map((params) => params.get(paramKey)),\n switchMap((slug) => {\n if (slug) {\n return getContentFile<Attributes>(\n contentFiles,\n prefix,\n slug,\n fallback,\n renderTaskService,\n contentRenderer,\n locale,\n );\n }\n return of({\n filename: '',\n slug: '',\n attributes: {},\n content: fallback,\n toc: [],\n });\n }),\n tap(() => renderTaskService.clearRenderTask(task)),\n );\n } else {\n return getContentFile<Attributes>(\n contentFiles,\n '',\n param.customFilename,\n fallback,\n renderTaskService,\n contentRenderer,\n locale,\n ).pipe(tap(() => renderTaskService.clearRenderTask(task)));\n }\n}\n","/**\n * Credit goes to Scully for original implementation\n * https://github.com/scullyio/scully/blob/main/libs/scully/src/lib/fileHanderPlugins/markdown.ts\n */\nimport { inject, Injectable } from '@angular/core';\nimport { marked } from 'marked';\nimport { gfmHeadingId } from 'marked-gfm-heading-id';\nimport { mangle } from 'marked-mangle';\nimport { MarkedContentHighlighter } from './marked-content-highlighter';\n\n@Injectable()\nexport class MarkedSetupService {\n private readonly marked: typeof marked;\n private readonly highlighter = inject(MarkedContentHighlighter, {\n optional: true,\n });\n\n constructor() {\n const renderer = new marked.Renderer();\n renderer.code = ({ text, lang }) => {\n // Let's do a language based detection like on GitHub\n // So we can still have non-interpreted mermaid code\n if (lang === 'mermaid') {\n return '<pre class=\"mermaid\">' + text + '</pre>';\n }\n\n if (!lang) {\n return '<pre><code>' + text + '</code></pre>';\n }\n\n if (this.highlighter?.augmentCodeBlock) {\n return this.highlighter?.augmentCodeBlock(text, lang);\n }\n\n return `<pre class=\"language-${lang}\"><code class=\"language-${lang}\">${text}</code></pre>`;\n };\n\n const extensions = [gfmHeadingId(), mangle()];\n\n if (this.highlighter) {\n extensions.push(this.highlighter.getHighlightExtension());\n }\n\n marked.use(...extensions, {\n renderer,\n pedantic: false,\n gfm: true,\n breaks: false,\n });\n\n this.marked = marked;\n }\n\n getMarkedInstance(): typeof marked {\n return this.marked;\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { getHeadingList } from 'marked-gfm-heading-id';\n\nimport {\n ContentRenderer,\n RenderedContent,\n TableOfContentItem,\n} from './content-renderer';\nimport { MarkedSetupService } from './marked-setup.service';\n\n@Injectable()\nexport class MarkdownContentRendererService implements ContentRenderer {\n #marked = inject(MarkedSetupService, { self: true });\n\n async render(content: string): Promise<RenderedContent> {\n const renderedContent = await this.#marked\n .getMarkedInstance()\n .parse(content);\n return {\n content: renderedContent,\n toc: getHeadingList(),\n };\n }\n\n getContentHeadings(content: string): TableOfContentItem[] {\n return [...content.matchAll(/^(#{1,6})\\s+(.+?)\\s*$/gm)].map((match) => ({\n id: match[2]\n .trim()\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, '')\n .replace(/\\s+/g, '-'),\n level: match[1].length,\n text: match[2].trim(),\n }));\n }\n\n // eslint-disable-next-line\n enhance(): void {}\n}\n","import { Provider, InjectionToken } from '@angular/core';\nimport { ContentRenderer, NoopContentRenderer } from './content-renderer';\nimport { RenderTaskService } from './render-task.service';\nimport { withContentFileLoader } from './content-file-loader';\nimport { withContentListLoader } from './content-list-loader';\n\nexport interface MarkdownRendererOptions {\n loadMermaid?: () => Promise<typeof import('mermaid')>;\n}\n\nconst CONTENT_RENDERER_PROVIDERS: Provider[] = [\n {\n provide: ContentRenderer,\n useClass: NoopContentRenderer,\n },\n withContentFileLoader(),\n withContentListLoader(),\n];\n\nexport function withMarkdownRenderer(\n options?: MarkdownRendererOptions,\n): Provider {\n return [\n CONTENT_RENDERER_PROVIDERS,\n options?.loadMermaid\n ? [\n {\n provide: MERMAID_IMPORT_TOKEN,\n useFactory: options.loadMermaid,\n },\n ]\n : [],\n ];\n}\n\nexport function provideContent(...features: Provider[]): Provider[] {\n return [\n { provide: RenderTaskService, useClass: RenderTaskService },\n ...features,\n ];\n}\n\nexport const MERMAID_IMPORT_TOKEN: InjectionToken<\n Promise<typeof import('mermaid')>\n> = new InjectionToken<Promise<typeof import('mermaid')>>('mermaid_import');\n","import {\n AfterViewChecked,\n Component,\n inject,\n Input,\n ViewEncapsulation,\n} from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { ContentRenderer } from './content-renderer';\nimport { AnchorNavigationDirective } from './anchor-navigation.directive';\n\n@Component({\n selector: 'analog-markdown-route',\n standalone: true,\n imports: [],\n hostDirectives: [AnchorNavigationDirective],\n preserveWhitespaces: true,\n encapsulation: ViewEncapsulation.None,\n template: `<div [innerHTML]=\"content\" [class]=\"classes\"></div>`,\n})\nexport default class AnalogMarkdownRouteComponent implements AfterViewChecked {\n private sanitizer = inject(DomSanitizer);\n private route = inject(ActivatedRoute);\n contentRenderer: ContentRenderer = inject(ContentRenderer);\n\n protected content: SafeHtml = this.sanitizer.bypassSecurityTrustHtml(\n this.route.snapshot.data['renderedAnalogContent'],\n );\n\n @Input() classes = 'analog-markdown-route';\n\n ngAfterViewChecked(): void {\n this.contentRenderer.enhance();\n }\n}\n","import { isPlatformBrowser } from '@angular/common';\nimport {\n AfterViewChecked,\n Component,\n InputSignal,\n NgZone,\n PLATFORM_ID,\n Signal,\n ViewEncapsulation,\n computed,\n inject,\n input,\n} from '@angular/core';\nimport { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { ActivatedRoute, Data } from '@angular/router';\nimport { from, Observable, of } from 'rxjs';\nimport { catchError, map, switchMap } from 'rxjs/operators';\n\nimport { AnchorNavigationDirective } from './anchor-navigation.directive';\nimport { ContentRenderer } from './content-renderer';\nimport { MERMAID_IMPORT_TOKEN } from './provide-content';\n\n@Component({\n selector: 'analog-markdown',\n standalone: true,\n hostDirectives: [AnchorNavigationDirective],\n preserveWhitespaces: true,\n encapsulation: ViewEncapsulation.None,\n template: ` <div [innerHTML]=\"htmlContent()\" [class]=\"classes()\"></div> `,\n})\nexport default class AnalogMarkdownComponent implements AfterViewChecked {\n private sanitizer = inject(DomSanitizer);\n private route = inject(ActivatedRoute);\n private zone = inject(NgZone);\n private readonly platformId = inject(PLATFORM_ID);\n private readonly mermaidImport = inject(MERMAID_IMPORT_TOKEN, {\n optional: true,\n });\n private mermaid: typeof import('mermaid') | undefined;\n\n private contentSource: Signal<SafeHtml | string | undefined> = toSignal(\n this.getContentSource(),\n );\n readonly htmlContent: Signal<SafeHtml | string | undefined> = computed(() => {\n const inputContent = this.content();\n\n if (inputContent) {\n return this.sanitizer.bypassSecurityTrustHtml(inputContent as string);\n }\n\n return this.contentSource();\n });\n readonly content: InputSignal<string | object | null | undefined> = input<\n string | object | null\n >();\n readonly classes: InputSignal<string> = input('analog-markdown');\n\n contentRenderer: ContentRenderer = inject(ContentRenderer);\n\n constructor() {\n if (isPlatformBrowser(this.platformId) && this.mermaidImport) {\n // Mermaid can only be loaded on client side\n this.loadMermaid(this.mermaidImport);\n }\n }\n\n getContentSource(): Observable<SafeHtml | string> {\n return this.route.data.pipe(\n map<Data, string>((data) => data['_analogContent'] ?? ''),\n switchMap((contentString) => this.renderContent(contentString)),\n map((content) => this.sanitizer.bypassSecurityTrustHtml(content)),\n catchError((e) => of(`There was an error ${e}`)),\n );\n }\n\n async renderContent(content: string): Promise<string> {\n const rendered = await this.contentRenderer.render(content);\n return rendered.content;\n }\n\n ngAfterViewChecked(): void {\n this.contentRenderer.enhance();\n this.zone.runOutsideAngular(() => this.mermaid?.default.run());\n }\n\n private loadMermaid(mermaidImport: Promise<typeof import('mermaid')>) {\n this.zone.runOutsideAngular(() =>\n // Wrap into an observable to avoid redundant initialization once\n // the markdown component is destroyed before the promise is resolved.\n from(mermaidImport)\n .pipe(takeUntilDestroyed())\n .subscribe((mermaid) => {\n this.mermaid = mermaid;\n this.mermaid.default.initialize({ startOnLoad: false });\n // Explicitly running mermaid as ngAfterViewChecked\n // has probably already been called\n this.mermaid?.default.run();\n }),\n );\n }\n}\n"],"mappings":"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"}