@ng-annotate/angular 0.5.3 → 0.5.4
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.
|
@@ -11,6 +11,18 @@ const node_crypto_1 = require("node:crypto");
|
|
|
11
11
|
const ws_1 = require("ws");
|
|
12
12
|
// ─── Store ────────────────────────────────────────────────────────────────────
|
|
13
13
|
const STORE_DIR = '.ng-annotate';
|
|
14
|
+
/** Walk up from startDir until we find a .git folder; return that dir or startDir. */
|
|
15
|
+
function findStoreRoot(startDir) {
|
|
16
|
+
let dir = node_path_1.default.resolve(startDir);
|
|
17
|
+
let parent = node_path_1.default.dirname(dir);
|
|
18
|
+
while (parent !== dir) {
|
|
19
|
+
if (node_fs_1.default.existsSync(node_path_1.default.join(dir, '.git')))
|
|
20
|
+
return dir;
|
|
21
|
+
dir = parent;
|
|
22
|
+
parent = node_path_1.default.dirname(dir);
|
|
23
|
+
}
|
|
24
|
+
return startDir;
|
|
25
|
+
}
|
|
14
26
|
function makeStore(projectRoot) {
|
|
15
27
|
const storePath = node_path_1.default.join(projectRoot, STORE_DIR, 'store.json');
|
|
16
28
|
function ensureStore() {
|
|
@@ -185,9 +197,10 @@ function createAnnotateWsHandler(store) {
|
|
|
185
197
|
}
|
|
186
198
|
// ─── Builder ──────────────────────────────────────────────────────────────────
|
|
187
199
|
exports.default = (0, architect_1.createBuilder)((options, context) => {
|
|
188
|
-
const
|
|
200
|
+
const workspaceRoot = context.workspaceRoot;
|
|
201
|
+
const projectRoot = findStoreRoot(workspaceRoot);
|
|
189
202
|
const store = makeStore(projectRoot);
|
|
190
|
-
const manifest = buildManifest(
|
|
203
|
+
const manifest = buildManifest(workspaceRoot);
|
|
191
204
|
const { wss } = createAnnotateWsHandler(store);
|
|
192
205
|
let wsAttached = false;
|
|
193
206
|
const middleware = (req, _res, next) => {
|
|
@@ -449,11 +449,12 @@ class OverlayComponent {
|
|
|
449
449
|
[(ngModel)]="annotationText"
|
|
450
450
|
placeholder="Describe the change..."
|
|
451
451
|
rows="4"
|
|
452
|
+
(keydown.shift.enter)="$event.preventDefault(); submit()"
|
|
452
453
|
></textarea>
|
|
453
454
|
|
|
454
455
|
<div class="nga-actions">
|
|
455
456
|
<button class="nga-btn nga-btn-submit" (click)="submit()" [disabled]="annotationText.trim() === ''">
|
|
456
|
-
Submit
|
|
457
|
+
Submit <small style="opacity:0.7;font-size:11px">Shift+Enter</small>
|
|
457
458
|
</button>
|
|
458
459
|
<button class="nga-btn nga-btn-cancel" (click)="cancel()">Cancel</button>
|
|
459
460
|
</div>
|
|
@@ -561,11 +562,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
|
|
|
561
562
|
[(ngModel)]="annotationText"
|
|
562
563
|
placeholder="Describe the change..."
|
|
563
564
|
rows="4"
|
|
565
|
+
(keydown.shift.enter)="$event.preventDefault(); submit()"
|
|
564
566
|
></textarea>
|
|
565
567
|
|
|
566
568
|
<div class="nga-actions">
|
|
567
569
|
<button class="nga-btn nga-btn-submit" (click)="submit()" [disabled]="annotationText.trim() === ''">
|
|
568
|
-
Submit
|
|
570
|
+
Submit <small style="opacity:0.7;font-size:11px">Shift+Enter</small>
|
|
569
571
|
</button>
|
|
570
572
|
<button class="nga-btn nga-btn-cancel" (click)="cancel()">Cancel</button>
|
|
571
573
|
</div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-annotate-angular.mjs","sources":["../../src/inspector.service.ts","../../src/bridge.service.ts","../../src/overlay/overlay.component.ts","../../src/ng-annotate.module.ts","../../src/provide-ng-annotate.ts","../../src/ng-annotate-angular.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport type { ComponentContext } from './types';\n\ninterface NgDevMode {\n getComponent: (element: Element) => unknown;\n}\n\ndeclare const ng: NgDevMode;\n\ninterface NgCmp {\n selectors?: unknown[][];\n inputs?: Record<string, string>;\n}\n\ninterface ComponentInstance {\n constructor: { name: string; ɵcmp?: NgCmp } & (new (...args: unknown[]) => unknown);\n [key: string]: unknown;\n}\n\ninterface ManifestEntry {\n component: string;\n template?: string;\n}\n\nconst DOM_SNAPSHOT_MAX = 5000;\n\n@Injectable()\nexport class InspectorService {\n getComponentContext(element: Element): ComponentContext | null {\n const component = this.findNearestComponent(element);\n if (!component) return null;\n\n const componentName = (component as ComponentInstance).constructor.name;\n const { component: componentFilePath, template: templateFilePath } =\n this.resolveFilePaths(componentName);\n const selector = this.getSelector(component as ComponentInstance);\n const inputs = this.getInputs(component as ComponentInstance);\n const domSnapshot = this.snapshot(element);\n const componentTreePath = this.buildTreePath(element);\n\n return {\n componentName,\n componentFilePath,\n ...(templateFilePath ? { templateFilePath } : {}),\n selector,\n inputs,\n domSnapshot,\n componentTreePath,\n };\n }\n\n private findNearestComponent(element: Element): unknown {\n let current: Element | null = element;\n while (current) {\n try {\n const comp = ng.getComponent(current);\n if (comp) return comp;\n } catch {\n // ignore\n }\n current = current.parentElement;\n }\n return null;\n }\n\n private getSelector(component: ComponentInstance): string {\n try {\n const cmp = component.constructor.ɵcmp;\n if (!cmp?.selectors?.length) return 'unknown-selector';\n const first = cmp.selectors[0];\n if (!first.length) return 'unknown-selector';\n\n // Element selector: [['app-foo']]\n // Attribute selector: [['', 'appFoo', '']]\n if (first[0] === '') {\n // Attribute selector — find non-empty entries\n const attrParts: string[] = [];\n for (let i = 1; i < first.length; i += 2) {\n if (typeof first[i] === 'string' && first[i]) {\n attrParts.push(`[${String(first[i])}]`);\n }\n }\n return attrParts.join('') || 'unknown-selector';\n }\n return String(first[0]);\n } catch {\n return 'unknown-selector';\n }\n }\n\n private getInputs(component: ComponentInstance): Record<string, unknown> {\n try {\n const cmp = component.constructor.ɵcmp;\n if (!cmp?.inputs) return {};\n const result: Record<string, unknown> = {};\n for (const [propName] of Object.entries(cmp.inputs)) {\n if (typeof propName === 'symbol') continue;\n if (propName.startsWith('ɵ')) continue;\n result[propName] = (component as Record<string, unknown>)[propName];\n }\n return result;\n } catch {\n return {};\n }\n }\n\n private buildTreePath(element: Element): string[] {\n const path: string[] = [];\n let current: Element | null = element.parentElement;\n while (current) {\n try {\n const comp = ng.getComponent(current);\n if (comp) {\n path.unshift((comp as ComponentInstance).constructor.name);\n }\n } catch {\n // ignore\n }\n current = current.parentElement;\n }\n return path;\n }\n\n private snapshot(element: Element): string {\n const html = element.outerHTML;\n if (html.length <= DOM_SNAPSHOT_MAX) return html;\n return html.slice(0, DOM_SNAPSHOT_MAX) + '<!-- truncated -->';\n }\n\n private resolveFilePaths(componentName: string): { component: string; template?: string } {\n try {\n const manifest = (window as unknown as { __NG_ANNOTATE_MANIFEST__?: Record<string, ManifestEntry> })\n .__NG_ANNOTATE_MANIFEST__;\n const entry = manifest?.[componentName];\n if (entry) return entry;\n } catch {\n // ignore\n }\n return { component: `(unresolved: ${componentName})` };\n }\n}\n","import { Injectable, NgZone, OnDestroy, inject } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport type { Session, Annotation } from './types';\n\ntype BridgeMessage =\n | { type: 'session:created'; session: Session }\n | { type: 'annotations:sync'; annotations: Annotation[] }\n | { type: 'annotation:created'; annotation: Annotation }\n | { type: 'manifest:update'; manifest: Record<string, unknown> }\n | { type: string };\n\n@Injectable()\nexport class BridgeService implements OnDestroy {\n readonly session$ = new BehaviorSubject<Session | null>(null);\n readonly annotations$ = new BehaviorSubject<Annotation[]>([]);\n readonly connected$ = new BehaviorSubject<boolean>(false);\n\n private readonly zone = inject(NgZone);\n private ws: WebSocket | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n\n init(): void {\n this.connect();\n }\n\n private connect(): void {\n const wsUrl = `ws://${location.host}/__annotate`;\n this.ws = new WebSocket(wsUrl);\n\n this.ws.onopen = () => {\n this.zone.run(() => {\n this.connected$.next(true);\n });\n };\n\n this.ws.onmessage = (event: MessageEvent<string>) => {\n this.zone.run(() => {\n try {\n const data = JSON.parse(event.data) as BridgeMessage;\n if (data.type === 'session:created') {\n this.session$.next((data as Extract<BridgeMessage, { type: 'session:created' }>).session);\n } else if (data.type === 'annotations:sync') {\n this.annotations$.next(\n (data as Extract<BridgeMessage, { type: 'annotations:sync' }>).annotations,\n );\n } else if (data.type === 'annotation:created') {\n const annotation = (\n data as Extract<BridgeMessage, { type: 'annotation:created' }>\n ).annotation;\n const current = this.annotations$.getValue();\n this.annotations$.next([...current, annotation]);\n } else if (data.type === 'manifest:update') {\n const { manifest } = data as Extract<BridgeMessage, { type: 'manifest:update' }>;\n (window as unknown as { __NG_ANNOTATE_MANIFEST__?: unknown }).__NG_ANNOTATE_MANIFEST__ = manifest;\n }\n } catch {\n // ignore malformed messages\n }\n });\n };\n\n this.ws.onclose = () => {\n this.zone.run(() => {\n this.connected$.next(false);\n this.reconnectTimer = setTimeout(() => { this.connect(); }, 3000);\n });\n };\n\n this.ws.onerror = (event) => {\n console.warn('[ng-annotate] WebSocket error', event);\n };\n }\n\n createAnnotation(payload: Record<string, unknown>): void {\n this.send({ type: 'annotation:create', payload });\n }\n\n replyToAnnotation(id: string, message: string): void {\n this.send({ type: 'annotation:reply', id, message });\n }\n\n deleteAnnotation(id: string): void {\n this.send({ type: 'annotation:delete', id });\n }\n\n private send(msg: Record<string, unknown>): void {\n if (this.ws?.readyState === WebSocket.OPEN) {\n this.ws.send(JSON.stringify(msg));\n }\n }\n\n ngOnDestroy(): void {\n if (this.reconnectTimer !== null) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n this.ws?.close();\n }\n}\n","import {\n Component,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n HostListener,\n OnInit,\n ViewChild,\n ElementRef,\n inject,\n} from '@angular/core';\nimport { JsonPipe } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { InspectorService } from '../inspector.service';\nimport { BridgeService } from '../bridge.service';\nimport type { Annotation, ComponentContext, AnnotationStatus } from '../types';\n\ntype OverlayMode = 'hidden' | 'inspect' | 'annotate' | 'thread';\n\ninterface HighlightRect {\n top: string;\n left: string;\n width: string;\n height: string;\n}\n\ninterface AnnotationBadge {\n annotation: Annotation;\n top: string;\n left: string;\n icon: string;\n label: string;\n}\n\n@Component({\n selector: 'nga-overlay',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [JsonPipe, FormsModule],\n styles: [`\n :host {\n position: fixed; top: 0; left: 0; width: 100%; height: 100%;\n pointer-events: none; z-index: 9999;\n }\n .nga-highlight-rect {\n position: fixed; border: 2px solid #3b82f6;\n background: rgba(59,130,246,0.1); pointer-events: none;\n transition: top 0.05s, left 0.05s, width 0.05s, height 0.05s;\n }\n .nga-component-label {\n position: absolute; top: -22px; left: 0; background: #1e293b; color: #f8fafc;\n font-family: monospace; font-size: 11px; padding: 2px 6px;\n border-radius: 3px; white-space: nowrap;\n }\n .nga-annotate-panel, .nga-thread-panel {\n pointer-events: all; position: fixed; right: 16px; top: 50%;\n transform: translateY(-50%); background: #ffffff; border: 1px solid #e2e8f0;\n border-radius: 8px; box-shadow: 0 4px 24px rgba(0,0,0,0.15);\n padding: 16px; min-width: 320px; max-width: 400px;\n }\n .nga-panel-title {\n margin: 0 0 12px; font-size: 14px; font-weight: 600;\n color: #1e293b; font-family: monospace;\n }\n .nga-inputs { margin-bottom: 10px; }\n .nga-input-row {\n display: flex; gap: 8px; font-size: 12px;\n font-family: monospace; margin-bottom: 4px;\n }\n .nga-input-key { color: #64748b; min-width: 80px; }\n .nga-input-val {\n color: #1e293b; overflow: hidden;\n text-overflow: ellipsis; white-space: nowrap;\n }\n .nga-selection {\n font-size: 12px; color: #475569; margin-bottom: 8px; font-style: italic;\n }\n .nga-textarea, .nga-reply-input {\n width: 100%; box-sizing: border-box; border: 1px solid #cbd5e1;\n border-radius: 4px; padding: 8px; font-size: 13px;\n font-family: inherit; resize: vertical; margin-bottom: 10px;\n }\n .nga-textarea:focus, .nga-reply-input:focus {\n outline: none; border-color: #3b82f6;\n }\n .nga-actions { display: flex; gap: 8px; }\n .nga-btn {\n padding: 6px 14px; border-radius: 4px; font-size: 13px;\n cursor: pointer; border: none; transition: opacity 0.15s;\n }\n .nga-btn:disabled { opacity: 0.4; cursor: not-allowed; }\n .nga-btn-submit { background: #3b82f6; color: #ffffff; }\n .nga-btn-cancel { background: #f1f5f9; color: #475569; }\n .nga-replies { max-height: 200px; overflow-y: auto; margin-bottom: 10px; }\n .nga-reply { display: flex; gap: 8px; margin-bottom: 8px; font-size: 13px; }\n .nga-reply-author { font-weight: 600; min-width: 48px; }\n .nga-reply-author--agent { color: #7c3aed; }\n .nga-reply-author--user { color: #2563eb; }\n .nga-badge {\n pointer-events: all; position: fixed; width: 18px; height: 18px;\n border-radius: 50%; display: flex; align-items: center;\n justify-content: center; font-size: 10px; cursor: pointer;\n transform: translate(-50%, -50%);\n }\n .nga-badge--pending { background: #3b82f6; color: #ffffff; }\n .nga-badge--acknowledged { background: #f59e0b; color: #ffffff; }\n .nga-badge--resolved { background: #22c55e; color: #ffffff; }\n .nga-badge--dismissed { background: #94a3b8; color: #ffffff; }\n .nga-keyboard-hint {\n pointer-events: none; position: fixed; bottom: 16px; right: 16px;\n background: rgba(15,23,42,0.7); color: #f8fafc; font-size: 12px;\n padding: 6px 10px; border-radius: 6px;\n }\n .nga-keyboard-hint kbd {\n background: rgba(255,255,255,0.15); border-radius: 3px;\n padding: 1px 5px; font-family: monospace;\n }\n `],\n template: `\n <!-- Keyboard hint -->\n @if (mode === 'hidden') {\n <div class=\"nga-keyboard-hint\">\n <kbd>Alt+Shift+A</kbd> to annotate\n </div>\n }\n @if (mode === 'inspect') {\n <div class=\"nga-keyboard-hint\">\n Click a component <kbd>Esc</kbd> to cancel\n </div>\n }\n\n <!-- Inspect highlight rect -->\n @if (mode === 'inspect' && hoveredContext !== null && highlightRect !== null) {\n <div\n class=\"nga-highlight-rect\"\n [style.top]=\"highlightRect.top\"\n [style.left]=\"highlightRect.left\"\n [style.width]=\"highlightRect.width\"\n [style.height]=\"highlightRect.height\"\n >\n <span class=\"nga-component-label\">{{ hoveredContext.componentName }}</span>\n </div>\n }\n\n <!-- Annotate panel -->\n @if (mode === 'annotate' && selectedContext !== null) {\n <div class=\"nga-annotate-panel\">\n <h3 class=\"nga-panel-title\">{{ selectedContext.componentName }}</h3>\n\n @if (inputEntries().length > 0) {\n <div class=\"nga-inputs\">\n @for (entry of inputEntries(); track entry.key) {\n <div class=\"nga-input-row\">\n <span class=\"nga-input-key\">{{ entry.key }}:</span>\n <span class=\"nga-input-val\">{{ entry.value | json }}</span>\n </div>\n }\n </div>\n }\n\n @if (selectionText) {\n <div class=\"nga-selection\">\n <em>\"{{ selectionText }}\"</em>\n </div>\n }\n\n <textarea\n #textArea\n class=\"nga-textarea\"\n [(ngModel)]=\"annotationText\"\n placeholder=\"Describe the change...\"\n rows=\"4\"\n ></textarea>\n\n <div class=\"nga-actions\">\n <button class=\"nga-btn nga-btn-submit\" (click)=\"submit()\" [disabled]=\"annotationText.trim() === ''\">\n Submit\n </button>\n <button class=\"nga-btn nga-btn-cancel\" (click)=\"cancel()\">Cancel</button>\n </div>\n </div>\n }\n\n <!-- Thread panel -->\n @if (mode === 'thread' && threadAnnotation !== null) {\n <div class=\"nga-thread-panel\">\n <h3 class=\"nga-panel-title\">{{ threadAnnotation.componentName }}</h3>\n\n <div class=\"nga-replies\">\n @for (reply of threadAnnotation.replies; track reply.message) {\n <div class=\"nga-reply\">\n <span class=\"nga-reply-author nga-reply-author--{{ reply.author }}\">{{ reply.author }}</span>\n <span class=\"nga-reply-text\">{{ reply.message }}</span>\n </div>\n }\n </div>\n\n <input\n class=\"nga-reply-input\"\n type=\"text\"\n [(ngModel)]=\"replyText\"\n placeholder=\"Reply...\"\n (keydown.enter)=\"sendReply()\"\n />\n\n <div class=\"nga-actions\">\n <button class=\"nga-btn nga-btn-submit\" (click)=\"sendReply()\" [disabled]=\"replyText.trim() === ''\">\n Send\n </button>\n <button class=\"nga-btn nga-btn-cancel\" (click)=\"closeThread()\">Close</button>\n </div>\n </div>\n }\n\n <!-- Annotation badges -->\n @for (badge of badges; track badge.annotation.id) {\n <div\n class=\"nga-badge nga-badge--{{ badge.annotation.status }}\"\n [style.top]=\"badge.top\"\n [style.left]=\"badge.left\"\n (click)=\"openThread(badge.annotation)\"\n [title]=\"badge.label\"\n >\n {{ badge.icon }}\n </div>\n }\n `,\n})\nexport class OverlayComponent implements OnInit {\n @ViewChild('textArea') textArea?: ElementRef<HTMLTextAreaElement>;\n\n mode: OverlayMode = 'hidden';\n hoveredContext: ComponentContext | null = null;\n highlightRect: HighlightRect | null = null;\n selectedContext: ComponentContext | null = null;\n annotationText = '';\n selectionText = '';\n threadAnnotation: Annotation | null = null;\n replyText = '';\n badges: AnnotationBadge[] = [];\n\n private readonly inspector = inject(InspectorService);\n private readonly bridge = inject(BridgeService);\n private readonly cdr = inject(ChangeDetectorRef);\n\n ngOnInit(): void {\n this.bridge.annotations$.subscribe((annotations) => {\n this.updateBadges(annotations);\n this.cdr.markForCheck();\n });\n }\n\n @HostListener('document:keydown.alt.shift.a', ['$event'])\n toggleInspect(event?: Event): void {\n event?.preventDefault();\n if (this.mode === 'hidden') this.mode = 'inspect';\n else if (this.mode === 'inspect') this.mode = 'hidden';\n else if (this.mode === 'annotate') this.mode = 'inspect';\n this.cdr.markForCheck();\n }\n\n @HostListener('document:keydown.escape')\n onEscape(): void {\n if (this.mode === 'annotate') this.mode = 'inspect';\n else if (this.mode === 'inspect') this.mode = 'hidden';\n else if (this.mode === 'thread') this.mode = 'hidden';\n this.cdr.markForCheck();\n }\n\n @HostListener('window:scroll')\n @HostListener('window:resize')\n onScrollOrResize(): void {\n if (this.badges.length > 0) {\n this.refreshBadgePositions();\n this.cdr.markForCheck();\n }\n }\n\n @HostListener('document:mousemove', ['$event'])\n onMouseMove(event: MouseEvent): void {\n if (this.mode !== 'inspect') return;\n const target = event.target as Element;\n if (target.closest('nga-overlay')) return;\n const context = this.inspector.getComponentContext(target);\n this.hoveredContext = context;\n if (context) {\n const rect = target.getBoundingClientRect();\n this.highlightRect = {\n top: `${rect.top.toString()}px`,\n left: `${rect.left.toString()}px`,\n width: `${rect.width.toString()}px`,\n height: `${rect.height.toString()}px`,\n };\n } else {\n this.highlightRect = null;\n }\n this.cdr.markForCheck();\n }\n\n @HostListener('document:click', ['$event'])\n onClick(event: MouseEvent): void {\n if (this.mode !== 'inspect') return;\n const target = event.target as Element;\n if (target.closest('nga-overlay')) return;\n const context = this.inspector.getComponentContext(target);\n if (!context) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n this.selectedContext = context;\n this.annotationText = '';\n this.selectionText = window.getSelection()?.toString() ?? '';\n this.mode = 'annotate';\n this.cdr.markForCheck();\n\n setTimeout(() => { this.textArea?.nativeElement.focus(); }, 0);\n }\n\n submit(): void {\n if (!this.selectedContext || !this.annotationText.trim()) return;\n this.bridge.createAnnotation({\n ...this.selectedContext,\n annotationText: this.annotationText.trim(),\n selectionText: this.selectionText || undefined,\n });\n this.selectedContext = null;\n this.annotationText = '';\n this.mode = 'inspect';\n this.cdr.markForCheck();\n }\n\n cancel(): void {\n this.mode = 'inspect';\n this.cdr.markForCheck();\n }\n\n openThread(annotation: Annotation): void {\n this.threadAnnotation = annotation;\n this.mode = 'thread';\n this.cdr.markForCheck();\n }\n\n closeThread(): void {\n this.threadAnnotation = null;\n this.mode = 'hidden';\n this.cdr.markForCheck();\n }\n\n sendReply(): void {\n if (!this.threadAnnotation || !this.replyText.trim()) return;\n this.bridge.replyToAnnotation(this.threadAnnotation.id, this.replyText.trim());\n this.replyText = '';\n this.cdr.markForCheck();\n }\n\n inputEntries(): { key: string; value: unknown }[] {\n if (!this.selectedContext) return [];\n return Object.entries(this.selectedContext.inputs)\n .slice(0, 5)\n .map(([key, value]) => ({ key, value }));\n }\n\n private updateBadges(annotations: Annotation[]): void {\n this.badges = annotations\n .map((annotation) => {\n const el = this.findComponentElement(annotation.componentName, annotation.selector);\n if (!el) return null;\n const rect = el.getBoundingClientRect();\n return {\n annotation,\n top: `${rect.top.toString()}px`,\n left: `${(rect.left + rect.width - 12).toString()}px`,\n icon: this.badgeIcon(annotation.status),\n label: `${annotation.componentName}: ${annotation.annotationText.slice(0, 40)}`,\n };\n })\n .filter((b): b is AnnotationBadge => b !== null);\n }\n\n private refreshBadgePositions(): void {\n this.badges = this.badges.map((badge) => {\n const el = this.findComponentElement(badge.annotation.componentName, badge.annotation.selector);\n if (!el) return badge;\n const rect = el.getBoundingClientRect();\n return {\n ...badge,\n top: `${rect.top.toString()}px`,\n left: `${(rect.left + rect.width - 12).toString()}px`,\n };\n });\n }\n\n private findComponentElement(componentName: string, selector: string): Element | null {\n const bySelector = document.querySelector(selector);\n if (bySelector) return bySelector;\n\n const all = document.querySelectorAll('*');\n for (const el of Array.from(all)) {\n try {\n const comp = (window as unknown as { ng?: { getComponent: (el: Element) => { constructor: { name: string } } | null } })\n .ng;\n if (comp?.getComponent(el)?.constructor.name === componentName) return el;\n } catch {\n // ignore\n }\n }\n return null;\n }\n\n private badgeIcon(status: AnnotationStatus): string {\n const icons: Record<AnnotationStatus, string> = {\n pending: '●',\n acknowledged: '◐',\n resolved: '✓',\n dismissed: '✕',\n };\n return icons[status];\n }\n}\n","import {\n NgModule,\n isDevMode,\n provideAppInitializer,\n inject,\n ApplicationRef,\n EnvironmentInjector,\n createComponent,\n} from '@angular/core';\nimport { InspectorService } from './inspector.service';\nimport { BridgeService } from './bridge.service';\nimport { OverlayComponent } from './overlay/overlay.component';\n\n@NgModule({\n providers: isDevMode()\n ? [\n InspectorService,\n BridgeService,\n provideAppInitializer(() => {\n const bridge = inject(BridgeService);\n const appRef = inject(ApplicationRef);\n const envInjector = inject(EnvironmentInjector);\n bridge.init();\n const overlayRef = createComponent(OverlayComponent, { environmentInjector: envInjector });\n appRef.attachView(overlayRef.hostView);\n document.body.appendChild(overlayRef.location.nativeElement);\n }),\n ]\n : [],\n})\n// eslint-disable-next-line @typescript-eslint/no-extraneous-class -- required by NgModule pattern\nexport class NgAnnotateModule {}\n","import {\n ApplicationRef,\n EnvironmentInjector,\n createComponent,\n inject,\n isDevMode,\n makeEnvironmentProviders,\n provideAppInitializer,\n} from '@angular/core';\nimport { InspectorService } from './inspector.service';\nimport { BridgeService } from './bridge.service';\nimport { OverlayComponent } from './overlay/overlay.component';\n\nexport function provideNgAnnotate() {\n return makeEnvironmentProviders([\n InspectorService,\n BridgeService,\n provideAppInitializer(() => {\n if (!isDevMode()) return;\n const bridge = inject(BridgeService);\n const appRef = inject(ApplicationRef);\n const envInjector = inject(EnvironmentInjector);\n bridge.init();\n const overlayRef = createComponent(OverlayComponent, { environmentInjector: envInjector });\n appRef.attachView(overlayRef.hostView);\n document.body.appendChild(overlayRef.location.nativeElement);\n }),\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ng-annotate-angular.mjs","sources":["../../src/inspector.service.ts","../../src/bridge.service.ts","../../src/overlay/overlay.component.ts","../../src/ng-annotate.module.ts","../../src/provide-ng-annotate.ts","../../src/ng-annotate-angular.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport type { ComponentContext } from './types';\n\ninterface NgDevMode {\n getComponent: (element: Element) => unknown;\n}\n\ndeclare const ng: NgDevMode;\n\ninterface NgCmp {\n selectors?: unknown[][];\n inputs?: Record<string, string>;\n}\n\ninterface ComponentInstance {\n constructor: { name: string; ɵcmp?: NgCmp } & (new (...args: unknown[]) => unknown);\n [key: string]: unknown;\n}\n\ninterface ManifestEntry {\n component: string;\n template?: string;\n}\n\nconst DOM_SNAPSHOT_MAX = 5000;\n\n@Injectable()\nexport class InspectorService {\n getComponentContext(element: Element): ComponentContext | null {\n const component = this.findNearestComponent(element);\n if (!component) return null;\n\n const componentName = (component as ComponentInstance).constructor.name;\n const { component: componentFilePath, template: templateFilePath } =\n this.resolveFilePaths(componentName);\n const selector = this.getSelector(component as ComponentInstance);\n const inputs = this.getInputs(component as ComponentInstance);\n const domSnapshot = this.snapshot(element);\n const componentTreePath = this.buildTreePath(element);\n\n return {\n componentName,\n componentFilePath,\n ...(templateFilePath ? { templateFilePath } : {}),\n selector,\n inputs,\n domSnapshot,\n componentTreePath,\n };\n }\n\n private findNearestComponent(element: Element): unknown {\n let current: Element | null = element;\n while (current) {\n try {\n const comp = ng.getComponent(current);\n if (comp) return comp;\n } catch {\n // ignore\n }\n current = current.parentElement;\n }\n return null;\n }\n\n private getSelector(component: ComponentInstance): string {\n try {\n const cmp = component.constructor.ɵcmp;\n if (!cmp?.selectors?.length) return 'unknown-selector';\n const first = cmp.selectors[0];\n if (!first.length) return 'unknown-selector';\n\n // Element selector: [['app-foo']]\n // Attribute selector: [['', 'appFoo', '']]\n if (first[0] === '') {\n // Attribute selector — find non-empty entries\n const attrParts: string[] = [];\n for (let i = 1; i < first.length; i += 2) {\n if (typeof first[i] === 'string' && first[i]) {\n attrParts.push(`[${String(first[i])}]`);\n }\n }\n return attrParts.join('') || 'unknown-selector';\n }\n return String(first[0]);\n } catch {\n return 'unknown-selector';\n }\n }\n\n private getInputs(component: ComponentInstance): Record<string, unknown> {\n try {\n const cmp = component.constructor.ɵcmp;\n if (!cmp?.inputs) return {};\n const result: Record<string, unknown> = {};\n for (const [propName] of Object.entries(cmp.inputs)) {\n if (typeof propName === 'symbol') continue;\n if (propName.startsWith('ɵ')) continue;\n result[propName] = (component as Record<string, unknown>)[propName];\n }\n return result;\n } catch {\n return {};\n }\n }\n\n private buildTreePath(element: Element): string[] {\n const path: string[] = [];\n let current: Element | null = element.parentElement;\n while (current) {\n try {\n const comp = ng.getComponent(current);\n if (comp) {\n path.unshift((comp as ComponentInstance).constructor.name);\n }\n } catch {\n // ignore\n }\n current = current.parentElement;\n }\n return path;\n }\n\n private snapshot(element: Element): string {\n const html = element.outerHTML;\n if (html.length <= DOM_SNAPSHOT_MAX) return html;\n return html.slice(0, DOM_SNAPSHOT_MAX) + '<!-- truncated -->';\n }\n\n private resolveFilePaths(componentName: string): { component: string; template?: string } {\n try {\n const manifest = (window as unknown as { __NG_ANNOTATE_MANIFEST__?: Record<string, ManifestEntry> })\n .__NG_ANNOTATE_MANIFEST__;\n const entry = manifest?.[componentName];\n if (entry) return entry;\n } catch {\n // ignore\n }\n return { component: `(unresolved: ${componentName})` };\n }\n}\n","import { Injectable, NgZone, OnDestroy, inject } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport type { Session, Annotation } from './types';\n\ntype BridgeMessage =\n | { type: 'session:created'; session: Session }\n | { type: 'annotations:sync'; annotations: Annotation[] }\n | { type: 'annotation:created'; annotation: Annotation }\n | { type: 'manifest:update'; manifest: Record<string, unknown> }\n | { type: string };\n\n@Injectable()\nexport class BridgeService implements OnDestroy {\n readonly session$ = new BehaviorSubject<Session | null>(null);\n readonly annotations$ = new BehaviorSubject<Annotation[]>([]);\n readonly connected$ = new BehaviorSubject<boolean>(false);\n\n private readonly zone = inject(NgZone);\n private ws: WebSocket | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n\n init(): void {\n this.connect();\n }\n\n private connect(): void {\n const wsUrl = `ws://${location.host}/__annotate`;\n this.ws = new WebSocket(wsUrl);\n\n this.ws.onopen = () => {\n this.zone.run(() => {\n this.connected$.next(true);\n });\n };\n\n this.ws.onmessage = (event: MessageEvent<string>) => {\n this.zone.run(() => {\n try {\n const data = JSON.parse(event.data) as BridgeMessage;\n if (data.type === 'session:created') {\n this.session$.next((data as Extract<BridgeMessage, { type: 'session:created' }>).session);\n } else if (data.type === 'annotations:sync') {\n this.annotations$.next(\n (data as Extract<BridgeMessage, { type: 'annotations:sync' }>).annotations,\n );\n } else if (data.type === 'annotation:created') {\n const annotation = (\n data as Extract<BridgeMessage, { type: 'annotation:created' }>\n ).annotation;\n const current = this.annotations$.getValue();\n this.annotations$.next([...current, annotation]);\n } else if (data.type === 'manifest:update') {\n const { manifest } = data as Extract<BridgeMessage, { type: 'manifest:update' }>;\n (window as unknown as { __NG_ANNOTATE_MANIFEST__?: unknown }).__NG_ANNOTATE_MANIFEST__ = manifest;\n }\n } catch {\n // ignore malformed messages\n }\n });\n };\n\n this.ws.onclose = () => {\n this.zone.run(() => {\n this.connected$.next(false);\n this.reconnectTimer = setTimeout(() => { this.connect(); }, 3000);\n });\n };\n\n this.ws.onerror = (event) => {\n console.warn('[ng-annotate] WebSocket error', event);\n };\n }\n\n createAnnotation(payload: Record<string, unknown>): void {\n this.send({ type: 'annotation:create', payload });\n }\n\n replyToAnnotation(id: string, message: string): void {\n this.send({ type: 'annotation:reply', id, message });\n }\n\n deleteAnnotation(id: string): void {\n this.send({ type: 'annotation:delete', id });\n }\n\n private send(msg: Record<string, unknown>): void {\n if (this.ws?.readyState === WebSocket.OPEN) {\n this.ws.send(JSON.stringify(msg));\n }\n }\n\n ngOnDestroy(): void {\n if (this.reconnectTimer !== null) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n this.ws?.close();\n }\n}\n","import {\n Component,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n HostListener,\n OnInit,\n ViewChild,\n ElementRef,\n inject,\n} from '@angular/core';\nimport { JsonPipe } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { InspectorService } from '../inspector.service';\nimport { BridgeService } from '../bridge.service';\nimport type { Annotation, ComponentContext, AnnotationStatus } from '../types';\n\ntype OverlayMode = 'hidden' | 'inspect' | 'annotate' | 'thread';\n\ninterface HighlightRect {\n top: string;\n left: string;\n width: string;\n height: string;\n}\n\ninterface AnnotationBadge {\n annotation: Annotation;\n top: string;\n left: string;\n icon: string;\n label: string;\n}\n\n@Component({\n selector: 'nga-overlay',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [JsonPipe, FormsModule],\n styles: [`\n :host {\n position: fixed; top: 0; left: 0; width: 100%; height: 100%;\n pointer-events: none; z-index: 9999;\n }\n .nga-highlight-rect {\n position: fixed; border: 2px solid #3b82f6;\n background: rgba(59,130,246,0.1); pointer-events: none;\n transition: top 0.05s, left 0.05s, width 0.05s, height 0.05s;\n }\n .nga-component-label {\n position: absolute; top: -22px; left: 0; background: #1e293b; color: #f8fafc;\n font-family: monospace; font-size: 11px; padding: 2px 6px;\n border-radius: 3px; white-space: nowrap;\n }\n .nga-annotate-panel, .nga-thread-panel {\n pointer-events: all; position: fixed; right: 16px; top: 50%;\n transform: translateY(-50%); background: #ffffff; border: 1px solid #e2e8f0;\n border-radius: 8px; box-shadow: 0 4px 24px rgba(0,0,0,0.15);\n padding: 16px; min-width: 320px; max-width: 400px;\n }\n .nga-panel-title {\n margin: 0 0 12px; font-size: 14px; font-weight: 600;\n color: #1e293b; font-family: monospace;\n }\n .nga-inputs { margin-bottom: 10px; }\n .nga-input-row {\n display: flex; gap: 8px; font-size: 12px;\n font-family: monospace; margin-bottom: 4px;\n }\n .nga-input-key { color: #64748b; min-width: 80px; }\n .nga-input-val {\n color: #1e293b; overflow: hidden;\n text-overflow: ellipsis; white-space: nowrap;\n }\n .nga-selection {\n font-size: 12px; color: #475569; margin-bottom: 8px; font-style: italic;\n }\n .nga-textarea, .nga-reply-input {\n width: 100%; box-sizing: border-box; border: 1px solid #cbd5e1;\n border-radius: 4px; padding: 8px; font-size: 13px;\n font-family: inherit; resize: vertical; margin-bottom: 10px;\n }\n .nga-textarea:focus, .nga-reply-input:focus {\n outline: none; border-color: #3b82f6;\n }\n .nga-actions { display: flex; gap: 8px; }\n .nga-btn {\n padding: 6px 14px; border-radius: 4px; font-size: 13px;\n cursor: pointer; border: none; transition: opacity 0.15s;\n }\n .nga-btn:disabled { opacity: 0.4; cursor: not-allowed; }\n .nga-btn-submit { background: #3b82f6; color: #ffffff; }\n .nga-btn-cancel { background: #f1f5f9; color: #475569; }\n .nga-replies { max-height: 200px; overflow-y: auto; margin-bottom: 10px; }\n .nga-reply { display: flex; gap: 8px; margin-bottom: 8px; font-size: 13px; }\n .nga-reply-author { font-weight: 600; min-width: 48px; }\n .nga-reply-author--agent { color: #7c3aed; }\n .nga-reply-author--user { color: #2563eb; }\n .nga-badge {\n pointer-events: all; position: fixed; width: 18px; height: 18px;\n border-radius: 50%; display: flex; align-items: center;\n justify-content: center; font-size: 10px; cursor: pointer;\n transform: translate(-50%, -50%);\n }\n .nga-badge--pending { background: #3b82f6; color: #ffffff; }\n .nga-badge--acknowledged { background: #f59e0b; color: #ffffff; }\n .nga-badge--resolved { background: #22c55e; color: #ffffff; }\n .nga-badge--dismissed { background: #94a3b8; color: #ffffff; }\n .nga-keyboard-hint {\n pointer-events: none; position: fixed; bottom: 16px; right: 16px;\n background: rgba(15,23,42,0.7); color: #f8fafc; font-size: 12px;\n padding: 6px 10px; border-radius: 6px;\n }\n .nga-keyboard-hint kbd {\n background: rgba(255,255,255,0.15); border-radius: 3px;\n padding: 1px 5px; font-family: monospace;\n }\n `],\n template: `\n <!-- Keyboard hint -->\n @if (mode === 'hidden') {\n <div class=\"nga-keyboard-hint\">\n <kbd>Alt+Shift+A</kbd> to annotate\n </div>\n }\n @if (mode === 'inspect') {\n <div class=\"nga-keyboard-hint\">\n Click a component <kbd>Esc</kbd> to cancel\n </div>\n }\n\n <!-- Inspect highlight rect -->\n @if (mode === 'inspect' && hoveredContext !== null && highlightRect !== null) {\n <div\n class=\"nga-highlight-rect\"\n [style.top]=\"highlightRect.top\"\n [style.left]=\"highlightRect.left\"\n [style.width]=\"highlightRect.width\"\n [style.height]=\"highlightRect.height\"\n >\n <span class=\"nga-component-label\">{{ hoveredContext.componentName }}</span>\n </div>\n }\n\n <!-- Annotate panel -->\n @if (mode === 'annotate' && selectedContext !== null) {\n <div class=\"nga-annotate-panel\">\n <h3 class=\"nga-panel-title\">{{ selectedContext.componentName }}</h3>\n\n @if (inputEntries().length > 0) {\n <div class=\"nga-inputs\">\n @for (entry of inputEntries(); track entry.key) {\n <div class=\"nga-input-row\">\n <span class=\"nga-input-key\">{{ entry.key }}:</span>\n <span class=\"nga-input-val\">{{ entry.value | json }}</span>\n </div>\n }\n </div>\n }\n\n @if (selectionText) {\n <div class=\"nga-selection\">\n <em>\"{{ selectionText }}\"</em>\n </div>\n }\n\n <textarea\n #textArea\n class=\"nga-textarea\"\n [(ngModel)]=\"annotationText\"\n placeholder=\"Describe the change...\"\n rows=\"4\"\n (keydown.shift.enter)=\"$event.preventDefault(); submit()\"\n ></textarea>\n\n <div class=\"nga-actions\">\n <button class=\"nga-btn nga-btn-submit\" (click)=\"submit()\" [disabled]=\"annotationText.trim() === ''\">\n Submit <small style=\"opacity:0.7;font-size:11px\">Shift+Enter</small>\n </button>\n <button class=\"nga-btn nga-btn-cancel\" (click)=\"cancel()\">Cancel</button>\n </div>\n </div>\n }\n\n <!-- Thread panel -->\n @if (mode === 'thread' && threadAnnotation !== null) {\n <div class=\"nga-thread-panel\">\n <h3 class=\"nga-panel-title\">{{ threadAnnotation.componentName }}</h3>\n\n <div class=\"nga-replies\">\n @for (reply of threadAnnotation.replies; track reply.message) {\n <div class=\"nga-reply\">\n <span class=\"nga-reply-author nga-reply-author--{{ reply.author }}\">{{ reply.author }}</span>\n <span class=\"nga-reply-text\">{{ reply.message }}</span>\n </div>\n }\n </div>\n\n <input\n class=\"nga-reply-input\"\n type=\"text\"\n [(ngModel)]=\"replyText\"\n placeholder=\"Reply...\"\n (keydown.enter)=\"sendReply()\"\n />\n\n <div class=\"nga-actions\">\n <button class=\"nga-btn nga-btn-submit\" (click)=\"sendReply()\" [disabled]=\"replyText.trim() === ''\">\n Send\n </button>\n <button class=\"nga-btn nga-btn-cancel\" (click)=\"closeThread()\">Close</button>\n </div>\n </div>\n }\n\n <!-- Annotation badges -->\n @for (badge of badges; track badge.annotation.id) {\n <div\n class=\"nga-badge nga-badge--{{ badge.annotation.status }}\"\n [style.top]=\"badge.top\"\n [style.left]=\"badge.left\"\n (click)=\"openThread(badge.annotation)\"\n [title]=\"badge.label\"\n >\n {{ badge.icon }}\n </div>\n }\n `,\n})\nexport class OverlayComponent implements OnInit {\n @ViewChild('textArea') textArea?: ElementRef<HTMLTextAreaElement>;\n\n mode: OverlayMode = 'hidden';\n hoveredContext: ComponentContext | null = null;\n highlightRect: HighlightRect | null = null;\n selectedContext: ComponentContext | null = null;\n annotationText = '';\n selectionText = '';\n threadAnnotation: Annotation | null = null;\n replyText = '';\n badges: AnnotationBadge[] = [];\n\n private readonly inspector = inject(InspectorService);\n private readonly bridge = inject(BridgeService);\n private readonly cdr = inject(ChangeDetectorRef);\n\n ngOnInit(): void {\n this.bridge.annotations$.subscribe((annotations) => {\n this.updateBadges(annotations);\n this.cdr.markForCheck();\n });\n }\n\n @HostListener('document:keydown.alt.shift.a', ['$event'])\n toggleInspect(event?: Event): void {\n event?.preventDefault();\n if (this.mode === 'hidden') this.mode = 'inspect';\n else if (this.mode === 'inspect') this.mode = 'hidden';\n else if (this.mode === 'annotate') this.mode = 'inspect';\n this.cdr.markForCheck();\n }\n\n @HostListener('document:keydown.escape')\n onEscape(): void {\n if (this.mode === 'annotate') this.mode = 'inspect';\n else if (this.mode === 'inspect') this.mode = 'hidden';\n else if (this.mode === 'thread') this.mode = 'hidden';\n this.cdr.markForCheck();\n }\n\n @HostListener('window:scroll')\n @HostListener('window:resize')\n onScrollOrResize(): void {\n if (this.badges.length > 0) {\n this.refreshBadgePositions();\n this.cdr.markForCheck();\n }\n }\n\n @HostListener('document:mousemove', ['$event'])\n onMouseMove(event: MouseEvent): void {\n if (this.mode !== 'inspect') return;\n const target = event.target as Element;\n if (target.closest('nga-overlay')) return;\n const context = this.inspector.getComponentContext(target);\n this.hoveredContext = context;\n if (context) {\n const rect = target.getBoundingClientRect();\n this.highlightRect = {\n top: `${rect.top.toString()}px`,\n left: `${rect.left.toString()}px`,\n width: `${rect.width.toString()}px`,\n height: `${rect.height.toString()}px`,\n };\n } else {\n this.highlightRect = null;\n }\n this.cdr.markForCheck();\n }\n\n @HostListener('document:click', ['$event'])\n onClick(event: MouseEvent): void {\n if (this.mode !== 'inspect') return;\n const target = event.target as Element;\n if (target.closest('nga-overlay')) return;\n const context = this.inspector.getComponentContext(target);\n if (!context) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n this.selectedContext = context;\n this.annotationText = '';\n this.selectionText = window.getSelection()?.toString() ?? '';\n this.mode = 'annotate';\n this.cdr.markForCheck();\n\n setTimeout(() => { this.textArea?.nativeElement.focus(); }, 0);\n }\n\n submit(): void {\n if (!this.selectedContext || !this.annotationText.trim()) return;\n this.bridge.createAnnotation({\n ...this.selectedContext,\n annotationText: this.annotationText.trim(),\n selectionText: this.selectionText || undefined,\n });\n this.selectedContext = null;\n this.annotationText = '';\n this.mode = 'inspect';\n this.cdr.markForCheck();\n }\n\n cancel(): void {\n this.mode = 'inspect';\n this.cdr.markForCheck();\n }\n\n openThread(annotation: Annotation): void {\n this.threadAnnotation = annotation;\n this.mode = 'thread';\n this.cdr.markForCheck();\n }\n\n closeThread(): void {\n this.threadAnnotation = null;\n this.mode = 'hidden';\n this.cdr.markForCheck();\n }\n\n sendReply(): void {\n if (!this.threadAnnotation || !this.replyText.trim()) return;\n this.bridge.replyToAnnotation(this.threadAnnotation.id, this.replyText.trim());\n this.replyText = '';\n this.cdr.markForCheck();\n }\n\n inputEntries(): { key: string; value: unknown }[] {\n if (!this.selectedContext) return [];\n return Object.entries(this.selectedContext.inputs)\n .slice(0, 5)\n .map(([key, value]) => ({ key, value }));\n }\n\n private updateBadges(annotations: Annotation[]): void {\n this.badges = annotations\n .map((annotation) => {\n const el = this.findComponentElement(annotation.componentName, annotation.selector);\n if (!el) return null;\n const rect = el.getBoundingClientRect();\n return {\n annotation,\n top: `${rect.top.toString()}px`,\n left: `${(rect.left + rect.width - 12).toString()}px`,\n icon: this.badgeIcon(annotation.status),\n label: `${annotation.componentName}: ${annotation.annotationText.slice(0, 40)}`,\n };\n })\n .filter((b): b is AnnotationBadge => b !== null);\n }\n\n private refreshBadgePositions(): void {\n this.badges = this.badges.map((badge) => {\n const el = this.findComponentElement(badge.annotation.componentName, badge.annotation.selector);\n if (!el) return badge;\n const rect = el.getBoundingClientRect();\n return {\n ...badge,\n top: `${rect.top.toString()}px`,\n left: `${(rect.left + rect.width - 12).toString()}px`,\n };\n });\n }\n\n private findComponentElement(componentName: string, selector: string): Element | null {\n const bySelector = document.querySelector(selector);\n if (bySelector) return bySelector;\n\n const all = document.querySelectorAll('*');\n for (const el of Array.from(all)) {\n try {\n const comp = (window as unknown as { ng?: { getComponent: (el: Element) => { constructor: { name: string } } | null } })\n .ng;\n if (comp?.getComponent(el)?.constructor.name === componentName) return el;\n } catch {\n // ignore\n }\n }\n return null;\n }\n\n private badgeIcon(status: AnnotationStatus): string {\n const icons: Record<AnnotationStatus, string> = {\n pending: '●',\n acknowledged: '◐',\n resolved: '✓',\n dismissed: '✕',\n };\n return icons[status];\n }\n}\n","import {\n NgModule,\n isDevMode,\n provideAppInitializer,\n inject,\n ApplicationRef,\n EnvironmentInjector,\n createComponent,\n} from '@angular/core';\nimport { InspectorService } from './inspector.service';\nimport { BridgeService } from './bridge.service';\nimport { OverlayComponent } from './overlay/overlay.component';\n\n@NgModule({\n providers: isDevMode()\n ? [\n InspectorService,\n BridgeService,\n provideAppInitializer(() => {\n const bridge = inject(BridgeService);\n const appRef = inject(ApplicationRef);\n const envInjector = inject(EnvironmentInjector);\n bridge.init();\n const overlayRef = createComponent(OverlayComponent, { environmentInjector: envInjector });\n appRef.attachView(overlayRef.hostView);\n document.body.appendChild(overlayRef.location.nativeElement);\n }),\n ]\n : [],\n})\n// eslint-disable-next-line @typescript-eslint/no-extraneous-class -- required by NgModule pattern\nexport class NgAnnotateModule {}\n","import {\n ApplicationRef,\n EnvironmentInjector,\n createComponent,\n inject,\n isDevMode,\n makeEnvironmentProviders,\n provideAppInitializer,\n} from '@angular/core';\nimport { InspectorService } from './inspector.service';\nimport { BridgeService } from './bridge.service';\nimport { OverlayComponent } from './overlay/overlay.component';\n\nexport function provideNgAnnotate() {\n return makeEnvironmentProviders([\n InspectorService,\n BridgeService,\n provideAppInitializer(() => {\n if (!isDevMode()) return;\n const bridge = inject(BridgeService);\n const appRef = inject(ApplicationRef);\n const envInjector = inject(EnvironmentInjector);\n bridge.init();\n const overlayRef = createComponent(OverlayComponent, { environmentInjector: envInjector });\n appRef.attachView(overlayRef.hostView);\n document.body.appendChild(overlayRef.location.nativeElement);\n }),\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ng-annotate/angular",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"schematics": "./schematics/collection.json",
|
|
5
5
|
"builders": "./builders.json",
|
|
6
6
|
"description": "Angular library for ng-annotate-mcp — browser overlay for annotating components and routing instructions to an AI agent",
|