waygraph 0.15.16 → 0.15.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -1
- package/dist/cli.js +25 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/trait.d.ts +16 -0
- package/dist/trait.js +30 -0
- package/examples/routed-demo/playwright.config.ts +2 -1
- package/examples/saucedemo/package-lock.json +498 -32
- package/examples/saucedemo/playwright.config.ts +2 -1
- package/examples/saucedemo/tests/auto-graph.spec.ts +16 -4
- package/examples/saucedemo/tests/chain-flow-episodes.spec.ts +5 -0
- package/examples/saucedemo/tests/flow-block-verify.spec.ts +7 -4
- package/package.json +1 -1
- package/templates/quickstart/playwright.config.ts +2 -1
- package/templates/scaffold/playwright.config.ts +2 -1
- package/templates/skills/waygraph-convention.skill.md +21 -0
- package/examples/routed-demo/test-results/.last-run.json +0 -4
package/README.md
CHANGED
|
@@ -412,6 +412,36 @@ engine.defineFlow([start, NavHomeBlock, AddItemBlock, AssertItemAddedBlock, Clea
|
|
|
412
412
|
Live reference: `templates/scaffold/src/map/(app_base)/home/_methods/assert-item-added.method.block.ts`,
|
|
413
413
|
wired into `shop.flow.ts`.
|
|
414
414
|
|
|
415
|
+
**An assert Block also names a feature *state*, not just a result or static content.** A
|
|
416
|
+
submit button greyed out until required fields are filled, a "Save" button re-enabling
|
|
417
|
+
after a successful edit, a field-level validation error appearing under one specific input
|
|
418
|
+
- these are conditions the UI is *in*, worth a nameable Checkpoint of their own the same way
|
|
419
|
+
`AssertItemAddedBlock` names "did add-item work." There's no built-in `Trait.disabled` -
|
|
420
|
+
write the state check as a custom Trait against the real DOM condition (`isDisabled()`, a
|
|
421
|
+
class, an `aria-disabled` attribute - whatever the app actually uses), the same pattern as
|
|
422
|
+
`removeButtonVisibleForSelectedItem` above:
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
const submitGatedUntilFieldsComplete: Trait = {
|
|
426
|
+
name: "submit-gated-until-fields-complete",
|
|
427
|
+
async check(page) {
|
|
428
|
+
return page.locator(CheckoutSel.submitButton).isDisabled();
|
|
429
|
+
},
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
export const AssertSubmitGatedBlock = defineAssertBlock<CheckoutInfoPage>({
|
|
433
|
+
name: "assert-submit-gated",
|
|
434
|
+
checkpoint: "CheckoutInfoPage",
|
|
435
|
+
verify: [submitGatedUntilFieldsComplete],
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
// wired right after the fields that gate it, before the ones that clear the gate:
|
|
439
|
+
engine.defineFlow([start, NavCheckoutInfoBlock, AssertSubmitGatedBlock, FillFirstNameBlock, ...])
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
Same rule as any other assert Block: give it an explicit type argument when it sits
|
|
443
|
+
mid-chain (see above), and keep the selector in a `*Sel` object, never inlined in the Trait.
|
|
444
|
+
|
|
415
445
|
**`methods/` folder:** on-page work lives next to the route, not free-floating.
|
|
416
446
|
|
|
417
447
|
**`*Sel`:** DOM selectors only (static strings + `(id) => ...` for item-no-1 style). Mem
|
|
@@ -748,6 +778,22 @@ actually shows. Doesn't crash or corrupt anything if you never need it - it's a
|
|
|
748
778
|
gap (confirmed by reading the exact code path, `src/auto-session.ts`'s `currentMenu()`), fixed
|
|
749
779
|
outright rather than left as a caveat.
|
|
750
780
|
|
|
781
|
+
**Coverage gaps `waygraph check`/`graph` can't see, because there's no Block to scan yet.**
|
|
782
|
+
Static tools only find gaps in Blocks that already exist - a real link or button on the live
|
|
783
|
+
page with *no Block written for it at all* has nothing in source to catch it. Every live
|
|
784
|
+
`auto`/`browser`/`pilot` session watches the real page instead and warns (once per element,
|
|
785
|
+
via `console.warn`) on a same-origin `<a href>` no `defineNavBlock` covers, or a visible
|
|
786
|
+
`button`/`[role=button]`/submit input no Method/NavClick Block selector matches:
|
|
787
|
+
|
|
788
|
+
```text
|
|
789
|
+
[waygraph] unmapped nav link on this page: /settings - no NavBlock covers this URL; add defineNavBlock
|
|
790
|
+
[waygraph] unmapped button on this page: #save-draft - no Method/NavClick Block selector matches; consider defineMethodBlock or defineNavClickBlock
|
|
791
|
+
```
|
|
792
|
+
|
|
793
|
+
Read them back with `auto console <sessionId>` - the same channel real console/network errors
|
|
794
|
+
already come through, not a separate command (`src/coverage-gap.ts`, wired into every session
|
|
795
|
+
in `src/auto-session.ts`).
|
|
796
|
+
|
|
751
797
|
**On-page indicator.** A headful (`--non-headless`) session looks like an ordinary browser
|
|
752
798
|
tab otherwise - no sign anything is driving it, which matters once a human might be watching
|
|
753
799
|
or co-driving the same visible session. Every session injects a small badge (bottom-right
|
|
@@ -1045,7 +1091,12 @@ suite - it forwards to the local `node_modules/.bin/playwright` (falling back to
|
|
|
1045
1091
|
exactly like `playwright test`, and anything after it (`--grep`, a spec path, `--headed`, …)
|
|
1046
1092
|
passes straight through. `waygraph test ui` (or `waygraph test --ui`) launches Playwright's
|
|
1047
1093
|
interactive UI Mode the same way. Scaffolded projects (`waygraph init`/`create-waygraph`)
|
|
1048
|
-
wire this up as `npm test` / `npm run test:ui
|
|
1094
|
+
wire this up as `npm test` / `npm run test:ui`, and ship `trace: "retain-on-failure"` plus
|
|
1095
|
+
the `html` reporter in `playwright.config.ts`, so a failing `waygraph test` already has a
|
|
1096
|
+
trace waiting - `waygraph test report` opens the HTML report, and
|
|
1097
|
+
`waygraph test show-trace <trace.zip>` opens one trace directly (both forward to Playwright's
|
|
1098
|
+
own `show-report`/`show-trace`, which live outside `playwright test`, so they're handled
|
|
1099
|
+
before the `test` forward rather than passed through it).
|
|
1049
1100
|
|
|
1050
1101
|
Flows are files (0.10.5+):
|
|
1051
1102
|
|
|
@@ -1079,6 +1130,8 @@ Flows are files (0.10.5+):
|
|
|
1079
1130
|
| Scope either to one element | `waygraph auto dom <sessionId> --selector ".inventory_list"` |
|
|
1080
1131
|
| Detached session with a real visible browser | `waygraph auto --cli --detach --non-headless` |
|
|
1081
1132
|
| Read the session's Checkpoint/Block history | `waygraph auto trace <sessionId>` |
|
|
1133
|
+
| Read real console/network errors + coverage-gap warnings | `waygraph auto console <sessionId>` |
|
|
1134
|
+
| Read localStorage/sessionStorage + service workers | `waygraph auto storage <sessionId>` |
|
|
1082
1135
|
| Whole-project nav-escape + inline-selector + orphan sweep | `waygraph check [project]` |
|
|
1083
1136
|
| `tsc --noEmit` + bad-practice warnings | `waygraph typecheck [project]` (`--no-practices` to skip scan) |
|
|
1084
1137
|
| Waygraph Map enforcement (verbatim url-vs-folder, exits 1 on a violation) | `waygraph map [project]` |
|
|
@@ -1088,6 +1141,8 @@ Flows are files (0.10.5+):
|
|
|
1088
1141
|
| One-shot temp-dir demo | `waygraph try demo` / `waygraph try auto` / `waygraph try auto:cli` |
|
|
1089
1142
|
| Run the project's `@playwright/test` suite | `waygraph test` |
|
|
1090
1143
|
| Same suite, Playwright's interactive UI Mode | `waygraph test ui` (or `--ui`) |
|
|
1144
|
+
| Open the last HTML report | `waygraph test report` |
|
|
1145
|
+
| Open one trace in the trace viewer | `waygraph test show-trace <trace.zip>` |
|
|
1091
1146
|
|
|
1092
1147
|
`--blocks` / positional accepts a Flow export, a `.flow.ts` path, or `"a then b"`.
|
|
1093
1148
|
`auto <file.flow.ts>` **runs** that flow (same as `run`); bare `auto` still explores.
|
package/dist/cli.js
CHANGED
|
@@ -7341,7 +7341,12 @@ Primary (less is more):
|
|
|
7341
7341
|
thin wrapper: forwards to the local playwright
|
|
7342
7342
|
binary (or npx playwright as a fallback)
|
|
7343
7343
|
test ui / test --ui Playwright UI Mode (interactive, watch + trace)
|
|
7344
|
+
test report [dir] Open the last HTML report (playwright show-report)
|
|
7345
|
+
test show-trace <file> Open one trace.zip in the trace viewer
|
|
7344
7346
|
<any other args> Forwarded verbatim (--grep, a spec path, --headed, …)
|
|
7347
|
+
Scaffolds ship trace: "retain-on-failure" + the
|
|
7348
|
+
html reporter, so a failed waygraph test already
|
|
7349
|
+
has a trace - test report opens it.
|
|
7345
7350
|
|
|
7346
7351
|
Also:
|
|
7347
7352
|
waygraph list | nav | validate | check | typecheck | graph | init <name>
|
|
@@ -7475,17 +7480,31 @@ async function main() {
|
|
|
7475
7480
|
}
|
|
7476
7481
|
case "test": {
|
|
7477
7482
|
const rest = args.slice(1);
|
|
7483
|
+
const proj = process.cwd();
|
|
7484
|
+
const localPlaywrightBin = join(proj, "node_modules", ".bin", "playwright");
|
|
7485
|
+
const runPw = (pwArgs) => existsSync(localPlaywrightBin)
|
|
7486
|
+
? runInherited(localPlaywrightBin, pwArgs, proj)
|
|
7487
|
+
: runInherited("npx", ["--yes", "playwright", ...pwArgs], proj);
|
|
7488
|
+
// report/show-trace are separate top-level `playwright` commands, not
|
|
7489
|
+
// `playwright test` subcommands - handled before the `test` forward below.
|
|
7490
|
+
if (rest[0] === "report") {
|
|
7491
|
+
process.exitCode = await runPw(["show-report", ...rest.slice(1)]);
|
|
7492
|
+
break;
|
|
7493
|
+
}
|
|
7494
|
+
if (rest[0] === "show-trace") {
|
|
7495
|
+
if (!rest[1]) {
|
|
7496
|
+
console.error("waygraph test show-trace: missing <trace.zip> (or a test-results/ dir)");
|
|
7497
|
+
process.exit(1);
|
|
7498
|
+
}
|
|
7499
|
+
process.exitCode = await runPw(["show-trace", ...rest.slice(1)]);
|
|
7500
|
+
break;
|
|
7501
|
+
}
|
|
7478
7502
|
const wantsUi = rest[0] === "ui" || rest.includes("--ui");
|
|
7479
7503
|
const forwarded = rest[0] === "ui" ? rest.slice(1) : rest;
|
|
7480
7504
|
const pwArgs = wantsUi && !forwarded.includes("--ui")
|
|
7481
7505
|
? ["test", "--ui", ...forwarded]
|
|
7482
7506
|
: ["test", ...forwarded];
|
|
7483
|
-
|
|
7484
|
-
const localPlaywrightBin = join(proj, "node_modules", ".bin", "playwright");
|
|
7485
|
-
const code = existsSync(localPlaywrightBin)
|
|
7486
|
-
? await runInherited(localPlaywrightBin, pwArgs, proj)
|
|
7487
|
-
: await runInherited("npx", ["--yes", "playwright", ...pwArgs], proj);
|
|
7488
|
-
process.exitCode = code;
|
|
7507
|
+
process.exitCode = await runPw(pwArgs);
|
|
7489
7508
|
break;
|
|
7490
7509
|
}
|
|
7491
7510
|
case "init": {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export type { Checkpoint, Instruction, Block, DefinedBlock, Start, WaygraphInstanceOption } from "./types.js";
|
|
2
2
|
export { connect, checkpoint } from "./types.js";
|
|
3
3
|
export { MemKey, MemPage, key, keyGroup } from "./mem-page.js";
|
|
4
|
-
export { Trait, urlMatches, textEquals, visible, frameVisible, frameTextEquals, frameContainsText } from "./trait.js";
|
|
4
|
+
export { Trait, urlMatches, textEquals, visible, disabled, enabled, frameVisible, frameTextEquals, frameContainsText, } from "./trait.js";
|
|
5
5
|
export { runGraph, spawnTab, narrate, Engine, start, end, branch, withVerify, modVerify, modVerifyAll, defineBlock, defineNavBlock, defineNavClickBlock, defineMethodBlock, defineActionBlock, defineAssertBlock, definePageBlock, defineEffectBlock, defineMemEffectBlock, defineMemNavBlock, locate, composeBlock, fastForwardComposeBlock, isFastForwardBlock, preflight, withSessionReset, withTitle, withDemoPace, withBlockPace, withHighlightStyle, withExpectedFailure, withHighlightFixtures, withStubBefore, withStubAfter, withStubOnError, chainFlow, defineLayout, map, MapBuilder, } from "./engine.js";
|
|
6
6
|
export { resolveHighlightSlots, resolveSlides, runStubPhase, resolveFixtureDwellMs, resolveSlideDwellMs, formatHighlightCaption, hasAuthoredStubAfter, hasAuthoredStubOnError, normalizeHighlightTone, normalizeDemoPace, normalizeHighlightSize, normalizeHighlightWeight, applyHighlightStyleDefaults, toneIconPrefix, resolveStepDemoPace, demoPaceScale, demoPaceIsBlitz, demoPaceIsFast, demoPaceIsSlow, demoPaceGateMs, formatDemoPaceBadge, formatDemoPaceLabel, normalizeTodos, normalizeTodoPos, normalizeTodoStyle, buildTodoDock, applyTodoPhase, advanceTodoDock, completeSequentialTodoDock, applyDevicePhase, resolveDeviceState, normalizeDevicePreset, normalizeDeviceOrientation, applyOrientation, orientationFromViewport, DEVICE_PRESETS, resolveTodoDockUi, FIXTURE_DURATION_MS_DEFAULT, FIXTURE_DURATION_FAST_MS_DEFAULT, FIXTURE_DURATION_SLOW_MS_DEFAULT, SLIDE_DURATION_MS_DEFAULT, SLIDE_DURATION_FAST_MS_DEFAULT, WAYGRAPH_RING_CSS, } from "./highlights.js";
|
|
7
7
|
export type { WaygraphHighlightStub, WaygraphHighlightFixture, WaygraphSlide, WaygraphTodoItem, WaygraphTodoInput, WaygraphTodoGroup, WaygraphTodoGroupInput, WaygraphTodosOpts, TodoDockUiOpts, TodoDockUiResolved, TodoDockState, TodoListStyle, FixtureDurationFields, HighlightStubPhase, HighlightStubPhaseName, HighlightFixtureMap, ResolvedHighlight, WaygraphHighlight, HighlightTone, HighlightSize, HighlightWeight, HighlightStyleDefaults, DemoPace, DemoPaceName, StubCtx, StubLifecycleFn, StubPhaseResult, StubPhaseFixtures, DevicePreset, DeviceViewport, DeviceState, DeviceOrientation, } from "./highlights.js";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { connect, checkpoint } from "./types.js";
|
|
2
2
|
export { MemKey, MemPage, key, keyGroup } from "./mem-page.js";
|
|
3
|
-
export { Trait, urlMatches, textEquals, visible, frameVisible, frameTextEquals, frameContainsText } from "./trait.js";
|
|
3
|
+
export { Trait, urlMatches, textEquals, visible, disabled, enabled, frameVisible, frameTextEquals, frameContainsText, } from "./trait.js";
|
|
4
4
|
export { runGraph, spawnTab, narrate, Engine, start, end, branch, withVerify, modVerify, modVerifyAll, defineBlock, defineNavBlock, defineNavClickBlock, defineMethodBlock, defineActionBlock, defineAssertBlock, definePageBlock, defineEffectBlock, defineMemEffectBlock, defineMemNavBlock, locate, composeBlock, fastForwardComposeBlock, isFastForwardBlock, preflight, withSessionReset, withTitle, withDemoPace, withBlockPace, withHighlightStyle, withExpectedFailure, withHighlightFixtures, withStubBefore, withStubAfter, withStubOnError, chainFlow, defineLayout, map, MapBuilder, } from "./engine.js";
|
|
5
5
|
export { resolveHighlightSlots, resolveSlides, runStubPhase, resolveFixtureDwellMs, resolveSlideDwellMs, formatHighlightCaption, hasAuthoredStubAfter, hasAuthoredStubOnError, normalizeHighlightTone, normalizeDemoPace, normalizeHighlightSize, normalizeHighlightWeight, applyHighlightStyleDefaults, toneIconPrefix, resolveStepDemoPace, demoPaceScale, demoPaceIsBlitz, demoPaceIsFast, demoPaceIsSlow, demoPaceGateMs, formatDemoPaceBadge, formatDemoPaceLabel, normalizeTodos, normalizeTodoPos, normalizeTodoStyle, buildTodoDock, applyTodoPhase, advanceTodoDock, completeSequentialTodoDock, applyDevicePhase, resolveDeviceState, normalizeDevicePreset, normalizeDeviceOrientation, applyOrientation, orientationFromViewport, DEVICE_PRESETS, resolveTodoDockUi, FIXTURE_DURATION_MS_DEFAULT, FIXTURE_DURATION_FAST_MS_DEFAULT, FIXTURE_DURATION_SLOW_MS_DEFAULT, SLIDE_DURATION_MS_DEFAULT, SLIDE_DURATION_FAST_MS_DEFAULT, WAYGRAPH_RING_CSS, } from "./highlights.js";
|
|
6
6
|
export { discoverGraph, toMermaid, findOrphanBlocks, findBlockPath } from "./graph.js";
|
package/dist/trait.d.ts
CHANGED
|
@@ -40,6 +40,20 @@ export declare function textEquals(selector: string, expected: string): Trait;
|
|
|
40
40
|
* "something matching is visible", not "the selector is unambiguous".
|
|
41
41
|
*/
|
|
42
42
|
export declare function visible(selector: string): Trait;
|
|
43
|
+
/**
|
|
44
|
+
* Passes when at least one element matching `selector` is currently disabled -
|
|
45
|
+
* a submit button greyed out until required fields are filled, a "Save" not
|
|
46
|
+
* yet re-enabled after a pending edit. A real, nameable feature *state*, not
|
|
47
|
+
* just static content or an action's result. Uses `.first()` for the same
|
|
48
|
+
* reason `visible` does. A point-in-time read via Playwright's own
|
|
49
|
+
* `isDisabled()` - no wait built in, so pair it with `Trait.visible` (or rely
|
|
50
|
+
* on `verify`'s own natural timing right after `resolve`) if the element
|
|
51
|
+
* itself might not be on the page yet.
|
|
52
|
+
* @example Trait.disabled(CheckoutSel.submitButton)
|
|
53
|
+
*/
|
|
54
|
+
export declare function disabled(selector: string): Trait;
|
|
55
|
+
/** The complement of {@link disabled} - passes once `selector` is enabled. */
|
|
56
|
+
export declare function enabled(selector: string): Trait;
|
|
43
57
|
/**
|
|
44
58
|
* `visible`, scoped to a frame (e.g. a mail catcher's message-preview iframe)
|
|
45
59
|
* instead of the top-level page. `page.locator(selector)` alone never reaches
|
|
@@ -73,6 +87,8 @@ export declare const Trait: {
|
|
|
73
87
|
url: typeof urlMatches;
|
|
74
88
|
text: typeof textEquals;
|
|
75
89
|
visible: typeof visible;
|
|
90
|
+
disabled: typeof disabled;
|
|
91
|
+
enabled: typeof enabled;
|
|
76
92
|
frameVisible: typeof frameVisible;
|
|
77
93
|
frameText: typeof frameTextEquals;
|
|
78
94
|
frameContains: typeof frameContainsText;
|
package/dist/trait.js
CHANGED
|
@@ -65,6 +65,34 @@ export function visible(selector) {
|
|
|
65
65
|
},
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Passes when at least one element matching `selector` is currently disabled -
|
|
70
|
+
* a submit button greyed out until required fields are filled, a "Save" not
|
|
71
|
+
* yet re-enabled after a pending edit. A real, nameable feature *state*, not
|
|
72
|
+
* just static content or an action's result. Uses `.first()` for the same
|
|
73
|
+
* reason `visible` does. A point-in-time read via Playwright's own
|
|
74
|
+
* `isDisabled()` - no wait built in, so pair it with `Trait.visible` (or rely
|
|
75
|
+
* on `verify`'s own natural timing right after `resolve`) if the element
|
|
76
|
+
* itself might not be on the page yet.
|
|
77
|
+
* @example Trait.disabled(CheckoutSel.submitButton)
|
|
78
|
+
*/
|
|
79
|
+
export function disabled(selector) {
|
|
80
|
+
return {
|
|
81
|
+
name: `disabled(${selector})`,
|
|
82
|
+
async check(page) {
|
|
83
|
+
return page.locator(selector).first().isDisabled();
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/** The complement of {@link disabled} - passes once `selector` is enabled. */
|
|
88
|
+
export function enabled(selector) {
|
|
89
|
+
return {
|
|
90
|
+
name: `enabled(${selector})`,
|
|
91
|
+
async check(page) {
|
|
92
|
+
return page.locator(selector).first().isEnabled();
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
68
96
|
/**
|
|
69
97
|
* `visible`, scoped to a frame (e.g. a mail catcher's message-preview iframe)
|
|
70
98
|
* instead of the top-level page. `page.locator(selector)` alone never reaches
|
|
@@ -121,6 +149,8 @@ export const Trait = {
|
|
|
121
149
|
url: urlMatches,
|
|
122
150
|
text: textEquals,
|
|
123
151
|
visible,
|
|
152
|
+
disabled,
|
|
153
|
+
enabled,
|
|
124
154
|
frameVisible,
|
|
125
155
|
frameText: frameTextEquals,
|
|
126
156
|
frameContains: frameContainsText,
|
|
@@ -8,10 +8,11 @@ export default defineConfig({
|
|
|
8
8
|
fullyParallel: false,
|
|
9
9
|
workers: 1,
|
|
10
10
|
timeout: 30_000,
|
|
11
|
-
reporter: "list",
|
|
11
|
+
reporter: [["list"], ["html", { open: "never" }]],
|
|
12
12
|
use: {
|
|
13
13
|
headless: true,
|
|
14
14
|
baseURL: process.env.WAYGRAPH_BASE_URL || `http://${HOST}:${PORT}`,
|
|
15
|
+
trace: "retain-on-failure",
|
|
15
16
|
launchOptions: {
|
|
16
17
|
executablePath: process.env.CHROME_PATH || process.env.CHROMIUM_PATH,
|
|
17
18
|
args: ["--no-sandbox", "--disable-dev-shm-usage"],
|
|
@@ -16,29 +16,424 @@
|
|
|
16
16
|
"typescript": "^5.6.0"
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
|
-
"
|
|
20
|
-
"version": "0.
|
|
19
|
+
"node_modules/@esbuild/aix-ppc64": {
|
|
20
|
+
"version": "0.28.2",
|
|
21
|
+
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz",
|
|
22
|
+
"integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==",
|
|
23
|
+
"cpu": [
|
|
24
|
+
"ppc64"
|
|
25
|
+
],
|
|
21
26
|
"license": "MIT",
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
|
|
27
|
+
"optional": true,
|
|
28
|
+
"os": [
|
|
29
|
+
"aix"
|
|
30
|
+
],
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=18"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"node_modules/@esbuild/android-arm": {
|
|
36
|
+
"version": "0.28.2",
|
|
37
|
+
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz",
|
|
38
|
+
"integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==",
|
|
39
|
+
"cpu": [
|
|
40
|
+
"arm"
|
|
41
|
+
],
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"optional": true,
|
|
44
|
+
"os": [
|
|
45
|
+
"android"
|
|
46
|
+
],
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"node_modules/@esbuild/android-arm64": {
|
|
52
|
+
"version": "0.28.2",
|
|
53
|
+
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz",
|
|
54
|
+
"integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==",
|
|
55
|
+
"cpu": [
|
|
56
|
+
"arm64"
|
|
57
|
+
],
|
|
58
|
+
"license": "MIT",
|
|
59
|
+
"optional": true,
|
|
60
|
+
"os": [
|
|
61
|
+
"android"
|
|
62
|
+
],
|
|
63
|
+
"engines": {
|
|
64
|
+
"node": ">=18"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"node_modules/@esbuild/android-x64": {
|
|
68
|
+
"version": "0.28.2",
|
|
69
|
+
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz",
|
|
70
|
+
"integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==",
|
|
71
|
+
"cpu": [
|
|
72
|
+
"x64"
|
|
73
|
+
],
|
|
74
|
+
"license": "MIT",
|
|
75
|
+
"optional": true,
|
|
76
|
+
"os": [
|
|
77
|
+
"android"
|
|
78
|
+
],
|
|
79
|
+
"engines": {
|
|
80
|
+
"node": ">=18"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"node_modules/@esbuild/darwin-arm64": {
|
|
84
|
+
"version": "0.28.2",
|
|
85
|
+
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz",
|
|
86
|
+
"integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==",
|
|
87
|
+
"cpu": [
|
|
88
|
+
"arm64"
|
|
89
|
+
],
|
|
90
|
+
"license": "MIT",
|
|
91
|
+
"optional": true,
|
|
92
|
+
"os": [
|
|
93
|
+
"darwin"
|
|
94
|
+
],
|
|
95
|
+
"engines": {
|
|
96
|
+
"node": ">=18"
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"node_modules/@esbuild/darwin-x64": {
|
|
100
|
+
"version": "0.28.2",
|
|
101
|
+
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz",
|
|
102
|
+
"integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==",
|
|
103
|
+
"cpu": [
|
|
104
|
+
"x64"
|
|
105
|
+
],
|
|
106
|
+
"license": "MIT",
|
|
107
|
+
"optional": true,
|
|
108
|
+
"os": [
|
|
109
|
+
"darwin"
|
|
110
|
+
],
|
|
111
|
+
"engines": {
|
|
112
|
+
"node": ">=18"
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
"node_modules/@esbuild/freebsd-arm64": {
|
|
116
|
+
"version": "0.28.2",
|
|
117
|
+
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz",
|
|
118
|
+
"integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==",
|
|
119
|
+
"cpu": [
|
|
120
|
+
"arm64"
|
|
121
|
+
],
|
|
122
|
+
"license": "MIT",
|
|
123
|
+
"optional": true,
|
|
124
|
+
"os": [
|
|
125
|
+
"freebsd"
|
|
126
|
+
],
|
|
127
|
+
"engines": {
|
|
128
|
+
"node": ">=18"
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
"node_modules/@esbuild/freebsd-x64": {
|
|
132
|
+
"version": "0.28.2",
|
|
133
|
+
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz",
|
|
134
|
+
"integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==",
|
|
135
|
+
"cpu": [
|
|
136
|
+
"x64"
|
|
137
|
+
],
|
|
138
|
+
"license": "MIT",
|
|
139
|
+
"optional": true,
|
|
140
|
+
"os": [
|
|
141
|
+
"freebsd"
|
|
142
|
+
],
|
|
143
|
+
"engines": {
|
|
144
|
+
"node": ">=18"
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
"node_modules/@esbuild/linux-arm": {
|
|
148
|
+
"version": "0.28.2",
|
|
149
|
+
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz",
|
|
150
|
+
"integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==",
|
|
151
|
+
"cpu": [
|
|
152
|
+
"arm"
|
|
153
|
+
],
|
|
154
|
+
"license": "MIT",
|
|
155
|
+
"optional": true,
|
|
156
|
+
"os": [
|
|
157
|
+
"linux"
|
|
158
|
+
],
|
|
159
|
+
"engines": {
|
|
160
|
+
"node": ">=18"
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
"node_modules/@esbuild/linux-arm64": {
|
|
164
|
+
"version": "0.28.2",
|
|
165
|
+
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz",
|
|
166
|
+
"integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==",
|
|
167
|
+
"cpu": [
|
|
168
|
+
"arm64"
|
|
169
|
+
],
|
|
170
|
+
"license": "MIT",
|
|
171
|
+
"optional": true,
|
|
172
|
+
"os": [
|
|
173
|
+
"linux"
|
|
174
|
+
],
|
|
175
|
+
"engines": {
|
|
176
|
+
"node": ">=18"
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
"node_modules/@esbuild/linux-ia32": {
|
|
180
|
+
"version": "0.28.2",
|
|
181
|
+
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz",
|
|
182
|
+
"integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==",
|
|
183
|
+
"cpu": [
|
|
184
|
+
"ia32"
|
|
185
|
+
],
|
|
186
|
+
"license": "MIT",
|
|
187
|
+
"optional": true,
|
|
188
|
+
"os": [
|
|
189
|
+
"linux"
|
|
190
|
+
],
|
|
191
|
+
"engines": {
|
|
192
|
+
"node": ">=18"
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
"node_modules/@esbuild/linux-loong64": {
|
|
196
|
+
"version": "0.28.2",
|
|
197
|
+
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz",
|
|
198
|
+
"integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==",
|
|
199
|
+
"cpu": [
|
|
200
|
+
"loong64"
|
|
201
|
+
],
|
|
202
|
+
"license": "MIT",
|
|
203
|
+
"optional": true,
|
|
204
|
+
"os": [
|
|
205
|
+
"linux"
|
|
206
|
+
],
|
|
207
|
+
"engines": {
|
|
208
|
+
"node": ">=18"
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
"node_modules/@esbuild/linux-mips64el": {
|
|
212
|
+
"version": "0.28.2",
|
|
213
|
+
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz",
|
|
214
|
+
"integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==",
|
|
215
|
+
"cpu": [
|
|
216
|
+
"mips64el"
|
|
217
|
+
],
|
|
218
|
+
"license": "MIT",
|
|
219
|
+
"optional": true,
|
|
220
|
+
"os": [
|
|
221
|
+
"linux"
|
|
222
|
+
],
|
|
223
|
+
"engines": {
|
|
224
|
+
"node": ">=18"
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
"node_modules/@esbuild/linux-ppc64": {
|
|
228
|
+
"version": "0.28.2",
|
|
229
|
+
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz",
|
|
230
|
+
"integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==",
|
|
231
|
+
"cpu": [
|
|
232
|
+
"ppc64"
|
|
233
|
+
],
|
|
234
|
+
"license": "MIT",
|
|
235
|
+
"optional": true,
|
|
236
|
+
"os": [
|
|
237
|
+
"linux"
|
|
238
|
+
],
|
|
239
|
+
"engines": {
|
|
240
|
+
"node": ">=18"
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
"node_modules/@esbuild/linux-riscv64": {
|
|
244
|
+
"version": "0.28.2",
|
|
245
|
+
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz",
|
|
246
|
+
"integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==",
|
|
247
|
+
"cpu": [
|
|
248
|
+
"riscv64"
|
|
249
|
+
],
|
|
250
|
+
"license": "MIT",
|
|
251
|
+
"optional": true,
|
|
252
|
+
"os": [
|
|
253
|
+
"linux"
|
|
254
|
+
],
|
|
255
|
+
"engines": {
|
|
256
|
+
"node": ">=18"
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
"node_modules/@esbuild/linux-s390x": {
|
|
260
|
+
"version": "0.28.2",
|
|
261
|
+
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz",
|
|
262
|
+
"integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==",
|
|
263
|
+
"cpu": [
|
|
264
|
+
"s390x"
|
|
265
|
+
],
|
|
266
|
+
"license": "MIT",
|
|
267
|
+
"optional": true,
|
|
268
|
+
"os": [
|
|
269
|
+
"linux"
|
|
270
|
+
],
|
|
271
|
+
"engines": {
|
|
272
|
+
"node": ">=18"
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
"node_modules/@esbuild/linux-x64": {
|
|
276
|
+
"version": "0.28.2",
|
|
277
|
+
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz",
|
|
278
|
+
"integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==",
|
|
279
|
+
"cpu": [
|
|
280
|
+
"x64"
|
|
281
|
+
],
|
|
282
|
+
"license": "MIT",
|
|
283
|
+
"optional": true,
|
|
284
|
+
"os": [
|
|
285
|
+
"linux"
|
|
286
|
+
],
|
|
287
|
+
"engines": {
|
|
288
|
+
"node": ">=18"
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
"node_modules/@esbuild/netbsd-arm64": {
|
|
292
|
+
"version": "0.28.2",
|
|
293
|
+
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz",
|
|
294
|
+
"integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==",
|
|
295
|
+
"cpu": [
|
|
296
|
+
"arm64"
|
|
297
|
+
],
|
|
298
|
+
"license": "MIT",
|
|
299
|
+
"optional": true,
|
|
300
|
+
"os": [
|
|
301
|
+
"netbsd"
|
|
302
|
+
],
|
|
303
|
+
"engines": {
|
|
304
|
+
"node": ">=18"
|
|
305
|
+
}
|
|
306
|
+
},
|
|
307
|
+
"node_modules/@esbuild/netbsd-x64": {
|
|
308
|
+
"version": "0.28.2",
|
|
309
|
+
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz",
|
|
310
|
+
"integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==",
|
|
311
|
+
"cpu": [
|
|
312
|
+
"x64"
|
|
313
|
+
],
|
|
314
|
+
"license": "MIT",
|
|
315
|
+
"optional": true,
|
|
316
|
+
"os": [
|
|
317
|
+
"netbsd"
|
|
318
|
+
],
|
|
319
|
+
"engines": {
|
|
320
|
+
"node": ">=18"
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
"node_modules/@esbuild/openbsd-arm64": {
|
|
324
|
+
"version": "0.28.2",
|
|
325
|
+
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz",
|
|
326
|
+
"integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==",
|
|
327
|
+
"cpu": [
|
|
328
|
+
"arm64"
|
|
329
|
+
],
|
|
330
|
+
"license": "MIT",
|
|
331
|
+
"optional": true,
|
|
332
|
+
"os": [
|
|
333
|
+
"openbsd"
|
|
334
|
+
],
|
|
335
|
+
"engines": {
|
|
336
|
+
"node": ">=18"
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
"node_modules/@esbuild/openbsd-x64": {
|
|
340
|
+
"version": "0.28.2",
|
|
341
|
+
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz",
|
|
342
|
+
"integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==",
|
|
343
|
+
"cpu": [
|
|
344
|
+
"x64"
|
|
345
|
+
],
|
|
346
|
+
"license": "MIT",
|
|
347
|
+
"optional": true,
|
|
348
|
+
"os": [
|
|
349
|
+
"openbsd"
|
|
350
|
+
],
|
|
351
|
+
"engines": {
|
|
352
|
+
"node": ">=18"
|
|
353
|
+
}
|
|
354
|
+
},
|
|
355
|
+
"node_modules/@esbuild/openharmony-arm64": {
|
|
356
|
+
"version": "0.28.2",
|
|
357
|
+
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz",
|
|
358
|
+
"integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==",
|
|
359
|
+
"cpu": [
|
|
360
|
+
"arm64"
|
|
361
|
+
],
|
|
362
|
+
"license": "MIT",
|
|
363
|
+
"optional": true,
|
|
364
|
+
"os": [
|
|
365
|
+
"openharmony"
|
|
366
|
+
],
|
|
367
|
+
"engines": {
|
|
368
|
+
"node": ">=18"
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
"node_modules/@esbuild/sunos-x64": {
|
|
372
|
+
"version": "0.28.2",
|
|
373
|
+
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz",
|
|
374
|
+
"integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==",
|
|
375
|
+
"cpu": [
|
|
376
|
+
"x64"
|
|
377
|
+
],
|
|
378
|
+
"license": "MIT",
|
|
379
|
+
"optional": true,
|
|
380
|
+
"os": [
|
|
381
|
+
"sunos"
|
|
382
|
+
],
|
|
383
|
+
"engines": {
|
|
384
|
+
"node": ">=18"
|
|
385
|
+
}
|
|
386
|
+
},
|
|
387
|
+
"node_modules/@esbuild/win32-arm64": {
|
|
388
|
+
"version": "0.28.2",
|
|
389
|
+
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz",
|
|
390
|
+
"integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==",
|
|
391
|
+
"cpu": [
|
|
392
|
+
"arm64"
|
|
393
|
+
],
|
|
394
|
+
"license": "MIT",
|
|
395
|
+
"optional": true,
|
|
396
|
+
"os": [
|
|
397
|
+
"win32"
|
|
398
|
+
],
|
|
399
|
+
"engines": {
|
|
400
|
+
"node": ">=18"
|
|
401
|
+
}
|
|
402
|
+
},
|
|
403
|
+
"node_modules/@esbuild/win32-ia32": {
|
|
404
|
+
"version": "0.28.2",
|
|
405
|
+
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz",
|
|
406
|
+
"integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==",
|
|
407
|
+
"cpu": [
|
|
408
|
+
"ia32"
|
|
409
|
+
],
|
|
410
|
+
"license": "MIT",
|
|
411
|
+
"optional": true,
|
|
412
|
+
"os": [
|
|
413
|
+
"win32"
|
|
414
|
+
],
|
|
415
|
+
"engines": {
|
|
416
|
+
"node": ">=18"
|
|
417
|
+
}
|
|
418
|
+
},
|
|
419
|
+
"node_modules/@esbuild/win32-x64": {
|
|
420
|
+
"version": "0.28.2",
|
|
421
|
+
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz",
|
|
422
|
+
"integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==",
|
|
423
|
+
"cpu": [
|
|
424
|
+
"x64"
|
|
425
|
+
],
|
|
426
|
+
"license": "MIT",
|
|
427
|
+
"optional": true,
|
|
428
|
+
"os": [
|
|
429
|
+
"win32"
|
|
430
|
+
],
|
|
431
|
+
"engines": {
|
|
432
|
+
"node": ">=18"
|
|
35
433
|
}
|
|
36
434
|
},
|
|
37
435
|
"node_modules/@playwright/test": {
|
|
38
436
|
"version": "1.63.0",
|
|
39
|
-
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.63.0.tgz",
|
|
40
|
-
"integrity": "sha512-oxMK4vllB9RK5NQ2l1pq1IfOf2AvnEuj/vYGDj0H2nMtmtZpKtCwt/l00GEO6xjGfpBNAvjovvYdCm50dRQkpQ==",
|
|
41
|
-
"dev": true,
|
|
42
437
|
"license": "Apache-2.0",
|
|
43
438
|
"dependencies": {
|
|
44
439
|
"playwright": "1.63.0"
|
|
@@ -52,19 +447,69 @@
|
|
|
52
447
|
},
|
|
53
448
|
"node_modules/@types/node": {
|
|
54
449
|
"version": "26.6.1",
|
|
55
|
-
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.1.tgz",
|
|
56
|
-
"integrity": "sha512-VqGJBMCtdhqkBUCcBLvywI0NJ+KLuVzgNnlBUNFOQjqVxzo2lxLUNg1DSey8+u2u6ktswSAxg+s68QLzWHNOuA==",
|
|
57
450
|
"dev": true,
|
|
58
451
|
"license": "MIT",
|
|
59
452
|
"dependencies": {
|
|
60
453
|
"undici-types": "~8.9.0"
|
|
61
454
|
}
|
|
62
455
|
},
|
|
456
|
+
"node_modules/esbuild": {
|
|
457
|
+
"version": "0.28.2",
|
|
458
|
+
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz",
|
|
459
|
+
"integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==",
|
|
460
|
+
"hasInstallScript": true,
|
|
461
|
+
"license": "MIT",
|
|
462
|
+
"bin": {
|
|
463
|
+
"esbuild": "bin/esbuild"
|
|
464
|
+
},
|
|
465
|
+
"engines": {
|
|
466
|
+
"node": ">=18"
|
|
467
|
+
},
|
|
468
|
+
"optionalDependencies": {
|
|
469
|
+
"@esbuild/aix-ppc64": "0.28.2",
|
|
470
|
+
"@esbuild/android-arm": "0.28.2",
|
|
471
|
+
"@esbuild/android-arm64": "0.28.2",
|
|
472
|
+
"@esbuild/android-x64": "0.28.2",
|
|
473
|
+
"@esbuild/darwin-arm64": "0.28.2",
|
|
474
|
+
"@esbuild/darwin-x64": "0.28.2",
|
|
475
|
+
"@esbuild/freebsd-arm64": "0.28.2",
|
|
476
|
+
"@esbuild/freebsd-x64": "0.28.2",
|
|
477
|
+
"@esbuild/linux-arm": "0.28.2",
|
|
478
|
+
"@esbuild/linux-arm64": "0.28.2",
|
|
479
|
+
"@esbuild/linux-ia32": "0.28.2",
|
|
480
|
+
"@esbuild/linux-loong64": "0.28.2",
|
|
481
|
+
"@esbuild/linux-mips64el": "0.28.2",
|
|
482
|
+
"@esbuild/linux-ppc64": "0.28.2",
|
|
483
|
+
"@esbuild/linux-riscv64": "0.28.2",
|
|
484
|
+
"@esbuild/linux-s390x": "0.28.2",
|
|
485
|
+
"@esbuild/linux-x64": "0.28.2",
|
|
486
|
+
"@esbuild/netbsd-arm64": "0.28.2",
|
|
487
|
+
"@esbuild/netbsd-x64": "0.28.2",
|
|
488
|
+
"@esbuild/openbsd-arm64": "0.28.2",
|
|
489
|
+
"@esbuild/openbsd-x64": "0.28.2",
|
|
490
|
+
"@esbuild/openharmony-arm64": "0.28.2",
|
|
491
|
+
"@esbuild/sunos-x64": "0.28.2",
|
|
492
|
+
"@esbuild/win32-arm64": "0.28.2",
|
|
493
|
+
"@esbuild/win32-ia32": "0.28.2",
|
|
494
|
+
"@esbuild/win32-x64": "0.28.2"
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
"node_modules/fsevents": {
|
|
498
|
+
"version": "2.3.3",
|
|
499
|
+
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
|
500
|
+
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
|
501
|
+
"hasInstallScript": true,
|
|
502
|
+
"license": "MIT",
|
|
503
|
+
"optional": true,
|
|
504
|
+
"os": [
|
|
505
|
+
"darwin"
|
|
506
|
+
],
|
|
507
|
+
"engines": {
|
|
508
|
+
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
|
509
|
+
}
|
|
510
|
+
},
|
|
63
511
|
"node_modules/playwright": {
|
|
64
512
|
"version": "1.63.0",
|
|
65
|
-
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.63.0.tgz",
|
|
66
|
-
"integrity": "sha512-+7ziBLidS4NaNCdt57SUDT+wYmmd5fmiQejUic/kb+YsYSCPyOOE9sebzMjNmQrsnNpDJqd4WHvV/8lfKfUDUg==",
|
|
67
|
-
"dev": true,
|
|
68
513
|
"license": "Apache-2.0",
|
|
69
514
|
"dependencies": {
|
|
70
515
|
"playwright-core": "1.63.0"
|
|
@@ -78,9 +523,6 @@
|
|
|
78
523
|
},
|
|
79
524
|
"node_modules/playwright-core": {
|
|
80
525
|
"version": "1.63.0",
|
|
81
|
-
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.63.0.tgz",
|
|
82
|
-
"integrity": "sha512-rYCsBF/M5HjUch52bbtVONEFjv6Xu8sm8h72dNlR5bzIE1fvC/bxgspzkjSfU+MweEMmPM8KJebG6nnyxo5mCg==",
|
|
83
|
-
"dev": true,
|
|
84
526
|
"license": "Apache-2.0",
|
|
85
527
|
"bin": {
|
|
86
528
|
"playwright-core": "cli.js"
|
|
@@ -89,10 +531,26 @@
|
|
|
89
531
|
"node": ">=20"
|
|
90
532
|
}
|
|
91
533
|
},
|
|
534
|
+
"node_modules/tsx": {
|
|
535
|
+
"version": "4.23.15",
|
|
536
|
+
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.15.tgz",
|
|
537
|
+
"integrity": "sha512-Yiex1Ovn8z2xPpOWckIiysV1SSyRMY9BkLF++q0yKiDxCqRhosKfMg3janKkiLBwZ5c/YryloKwGZcrEmtwxKw==",
|
|
538
|
+
"license": "MIT",
|
|
539
|
+
"dependencies": {
|
|
540
|
+
"esbuild": "~0.28.0"
|
|
541
|
+
},
|
|
542
|
+
"bin": {
|
|
543
|
+
"tsx": "dist/cli.mjs"
|
|
544
|
+
},
|
|
545
|
+
"engines": {
|
|
546
|
+
"node": ">=18.0.0"
|
|
547
|
+
},
|
|
548
|
+
"optionalDependencies": {
|
|
549
|
+
"fsevents": "~2.3.3"
|
|
550
|
+
}
|
|
551
|
+
},
|
|
92
552
|
"node_modules/typescript": {
|
|
93
553
|
"version": "5.9.3",
|
|
94
|
-
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
|
95
|
-
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
|
96
554
|
"dev": true,
|
|
97
555
|
"license": "Apache-2.0",
|
|
98
556
|
"bin": {
|
|
@@ -105,14 +563,22 @@
|
|
|
105
563
|
},
|
|
106
564
|
"node_modules/undici-types": {
|
|
107
565
|
"version": "8.9.0",
|
|
108
|
-
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.9.0.tgz",
|
|
109
|
-
"integrity": "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==",
|
|
110
566
|
"dev": true,
|
|
111
567
|
"license": "MIT"
|
|
112
568
|
},
|
|
113
569
|
"node_modules/waygraph": {
|
|
114
|
-
"
|
|
115
|
-
"
|
|
570
|
+
"version": "0.15.17",
|
|
571
|
+
"resolved": "file:../..",
|
|
572
|
+
"license": "MIT",
|
|
573
|
+
"dependencies": {
|
|
574
|
+
"tsx": "^4.0.0"
|
|
575
|
+
},
|
|
576
|
+
"bin": {
|
|
577
|
+
"waygraph": "bin/waygraph"
|
|
578
|
+
},
|
|
579
|
+
"peerDependencies": {
|
|
580
|
+
"@playwright/test": "^1.40.0"
|
|
581
|
+
}
|
|
116
582
|
}
|
|
117
583
|
}
|
|
118
584
|
}
|
|
@@ -5,10 +5,11 @@ export default defineConfig({
|
|
|
5
5
|
fullyParallel: false,
|
|
6
6
|
workers: 1,
|
|
7
7
|
timeout: 30_000,
|
|
8
|
-
reporter: "list",
|
|
8
|
+
reporter: [["list"], ["html", { open: "never" }]],
|
|
9
9
|
use: {
|
|
10
10
|
headless: true,
|
|
11
11
|
baseURL: "https://www.saucedemo.com",
|
|
12
|
+
trace: "retain-on-failure",
|
|
12
13
|
launchOptions: {
|
|
13
14
|
// Canonical Chromium on this machine is the Flatpak install - never let
|
|
14
15
|
// Playwright download its own bundled binary. See .agent/manager-agent.md.
|
|
@@ -5,7 +5,7 @@ import { dirname, join } from "node:path";
|
|
|
5
5
|
|
|
6
6
|
const projectDir = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
7
7
|
|
|
8
|
-
test("waygraph auto discovers the decomposed saucedemo graph
|
|
8
|
+
test("waygraph auto discovers the decomposed saucedemo graph, skipping only the FFCompose auth step", async () => {
|
|
9
9
|
const graph = await discoverGraph(projectDir);
|
|
10
10
|
|
|
11
11
|
expect(graph.nodes.map((n) => n.checkpoint).sort()).toEqual(
|
|
@@ -20,8 +20,12 @@ test("waygraph auto discovers the decomposed saucedemo graph with zero skipped B
|
|
|
20
20
|
"OrderComplete",
|
|
21
21
|
].sort(),
|
|
22
22
|
);
|
|
23
|
-
//
|
|
24
|
-
|
|
23
|
+
// 24 vs the earlier 15: checkout-info split into fill-first-name/
|
|
24
|
+
// fill-last-name/fill-postal-code (+2 net) plus the atomic login Blocks
|
|
25
|
+
// (fill-username/fill-password/submit-login's 2 branches) that static
|
|
26
|
+
// discovery still sees even though checkoutFlow itself now drives them
|
|
27
|
+
// through the ff-owner-auth composition below.
|
|
28
|
+
expect(graph.edges.length).toBe(24);
|
|
25
29
|
const removeEdges = graph.edges.filter((e) => e.block === "remove-from-cart");
|
|
26
30
|
expect(removeEdges).toEqual(
|
|
27
31
|
expect.arrayContaining([
|
|
@@ -32,7 +36,15 @@ test("waygraph auto discovers the decomposed saucedemo graph with zero skipped B
|
|
|
32
36
|
|
|
33
37
|
const loginFail = graph.edges.find((e) => e.block === "submit-login" && e.to === "LoginPage");
|
|
34
38
|
expect(loginFail).toMatchObject({ from: "LoginPage", to: "LoginPage", kind: "action" });
|
|
35
|
-
|
|
39
|
+
|
|
40
|
+
// ff-owner-auth (fastForwardComposeBlock) collapses nav-login + fill-username
|
|
41
|
+
// + fill-password + submit-login into one opaque demo/run step - discoverGraph
|
|
42
|
+
// only understands plain defineMethodBlock/defineEffectBlock<In, Out> generic
|
|
43
|
+
// calls, so this one Block is expected to be skipped by static discovery even
|
|
44
|
+
// though it's a real, used step (see src/blocks/saucedemo-web/ff-owner-auth.block.ts).
|
|
45
|
+
expect(graph.skipped).toEqual([
|
|
46
|
+
expect.objectContaining({ block: "ff-owner-auth" }),
|
|
47
|
+
]);
|
|
36
48
|
|
|
37
49
|
const logout = graph.edges.find((e) => e.block === "submit-logout");
|
|
38
50
|
expect(logout).toMatchObject({ from: "LoggedIn", to: "LoginPage", kind: "action" });
|
|
@@ -29,10 +29,15 @@ test("each episode's title survives chaining, and blocks() reports the flattened
|
|
|
29
29
|
|
|
30
30
|
expect(blocks.map((b) => b.name)).toEqual([
|
|
31
31
|
"nav-login",
|
|
32
|
+
"fill-username",
|
|
33
|
+
"fill-password",
|
|
32
34
|
"submit-login",
|
|
33
35
|
"add-to-cart",
|
|
34
36
|
"nav-cart",
|
|
35
37
|
"nav-checkout-info",
|
|
38
|
+
"fill-first-name",
|
|
39
|
+
"fill-last-name",
|
|
40
|
+
"fill-postal-code",
|
|
36
41
|
"submit-checkout-info",
|
|
37
42
|
"finish-order",
|
|
38
43
|
]);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { test, expect } from "@playwright/test";
|
|
2
2
|
import { MemPage, checkpoint, Trait } from "waygraph";
|
|
3
3
|
import { checkoutFlow } from "../src/flows/checkout.flow.js";
|
|
4
|
-
import {
|
|
4
|
+
import { FfOwnerAuthBlock } from "../src/blocks/saucedemo-web/ff-owner-auth.block.js";
|
|
5
5
|
import { LoginCreds, SelectedItem } from "../src/states/checkout.mem-keys.js";
|
|
6
6
|
|
|
7
7
|
// checkoutFlow.withBlockVerify/modBlockVerify - a spec that only imports the
|
|
@@ -31,9 +31,12 @@ test("withBlockVerify: replacing login's verify with an extra real check still p
|
|
|
31
31
|
mem.set(LoginCreds({ username: "standard_user", password: "secret_sauce" }));
|
|
32
32
|
mem.set(SelectedItem({ id: "sauce-labs-backpack", name: "Sauce Labs Backpack" }));
|
|
33
33
|
|
|
34
|
-
// Addressed by the actual
|
|
35
|
-
// form: no typo risk, refactor-safe, jump-to-definition works.
|
|
36
|
-
|
|
34
|
+
// Addressed by the actual FfOwnerAuthBlock reference - the preferred
|
|
35
|
+
// form: no typo risk, refactor-safe, jump-to-definition works. checkoutFlow
|
|
36
|
+
// drives login through the ff-owner-auth FFCompose step (collapsed
|
|
37
|
+
// nav-login + fill-username + fill-password + submit-login), not a bare
|
|
38
|
+
// SubmitLoginBlock reference, so that's the Block whose verify this patches.
|
|
39
|
+
const patched = checkoutFlow.withBlockVerify(FfOwnerAuthBlock, [
|
|
37
40
|
Trait.url({ pathname: "/inventory.html" }),
|
|
38
41
|
Trait.visible(".inventory_list"),
|
|
39
42
|
]);
|
package/package.json
CHANGED
|
@@ -5,10 +5,11 @@ export default defineConfig({
|
|
|
5
5
|
fullyParallel: false,
|
|
6
6
|
workers: 1,
|
|
7
7
|
timeout: 30_000,
|
|
8
|
-
reporter: "list",
|
|
8
|
+
reporter: [["list"], ["html", { open: "never" }]],
|
|
9
9
|
use: {
|
|
10
10
|
headless: true,
|
|
11
11
|
baseURL: "https://www.saucedemo.com",
|
|
12
|
+
trace: "retain-on-failure",
|
|
12
13
|
launchOptions: {
|
|
13
14
|
// Canonical Chromium on this machine is the Flatpak install - never let
|
|
14
15
|
// Playwright download its own bundled binary. See .agent/manager-agent.md.
|
|
@@ -7,9 +7,10 @@ const FIXTURE_ORIGIN = `http://${FIXTURE_HOST}:${FIXTURE_PORT}`;
|
|
|
7
7
|
export default defineConfig({
|
|
8
8
|
testDir: "./tests",
|
|
9
9
|
fullyParallel: true,
|
|
10
|
-
reporter: "list",
|
|
10
|
+
reporter: [["list"], ["html", { open: "never" }]],
|
|
11
11
|
use: {
|
|
12
12
|
baseURL: FIXTURE_ORIGIN,
|
|
13
|
+
trace: "retain-on-failure",
|
|
13
14
|
launchOptions: {
|
|
14
15
|
executablePath: process.env.CHROME_PATH || process.env.CHROMIUM_PATH,
|
|
15
16
|
},
|
|
@@ -22,6 +22,11 @@ against a live site, use `--skill-pilot-blind`.
|
|
|
22
22
|
inline selector literals in `Trait.visible` / `Trait.text`.
|
|
23
23
|
4. **Assert-only = `defineAssertBlock`.** Self-loop, no hand-written `act`/`resolve`. Pass
|
|
24
24
|
an explicit type argument when it sits between two specifically-typed Blocks in a Flow.
|
|
25
|
+
Not just static content or an action's result - it also names a *feature state* worth a
|
|
26
|
+
Checkpoint of its own (a submit button greyed out until required fields are filled, a
|
|
27
|
+
field error under one input, a stale "Save" re-enabling). No built-in `Trait.disabled` -
|
|
28
|
+
write the state condition as a custom Trait (`isDisabled()`, a class, `aria-disabled`),
|
|
29
|
+
same as any other Trait: real DOM check, no inline selector.
|
|
25
30
|
5. **`requires` = externally supplied.** A key an earlier Block in the same chain produces
|
|
26
31
|
is never listed under `requires` - preflight checks the whole chain up front.
|
|
27
32
|
6. **Keep Checkpoints typed — never `Checkpoint<string>`.** Block helpers take concrete
|
|
@@ -105,6 +110,22 @@ npm run typecheck # when the consumer has it
|
|
|
105
110
|
are still runnable in Pilot's live menu - orphan status only blocks
|
|
106
111
|
`auto --blocks <From> <To>` pathfinding.
|
|
107
112
|
|
|
113
|
+
**Static tools above only find gaps in Blocks that already exist.** A real link/button on
|
|
114
|
+
the live page with *no Block written for it at all* has nothing in source for `check`/
|
|
115
|
+
`graph` to scan - the only way to find that is to actually run the app. Every live
|
|
116
|
+
`auto`/`browser`/`pilot` session watches the real page and warns (once per element) on
|
|
117
|
+
anything with no matching Block:
|
|
118
|
+
|
|
119
|
+
```text
|
|
120
|
+
[waygraph] unmapped nav link on this page: /settings - no NavBlock covers this URL; add defineNavBlock
|
|
121
|
+
[waygraph] unmapped button on this page: #save-draft - no Method/NavClick Block selector matches; consider defineMethodBlock or defineNavClickBlock
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Read them back with `auto console <sessionId>` (same channel as real console/network
|
|
125
|
+
errors) - see `--skill-pilot`'s "Coverage gaps on the live page" section for the full
|
|
126
|
+
detection rules (same-origin `<a href>` only, visible clickables only, one warning per
|
|
127
|
+
element per session).
|
|
128
|
+
|
|
108
129
|
## Related skills (print via CLI)
|
|
109
130
|
|
|
110
131
|
```bash
|