@ingcreators/annot-product-docs-astro 0.2.2 → 0.3.0
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/CHANGELOG.md +141 -0
- package/README.md +22 -33
- package/dist/index.d.ts +1 -1
- package/dist/index.js +112 -6
- package/dist/playwright/index.d.ts +35 -4
- package/dist/playwright/index.js +6 -224
- package/dist/render.d.ts +1 -57
- package/package.json +3 -8
- package/dist/playwright/fixture.d.ts +0 -72
- package/dist/playwright/rebase.d.ts +0 -36
- package/dist/render-BSQOeqPB.js +0 -164
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,146 @@
|
|
|
1
1
|
# @ingcreators/annot-product-docs-astro
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- f5dc7cb: **`@ingcreators/annot-product-docs-astro/playwright` becomes a
|
|
8
|
+
deprecated re-export** — Phase 4 of
|
|
9
|
+
`docs/plans/playwright-screenshot-fixture-relayer.md`. The fixture
|
|
10
|
+
that originally lived here moved to `@ingcreators/annot-playwright`
|
|
11
|
+
(generic patch) + `@ingcreators/annot-product-docs` (MDX resolver)
|
|
12
|
+
in Phases 1–3 of the plan. Phase 4 deletes the duplicate code
|
|
13
|
+
from this package and converts the `/playwright` subpath into a
|
|
14
|
+
shim that re-exports the canonical surface so existing callers
|
|
15
|
+
keep compiling.
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
// Was:
|
|
19
|
+
import { test } from "@ingcreators/annot-product-docs-astro/playwright";
|
|
20
|
+
|
|
21
|
+
// Now (recommended):
|
|
22
|
+
import { test } from "@ingcreators/annot-product-docs"; // with MDX
|
|
23
|
+
// or
|
|
24
|
+
import { test } from "@ingcreators/annot-playwright"; // without MDX
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The deprecated subpath emits a one-time
|
|
28
|
+
`process.emitWarning("DeprecationWarning", …)` at import time so
|
|
29
|
+
the migration prompt shows up in CI logs. **Reference equality
|
|
30
|
+
preserved** — `test`, `expect`, `patchScreenshot`,
|
|
31
|
+
`rebaseAnnotations`, `describeAnnotation` are reference-equal to
|
|
32
|
+
their canonical homes; a new
|
|
33
|
+
`packages/product-docs-astro/src/playwright/index.test.ts`
|
|
34
|
+
asserts this.
|
|
35
|
+
|
|
36
|
+
**Removal target**: `@ingcreators/annot-product-docs-astro@0.5.0`,
|
|
37
|
+
matching the OQ-2 decision (b) in the parent plan — visible
|
|
38
|
+
deprecation, known sunset.
|
|
39
|
+
|
|
40
|
+
## render.ts switches to the canonical helpers
|
|
41
|
+
|
|
42
|
+
`renderAnnotatedScreen()` previously carried its own copies of
|
|
43
|
+
`resolveMdxAnnotations` / `parseSnapshotBoxes` /
|
|
44
|
+
`buildBadgeAnnotations` / `svgFromBadges` / `svgFromBboxAnnotations`
|
|
45
|
+
/ `emptyAnnotationsSvg`. Phase 2 of the plan moved the canonical
|
|
46
|
+
home into `@ingcreators/annot-product-docs`; this PR deletes the
|
|
47
|
+
duplicates from `product-docs-astro/render.ts` and consumes the
|
|
48
|
+
ones in product-docs going forward.
|
|
49
|
+
|
|
50
|
+
`resolveMdxAnnotations` + `svgFromBboxAnnotations` are re-exported
|
|
51
|
+
from `render.ts` for one deprecation cycle so existing callers
|
|
52
|
+
that imported them from `@ingcreators/annot-product-docs-astro`
|
|
53
|
+
keep compiling. `parseSnapshotBoxes` is dropped from the public
|
|
54
|
+
surface — new code should import it from
|
|
55
|
+
`@ingcreators/annot-product-docs` directly.
|
|
56
|
+
|
|
57
|
+
## peerDependencies cleanup
|
|
58
|
+
|
|
59
|
+
`@playwright/test` is removed from `peerDependencies` (and from
|
|
60
|
+
`peerDependenciesMeta`). The package no longer has a Playwright
|
|
61
|
+
relationship to advertise — the `/playwright` subpath is purely
|
|
62
|
+
a re-export shim, and its types flow through the
|
|
63
|
+
`@ingcreators/annot-product-docs` workspace dep transitively.
|
|
64
|
+
This matches the OQ-3 decision (b) in the parent plan.
|
|
65
|
+
|
|
66
|
+
## Verified
|
|
67
|
+
- `pnpm -r typecheck` — 20 packages, all pass.
|
|
68
|
+
- `pnpm test` — 252 files, 3641 tests, 0 failures. New
|
|
69
|
+
`playwright/index.test.ts` (5 reference-equality assertions)
|
|
70
|
+
passes; the deprecation `process.emitWarning` fires on
|
|
71
|
+
import (visible in vitest output) but does not break anything.
|
|
72
|
+
- `pnpm lint` — exit 0; 29 pre-existing warnings unchanged.
|
|
73
|
+
- `pnpm --filter @ingcreators/annot-product-docs-astro build` —
|
|
74
|
+
emits `dist/index.js` (3.96 kB / 1.71 kB gzip) +
|
|
75
|
+
`dist/playwright/index.js` (0.85 kB / 0.39 kB gzip) — the
|
|
76
|
+
shrunken subpath bundle reflects the re-export-only shape.
|
|
77
|
+
|
|
78
|
+
### Patch Changes
|
|
79
|
+
|
|
80
|
+
- 85d40e6: **Docs + CLAUDE.md + plan archive** — Phase 5 (final) of
|
|
81
|
+
`docs/plans/_done/playwright-screenshot-fixture-relayer.md`.
|
|
82
|
+
Refreshes the doc surfaces, the operational CLAUDE.md notes,
|
|
83
|
+
and archives the relayer plan into `_done/`.
|
|
84
|
+
|
|
85
|
+
## Doc surface updates
|
|
86
|
+
- `packages/docs-site/src/content/docs/product-docs/playwright-fixture.mdx`
|
|
87
|
+
— recommended import paths updated; new "Choosing your import"
|
|
88
|
+
section covers the `@ingcreators/annot-product-docs` (MDX)
|
|
89
|
+
vs. `@ingcreators/annot-playwright` (no MDX) split; companion
|
|
90
|
+
helpers section now imports from the canonical homes; codegen
|
|
91
|
+
workflow example swapped to `@ingcreators/annot-product-docs`.
|
|
92
|
+
- `packages/docs-site/src/content/docs/api/create-annotator.mdx`
|
|
93
|
+
— "From a Playwright test" example imports from the canonical
|
|
94
|
+
home; mentions the no-MDX alternative.
|
|
95
|
+
- `packages/playwright/README.md` — adds the
|
|
96
|
+
`page.screenshot({ annot: { … } })` (recommended) section
|
|
97
|
+
above the existing `annotator.annotateScreenshot(...)` flow;
|
|
98
|
+
documents the `annotSourceResolvers` extension hook + the
|
|
99
|
+
coordinate-rebase helpers.
|
|
100
|
+
- `packages/product-docs/README.md` — adds a `page.screenshot({
|
|
101
|
+
annot })` Playwright fixture section explaining the
|
|
102
|
+
productDocs.sync + MDX-resolver bundle.
|
|
103
|
+
- `packages/product-docs-astro/README.md` — replaces the
|
|
104
|
+
Playwright fixture section with a Migration note pointing at
|
|
105
|
+
the canonical homes; documents the `0.5.0` removal target.
|
|
106
|
+
|
|
107
|
+
## CLAUDE.md monorepo layout
|
|
108
|
+
- `playwright/` entry now describes the canonical
|
|
109
|
+
`page.screenshot({ annot })` patch + `annotSourceResolvers`
|
|
110
|
+
extension hook. Version bumped to 0.4.0.
|
|
111
|
+
- `product-docs/` entry mentions the `productDocs` fixture
|
|
112
|
+
rename + the MDX-aware resolver registration via the hook
|
|
113
|
+
registry. Version bumped to 0.3.0.
|
|
114
|
+
- `product-docs-astro/` entry calls out the deprecated
|
|
115
|
+
`/playwright` re-export shim + 0.5.0 removal target.
|
|
116
|
+
`@playwright/test` no longer a peer dep. Version bumped to
|
|
117
|
+
0.3.0.
|
|
118
|
+
|
|
119
|
+
## Plan archive
|
|
120
|
+
- `docs/plans/playwright-screenshot-fixture-relayer.md` →
|
|
121
|
+
`docs/plans/_done/playwright-screenshot-fixture-relayer.md`.
|
|
122
|
+
Status header switched to `Done` with the four landing PRs
|
|
123
|
+
enumerated. Internal `./_done/...` link paths updated to
|
|
124
|
+
`./...` (the plan is itself inside `_done/` now).
|
|
125
|
+
- `docs/plans/README.md` — removed the active entry, added a
|
|
126
|
+
"Recently landed plans" row pointing at the archived plan
|
|
127
|
+
with a multi-phase summary covering all four landing PRs.
|
|
128
|
+
- `docs/plans/living-spec-authoring-roadmap.md` — three link
|
|
129
|
+
references updated to point at the archived path; the "How
|
|
130
|
+
this relates" line switched from "Already Draft" to "Landed
|
|
131
|
+
2026-05-22 (PRs #962 / #963 / #964 / #966)".
|
|
132
|
+
|
|
133
|
+
No source code changes; verified via `pnpm -r typecheck`,
|
|
134
|
+
`pnpm test`, `pnpm lint` regardless to confirm the doc/comment
|
|
135
|
+
edits parse cleanly.
|
|
136
|
+
|
|
137
|
+
- Updated dependencies [f979374]
|
|
138
|
+
- Updated dependencies [5778902]
|
|
139
|
+
- Updated dependencies [96e7625]
|
|
140
|
+
- Updated dependencies [85d40e6]
|
|
141
|
+
- @ingcreators/annot-playwright@0.4.0
|
|
142
|
+
- @ingcreators/annot-product-docs@0.3.0
|
|
143
|
+
|
|
3
144
|
## 0.2.2
|
|
4
145
|
|
|
5
146
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -89,41 +89,30 @@ When the stored snapshot lacks `[box=x,y,w,h]` markers (no
|
|
|
89
89
|
Playwright tour has run yet), the function returns the base
|
|
90
90
|
PNG verbatim with `hadBoundingBoxes: false`.
|
|
91
91
|
|
|
92
|
-
## Playwright fixture
|
|
92
|
+
## Migration — Playwright fixture moved
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
`
|
|
98
|
-
|
|
99
|
-
one
|
|
100
|
-
`page.screenshot` + `screen.capture` + `renderAnnotatedScreen`
|
|
101
|
-
+ `writeFile` quartet:
|
|
94
|
+
> The Playwright fixture that previously lived at
|
|
95
|
+
> `@ingcreators/annot-product-docs-astro/playwright` moved out
|
|
96
|
+
> of this package as part of
|
|
97
|
+
> [`docs/plans/_done/playwright-screenshot-fixture-relayer.md`](https://github.com/ingcreators/annot/blob/main/docs/plans/_done/playwright-screenshot-fixture-relayer.md)
|
|
98
|
+
> (Phases 1–4). Code authoring a Playwright spec should pick
|
|
99
|
+
> one of the two canonical homes:
|
|
102
100
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
Calls without `annot` (or with `annot: true` / `{}`) fall
|
|
119
|
-
through to vanilla Playwright byte-for-byte — codegen-emitted
|
|
120
|
-
calls keep working unedited. See the docs at
|
|
121
|
-
[`annot.work/docs/product-docs/playwright-fixture/`](https://annot.work/docs/product-docs/playwright-fixture/)
|
|
122
|
-
for the compositional vocabulary, locator screenshot semantics,
|
|
123
|
-
and the codegen→hand-edit workflow.
|
|
124
|
-
|
|
125
|
-
`@playwright/test` is an **optional peer** — Astro-only users
|
|
126
|
-
don't need to install it.
|
|
101
|
+
| Use case | Import |
|
|
102
|
+
|---|---|
|
|
103
|
+
| Living-product-docs tour (MDX-linked `annot.mdx`) | `import { test } from "@ingcreators/annot-product-docs";` |
|
|
104
|
+
| VRT specs / marketing screenshots / AI agent flows (no MDX) | `import { test } from "@ingcreators/annot-playwright";` |
|
|
105
|
+
|
|
106
|
+
The `@ingcreators/annot-product-docs-astro/playwright` subpath
|
|
107
|
+
remains as a deprecated re-export so existing callers still
|
|
108
|
+
compile; it emits a `DeprecationWarning` at import time and
|
|
109
|
+
will be removed in `@ingcreators/annot-product-docs-astro@0.5.0`.
|
|
110
|
+
`@playwright/test` is no longer a peer dep of this package —
|
|
111
|
+
the canonical homes carry the relationship now.
|
|
112
|
+
|
|
113
|
+
`renderAnnotatedScreen` (the Astro Image Service) lives on as
|
|
114
|
+
the build-time renderer for the `<Screen>` block; this section
|
|
115
|
+
isn't going anywhere.
|
|
127
116
|
|
|
128
117
|
## Tier
|
|
129
118
|
|
package/dist/index.d.ts
CHANGED
|
@@ -4,4 +4,4 @@ export type { GraphDirection, GraphEdge, Match, OverlayIntent, ScreenListEntry,
|
|
|
4
4
|
export type { ProductDocsIntegrationOptions } from './integration.js';
|
|
5
5
|
export { productDocsIntegration } from './integration.js';
|
|
6
6
|
export type { RenderAnnotatedScreenOptions, RenderResult, } from './render.js';
|
|
7
|
-
export {
|
|
7
|
+
export { renderAnnotatedScreen, resolveMdxAnnotations, svgFromBboxAnnotations } from './render.js';
|
package/dist/index.js
CHANGED
|
@@ -1,18 +1,124 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createHash as e } from "node:crypto";
|
|
2
|
+
import { mkdir as t, readFile as n, writeFile as r } from "node:fs/promises";
|
|
3
|
+
import { dirname as i, isAbsolute as a, join as o, resolve as s } from "node:path";
|
|
4
|
+
import { createAnnotator as c } from "@ingcreators/annot-annotator";
|
|
5
|
+
import { buildBadgeAnnotations as l, emptyAnnotationsSvg as u, parseMdxFile as d, parseSnapshotBoxes as f, resolveMdxAnnotations as p, svgFromBadges as m, svgFromBboxAnnotations as h } from "@ingcreators/annot-product-docs";
|
|
6
|
+
//#region src/cache.ts
|
|
7
|
+
var g = 1;
|
|
8
|
+
function _(t) {
|
|
9
|
+
let n = e("sha256");
|
|
10
|
+
return n.update("v1\n"), n.update(t.mdxSource), n.update("\0"), n.update(t.screenId), t.editable && n.update("\0editable"), n.digest("hex");
|
|
11
|
+
}
|
|
12
|
+
function v(e) {
|
|
13
|
+
return {
|
|
14
|
+
dir: e,
|
|
15
|
+
async get(t) {
|
|
16
|
+
try {
|
|
17
|
+
let r = await n(o(e, `${t}.png`));
|
|
18
|
+
return new Uint8Array(r.buffer, r.byteOffset, r.byteLength);
|
|
19
|
+
} catch (e) {
|
|
20
|
+
if (e.code === "ENOENT") return null;
|
|
21
|
+
throw e;
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
async set(n, a) {
|
|
25
|
+
let s = o(e, `${n}.png`);
|
|
26
|
+
await t(i(s), { recursive: !0 }), await r(s, a);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function y() {
|
|
31
|
+
let e = /* @__PURE__ */ new Map();
|
|
32
|
+
return {
|
|
33
|
+
dir: ":memory:",
|
|
34
|
+
async get(t) {
|
|
35
|
+
return e.get(t) ?? null;
|
|
36
|
+
},
|
|
37
|
+
async set(t, n) {
|
|
38
|
+
e.set(t, n);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
2
43
|
//#region src/integration.ts
|
|
3
|
-
var
|
|
4
|
-
function
|
|
44
|
+
var b = "@ingcreators/annot-product-docs-astro";
|
|
45
|
+
function x(e = {}) {
|
|
5
46
|
let t = {
|
|
6
47
|
contentDir: e.contentDir ?? "docs",
|
|
7
48
|
configPath: e.configPath ?? "annot-docs.config.ts",
|
|
8
49
|
verbose: e.verbose ?? !1
|
|
9
50
|
};
|
|
10
51
|
return {
|
|
11
|
-
name:
|
|
52
|
+
name: b,
|
|
12
53
|
hooks: { "astro:config:setup": ({ logger: e }) => {
|
|
13
|
-
t.verbose && e.info(`${
|
|
54
|
+
t.verbose && e.info(`${b} installed — contentDir=${t.contentDir} configPath=${t.configPath}`);
|
|
14
55
|
} }
|
|
15
56
|
};
|
|
16
57
|
}
|
|
17
58
|
//#endregion
|
|
18
|
-
|
|
59
|
+
//#region src/render.ts
|
|
60
|
+
async function S(e) {
|
|
61
|
+
let t = e.cwd ?? process.cwd(), n = a(e.mdxPath) ? e.mdxPath : s(t, e.mdxPath), r = await d(n);
|
|
62
|
+
if (!r) throw Error(`renderAnnotatedScreen: ${e.mdxPath} has no \`annot:\` frontmatter — cannot render.`);
|
|
63
|
+
let o = r.screens.find((t) => t.id === e.screenId);
|
|
64
|
+
if (!o) throw Error(`renderAnnotatedScreen: ${e.mdxPath} has no <Screen id="${e.screenId}"> block.`);
|
|
65
|
+
let p = C(e.editable), h = _({
|
|
66
|
+
mdxSource: r.source,
|
|
67
|
+
screenId: e.screenId,
|
|
68
|
+
editable: p !== null
|
|
69
|
+
});
|
|
70
|
+
if (e.cache) {
|
|
71
|
+
let t = await e.cache.get(h);
|
|
72
|
+
if (t) return {
|
|
73
|
+
bytes: t,
|
|
74
|
+
fromCache: !0,
|
|
75
|
+
hadBoundingBoxes: !0
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
let g = e.basePngBytes ?? await w(r, o.src, i(n)), v = T(g), y = f(r.commentBlocks.snapshot ?? ""), b = l(o.overlays, y, v), x, S;
|
|
79
|
+
if (b.length === 0) if (S = !1, p !== null) {
|
|
80
|
+
let e = `data:image/png;base64,${Buffer.from(g).toString("base64")}`;
|
|
81
|
+
x = c({ loadSystemFonts: !0 }).toEditablePng({
|
|
82
|
+
originalDataUrl: e,
|
|
83
|
+
annotationsSvg: u(),
|
|
84
|
+
width: v.width,
|
|
85
|
+
height: v.height,
|
|
86
|
+
tags: p.tags
|
|
87
|
+
});
|
|
88
|
+
} else x = g;
|
|
89
|
+
else {
|
|
90
|
+
let e = `data:image/png;base64,${Buffer.from(g).toString("base64")}`, t = m(b), n = c({ loadSystemFonts: !0 }), r = {
|
|
91
|
+
originalDataUrl: e,
|
|
92
|
+
annotationsSvg: t,
|
|
93
|
+
width: v.width,
|
|
94
|
+
height: v.height
|
|
95
|
+
};
|
|
96
|
+
x = p === null ? n.toPng(r) : n.toEditablePng({
|
|
97
|
+
...r,
|
|
98
|
+
tags: p.tags
|
|
99
|
+
}), S = !0;
|
|
100
|
+
}
|
|
101
|
+
return e.cache && await e.cache.set(h, x), {
|
|
102
|
+
bytes: x,
|
|
103
|
+
fromCache: !1,
|
|
104
|
+
hadBoundingBoxes: S
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function C(e) {
|
|
108
|
+
return e ? e === !0 ? {} : e : null;
|
|
109
|
+
}
|
|
110
|
+
async function w(e, t, r) {
|
|
111
|
+
if (!t) throw Error("renderAnnotatedScreen: <Screen src=...> is required — cannot render without a base image.");
|
|
112
|
+
let i = await n(a(t) ? t : s(r, t));
|
|
113
|
+
return new Uint8Array(i.buffer, i.byteOffset, i.byteLength);
|
|
114
|
+
}
|
|
115
|
+
function T(e) {
|
|
116
|
+
if (e.length < 24) throw Error("renderAnnotatedScreen: base PNG too short to contain IHDR.");
|
|
117
|
+
let t = new DataView(e.buffer, e.byteOffset, e.byteLength);
|
|
118
|
+
return {
|
|
119
|
+
width: t.getUint32(16, !1),
|
|
120
|
+
height: t.getUint32(20, !1)
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
//#endregion
|
|
124
|
+
export { g as RENDER_PIPELINE_VERSION, _ as cacheKey, v as createFileCache, y as createMemoryCache, x as productDocsIntegration, S as renderAnnotatedScreen, p as resolveMdxAnnotations, h as svgFromBboxAnnotations };
|
|
@@ -1,5 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated Import `AnnotScreenshotOptions` from
|
|
3
|
+
* `@ingcreators/annot-playwright` — that package owns the
|
|
4
|
+
* canonical interface; `@ingcreators/annot-product-docs` augments
|
|
5
|
+
* it with `mdx`. Re-exporting here is back-compat only and will
|
|
6
|
+
* be removed in `@ingcreators/annot-product-docs-astro@0.5.0`.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* @deprecated Import the rebase helpers (`Clip`, `RebaseResult`,
|
|
10
|
+
* `describeAnnotation`, `rebaseAnnotations`) from
|
|
11
|
+
* `@ingcreators/annot-playwright`. Re-exporting here is
|
|
12
|
+
* back-compat only and will be removed in
|
|
13
|
+
* `@ingcreators/annot-product-docs-astro@0.5.0`.
|
|
14
|
+
*/
|
|
15
|
+
export type { AnnotScreenshotOptions, Clip, RebaseResult } from '@ingcreators/annot-playwright';
|
|
16
|
+
/**
|
|
17
|
+
* @deprecated Import `patchScreenshot` from
|
|
18
|
+
* `@ingcreators/annot-playwright`. Re-exporting here is
|
|
19
|
+
* back-compat only and will be removed in
|
|
20
|
+
* `@ingcreators/annot-product-docs-astro@0.5.0`.
|
|
21
|
+
*/
|
|
22
|
+
export { describeAnnotation, patchScreenshot, rebaseAnnotations, } from '@ingcreators/annot-playwright';
|
|
23
|
+
/**
|
|
24
|
+
* @deprecated Import `test` from `@ingcreators/annot-product-docs`
|
|
25
|
+
* (with MDX support) or `@ingcreators/annot-playwright` (without).
|
|
26
|
+
* Re-exporting here is back-compat only and will be removed in
|
|
27
|
+
* `@ingcreators/annot-product-docs-astro@0.5.0`.
|
|
28
|
+
*/
|
|
29
|
+
export { test } from '@ingcreators/annot-product-docs';
|
|
30
|
+
/**
|
|
31
|
+
* @deprecated Import `expect` from `@ingcreators/annot-playwright`
|
|
32
|
+
* or `@playwright/test` directly. Re-exporting here is back-compat
|
|
33
|
+
* only and will be removed in
|
|
34
|
+
* `@ingcreators/annot-product-docs-astro@0.5.0`.
|
|
35
|
+
*/
|
|
1
36
|
export { expect } from '@playwright/test';
|
|
2
|
-
export type { AnnotScreenshotOptions } from './fixture.js';
|
|
3
|
-
export { patchScreenshot, test } from './fixture.js';
|
|
4
|
-
export type { Clip, RebaseResult } from './rebase.js';
|
|
5
|
-
export { describeAnnotation, rebaseAnnotations } from './rebase.js';
|
package/dist/playwright/index.js
CHANGED
|
@@ -1,225 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import { writePngWithTagsOnly as s } from "@ingcreators/annot-core/xmp-bytes";
|
|
7
|
-
//#region src/playwright/rebase.ts
|
|
8
|
-
function c(e, t) {
|
|
9
|
-
let n = [], r = [];
|
|
10
|
-
for (let i of e) {
|
|
11
|
-
let e = l(i, t);
|
|
12
|
-
e ? n.push(e) : r.push(i);
|
|
13
|
-
}
|
|
14
|
-
return {
|
|
15
|
-
kept: n,
|
|
16
|
-
dropped: r
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
function l(e, t) {
|
|
20
|
-
switch (e.type) {
|
|
21
|
-
case "rect": return u(e, t);
|
|
22
|
-
case "numberedBadge": return d(e, t);
|
|
23
|
-
case "callout": return f(e, t);
|
|
24
|
-
case "circle": return p(e, t);
|
|
25
|
-
case "arrow": return m(e, t);
|
|
26
|
-
case "text": return h(e, t);
|
|
27
|
-
case "raw": return g(e);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
function u(e, t) {
|
|
31
|
-
return y(e.bbox, t) ? {
|
|
32
|
-
...e,
|
|
33
|
-
bbox: _(e.bbox, t)
|
|
34
|
-
} : null;
|
|
35
|
-
}
|
|
36
|
-
function d(e, t) {
|
|
37
|
-
return y(e.bbox, t) ? {
|
|
38
|
-
...e,
|
|
39
|
-
bbox: _(e.bbox, t),
|
|
40
|
-
imageWidth: t.width,
|
|
41
|
-
imageHeight: t.height
|
|
42
|
-
} : null;
|
|
43
|
-
}
|
|
44
|
-
function f(e, t) {
|
|
45
|
-
return !y(e.targetBbox, t) || !b(e.at, t) ? null : {
|
|
46
|
-
...e,
|
|
47
|
-
at: v(e.at, t),
|
|
48
|
-
targetBbox: _(e.targetBbox, t)
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
function p(e, t) {
|
|
52
|
-
return y({
|
|
53
|
-
x: e.center.x - e.radius,
|
|
54
|
-
y: e.center.y - e.radius,
|
|
55
|
-
width: e.radius * 2,
|
|
56
|
-
height: e.radius * 2
|
|
57
|
-
}, t) ? {
|
|
58
|
-
...e,
|
|
59
|
-
center: v(e.center, t)
|
|
60
|
-
} : null;
|
|
61
|
-
}
|
|
62
|
-
function m(e, t) {
|
|
63
|
-
return !b(e.from, t) || !b(e.to, t) ? null : {
|
|
64
|
-
...e,
|
|
65
|
-
from: v(e.from, t),
|
|
66
|
-
to: v(e.to, t)
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
function h(e, t) {
|
|
70
|
-
return b(e.at, t) ? {
|
|
71
|
-
...e,
|
|
72
|
-
at: v(e.at, t)
|
|
73
|
-
} : null;
|
|
74
|
-
}
|
|
75
|
-
function g(e) {
|
|
76
|
-
return e;
|
|
77
|
-
}
|
|
78
|
-
function _(e, t) {
|
|
79
|
-
return {
|
|
80
|
-
x: e.x - t.x,
|
|
81
|
-
y: e.y - t.y,
|
|
82
|
-
width: e.width,
|
|
83
|
-
height: e.height
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
function v(e, t) {
|
|
87
|
-
return {
|
|
88
|
-
x: e.x - t.x,
|
|
89
|
-
y: e.y - t.y
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
function y(e, t) {
|
|
93
|
-
return e.x >= t.x && e.y >= t.y && e.x + e.width <= t.x + t.width && e.y + e.height <= t.y + t.height;
|
|
94
|
-
}
|
|
95
|
-
function b(e, t) {
|
|
96
|
-
return e.x >= t.x && e.y >= t.y && e.x <= t.x + t.width && e.y <= t.y + t.height;
|
|
97
|
-
}
|
|
98
|
-
function x(e) {
|
|
99
|
-
switch (e.type) {
|
|
100
|
-
case "rect":
|
|
101
|
-
case "numberedBadge": return `${e.type}@(${e.bbox.x},${e.bbox.y},${e.bbox.width},${e.bbox.height})`;
|
|
102
|
-
case "callout": return `callout@(${e.targetBbox.x},${e.targetBbox.y},${e.targetBbox.width},${e.targetBbox.height})`;
|
|
103
|
-
case "circle": return `circle@(${e.center.x},${e.center.y},r=${e.radius})`;
|
|
104
|
-
case "arrow": return `arrow@(${e.from.x},${e.from.y})→(${e.to.x},${e.to.y})`;
|
|
105
|
-
case "text": return `text@(${e.at.x},${e.at.y})`;
|
|
106
|
-
case "raw": return "raw[<svg fragment>]";
|
|
107
|
-
}
|
|
108
|
-
}
|
|
1
|
+
import { test as e } from "@ingcreators/annot-product-docs";
|
|
2
|
+
import { describeAnnotation as t, patchScreenshot as n, rebaseAnnotations as r } from "@ingcreators/annot-playwright";
|
|
3
|
+
import { expect as i } from "@playwright/test";
|
|
4
|
+
//#region src/playwright/index.ts
|
|
5
|
+
typeof process < "u" && typeof process.emitWarning == "function" && !globalThis.__annotProductDocsAstroPlaywrightWarned && (globalThis.__annotProductDocsAstroPlaywrightWarned = !0, process.emitWarning("@ingcreators/annot-product-docs-astro/playwright is deprecated. Import from @ingcreators/annot-product-docs (with MDX support) or @ingcreators/annot-playwright (without). This subpath will be removed in @ingcreators/annot-product-docs-astro@0.5.0.", "DeprecationWarning"));
|
|
109
6
|
//#endregion
|
|
110
|
-
|
|
111
|
-
var S = Symbol.for("@ingcreators/annot:screenshot-patched");
|
|
112
|
-
function C(e) {
|
|
113
|
-
let t = e;
|
|
114
|
-
if (t[S]) return;
|
|
115
|
-
let n = e.screenshot;
|
|
116
|
-
e.screenshot = async function(e = {}) {
|
|
117
|
-
let t = e?.annot;
|
|
118
|
-
return w(t) ? D.call(this, n, e) : n.call(this, e);
|
|
119
|
-
}, t[S] = !0;
|
|
120
|
-
}
|
|
121
|
-
function w(e) {
|
|
122
|
-
return !e || e === !0 ? !1 : !!(e.mdx || e.overlays && e.overlays.length > 0 || e.tags);
|
|
123
|
-
}
|
|
124
|
-
function T(e) {
|
|
125
|
-
return typeof e.boundingBox == "function";
|
|
126
|
-
}
|
|
127
|
-
function E(e) {
|
|
128
|
-
return T(e) ? e.page() : e;
|
|
129
|
-
}
|
|
130
|
-
async function D(e, t) {
|
|
131
|
-
let { annot: r, path: a, ...o } = t, s = o, c = r.editable ?? !0;
|
|
132
|
-
r.mdx && await i(E(this), {
|
|
133
|
-
id: r.mdx.id,
|
|
134
|
-
mdxPath: r.mdx.path
|
|
135
|
-
});
|
|
136
|
-
let l = await O(this, t.clip), u = await A({
|
|
137
|
-
rawBytes: k(await e.call(this, {
|
|
138
|
-
...s,
|
|
139
|
-
path: void 0
|
|
140
|
-
})),
|
|
141
|
-
annot: r,
|
|
142
|
-
editable: c,
|
|
143
|
-
clip: l
|
|
144
|
-
});
|
|
145
|
-
return a && await n(a, u), Buffer.from(u);
|
|
146
|
-
}
|
|
147
|
-
async function O(e, t) {
|
|
148
|
-
if (T(e)) {
|
|
149
|
-
let t = await e.boundingBox();
|
|
150
|
-
if (!t) throw Error("locator.screenshot({ annot }): locator has no bounding box (probably not visible). Re-test with a stable selector / waitFor().");
|
|
151
|
-
return t;
|
|
152
|
-
}
|
|
153
|
-
return t ?? null;
|
|
154
|
-
}
|
|
155
|
-
function k(e) {
|
|
156
|
-
return e instanceof Uint8Array && !(e instanceof Buffer) ? e : new Uint8Array(e.buffer, e.byteOffset, e.byteLength);
|
|
157
|
-
}
|
|
158
|
-
async function A(n) {
|
|
159
|
-
let { rawBytes: i, annot: a, editable: o, clip: l } = n, u = N(i), d = [];
|
|
160
|
-
if (a.mdx) {
|
|
161
|
-
let e = l ? {
|
|
162
|
-
width: l.x + l.width,
|
|
163
|
-
height: l.y + l.height
|
|
164
|
-
} : u, n = await t({
|
|
165
|
-
mdxPath: a.mdx.path,
|
|
166
|
-
screenId: a.mdx.id,
|
|
167
|
-
dims: e
|
|
168
|
-
});
|
|
169
|
-
d.push(...n);
|
|
170
|
-
}
|
|
171
|
-
a.overlays && d.push(...a.overlays);
|
|
172
|
-
let f;
|
|
173
|
-
if (l) {
|
|
174
|
-
let { kept: e, dropped: t } = c(d, l);
|
|
175
|
-
f = e, t.length > 0 && j(t);
|
|
176
|
-
} else f = d;
|
|
177
|
-
let p = !!(a.mdx || a.overlays);
|
|
178
|
-
if (p && !o) {
|
|
179
|
-
let t = e(f), n = `data:image/png;base64,${Buffer.from(i).toString("base64")}`, o = r({ loadSystemFonts: !0 }).toPng({
|
|
180
|
-
originalDataUrl: n,
|
|
181
|
-
annotationsSvg: t,
|
|
182
|
-
width: u.width,
|
|
183
|
-
height: u.height
|
|
184
|
-
});
|
|
185
|
-
return a.tags ? s(o, a.tags) : o;
|
|
186
|
-
}
|
|
187
|
-
if (p) {
|
|
188
|
-
let t = e(f), n = `data:image/png;base64,${Buffer.from(i).toString("base64")}`;
|
|
189
|
-
return r({ loadSystemFonts: !0 }).toEditablePng({
|
|
190
|
-
originalDataUrl: n,
|
|
191
|
-
annotationsSvg: t,
|
|
192
|
-
width: u.width,
|
|
193
|
-
height: u.height,
|
|
194
|
-
tags: a.tags
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
return a.tags ? s(i, a.tags) : i;
|
|
198
|
-
}
|
|
199
|
-
function j(e) {
|
|
200
|
-
let t = e.map(x).join(", "), n = `annot fixture: dropped ${e.length} overlay(s) outside the screenshot clip — ${t}`;
|
|
201
|
-
console.warn(n), M(n, e);
|
|
202
|
-
}
|
|
203
|
-
function M(e, t) {
|
|
204
|
-
try {
|
|
205
|
-
let n = a.info?.();
|
|
206
|
-
if (!n?.annotations) return;
|
|
207
|
-
n.annotations.push({
|
|
208
|
-
type: "warning",
|
|
209
|
-
description: `${e} (${t.length} dropped)`
|
|
210
|
-
});
|
|
211
|
-
} catch {}
|
|
212
|
-
}
|
|
213
|
-
function N(e) {
|
|
214
|
-
if (e.length < 24) throw Error("Playwright annot fixture: raw screenshot too short to contain PNG IHDR.");
|
|
215
|
-
let t = new DataView(e.buffer, e.byteOffset, e.byteLength);
|
|
216
|
-
return {
|
|
217
|
-
width: t.getUint32(16, !1),
|
|
218
|
-
height: t.getUint32(20, !1)
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
var P = a.extend({ page: async ({ page: e }, t) => {
|
|
222
|
-
C(Object.getPrototypeOf(e)), C(Object.getPrototypeOf(e.locator("html"))), await t(e);
|
|
223
|
-
} });
|
|
224
|
-
//#endregion
|
|
225
|
-
export { x as describeAnnotation, o as expect, C as patchScreenshot, c as rebaseAnnotations, P as test };
|
|
7
|
+
export { t as describeAnnotation, i as expect, n as patchScreenshot, r as rebaseAnnotations, e as test };
|
package/dist/render.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { BboxNumberedBadgeAnnotation } from '@ingcreators/annot-annotator';
|
|
2
1
|
import { FileCache } from './cache.js';
|
|
2
|
+
export { resolveMdxAnnotations, svgFromBboxAnnotations } from '@ingcreators/annot-product-docs';
|
|
3
3
|
export interface RenderAnnotatedScreenOptions {
|
|
4
4
|
/** Path to the `.mdx` file (absolute or relative to cwd). */
|
|
5
5
|
mdxPath: string;
|
|
@@ -71,59 +71,3 @@ export interface RenderResult {
|
|
|
71
71
|
* and return the result.
|
|
72
72
|
*/
|
|
73
73
|
export declare function renderAnnotatedScreen(options: RenderAnnotatedScreenOptions): Promise<RenderResult>;
|
|
74
|
-
interface BoxedEntry {
|
|
75
|
-
role: string;
|
|
76
|
-
name: string;
|
|
77
|
-
ref: string;
|
|
78
|
-
box: {
|
|
79
|
-
x: number;
|
|
80
|
-
y: number;
|
|
81
|
-
width: number;
|
|
82
|
-
height: number;
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Parse aria-snapshot YAML for entries that carry both `[ref=…]`
|
|
87
|
-
* and `[box=x,y,w,h]` markers. `box` is the Playwright addition
|
|
88
|
-
* available when `ariaSnapshot({ boxes: true })` was passed.
|
|
89
|
-
*
|
|
90
|
-
* Exposed for unit testing. Returns an empty array if no entries
|
|
91
|
-
* have boxes — the caller falls back to a non-annotated render.
|
|
92
|
-
*/
|
|
93
|
-
export declare function parseSnapshotBoxes(yaml: string): BoxedEntry[];
|
|
94
|
-
/**
|
|
95
|
-
* Resolve the `<Overlay>` blocks inside `screenId` against the MDX
|
|
96
|
-
* file's stored `annot:snapshot` block and return a typed annotation
|
|
97
|
-
* array ready to feed into `createAnnotator().toEditablePng()`.
|
|
98
|
-
*
|
|
99
|
-
* Exposed so the Playwright fixture can compose MDX-derived overlays
|
|
100
|
-
* with caller-supplied inline overlays before rasterisation. Throws
|
|
101
|
-
* the same diagnostics `renderAnnotatedScreen` would (no annot
|
|
102
|
-
* frontmatter / no matching `<Screen id>`).
|
|
103
|
-
*
|
|
104
|
-
* Returns an empty array when no `<Overlay>` matches a bbox marker
|
|
105
|
-
* — e.g. the snapshot was never captured, or `<Overlay match>`
|
|
106
|
-
* targets an element that's no longer in the page.
|
|
107
|
-
*/
|
|
108
|
-
export declare function resolveMdxAnnotations(opts: {
|
|
109
|
-
mdxPath: string;
|
|
110
|
-
screenId: string;
|
|
111
|
-
dims: {
|
|
112
|
-
width: number;
|
|
113
|
-
height: number;
|
|
114
|
-
};
|
|
115
|
-
cwd?: string;
|
|
116
|
-
}): Promise<BboxNumberedBadgeAnnotation[]>;
|
|
117
|
-
/**
|
|
118
|
-
* Wrap a generic `BboxAnnotation[]` (the union DSL accepted by
|
|
119
|
-
* `@ingcreators/annot-annotator`) into a single-root `<svg>` ready
|
|
120
|
-
* for the annotator's `annotationsSvg` input. Mirrors `svgFromBadges`
|
|
121
|
-
* but stays type-permissive — the Playwright fixture's inline overlays
|
|
122
|
-
* can be any `BboxAnnotation` shape, not just numbered badges.
|
|
123
|
-
*
|
|
124
|
-
* Returns the empty wrapper `<svg/>` when `annotations` is empty —
|
|
125
|
-
* lets the editor open the file with no annotations layer rather
|
|
126
|
-
* than throwing.
|
|
127
|
-
*/
|
|
128
|
-
export declare function svgFromBboxAnnotations(annotations: import('@ingcreators/annot-annotator').BboxAnnotation[]): string;
|
|
129
|
-
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ingcreators/annot-product-docs-astro",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Astro integration for `@ingcreators/annot-product-docs`. Wires the MDX components (`<Screen>` / `<Overlay>` / `<Transition>` / `<HistoryEntry>` / `<ScreenList>` / `<TransitionGraph>`) into an Astro site and supplies the Image Service that renders annotated PNGs from `<Screen>` blocks at build time. Phase 2 of docs/plans/living-product-docs.md.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "ingcreators",
|
|
@@ -63,17 +63,12 @@
|
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@ingcreators/annot-annotator": "0.5.0",
|
|
65
65
|
"@ingcreators/annot-core": "0.2.1",
|
|
66
|
-
"@ingcreators/annot-product-docs": "0.
|
|
66
|
+
"@ingcreators/annot-product-docs": "0.3.0",
|
|
67
|
+
"@ingcreators/annot-playwright": "0.4.0"
|
|
67
68
|
},
|
|
68
69
|
"peerDependencies": {
|
|
69
|
-
"@playwright/test": "^1.42.0",
|
|
70
70
|
"astro": "^5.0.0 || ^6.0.0"
|
|
71
71
|
},
|
|
72
|
-
"peerDependenciesMeta": {
|
|
73
|
-
"@playwright/test": {
|
|
74
|
-
"optional": true
|
|
75
|
-
}
|
|
76
|
-
},
|
|
77
72
|
"scripts": {
|
|
78
73
|
"build": "vite build",
|
|
79
74
|
"typecheck": "tsc --noEmit"
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { BboxAnnotation } from '@ingcreators/annot-annotator';
|
|
2
|
-
/**
|
|
3
|
-
* Compositional options for `page.screenshot({ annot })` /
|
|
4
|
-
* `locator.screenshot({ annot })`. Each field is an independent
|
|
5
|
-
* contribution to the embedded XMP record:
|
|
6
|
-
*
|
|
7
|
-
* - `mdx` — refresh + resolve MDX `<Overlay>` annotations
|
|
8
|
-
* - `overlays`— inline `BboxAnnotation[]` (the DSL accepted by
|
|
9
|
-
* `@ingcreators/annot-annotator`)
|
|
10
|
-
* - `tags` — provenance metadata written verbatim into the XMP
|
|
11
|
-
* - `editable`— bake-vs-preserve toggle (default `true`)
|
|
12
|
-
*
|
|
13
|
-
* `annot: true` / `annot: {}` is treated as a no-op shorthand — the
|
|
14
|
-
* fixture detects no contribution and the screenshot falls through
|
|
15
|
-
* to vanilla Playwright behaviour.
|
|
16
|
-
*/
|
|
17
|
-
export interface AnnotScreenshotOptions {
|
|
18
|
-
/** Refresh the MDX `annot:snapshot` block and resolve the
|
|
19
|
-
* `<Screen id>`'s overlays. The MDX file is rewritten in-place
|
|
20
|
-
* with the current page's aria-snapshot before overlays resolve.
|
|
21
|
-
*/
|
|
22
|
-
mdx?: {
|
|
23
|
-
id: string;
|
|
24
|
-
path: string;
|
|
25
|
-
};
|
|
26
|
-
/** Caller-supplied annotations — merged with MDX-derived ones if
|
|
27
|
-
* `mdx` is also set. Same DSL `@ingcreators/annot-annotator`
|
|
28
|
-
* accepts. */
|
|
29
|
-
overlays?: BboxAnnotation[];
|
|
30
|
-
/** Provenance metadata written verbatim into the PNG's XMP. The
|
|
31
|
-
* fixture adds no defaults; callers who want `WELL_KNOWN_TAG_KEYS`
|
|
32
|
-
* (`source` / `screen` / `capturedAt` / `commit`) write them. */
|
|
33
|
-
tags?: Record<string, string>;
|
|
34
|
-
/** When `true` (default): annotations stored as SVG in XMP +
|
|
35
|
-
* original capture embedded → re-editable in Annot Cloud. When
|
|
36
|
-
* `false`: annotations baked into the visible pixels, no XMP
|
|
37
|
-
* layer, no embedded original — flat PNG, no round-trip. */
|
|
38
|
-
editable?: boolean;
|
|
39
|
-
}
|
|
40
|
-
declare module "@playwright/test" {
|
|
41
|
-
interface PageScreenshotOptions {
|
|
42
|
-
annot?: AnnotScreenshotOptions;
|
|
43
|
-
}
|
|
44
|
-
interface LocatorScreenshotOptions {
|
|
45
|
-
annot?: AnnotScreenshotOptions;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Idempotent prototype patch — wrap `screenshot` to intercept the
|
|
50
|
-
* `annot` opt while falling through to the original method when
|
|
51
|
-
* absent / empty. Exported for unit tests; production usage flows
|
|
52
|
-
* through the fixture `extend({ page })` body which calls this once
|
|
53
|
-
* per worker on the first page (and once for the locator prototype).
|
|
54
|
-
*/
|
|
55
|
-
export declare function patchScreenshot(proto: {
|
|
56
|
-
screenshot: (opts?: unknown) => Promise<Buffer>;
|
|
57
|
-
}): void;
|
|
58
|
-
/**
|
|
59
|
-
* `test = base.extend({ page })` — drop-in for `@playwright/test`'s
|
|
60
|
-
* `test` plus a one-time patch of `Page.prototype.screenshot` AND
|
|
61
|
-
* `Locator.prototype.screenshot` (per worker process) so calls
|
|
62
|
-
* carrying `annot: { ... }` run the annot pipeline above.
|
|
63
|
-
*
|
|
64
|
-
* The base `test` is `@ingcreators/annot-product-docs`'s test which
|
|
65
|
-
* already extends `@ingcreators/annot-playwright` — callers get
|
|
66
|
-
* `page` + `annotator` + `screen` plus the annot-aware screenshot.
|
|
67
|
-
*/
|
|
68
|
-
export declare const test: import('@playwright/test').TestType<import('@playwright/test').PlaywrightTestArgs & import('@playwright/test').PlaywrightTestOptions & {
|
|
69
|
-
annotator: import('@ingcreators/annot-playwright').PlaywrightAnnotator;
|
|
70
|
-
} & {
|
|
71
|
-
screen: import('@ingcreators/annot-product-docs').Screen;
|
|
72
|
-
}, import('@playwright/test').PlaywrightWorkerArgs & import('@playwright/test').PlaywrightWorkerOptions>;
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { BboxAnnotation } from '@ingcreators/annot-annotator';
|
|
2
|
-
export interface Clip {
|
|
3
|
-
x: number;
|
|
4
|
-
y: number;
|
|
5
|
-
width: number;
|
|
6
|
-
height: number;
|
|
7
|
-
}
|
|
8
|
-
export interface RebaseResult {
|
|
9
|
-
/** Annotations whose coordinates were rebased into clip-space. */
|
|
10
|
-
kept: BboxAnnotation[];
|
|
11
|
-
/** Annotations that fell outside `clip` and were dropped. The
|
|
12
|
-
* caller surfaces these as `RenderResult.droppedOverlays` /
|
|
13
|
-
* `test.info().annotations` warnings. */
|
|
14
|
-
dropped: BboxAnnotation[];
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Rebase + filter a `BboxAnnotation[]` against a clip rectangle.
|
|
18
|
-
*
|
|
19
|
-
* - `kept` = annotations whose visible coords were translated by
|
|
20
|
-
* `(-clip.x, -clip.y)`. The new coords are in the clipped image's
|
|
21
|
-
* coordinate space (0,0 at the top-left of the screenshot).
|
|
22
|
-
* - `dropped` = annotations whose bbox / endpoints fell outside the
|
|
23
|
-
* clip. Returned verbatim (un-rebased) so the caller can log
|
|
24
|
-
* which originals were skipped.
|
|
25
|
-
*
|
|
26
|
-
* `numberedBadge`'s `imageWidth` / `imageHeight` are also rebased
|
|
27
|
-
* to match the clip dimensions, so `placement: "auto"` picks the
|
|
28
|
-
* corner against the cropped image edge rather than the page edge.
|
|
29
|
-
*/
|
|
30
|
-
export declare function rebaseAnnotations(annotations: BboxAnnotation[], clip: Clip): RebaseResult;
|
|
31
|
-
/**
|
|
32
|
-
* Format a short identifier for an annotation so dropped diagnostics
|
|
33
|
-
* stay readable. We don't have a stable id field on the DSL types —
|
|
34
|
-
* use `type` + first bbox coords as a heuristic.
|
|
35
|
-
*/
|
|
36
|
-
export declare function describeAnnotation(ann: BboxAnnotation): string;
|
package/dist/render-BSQOeqPB.js
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import { createHash as e } from "node:crypto";
|
|
2
|
-
import { mkdir as t, readFile as n, writeFile as r } from "node:fs/promises";
|
|
3
|
-
import { dirname as i, isAbsolute as a, join as o, resolve as s } from "node:path";
|
|
4
|
-
import { bboxAnnotationsToSvg as c, createAnnotator as l } from "@ingcreators/annot-annotator";
|
|
5
|
-
import { parseMdxFile as u } from "@ingcreators/annot-product-docs";
|
|
6
|
-
//#region src/cache.ts
|
|
7
|
-
var d = 1;
|
|
8
|
-
function f(t) {
|
|
9
|
-
let n = e("sha256");
|
|
10
|
-
return n.update("v1\n"), n.update(t.mdxSource), n.update("\0"), n.update(t.screenId), t.editable && n.update("\0editable"), n.digest("hex");
|
|
11
|
-
}
|
|
12
|
-
function p(e) {
|
|
13
|
-
return {
|
|
14
|
-
dir: e,
|
|
15
|
-
async get(t) {
|
|
16
|
-
try {
|
|
17
|
-
let r = await n(o(e, `${t}.png`));
|
|
18
|
-
return new Uint8Array(r.buffer, r.byteOffset, r.byteLength);
|
|
19
|
-
} catch (e) {
|
|
20
|
-
if (e.code === "ENOENT") return null;
|
|
21
|
-
throw e;
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
async set(n, a) {
|
|
25
|
-
let s = o(e, `${n}.png`);
|
|
26
|
-
await t(i(s), { recursive: !0 }), await r(s, a);
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
function m() {
|
|
31
|
-
let e = /* @__PURE__ */ new Map();
|
|
32
|
-
return {
|
|
33
|
-
dir: ":memory:",
|
|
34
|
-
async get(t) {
|
|
35
|
-
return e.get(t) ?? null;
|
|
36
|
-
},
|
|
37
|
-
async set(t, n) {
|
|
38
|
-
e.set(t, n);
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
//#endregion
|
|
43
|
-
//#region src/render.ts
|
|
44
|
-
async function h(e) {
|
|
45
|
-
let t = e.cwd ?? process.cwd(), n = a(e.mdxPath) ? e.mdxPath : s(t, e.mdxPath), r = await u(n);
|
|
46
|
-
if (!r) throw Error(`renderAnnotatedScreen: ${e.mdxPath} has no \`annot:\` frontmatter — cannot render.`);
|
|
47
|
-
let o = r.screens.find((t) => t.id === e.screenId);
|
|
48
|
-
if (!o) throw Error(`renderAnnotatedScreen: ${e.mdxPath} has no <Screen id="${e.screenId}"> block.`);
|
|
49
|
-
let c = g(e.editable), d = f({
|
|
50
|
-
mdxSource: r.source,
|
|
51
|
-
screenId: e.screenId,
|
|
52
|
-
editable: c !== null
|
|
53
|
-
});
|
|
54
|
-
if (e.cache) {
|
|
55
|
-
let t = await e.cache.get(d);
|
|
56
|
-
if (t) return {
|
|
57
|
-
bytes: t,
|
|
58
|
-
fromCache: !0,
|
|
59
|
-
hadBoundingBoxes: !0
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
let p = e.basePngBytes ?? await C(r, o.src, i(n)), m = w(p), h = v(r.commentBlocks.snapshot ?? ""), y = b(o.overlays, h, m), S, T;
|
|
63
|
-
if (y.length === 0) if (T = !1, c !== null) {
|
|
64
|
-
let e = `data:image/png;base64,${Buffer.from(p).toString("base64")}`;
|
|
65
|
-
S = l({ loadSystemFonts: !0 }).toEditablePng({
|
|
66
|
-
originalDataUrl: e,
|
|
67
|
-
annotationsSvg: _(),
|
|
68
|
-
width: m.width,
|
|
69
|
-
height: m.height,
|
|
70
|
-
tags: c.tags
|
|
71
|
-
});
|
|
72
|
-
} else S = p;
|
|
73
|
-
else {
|
|
74
|
-
let e = `data:image/png;base64,${Buffer.from(p).toString("base64")}`, t = x(y), n = l({ loadSystemFonts: !0 }), r = {
|
|
75
|
-
originalDataUrl: e,
|
|
76
|
-
annotationsSvg: t,
|
|
77
|
-
width: m.width,
|
|
78
|
-
height: m.height
|
|
79
|
-
};
|
|
80
|
-
S = c === null ? n.toPng(r) : n.toEditablePng({
|
|
81
|
-
...r,
|
|
82
|
-
tags: c.tags
|
|
83
|
-
}), T = !0;
|
|
84
|
-
}
|
|
85
|
-
return e.cache && await e.cache.set(d, S), {
|
|
86
|
-
bytes: S,
|
|
87
|
-
fromCache: !1,
|
|
88
|
-
hadBoundingBoxes: T
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
function g(e) {
|
|
92
|
-
return e ? e === !0 ? {} : e : null;
|
|
93
|
-
}
|
|
94
|
-
function _() {
|
|
95
|
-
return "<svg xmlns=\"http://www.w3.org/2000/svg\"></svg>";
|
|
96
|
-
}
|
|
97
|
-
function v(e) {
|
|
98
|
-
let t = [];
|
|
99
|
-
for (let n of e.split(/\r?\n/)) {
|
|
100
|
-
if (!n.trim()) continue;
|
|
101
|
-
let e = n.match(/^\s*-\s+([a-z]+)(?:\s+"([^"]*?)")?/);
|
|
102
|
-
if (!e) continue;
|
|
103
|
-
let r = e[1] ?? "", i = e[2] ?? "", a = n.match(/\[ref=(e\d+)\]/)?.[1], o = n.match(/\[box=(-?\d+(?:\.\d+)?),(-?\d+(?:\.\d+)?),(-?\d+(?:\.\d+)?),(-?\d+(?:\.\d+)?)\]/);
|
|
104
|
-
!a || !o || t.push({
|
|
105
|
-
role: r,
|
|
106
|
-
name: i,
|
|
107
|
-
ref: a,
|
|
108
|
-
box: {
|
|
109
|
-
x: Number.parseFloat(o[1]),
|
|
110
|
-
y: Number.parseFloat(o[2]),
|
|
111
|
-
width: Number.parseFloat(o[3]),
|
|
112
|
-
height: Number.parseFloat(o[4])
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
return t;
|
|
117
|
-
}
|
|
118
|
-
async function y(e) {
|
|
119
|
-
let t = e.cwd ?? process.cwd(), n = await u(a(e.mdxPath) ? e.mdxPath : s(t, e.mdxPath));
|
|
120
|
-
if (!n) throw Error(`resolveMdxAnnotations: ${e.mdxPath} has no \`annot:\` frontmatter — cannot resolve.`);
|
|
121
|
-
let r = n.screens.find((t) => t.id === e.screenId);
|
|
122
|
-
if (!r) throw Error(`resolveMdxAnnotations: ${e.mdxPath} has no <Screen id="${e.screenId}"> block.`);
|
|
123
|
-
let i = v(n.commentBlocks.snapshot ?? "");
|
|
124
|
-
return b(r.overlays, i, e.dims);
|
|
125
|
-
}
|
|
126
|
-
function b(e, t, n) {
|
|
127
|
-
let r = [], i = 1;
|
|
128
|
-
for (let a of e) {
|
|
129
|
-
let e = t.find((e) => e.role === a.match.role && e.name === a.match.name);
|
|
130
|
-
if (!e) continue;
|
|
131
|
-
let o = a.number ?? i++;
|
|
132
|
-
r.push({
|
|
133
|
-
type: "numberedBadge",
|
|
134
|
-
bbox: e.box,
|
|
135
|
-
number: o,
|
|
136
|
-
placement: "auto",
|
|
137
|
-
imageWidth: n.width,
|
|
138
|
-
imageHeight: n.height,
|
|
139
|
-
intent: a.intent === "action" ? "warning" : a.intent === "required" ? "error" : "info"
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
return r;
|
|
143
|
-
}
|
|
144
|
-
function x(e) {
|
|
145
|
-
return `<svg xmlns="http://www.w3.org/2000/svg">${c(e)}</svg>`;
|
|
146
|
-
}
|
|
147
|
-
function S(e) {
|
|
148
|
-
return e.length === 0 ? "<svg xmlns=\"http://www.w3.org/2000/svg\"></svg>" : `<svg xmlns="http://www.w3.org/2000/svg">${c(e)}</svg>`;
|
|
149
|
-
}
|
|
150
|
-
async function C(e, t, r) {
|
|
151
|
-
if (!t) throw Error("renderAnnotatedScreen: <Screen src=...> is required — cannot render without a base image.");
|
|
152
|
-
let i = await n(a(t) ? t : s(r, t));
|
|
153
|
-
return new Uint8Array(i.buffer, i.byteOffset, i.byteLength);
|
|
154
|
-
}
|
|
155
|
-
function w(e) {
|
|
156
|
-
if (e.length < 24) throw Error("renderAnnotatedScreen: base PNG too short to contain IHDR.");
|
|
157
|
-
let t = new DataView(e.buffer, e.byteOffset, e.byteLength);
|
|
158
|
-
return {
|
|
159
|
-
width: t.getUint32(16, !1),
|
|
160
|
-
height: t.getUint32(20, !1)
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
//#endregion
|
|
164
|
-
export { d as a, m as c, S as i, h as n, f as o, y as r, p as s, v as t };
|