@analogjs/content 3.0.0-alpha.2 → 3.0.0-alpha.21
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/LICENSE +21 -0
- package/fesm2022/analogjs-content-md4x.mjs +290 -0
- package/fesm2022/analogjs-content-md4x.mjs.map +1 -0
- package/fesm2022/analogjs-content-mdc.mjs +170 -0
- package/fesm2022/analogjs-content-mdc.mjs.map +1 -0
- package/fesm2022/analogjs-content-og.mjs +34 -46
- package/fesm2022/analogjs-content-og.mjs.map +1 -1
- package/fesm2022/analogjs-content-prism-highlighter.mjs +81 -68
- package/fesm2022/analogjs-content-prism-highlighter.mjs.map +1 -1
- package/fesm2022/analogjs-content-resources.mjs +113 -124
- package/fesm2022/analogjs-content-resources.mjs.map +1 -1
- package/fesm2022/analogjs-content-shiki-highlighter.mjs +9 -14
- package/fesm2022/analogjs-content-shiki-highlighter.mjs.map +1 -1
- package/fesm2022/analogjs-content.mjs +658 -636
- package/fesm2022/analogjs-content.mjs.map +1 -1
- package/fesm2022/content-list-loader.mjs +284 -0
- package/fesm2022/content-list-loader.mjs.map +1 -0
- package/md4x/package.json +4 -0
- package/mdc/package.json +4 -0
- package/og/package.json +2 -2
- package/package.json +67 -38
- package/plugin/package.json +2 -22
- package/plugin/src/index.d.ts +4 -2
- package/plugin/src/index.js +6 -3
- package/plugin/src/index.js.map +1 -1
- package/plugin/src/migrations/update-markdown-version/compat.d.ts +6 -2
- package/plugin/src/migrations/update-markdown-version/compat.js +8 -5
- package/plugin/src/migrations/update-markdown-version/compat.js.map +1 -1
- package/plugin/src/migrations/update-markdown-version/update-markdown-version.d.ts +6 -2
- package/plugin/src/migrations/update-markdown-version/update-markdown-version.js +18 -20
- package/plugin/src/migrations/update-markdown-version/update-markdown-version.js.map +1 -1
- package/prism-highlighter/package.json +2 -2
- package/resources/package.json +2 -2
- package/shiki-highlighter/package.json +2 -2
- package/src/lib/devtools/content-devtools-client.ts +215 -0
- package/src/lib/devtools/content-devtools.styles.css +194 -0
- package/types/md4x/src/index.d.ts +5 -0
- package/types/md4x/src/lib/md4x-content-renderer.service.d.ts +33 -0
- package/types/md4x/src/lib/md4x-wasm-content-renderer.service.d.ts +16 -0
- package/types/md4x/src/lib/provide-md4x.d.ts +26 -0
- package/types/md4x/src/lib/streaming-markdown-renderer.d.ts +21 -0
- package/types/mdc/src/index.d.ts +2 -0
- package/types/mdc/src/lib/mdc-component-registry.d.ts +25 -0
- package/types/mdc/src/lib/mdc-renderer.directive.d.ts +33 -0
- package/types/og/src/index.d.ts +2 -0
- package/types/og/src/lib/og.d.ts +5 -0
- package/types/og/src/lib/options.d.ts +11 -0
- package/types/prism-highlighter/src/index.d.ts +8 -0
- package/types/prism-highlighter/src/lib/prism/angular.d.ts +1 -0
- package/types/prism-highlighter/src/lib/prism-highlighter.d.ts +8 -0
- package/types/resources/src/content-file-resource.d.ts +39 -0
- package/types/resources/src/content-files-resource.d.ts +3 -0
- package/types/resources/src/index.d.ts +2 -0
- package/types/shiki-highlighter/src/index.d.ts +7 -0
- package/types/src/index.d.ts +18 -0
- package/types/src/lib/anchor-navigation.directive.d.ts +9 -0
- package/types/src/lib/content-file-loader.d.ts +6 -0
- package/types/src/lib/content-file.d.ts +8 -0
- package/types/src/lib/content-files-list-token.d.ts +3 -0
- package/types/src/lib/content-files-token.d.ts +3 -0
- package/types/src/lib/content-list-loader.d.ts +7 -0
- package/types/src/lib/content-renderer.d.ts +33 -0
- package/types/src/lib/content.d.ts +14 -0
- package/types/src/lib/devtools/content-devtools-plugin.d.ts +23 -0
- package/types/src/lib/devtools/content-devtools-renderer.d.ts +23 -0
- package/types/src/lib/devtools/index.d.ts +23 -0
- package/types/src/lib/get-content-files.d.ts +14 -0
- package/types/src/lib/inject-content-files.d.ts +4 -0
- package/types/src/lib/markdown-content-renderer.service.d.ts +10 -0
- package/types/src/lib/markdown-route.component.d.ts +15 -0
- package/types/src/lib/markdown.component.d.ts +26 -0
- package/types/src/lib/marked-content-highlighter.d.ts +17 -0
- package/types/src/lib/marked-setup.service.d.ts +10 -0
- package/types/src/lib/parse-raw-content-file.d.ts +18 -0
- package/types/src/lib/provide-content.d.ts +7 -0
- package/types/src/lib/render-task.service.d.ts +8 -0
- package/types/src/lib/utils/zone-wait-for.d.ts +2 -0
- package/og/README.md +0 -3
- package/plugin/README.md +0 -11
- package/plugin/src/migrations/update-markdown-renderer-feature/compat.d.ts +0 -2
- package/plugin/src/migrations/update-markdown-renderer-feature/compat.js +0 -6
- package/plugin/src/migrations/update-markdown-renderer-feature/compat.js.map +0 -1
- package/plugin/src/migrations/update-markdown-renderer-feature/update-markdown-renderer-feature.d.ts +0 -2
- package/plugin/src/migrations/update-markdown-renderer-feature/update-markdown-renderer-feature.js +0 -48
- package/plugin/src/migrations/update-markdown-renderer-feature/update-markdown-renderer-feature.js.map +0 -1
- package/prism-highlighter/README.md +0 -3
- package/resources/README.md +0 -3
- package/shiki-highlighter/README.md +0 -3
- package/types/analogjs-content-og.d.ts +0 -19
- package/types/analogjs-content-prism-highlighter.d.ts +0 -15
- package/types/analogjs-content-resources.d.ts +0 -20
- package/types/analogjs-content-shiki-highlighter.d.ts +0 -11
- package/types/analogjs-content.d.ts +0 -168
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analogjs-content.mjs","sources":["../../../../packages/content/src/lib/anchor-navigation.directive.ts","../../../../packages/content/src/lib/content-renderer.ts","../../../../packages/content/src/lib/get-content-files.ts","../../../../packages/content/src/lib/content-files-list-token.ts","../../../../packages/content/src/lib/content-files-token.ts","../../../../packages/content/src/lib/parse-raw-content-file.ts","../../../../packages/content/src/lib/utils/zone-wait-for.ts","../../../../packages/content/src/lib/render-task.service.ts","../../../../packages/content/src/lib/content.ts","../../../../packages/content/src/lib/inject-content-files.ts","../../../../packages/content/src/lib/marked-content-highlighter.ts","../../../../packages/content/src/lib/marked-setup.service.ts","../../../../packages/content/src/lib/markdown-content-renderer.service.ts","../../../../packages/content/src/lib/content-file-loader.ts","../../../../packages/content/src/lib/content-list-loader.ts","../../../../packages/content/src/lib/provide-content.ts","../../../../packages/content/src/lib/markdown-route.component.ts","../../../../packages/content/src/lib/markdown.component.ts","../../../../packages/content/src/analogjs-content.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","/// <reference types=\"vite/client\" />\n\nimport { Injectable, TransferState, inject, makeStateKey } from '@angular/core';\n\nexport type TableOfContentItem = {\n id: string;\n level: number; // starts at 1\n text: string;\n};\n\nexport type RenderedContent = {\n content: string;\n toc: TableOfContentItem[];\n};\n\n@Injectable()\nexport abstract class ContentRenderer {\n async render(content: string): Promise<RenderedContent> {\n return { content, toc: [] };\n }\n\n // Backward-compatible API for consumers that read headings directly.\n getContentHeadings(_content: string): TableOfContentItem[] {\n return [];\n }\n\n // eslint-disable-next-line\n enhance() {}\n}\n\nexport class NoopContentRenderer implements ContentRenderer {\n private readonly transferState = inject(TransferState);\n private contentId = 0;\n\n /**\n * Generates a hash from the content string\n * to be used with the transfer state\n */\n private generateHash(str: string) {\n let hash = 0;\n for (let i = 0, len = str.length; i < len; i++) {\n let chr = str.charCodeAt(i);\n hash = (hash << 5) - hash + chr;\n hash |= 0; // Convert to 32bit integer\n }\n return hash;\n }\n\n async render(content: string): Promise<RenderedContent> {\n this.contentId = this.generateHash(content);\n const toc = this.getContentHeadings(content);\n const key = makeStateKey<TableOfContentItem[]>(\n `content-headings-${this.contentId}`,\n );\n\n if (import.meta.env.SSR === true) {\n this.transferState.set(key, toc);\n return { content, toc };\n }\n\n return {\n content,\n toc: this.transferState.get(key, toc),\n };\n }\n enhance() {}\n\n getContentHeadings(content: string): TableOfContentItem[] {\n return this.extractHeadings(content);\n }\n\n private extractHeadings(content: string): TableOfContentItem[] {\n const markdownHeadings = this.extractHeadingsFromMarkdown(content);\n if (markdownHeadings.length > 0) {\n return markdownHeadings;\n }\n\n const htmlHeadings = this.extractHeadingsFromHtml(content);\n return htmlHeadings;\n }\n\n private extractHeadingsFromMarkdown(content: string): TableOfContentItem[] {\n const lines = content.split('\\n');\n const toc: TableOfContentItem[] = [];\n const slugCounts = new Map<string, number>();\n\n for (const line of lines) {\n const match = /^(#{1,6})\\s+(.+?)\\s*$/.exec(line);\n if (!match) {\n continue;\n }\n\n const level = match[1].length;\n const text = match[2].trim();\n if (!text) {\n continue;\n }\n\n const baseSlug = text\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, '')\n .trim()\n .replace(/\\s+/g, '-');\n const count = slugCounts.get(baseSlug) ?? 0;\n slugCounts.set(baseSlug, count + 1);\n const id = count === 0 ? baseSlug : `${baseSlug}-${count}`;\n\n toc.push({ id, level, text });\n }\n\n return toc;\n }\n\n private extractHeadingsFromHtml(content: string): TableOfContentItem[] {\n const toc: TableOfContentItem[] = [];\n const slugCounts = new Map<string, number>();\n const headingRegex = /<h([1-6])([^>]*)>([\\s\\S]*?)<\\/h\\1>/gi;\n\n for (const match of content.matchAll(headingRegex)) {\n const level = Number(match[1]);\n const attrs = match[2] ?? '';\n const rawInner = match[3] ?? '';\n const text = rawInner.replace(/<[^>]+>/g, '').trim();\n if (!text) {\n continue;\n }\n\n const idMatch =\n /\\sid=(['\"])(.*?)\\1/i.exec(attrs) ?? /\\sid=([^\\s>]+)/i.exec(attrs);\n let id = idMatch?.[2] ?? idMatch?.[1] ?? '';\n if (!id) {\n id = this.makeSlug(text, slugCounts);\n }\n\n toc.push({ id, level, text });\n }\n\n return toc;\n }\n\n private makeSlug(text: string, slugCounts: Map<string, number>): string {\n const baseSlug = text\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, '')\n .trim()\n .replace(/\\s+/g, '-');\n const count = slugCounts.get(baseSlug) ?? 0;\n slugCounts.set(baseSlug, count + 1);\n return count === 0 ? baseSlug : `${baseSlug}-${count}`;\n }\n}\n","/**\n * Returns the list of content files by filename with ?analog-content-list=true.\n * We use the query param to transform the return into an array of\n * just front matter attributes.\n *\n * @returns\n */\nexport const getContentFilesList = () => {\n let ANALOG_CONTENT_FILE_LIST = {};\n\n return ANALOG_CONTENT_FILE_LIST as Record<string, Record<string, any>>;\n};\n\n/**\n * Returns the lazy loaded content files for lookups.\n *\n * @returns\n */\nexport const getContentFiles = () => {\n let ANALOG_CONTENT_ROUTE_FILES = {};\n\n return ANALOG_CONTENT_ROUTE_FILES;\n};\n","import { InjectionToken } from '@angular/core';\nimport { ContentFile } from './content-file';\nimport { getContentFilesList } from './get-content-files';\n\nfunction getSlug(filename: string) {\n // Extract the last path segment without its extension.\n // Handles names with dots like [[...slug]].md by stripping only the final extension.\n const lastSegment = (filename.split(/[/\\\\]/).pop() || '').trim();\n const base = lastSegment.replace(/\\.[^./\\\\]+$/, ''); // strip only the final extension\n // Treat index.md as index route => empty slug\n return base === 'index' ? '' : base;\n}\n\nexport const CONTENT_FILES_LIST_TOKEN = new InjectionToken<ContentFile[]>(\n '@analogjs/content Content Files List',\n {\n providedIn: 'root',\n factory() {\n const contentFiles = getContentFilesList();\n\n return Object.keys(contentFiles).map((filename) => {\n const attributes = contentFiles[filename];\n const slug = attributes['slug'];\n\n return {\n filename,\n attributes,\n slug: slug ? encodeURI(slug) : encodeURI(getSlug(filename)),\n };\n });\n },\n },\n);\n","import { InjectionToken, Signal, inject, signal } from '@angular/core';\n\nimport { getContentFiles } from './get-content-files';\nimport { CONTENT_FILES_LIST_TOKEN } from './content-files-list-token';\n\nexport const CONTENT_FILES_TOKEN = new InjectionToken<\n Record<string, () => Promise<string>>\n>('@analogjs/content Content Files', {\n providedIn: 'root',\n factory() {\n const contentFiles = getContentFiles();\n const allFiles = { ...contentFiles };\n const contentFilesList = inject(CONTENT_FILES_LIST_TOKEN);\n\n const lookup: Record<string, string> = {};\n contentFilesList.forEach((item) => {\n const contentFilename = item.filename.replace(\n /(.*?)\\/content/,\n '/src/content',\n );\n const fileParts = contentFilename.split('/');\n const filePath = fileParts.slice(0, fileParts.length - 1).join('/');\n const fileNameParts = fileParts[fileParts.length - 1].split('.');\n const ext = fileNameParts[fileNameParts.length - 1];\n let slug = (item.slug ?? '') as string;\n // Default empty slug to 'index'\n if (slug === '') {\n slug = 'index';\n }\n // If slug contains path separators, treat it as root-relative to /src/content\n const newBase = slug.includes('/')\n ? `/src/content/${slug}`\n : `${filePath}/${slug}`;\n lookup[contentFilename] = `${newBase}.${ext}`.replace(/\\/{2,}/g, '/');\n });\n\n const objectUsingSlugAttribute: Record<string, () => Promise<string>> = {};\n Object.entries(allFiles).forEach((entry) => {\n const filename = entry[0];\n const value = entry[1];\n const strippedFilename = filename.replace(\n /^\\/(.*?)\\/content/,\n '/src/content',\n );\n\n const newFilename = lookup[strippedFilename];\n if (newFilename !== undefined) {\n const objectFilename = newFilename.replace(\n /^\\/(.*?)\\/content/,\n '/src/content',\n );\n objectUsingSlugAttribute[objectFilename] =\n value as () => Promise<string>;\n }\n });\n\n return objectUsingSlugAttribute;\n },\n});\n\nexport const CONTENT_FILES_MAP_TOKEN = new InjectionToken<\n Signal<Record<string, () => Promise<string>>>\n>('@analogjs/content Content Files', {\n providedIn: 'root',\n factory() {\n return signal(inject(CONTENT_FILES_TOKEN));\n },\n});\n","import fm from 'front-matter';\n\nexport function parseRawContentFile<Attributes extends Record<string, any>>(\n rawContentFile: string,\n): { content: string; attributes: Attributes } {\n const { body, attributes } = fm<Attributes>(rawContentFile);\n return { content: body, attributes };\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 {},\n () => {},\n );\n return prom.then((p: T) => {\n macroTask.invoke();\n return p;\n });\n}\n","import { Injectable, inject } from '@angular/core';\nimport { ɵPendingTasksInternal as ɵPendingTasks } from '@angular/core';\n\n@Injectable()\nexport class RenderTaskService {\n #pendingTasks = inject(ɵPendingTasks);\n\n addRenderTask() {\n return this.#pendingTasks.add();\n }\n\n clearRenderTask(clear: number | Function) {\n if (typeof clear === 'function') {\n clear();\n } else if (typeof (this.#pendingTasks as any).remove === 'function') {\n (this.#pendingTasks as any).remove(clear);\n }\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_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): 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 = [\n `${base}.md`,\n `${base}.agx`,\n `${base}/index.md`,\n `${base}/index.agx`,\n ];\n\n const matchKey = candidates.find((k) => k in normalizedFiles);\n const contentFile = matchKey ? normalizedFiles[matchKey] : undefined;\n const resolvedBase = (matchKey || `${base}.md`).replace(/\\.(md|agx)$/, '');\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: any; metadata: any }>(\n (observer) => {\n const contentResolver = contentFile();\n\n if (import.meta.env.SSR === true) {\n waitFor(contentResolver).then((content) => {\n observer.next(content);\n observer.complete();\n\n setTimeout(() => renderTaskService.clearRenderTask(contentTask), 10);\n });\n } else {\n contentResolver.then((content) => {\n observer.next(content);\n observer.complete();\n });\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 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 );\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 ).pipe(tap(() => renderTaskService.clearRenderTask(task)));\n }\n}\n","import { inject } from '@angular/core';\n\nimport { ContentFile } from './content-file';\nimport { CONTENT_FILES_LIST_TOKEN } from './content-files-list-token';\nimport { CONTENT_FILES_TOKEN } from './content-files-token';\nimport { RenderTaskService } from './render-task.service';\n\nexport function injectContentFiles<Attributes extends Record<string, any>>(\n filterFn?: InjectContentFilesFilterFunction<Attributes>,\n): ContentFile<Attributes>[] {\n const renderTaskService = inject(RenderTaskService);\n const task = renderTaskService.addRenderTask();\n const allContentFiles = inject(\n CONTENT_FILES_LIST_TOKEN,\n ) as ContentFile<Attributes>[];\n renderTaskService.clearRenderTask(task);\n\n if (filterFn) {\n const filteredContentFiles = allContentFiles.filter(filterFn);\n\n return filteredContentFiles;\n }\n\n return allContentFiles;\n}\n\nexport type InjectContentFilesFilterFunction<T extends Record<string, any>> = (\n value: ContentFile<T>,\n index: number,\n array: ContentFile<T>[],\n) => boolean;\n\nexport function injectContentFilesMap() {\n return inject(CONTENT_FILES_TOKEN);\n}\n","import {\n AbstractType,\n Injectable,\n Provider,\n ProviderToken,\n Type,\n} from '@angular/core';\n\nexport interface MarkedContentHighlighter {\n augmentCodeBlock?(code: string, lang: string): string;\n}\n\n@Injectable()\nexport abstract class MarkedContentHighlighter {\n abstract getHighlightExtension(): import('marked').MarkedExtension;\n}\n\nexport function withHighlighter(\n provider: (\n | { useValue: MarkedContentHighlighter }\n | {\n useClass:\n | Type<MarkedContentHighlighter>\n | AbstractType<MarkedContentHighlighter>;\n }\n | { useFactory: (...deps: any[]) => MarkedContentHighlighter }\n ) & { deps?: ProviderToken<any>[] },\n): Provider {\n return { provide: MarkedContentHighlighter, ...provider } as Provider;\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() {}\n}\n","import { InjectionToken, Provider } from '@angular/core';\nimport { inject } from '@angular/core';\n\nimport { injectContentFilesMap } from './inject-content-files';\n\ntype ContentFileLoaderFunction = () => Promise<\n Record<string, () => Promise<string>>\n>;\n\nexport const CONTENT_FILE_LOADER =\n new InjectionToken<ContentFileLoaderFunction>(\n '@analogjs/content/resource File Loader',\n );\n\nexport function injectContentFileLoader() {\n return inject(CONTENT_FILE_LOADER) as ContentFileLoaderFunction;\n}\n\nexport function withContentFileLoader(): Provider {\n return {\n provide: CONTENT_FILE_LOADER,\n useFactory() {\n return async () => injectContentFilesMap();\n },\n };\n}\n","import { InjectionToken, Provider } from '@angular/core';\nimport { inject } from '@angular/core';\n\nimport { ContentFile } from './content-file';\nimport { injectContentFiles } from './inject-content-files';\n\ntype ContentListLoaderFunction<Attributes extends Record<string, any>> =\n () => Promise<ContentFile<Attributes>[]>;\n\nexport const CONTENT_LIST_LOADER = new InjectionToken<\n ContentListLoaderFunction<any>\n>('@analogjs/content/resource List Loader');\n\nexport function injectContentListLoader<\n Attributes extends Record<string, any>,\n>() {\n return inject(CONTENT_LIST_LOADER) as ContentListLoaderFunction<Attributes>;\n}\n\nexport function withContentListLoader(): Provider {\n return {\n provide: CONTENT_LIST_LOADER,\n useFactory() {\n return async () => injectContentFiles();\n },\n };\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[]) {\n return [\n { provide: RenderTaskService, useClass: RenderTaskService },\n ...features,\n ];\n}\n\nexport const MERMAID_IMPORT_TOKEN = new InjectionToken<\n Promise<typeof import('mermaid')>\n>('mermaid_import');\n","import { AsyncPipe } from '@angular/common';\nimport {\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: [AsyncPipe],\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 = 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() {\n this.contentRenderer.enhance();\n }\n}\n","import { isPlatformBrowser } from '@angular/common';\nimport {\n AfterViewChecked,\n Component,\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, 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 = 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 = input<string | object | null>();\n readonly classes = input('analog-markdown');\n\n 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() {\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() {\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","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["ɵPendingTasks"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"analogjs-content.mjs","names":["#marked"],"sources":["../../src/lib/anchor-navigation.directive.ts","../../src/lib/parse-raw-content-file.ts","../../src/lib/content.ts","../../src/lib/marked-content-highlighter.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","../../src/lib/devtools/content-devtools-renderer.ts","../../../../__vite-browser-external","../../src/lib/devtools/content-devtools-plugin.ts","../../src/lib/devtools/index.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 type { StandardSchemaV1 } from '@standard-schema/spec';\nimport fm from 'front-matter';\n\nexport class FrontmatterValidationError extends Error {\n constructor(\n public readonly issues: ReadonlyArray<StandardSchemaV1.Issue>,\n public readonly filename?: string,\n ) {\n const issueMessages = issues\n .map((i) => {\n const path = i.path\n ? ` at \"${i.path.map((p) => (typeof p === 'object' ? p.key : p)).join('.')}\"`\n : '';\n return ` - ${i.message}${path}`;\n })\n .join('\\n');\n const prefix = filename ? `\"${filename}\" f` : 'F';\n super(`${prefix}rontmatter validation failed:\\n${issueMessages}`);\n this.name = 'FrontmatterValidationError';\n }\n}\n\nexport function parseRawContentFile<\n Attributes extends Record<string, any> = Record<string, any>,\n>(rawContentFile: string): { content: string; attributes: Attributes };\n\nexport function parseRawContentFile<TSchema extends StandardSchemaV1>(\n rawContentFile: string,\n schema: TSchema,\n filename?: string,\n): { content: string; attributes: StandardSchemaV1.InferOutput<TSchema> };\n\nexport function parseRawContentFile(\n rawContentFile: string,\n schema?: StandardSchemaV1,\n filename?: string,\n): { content: string; attributes: unknown } {\n const { body, attributes } = fm(rawContentFile);\n\n if (schema) {\n const result = schema['~standard'].validate(attributes);\n if (\n result != null &&\n typeof (result as PromiseLike<unknown>).then === 'function'\n ) {\n throw new Error(\n 'parseRawContentFile does not support async schema validation. ' +\n 'Use parseRawContentFileAsync() for async schemas.',\n );\n }\n const syncResult = result as StandardSchemaV1.Result<\n StandardSchemaV1.InferOutput<typeof schema>\n >;\n if (syncResult.issues) {\n throw new FrontmatterValidationError(syncResult.issues, filename);\n }\n return { content: body, attributes: syncResult.value };\n }\n\n return { content: body, attributes };\n}\n\nexport async function parseRawContentFileAsync<\n TSchema extends StandardSchemaV1,\n>(\n rawContentFile: string,\n schema: TSchema,\n filename?: string,\n): Promise<{\n content: string;\n attributes: StandardSchemaV1.InferOutput<TSchema>;\n}> {\n const { body, attributes } = fm(rawContentFile);\n const result = await schema['~standard'].validate(attributes);\n if (result.issues) {\n throw new FrontmatterValidationError(result.issues, filename);\n }\n return { content: body, attributes: result.value };\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_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): 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 matchKey = candidates.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 const contentResolver = contentFile();\n\n if (import.meta.env.SSR === true) {\n waitFor(contentResolver).then((content) => {\n observer.next(content);\n observer.complete();\n\n setTimeout(() => renderTaskService.clearRenderTask(contentTask), 10);\n });\n } else {\n contentResolver.then((content) => {\n observer.next(content);\n observer.complete();\n });\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 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 );\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 ).pipe(tap(() => renderTaskService.clearRenderTask(task)));\n }\n}\n","import {\n AbstractType,\n Injectable,\n Provider,\n ProviderToken,\n Type,\n} from '@angular/core';\n\n@Injectable()\nexport abstract class MarkedContentHighlighter {\n augmentCodeBlock?(code: string, lang: string): string;\n abstract getHighlightExtension(): import('marked').MarkedExtension;\n}\n\nexport function withHighlighter(\n provider: (\n | { useValue: MarkedContentHighlighter }\n | {\n useClass:\n | Type<MarkedContentHighlighter>\n | AbstractType<MarkedContentHighlighter>;\n }\n | { useFactory: (...deps: any[]) => MarkedContentHighlighter }\n ) & { deps?: ProviderToken<any>[] },\n): Provider {\n return { provide: MarkedContentHighlighter, ...provider } as Provider;\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","import { Injectable, InjectionToken, inject } from '@angular/core';\n\nimport {\n ContentRenderer,\n RenderedContent,\n TableOfContentItem,\n} from '../content-renderer';\n\n/**\n * Token for the wrapped renderer that DevTools delegates to.\n * @internal\n */\nexport const DEVTOOLS_INNER_RENDERER: InjectionToken<ContentRenderer> =\n new InjectionToken<ContentRenderer>('devtools_inner_renderer');\n\n/**\n * Wraps an existing ContentRenderer to collect timing and metadata for the\n * Content DevTools panel. Dispatches a custom event on the window after\n * each render so the devtools client can update.\n *\n * @experimental Content DevTools is experimental and may change in future releases.\n */\n@Injectable()\nexport class DevToolsContentRenderer extends ContentRenderer {\n private readonly inner = inject(DEVTOOLS_INNER_RENDERER);\n\n override async render(content: string): Promise<RenderedContent> {\n const start = performance.now();\n const result = await this.inner.render(content);\n const elapsed = performance.now() - start;\n\n if (typeof window !== 'undefined') {\n window.dispatchEvent(\n new CustomEvent('analog-content-devtools-data', {\n detail: {\n renderer: this.inner.constructor.name,\n renderTimeMs: elapsed,\n toc: result.toc,\n contentLength: content.length,\n headingCount: result.toc.length,\n frontmatter: {},\n },\n }),\n );\n }\n\n return result;\n }\n\n override getContentHeadings(content: string): TableOfContentItem[] {\n return this.inner.getContentHeadings(content);\n }\n\n override enhance(): void {\n this.inner.enhance();\n }\n}\n","module.exports = {}","import { readFileSync } from 'node:fs';\nimport { resolve, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport type { Plugin } from 'vite';\nimport { transformWithOxc } from 'vite';\n\n/**\n * Vite plugin that injects the Analog Content DevTools panel in dev mode.\n *\n * Shows render time, frontmatter data, TOC, and content stats in a floating\n * panel. Dev-only — completely stripped from production builds.\n *\n * @experimental Content DevTools is experimental and may change in future releases.\n *\n * @example\n * ```typescript\n * // vite.config.ts\n * import { contentDevToolsPlugin } from '@analogjs/content/devtools';\n *\n * export default defineConfig({\n * plugins: [\n * analog({ ... }),\n * contentDevToolsPlugin(),\n * ],\n * });\n * ```\n */\nexport function contentDevToolsPlugin(): Plugin {\n let isDev = false;\n\n return {\n name: 'analog-content-devtools',\n apply: 'serve',\n\n configResolved(config) {\n isDev = config.command === 'serve';\n },\n\n transformIndexHtml: {\n order: 'post',\n async handler(html) {\n if (!isDev) return html;\n\n const pluginDir = dirname(fileURLToPath(import.meta.url));\n const cssPath = resolve(pluginDir, 'content-devtools.styles.css');\n const clientPath = resolve(pluginDir, 'content-devtools-client.ts');\n\n let css: string;\n let clientCode: string;\n try {\n css = readFileSync(cssPath, 'utf-8');\n clientCode = readFileSync(clientPath, 'utf-8');\n } catch {\n // Fallback: files may not exist if running from compiled output.\n // The plugin silently degrades — no devtools panel.\n return html;\n }\n\n const transformResult = await transformWithOxc(\n clientCode,\n 'content-devtools-client.ts',\n { lang: 'ts' },\n );\n\n const injection = `\n<style>${css}</style>\n<script type=\"module\">${transformResult.code}</script>`;\n\n return html.replace('</body>', `${injection}\\n</body>`);\n },\n },\n };\n}\n","import { Provider, Type } from '@angular/core';\nimport { ContentRenderer } from '../content-renderer';\nimport {\n DevToolsContentRenderer,\n DEVTOOLS_INNER_RENDERER,\n} from './content-devtools-renderer';\n\nexport { contentDevToolsPlugin } from './content-devtools-plugin';\nexport {\n DevToolsContentRenderer,\n DEVTOOLS_INNER_RENDERER,\n} from './content-devtools-renderer';\n\n/**\n * Wraps the given ContentRenderer with DevTools instrumentation.\n *\n * The supplied renderer class is provided under DEVTOOLS_INNER_RENDERER and\n * DevToolsContentRenderer becomes the new ContentRenderer, delegating\n * all calls and collecting timing data.\n *\n * @param innerRenderer The renderer class to wrap with devtools instrumentation.\n *\n * @experimental Content DevTools is experimental and may change in future releases.\n *\n * @example\n * ```typescript\n * provideContent(\n * withContentDevTools(NoopContentRenderer),\n * );\n * ```\n */\nexport function withContentDevTools(\n innerRenderer: Type<ContentRenderer>,\n): Provider {\n return [\n {\n provide: DEVTOOLS_INNER_RENDERER,\n useClass: innerRenderer,\n },\n {\n provide: ContentRenderer,\n useClass: DevToolsContentRenderer,\n },\n ];\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { Injectable, InjectionToken, TransferState, inject, makeStateKey, signal, ɵPendingTasksInternal } from "@angular/core";
|
|
3
|
+
//#region packages/content/src/lib/content-renderer.ts
|
|
4
|
+
var ContentRenderer = class ContentRenderer {
|
|
5
|
+
async render(content) {
|
|
6
|
+
return {
|
|
7
|
+
content,
|
|
8
|
+
toc: []
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
getContentHeadings(_content) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
enhance() {}
|
|
15
|
+
static {
|
|
16
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
17
|
+
minVersion: "12.0.0",
|
|
18
|
+
version: "21.2.6",
|
|
19
|
+
ngImport: i0,
|
|
20
|
+
type: ContentRenderer,
|
|
21
|
+
deps: [],
|
|
22
|
+
target: i0.ɵɵFactoryTarget.Injectable
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
static {
|
|
26
|
+
this.ɵprov = i0.ɵɵngDeclareInjectable({
|
|
27
|
+
minVersion: "12.0.0",
|
|
28
|
+
version: "21.2.6",
|
|
29
|
+
ngImport: i0,
|
|
30
|
+
type: ContentRenderer
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
35
|
+
minVersion: "12.0.0",
|
|
36
|
+
version: "21.2.6",
|
|
37
|
+
ngImport: i0,
|
|
38
|
+
type: ContentRenderer,
|
|
39
|
+
decorators: [{ type: Injectable }]
|
|
40
|
+
});
|
|
41
|
+
var NoopContentRenderer = class {
|
|
42
|
+
constructor() {
|
|
43
|
+
this.transferState = inject(TransferState);
|
|
44
|
+
this.contentId = 0;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Generates a hash from the content string
|
|
48
|
+
* to be used with the transfer state
|
|
49
|
+
*/
|
|
50
|
+
generateHash(str) {
|
|
51
|
+
let hash = 0;
|
|
52
|
+
for (let i = 0, len = str.length; i < len; i++) {
|
|
53
|
+
const chr = str.charCodeAt(i);
|
|
54
|
+
hash = (hash << 5) - hash + chr;
|
|
55
|
+
hash |= 0;
|
|
56
|
+
}
|
|
57
|
+
return hash;
|
|
58
|
+
}
|
|
59
|
+
async render(content) {
|
|
60
|
+
this.contentId = this.generateHash(content);
|
|
61
|
+
const toc = this.getContentHeadings(content);
|
|
62
|
+
const key = makeStateKey(`content-headings-${this.contentId}`);
|
|
63
|
+
return {
|
|
64
|
+
content,
|
|
65
|
+
toc: this.transferState.get(key, toc)
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
enhance() {}
|
|
69
|
+
getContentHeadings(content) {
|
|
70
|
+
return this.extractHeadings(content);
|
|
71
|
+
}
|
|
72
|
+
extractHeadings(content) {
|
|
73
|
+
const markdownHeadings = this.extractHeadingsFromMarkdown(content);
|
|
74
|
+
if (markdownHeadings.length > 0) return markdownHeadings;
|
|
75
|
+
return this.extractHeadingsFromHtml(content);
|
|
76
|
+
}
|
|
77
|
+
extractHeadingsFromMarkdown(content) {
|
|
78
|
+
const lines = content.split("\n");
|
|
79
|
+
const toc = [];
|
|
80
|
+
const slugCounts = /* @__PURE__ */ new Map();
|
|
81
|
+
for (const line of lines) {
|
|
82
|
+
const match = /^(#{1,6})\s+(.+?)\s*$/.exec(line);
|
|
83
|
+
if (!match) continue;
|
|
84
|
+
const level = match[1].length;
|
|
85
|
+
const text = match[2].trim();
|
|
86
|
+
if (!text) continue;
|
|
87
|
+
const baseSlug = text.toLowerCase().replace(/[^\w\s-]/g, "").trim().replace(/\s+/g, "-");
|
|
88
|
+
const count = slugCounts.get(baseSlug) ?? 0;
|
|
89
|
+
slugCounts.set(baseSlug, count + 1);
|
|
90
|
+
const id = count === 0 ? baseSlug : `${baseSlug}-${count}`;
|
|
91
|
+
toc.push({
|
|
92
|
+
id,
|
|
93
|
+
level,
|
|
94
|
+
text
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
return toc;
|
|
98
|
+
}
|
|
99
|
+
extractHeadingsFromHtml(content) {
|
|
100
|
+
const toc = [];
|
|
101
|
+
const slugCounts = /* @__PURE__ */ new Map();
|
|
102
|
+
for (const match of content.matchAll(/<h([1-6])([^>]*)>([\s\S]*?)<\/h\1>/gi)) {
|
|
103
|
+
const level = Number(match[1]);
|
|
104
|
+
const attrs = match[2] ?? "";
|
|
105
|
+
const text = (match[3] ?? "").replace(/<[^>]+>/g, "").trim();
|
|
106
|
+
if (!text) continue;
|
|
107
|
+
const idMatch = /\sid=(['"])(.*?)\1/i.exec(attrs) ?? /\sid=([^\s>]+)/i.exec(attrs);
|
|
108
|
+
let id = idMatch?.[2] ?? idMatch?.[1] ?? "";
|
|
109
|
+
if (!id) id = this.makeSlug(text, slugCounts);
|
|
110
|
+
toc.push({
|
|
111
|
+
id,
|
|
112
|
+
level,
|
|
113
|
+
text
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return toc;
|
|
117
|
+
}
|
|
118
|
+
makeSlug(text, slugCounts) {
|
|
119
|
+
const baseSlug = text.toLowerCase().replace(/[^\w\s-]/g, "").trim().replace(/\s+/g, "-");
|
|
120
|
+
const count = slugCounts.get(baseSlug) ?? 0;
|
|
121
|
+
slugCounts.set(baseSlug, count + 1);
|
|
122
|
+
return count === 0 ? baseSlug : `${baseSlug}-${count}`;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
//#endregion
|
|
126
|
+
//#region packages/content/src/lib/get-content-files.ts
|
|
127
|
+
/**
|
|
128
|
+
* Returns the list of content files by filename with ?analog-content-list=true.
|
|
129
|
+
* We use the query param to transform the return into an array of
|
|
130
|
+
* just front matter attributes.
|
|
131
|
+
*
|
|
132
|
+
* @returns
|
|
133
|
+
*/
|
|
134
|
+
var getContentFilesList = () => {
|
|
135
|
+
return {};
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* Returns the lazy loaded content files for lookups.
|
|
139
|
+
*
|
|
140
|
+
* @returns
|
|
141
|
+
*/
|
|
142
|
+
var getContentFiles = () => {
|
|
143
|
+
return {};
|
|
144
|
+
};
|
|
145
|
+
//#endregion
|
|
146
|
+
//#region packages/content/src/lib/content-files-list-token.ts
|
|
147
|
+
function getSlug(filename) {
|
|
148
|
+
const base = (filename.split(/[/\\]/).pop() || "").trim().replace(/\.[^./\\]+$/, "");
|
|
149
|
+
return base === "index" ? "" : base;
|
|
150
|
+
}
|
|
151
|
+
var CONTENT_FILES_LIST_TOKEN = new InjectionToken("@analogjs/content Content Files List", {
|
|
152
|
+
providedIn: "root",
|
|
153
|
+
factory() {
|
|
154
|
+
const contentFiles = getContentFilesList();
|
|
155
|
+
return Object.keys(contentFiles).map((filename) => {
|
|
156
|
+
const attributes = contentFiles[filename];
|
|
157
|
+
const slug = attributes["slug"];
|
|
158
|
+
return {
|
|
159
|
+
filename,
|
|
160
|
+
attributes,
|
|
161
|
+
slug: slug ? encodeURI(slug) : encodeURI(getSlug(filename))
|
|
162
|
+
};
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
//#endregion
|
|
167
|
+
//#region packages/content/src/lib/content-files-token.ts
|
|
168
|
+
var CONTENT_FILES_TOKEN = new InjectionToken("@analogjs/content Content Files", {
|
|
169
|
+
providedIn: "root",
|
|
170
|
+
factory() {
|
|
171
|
+
const allFiles = { ...getContentFiles() };
|
|
172
|
+
const contentFilesList = inject(CONTENT_FILES_LIST_TOKEN);
|
|
173
|
+
const lookup = {};
|
|
174
|
+
contentFilesList.forEach((item) => {
|
|
175
|
+
const contentFilename = item.filename.replace(/(.*?)\/content/, "/src/content");
|
|
176
|
+
const fileParts = contentFilename.split("/");
|
|
177
|
+
const filePath = fileParts.slice(0, fileParts.length - 1).join("/");
|
|
178
|
+
const fileNameParts = fileParts[fileParts.length - 1].split(".");
|
|
179
|
+
const ext = fileNameParts[fileNameParts.length - 1];
|
|
180
|
+
let slug = item.slug ?? "";
|
|
181
|
+
if (slug === "") slug = "index";
|
|
182
|
+
lookup[contentFilename] = `${slug.includes("/") ? `/src/content/${slug}` : `${filePath}/${slug}`}.${ext}`.replace(/\/{2,}/g, "/");
|
|
183
|
+
});
|
|
184
|
+
const objectUsingSlugAttribute = {};
|
|
185
|
+
Object.entries(allFiles).forEach((entry) => {
|
|
186
|
+
const filename = entry[0];
|
|
187
|
+
const value = entry[1];
|
|
188
|
+
const newFilename = lookup[filename.replace(/^\/(.*?)\/content/, "/src/content")];
|
|
189
|
+
if (newFilename !== void 0) {
|
|
190
|
+
const objectFilename = newFilename.replace(/^\/(.*?)\/content/, "/src/content");
|
|
191
|
+
objectUsingSlugAttribute[objectFilename] = value;
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
return objectUsingSlugAttribute;
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
new InjectionToken("@analogjs/content Content Files", {
|
|
198
|
+
providedIn: "root",
|
|
199
|
+
factory() {
|
|
200
|
+
return signal(inject(CONTENT_FILES_TOKEN));
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
//#endregion
|
|
204
|
+
//#region packages/content/src/lib/render-task.service.ts
|
|
205
|
+
var RenderTaskService = class RenderTaskService {
|
|
206
|
+
#pendingTasks = inject(ɵPendingTasksInternal);
|
|
207
|
+
addRenderTask() {
|
|
208
|
+
return this.#pendingTasks.add();
|
|
209
|
+
}
|
|
210
|
+
clearRenderTask(clear) {
|
|
211
|
+
if (typeof clear === "function") clear();
|
|
212
|
+
else if (typeof this.#pendingTasks.remove === "function") this.#pendingTasks.remove(clear);
|
|
213
|
+
}
|
|
214
|
+
static {
|
|
215
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
216
|
+
minVersion: "12.0.0",
|
|
217
|
+
version: "21.2.6",
|
|
218
|
+
ngImport: i0,
|
|
219
|
+
type: RenderTaskService,
|
|
220
|
+
deps: [],
|
|
221
|
+
target: i0.ɵɵFactoryTarget.Injectable
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
static {
|
|
225
|
+
this.ɵprov = i0.ɵɵngDeclareInjectable({
|
|
226
|
+
minVersion: "12.0.0",
|
|
227
|
+
version: "21.2.6",
|
|
228
|
+
ngImport: i0,
|
|
229
|
+
type: RenderTaskService
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
234
|
+
minVersion: "12.0.0",
|
|
235
|
+
version: "21.2.6",
|
|
236
|
+
ngImport: i0,
|
|
237
|
+
type: RenderTaskService,
|
|
238
|
+
decorators: [{ type: Injectable }]
|
|
239
|
+
});
|
|
240
|
+
//#endregion
|
|
241
|
+
//#region packages/content/src/lib/inject-content-files.ts
|
|
242
|
+
function injectContentFiles(filterFn) {
|
|
243
|
+
const renderTaskService = inject(RenderTaskService);
|
|
244
|
+
const task = renderTaskService.addRenderTask();
|
|
245
|
+
const allContentFiles = inject(CONTENT_FILES_LIST_TOKEN);
|
|
246
|
+
renderTaskService.clearRenderTask(task);
|
|
247
|
+
if (filterFn) return allContentFiles.filter(filterFn);
|
|
248
|
+
return allContentFiles;
|
|
249
|
+
}
|
|
250
|
+
function injectContentFilesMap() {
|
|
251
|
+
return inject(CONTENT_FILES_TOKEN);
|
|
252
|
+
}
|
|
253
|
+
//#endregion
|
|
254
|
+
//#region packages/content/src/lib/content-file-loader.ts
|
|
255
|
+
var CONTENT_FILE_LOADER = new InjectionToken("@analogjs/content/resource File Loader");
|
|
256
|
+
function injectContentFileLoader() {
|
|
257
|
+
return inject(CONTENT_FILE_LOADER);
|
|
258
|
+
}
|
|
259
|
+
function withContentFileLoader() {
|
|
260
|
+
return {
|
|
261
|
+
provide: CONTENT_FILE_LOADER,
|
|
262
|
+
useFactory() {
|
|
263
|
+
return async () => injectContentFilesMap();
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
//#endregion
|
|
268
|
+
//#region packages/content/src/lib/content-list-loader.ts
|
|
269
|
+
var CONTENT_LIST_LOADER = new InjectionToken("@analogjs/content/resource List Loader");
|
|
270
|
+
function injectContentListLoader() {
|
|
271
|
+
return inject(CONTENT_LIST_LOADER);
|
|
272
|
+
}
|
|
273
|
+
function withContentListLoader() {
|
|
274
|
+
return {
|
|
275
|
+
provide: CONTENT_LIST_LOADER,
|
|
276
|
+
useFactory() {
|
|
277
|
+
return async () => injectContentFiles();
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
//#endregion
|
|
282
|
+
export { injectContentFileLoader as a, injectContentFilesMap as c, ContentRenderer as d, NoopContentRenderer as f, CONTENT_FILE_LOADER as i, RenderTaskService as l, injectContentListLoader as n, withContentFileLoader as o, withContentListLoader as r, injectContentFiles as s, CONTENT_LIST_LOADER as t, CONTENT_FILES_TOKEN as u };
|
|
283
|
+
|
|
284
|
+
//# sourceMappingURL=content-list-loader.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-list-loader.mjs","names":["#pendingTasks"],"sources":["../../src/lib/content-renderer.ts","../../src/lib/get-content-files.ts","../../src/lib/content-files-list-token.ts","../../src/lib/content-files-token.ts","../../src/lib/render-task.service.ts","../../src/lib/inject-content-files.ts","../../src/lib/content-file-loader.ts","../../src/lib/content-list-loader.ts"],"sourcesContent":["/// <reference types=\"vite/client\" />\n\nimport { Injectable, TransferState, inject, makeStateKey } from '@angular/core';\n\nexport type TableOfContentItem = {\n id: string;\n level: number; // starts at 1\n text: string;\n};\n\nexport type RenderedContent = {\n content: string;\n toc: TableOfContentItem[];\n};\n\n@Injectable()\nexport abstract class ContentRenderer {\n async render(content: string): Promise<RenderedContent> {\n return { content, toc: [] };\n }\n\n // Backward-compatible API for consumers that read headings directly.\n getContentHeadings(_content: string): TableOfContentItem[] {\n return [];\n }\n\n // eslint-disable-next-line\n enhance(): void {}\n}\n\nexport class NoopContentRenderer implements ContentRenderer {\n private readonly transferState = inject(TransferState);\n private contentId = 0;\n\n /**\n * Generates a hash from the content string\n * to be used with the transfer state\n */\n private generateHash(str: string) {\n let hash = 0;\n for (let i = 0, len = str.length; i < len; i++) {\n const chr = str.charCodeAt(i);\n hash = (hash << 5) - hash + chr;\n hash |= 0; // Convert to 32bit integer\n }\n return hash;\n }\n\n async render(content: string): Promise<RenderedContent> {\n this.contentId = this.generateHash(content);\n const toc = this.getContentHeadings(content);\n const key = makeStateKey<TableOfContentItem[]>(\n `content-headings-${this.contentId}`,\n );\n\n if (import.meta.env.SSR === true) {\n this.transferState.set(key, toc);\n return { content, toc };\n }\n\n return {\n content,\n toc: this.transferState.get(key, toc),\n };\n }\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n enhance(): void {}\n\n getContentHeadings(content: string): TableOfContentItem[] {\n return this.extractHeadings(content);\n }\n\n private extractHeadings(content: string): TableOfContentItem[] {\n const markdownHeadings = this.extractHeadingsFromMarkdown(content);\n if (markdownHeadings.length > 0) {\n return markdownHeadings;\n }\n\n const htmlHeadings = this.extractHeadingsFromHtml(content);\n return htmlHeadings;\n }\n\n private extractHeadingsFromMarkdown(content: string): TableOfContentItem[] {\n const lines = content.split('\\n');\n const toc: TableOfContentItem[] = [];\n const slugCounts = new Map<string, number>();\n\n for (const line of lines) {\n const match = /^(#{1,6})\\s+(.+?)\\s*$/.exec(line);\n if (!match) {\n continue;\n }\n\n const level = match[1].length;\n const text = match[2].trim();\n if (!text) {\n continue;\n }\n\n const baseSlug = text\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, '')\n .trim()\n .replace(/\\s+/g, '-');\n const count = slugCounts.get(baseSlug) ?? 0;\n slugCounts.set(baseSlug, count + 1);\n const id = count === 0 ? baseSlug : `${baseSlug}-${count}`;\n\n toc.push({ id, level, text });\n }\n\n return toc;\n }\n\n private extractHeadingsFromHtml(content: string): TableOfContentItem[] {\n const toc: TableOfContentItem[] = [];\n const slugCounts = new Map<string, number>();\n const headingRegex = /<h([1-6])([^>]*)>([\\s\\S]*?)<\\/h\\1>/gi;\n\n for (const match of content.matchAll(headingRegex)) {\n const level = Number(match[1]);\n const attrs = match[2] ?? '';\n const rawInner = match[3] ?? '';\n const text = rawInner.replace(/<[^>]+>/g, '').trim();\n if (!text) {\n continue;\n }\n\n const idMatch =\n /\\sid=(['\"])(.*?)\\1/i.exec(attrs) ?? /\\sid=([^\\s>]+)/i.exec(attrs);\n let id = idMatch?.[2] ?? idMatch?.[1] ?? '';\n if (!id) {\n id = this.makeSlug(text, slugCounts);\n }\n\n toc.push({ id, level, text });\n }\n\n return toc;\n }\n\n private makeSlug(text: string, slugCounts: Map<string, number>): string {\n const baseSlug = text\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, '')\n .trim()\n .replace(/\\s+/g, '-');\n const count = slugCounts.get(baseSlug) ?? 0;\n slugCounts.set(baseSlug, count + 1);\n return count === 0 ? baseSlug : `${baseSlug}-${count}`;\n }\n}\n","/**\n * Returns the list of content files by filename with ?analog-content-list=true.\n * We use the query param to transform the return into an array of\n * just front matter attributes.\n *\n * @returns\n */\nexport const getContentFilesList = () => {\n const ANALOG_CONTENT_FILE_LIST = {};\n\n return ANALOG_CONTENT_FILE_LIST as Record<string, Record<string, any>>;\n};\n\n/**\n * Returns the lazy loaded content files for lookups.\n *\n * @returns\n */\nexport const getContentFiles = (): Record<string, () => Promise<string>> => {\n const ANALOG_CONTENT_ROUTE_FILES = {};\n\n return ANALOG_CONTENT_ROUTE_FILES as Record<string, () => Promise<string>>;\n};\n","import { InjectionToken } from '@angular/core';\nimport { ContentFile } from './content-file';\nimport { getContentFilesList } from './get-content-files';\n\nfunction getSlug(filename: string) {\n // Extract the last path segment without its extension.\n // Handles names with dots like [[...slug]].md by stripping only the final extension.\n const lastSegment = (filename.split(/[/\\\\]/).pop() || '').trim();\n const base = lastSegment.replace(/\\.[^./\\\\]+$/, ''); // strip only the final extension\n // Treat index.md as index route => empty slug\n return base === 'index' ? '' : base;\n}\n\nexport const CONTENT_FILES_LIST_TOKEN: InjectionToken<ContentFile[]> =\n new InjectionToken<ContentFile[]>('@analogjs/content Content Files List', {\n providedIn: 'root',\n factory() {\n const contentFiles = getContentFilesList();\n\n return Object.keys(contentFiles).map((filename) => {\n const attributes = contentFiles[filename];\n const slug = attributes['slug'];\n\n return {\n filename,\n attributes,\n slug: slug ? encodeURI(slug) : encodeURI(getSlug(filename)),\n };\n });\n },\n });\n","import { InjectionToken, Signal, inject, signal } from '@angular/core';\n\nimport { getContentFiles } from './get-content-files';\nimport { CONTENT_FILES_LIST_TOKEN } from './content-files-list-token';\n\nexport const CONTENT_FILES_TOKEN: InjectionToken<\n Record<string, () => Promise<string>>\n> = new InjectionToken<Record<string, () => Promise<string>>>(\n '@analogjs/content Content Files',\n {\n providedIn: 'root',\n factory() {\n const contentFiles = getContentFiles();\n const allFiles = { ...contentFiles };\n const contentFilesList = inject(CONTENT_FILES_LIST_TOKEN);\n\n const lookup: Record<string, string> = {};\n contentFilesList.forEach((item) => {\n const contentFilename = item.filename.replace(\n /(.*?)\\/content/,\n '/src/content',\n );\n const fileParts = contentFilename.split('/');\n const filePath = fileParts.slice(0, fileParts.length - 1).join('/');\n const fileNameParts = fileParts[fileParts.length - 1].split('.');\n const ext = fileNameParts[fileNameParts.length - 1];\n let slug = (item.slug ?? '') as string;\n // Default empty slug to 'index'\n if (slug === '') {\n slug = 'index';\n }\n // If slug contains path separators, treat it as root-relative to /src/content\n const newBase = slug.includes('/')\n ? `/src/content/${slug}`\n : `${filePath}/${slug}`;\n lookup[contentFilename] = `${newBase}.${ext}`.replace(/\\/{2,}/g, '/');\n });\n\n const objectUsingSlugAttribute: Record<string, () => Promise<string>> =\n {};\n Object.entries(allFiles).forEach((entry) => {\n const filename = entry[0];\n const value = entry[1];\n const strippedFilename = filename.replace(\n /^\\/(.*?)\\/content/,\n '/src/content',\n );\n\n const newFilename = lookup[strippedFilename];\n if (newFilename !== undefined) {\n const objectFilename = newFilename.replace(\n /^\\/(.*?)\\/content/,\n '/src/content',\n );\n objectUsingSlugAttribute[objectFilename] =\n value as () => Promise<string>;\n }\n });\n\n return objectUsingSlugAttribute;\n },\n },\n);\n\nexport const CONTENT_FILES_MAP_TOKEN: InjectionToken<\n Signal<Record<string, () => Promise<string>>>\n> = new InjectionToken<Signal<Record<string, () => Promise<string>>>>(\n '@analogjs/content Content Files',\n {\n providedIn: 'root',\n factory() {\n return signal(inject(CONTENT_FILES_TOKEN));\n },\n },\n);\n","import { Injectable, inject } from '@angular/core';\nimport { ɵPendingTasksInternal as ɵPendingTasks } from '@angular/core';\n\n@Injectable()\nexport class RenderTaskService {\n #pendingTasks = inject(ɵPendingTasks);\n\n addRenderTask(): number {\n return this.#pendingTasks.add();\n }\n\n clearRenderTask(clear: number | (() => void)): void {\n if (typeof clear === 'function') {\n clear();\n } else if (typeof (this.#pendingTasks as any).remove === 'function') {\n (this.#pendingTasks as any).remove(clear);\n }\n }\n}\n","import { inject } from '@angular/core';\n\nimport { ContentFile } from './content-file';\nimport { CONTENT_FILES_LIST_TOKEN } from './content-files-list-token';\nimport { CONTENT_FILES_TOKEN } from './content-files-token';\nimport { RenderTaskService } from './render-task.service';\n\nexport function injectContentFiles<Attributes extends Record<string, any>>(\n filterFn?: InjectContentFilesFilterFunction<Attributes>,\n): ContentFile<Attributes>[] {\n const renderTaskService = inject(RenderTaskService);\n const task = renderTaskService.addRenderTask();\n const allContentFiles = inject(\n CONTENT_FILES_LIST_TOKEN,\n ) as ContentFile<Attributes>[];\n renderTaskService.clearRenderTask(task);\n\n if (filterFn) {\n const filteredContentFiles = allContentFiles.filter(filterFn);\n\n return filteredContentFiles;\n }\n\n return allContentFiles;\n}\n\nexport type InjectContentFilesFilterFunction<T extends Record<string, any>> = (\n value: ContentFile<T>,\n index: number,\n array: ContentFile<T>[],\n) => boolean;\n\nexport function injectContentFilesMap(): Record<string, () => Promise<string>> {\n return inject(CONTENT_FILES_TOKEN);\n}\n","import { InjectionToken, Provider } from '@angular/core';\nimport { inject } from '@angular/core';\n\nimport { injectContentFilesMap } from './inject-content-files';\n\ntype ContentFileLoaderFunction = () => Promise<\n Record<string, () => Promise<string>>\n>;\n\nexport const CONTENT_FILE_LOADER: InjectionToken<ContentFileLoaderFunction> =\n new InjectionToken<ContentFileLoaderFunction>(\n '@analogjs/content/resource File Loader',\n );\n\nexport function injectContentFileLoader() {\n return inject(CONTENT_FILE_LOADER) as ContentFileLoaderFunction;\n}\n\nexport function withContentFileLoader(): Provider {\n return {\n provide: CONTENT_FILE_LOADER,\n useFactory() {\n return async () => injectContentFilesMap();\n },\n };\n}\n","import { InjectionToken, Provider } from '@angular/core';\nimport { inject } from '@angular/core';\n\nimport { ContentFile } from './content-file';\nimport { injectContentFiles } from './inject-content-files';\n\ntype ContentListLoaderFunction<Attributes extends Record<string, any>> =\n () => Promise<ContentFile<Attributes>[]>;\n\nexport const CONTENT_LIST_LOADER: InjectionToken<\n ContentListLoaderFunction<any>\n> = new InjectionToken<ContentListLoaderFunction<any>>(\n '@analogjs/content/resource List Loader',\n);\n\nexport function injectContentListLoader<\n Attributes extends Record<string, any>,\n>() {\n return inject(CONTENT_LIST_LOADER) as ContentListLoaderFunction<Attributes>;\n}\n\nexport function withContentListLoader(): Provider {\n return {\n provide: CONTENT_LIST_LOADER,\n useFactory() {\n return async () => injectContentFiles();\n },\n };\n}\n"],"mappings":"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"}
|
package/mdc/package.json
ADDED
package/og/package.json
CHANGED