@codeyam-editor/codeyam-editor 0.1.4 → 0.1.6
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/npm/cli.js +5 -1
- package/npm/cloud-branch-switch.js +1 -1
- package/npm/cloud.js +3166 -150
- package/npm/codesign-plan.js +68 -0
- package/npm/container.js +3 -0
- package/npm/disk-pressure.js +78 -0
- package/npm/editor-dev.js +96 -15
- package/npm/editor.js +85 -37
- package/npm/empty-project-dir.js +92 -7
- package/npm/fleet-add-failure.js +252 -0
- package/npm/fleet-asset-version.js +37 -0
- package/npm/fleet-auth-health.js +213 -0
- package/npm/fleet-auth.js +6 -1
- package/npm/fleet-build-data.js +109 -5
- package/npm/fleet-cleanup.js +232 -16
- package/npm/fleet-destroy-safety.js +272 -0
- package/npm/fleet-early-roster.js +87 -0
- package/npm/fleet-effect-poll.js +110 -0
- package/npm/fleet-effect-status.js +33 -32
- package/npm/fleet-env.js +86 -0
- package/npm/fleet-ghcr-secret.js +129 -0
- package/npm/fleet-git-maintenance.js +142 -0
- package/npm/fleet-host-op-limiter.js +68 -0
- package/npm/fleet-host.js +74 -0
- package/npm/fleet-iap-token.js +165 -0
- package/npm/fleet-job-badge.js +1 -1
- package/npm/fleet-launchd.js +171 -0
- package/npm/fleet-live-status.js +155 -0
- package/npm/fleet-memory.js +245 -9
- package/npm/fleet-plans.js +233 -4
- package/npm/fleet-pool.js +75 -16
- package/npm/fleet-prewarm.js +241 -0
- package/npm/fleet-project-drift.js +58 -0
- package/npm/fleet-public-url.js +394 -0
- package/npm/fleet-queue.js +95 -1
- package/npm/fleet-reachability-debounce.js +69 -0
- package/npm/fleet-reachability.js +80 -0
- package/npm/fleet-reconcile.js +43 -1
- package/npm/fleet-reset.js +330 -13
- package/npm/fleet-roster.js +6 -8
- package/npm/fleet-running-plan.js +85 -0
- package/npm/fleet-self-update.js +142 -0
- package/npm/fleet-session-token-cache.js +65 -0
- package/npm/fleet-setup-steps.js +112 -0
- package/npm/fleet-sleep-status.js +33 -0
- package/npm/fleet-status-refs.js +96 -0
- package/npm/fleet-strand.js +181 -0
- package/npm/fleet-stuck-status.js +117 -0
- package/npm/fleet-vm-access.js +404 -0
- package/npm/fleet-vm-probe-target.js +282 -0
- package/npm/fleet-vm-readiness.js +237 -0
- package/npm/fleet-vm-slugs.js +116 -0
- package/npm/google-ingress.js +226 -0
- package/npm/ingress-invoke.js +770 -0
- package/npm/launch-config.js +386 -9
- package/npm/scenario-check.js +880 -37
- package/npm/scenario-handlers.js +154 -30
- package/npm/scenario-interactivity.js +145 -6
- package/npm/scenario-issues.js +13 -1
- package/npm/scenario-metrics.js +116 -1
- package/npm/scenario-mocks.js +144 -21
- package/npm/scenario-playwright.js +649 -38
- package/npm/script-drift.js +152 -0
- package/npm/utils.js +365 -52
- package/npm/vm-urls.js +69 -8
- package/package.json +5 -5
- package/ui/dist/assets/ContainerInspector-DgM0pTAx.js +2 -0
- package/ui/dist/assets/EditorShell-B7Q06uJ_.js +252 -0
- package/ui/dist/assets/EditorShell-DP5UY20G.css +1 -0
- package/ui/dist/assets/{Markdown-BHBqz-Mj.js → Markdown-Chgdf3PW.js} +1 -1
- package/ui/dist/assets/ProjectLauncherScreen-BRrEr8Ng.js +1 -0
- package/ui/dist/assets/ScenarioDataPanel-BeQfa28g.js +9 -0
- package/ui/dist/assets/{ScenarioDataPanel-DYP7pi_n.css → ScenarioDataPanel-C1LukYI6.css} +1 -1
- package/ui/dist/assets/ScenarioDataPanelFullPage-BLqRCxQX.js +1 -0
- package/ui/dist/assets/ScenarioRenderer-CIAxfHPh.js +21 -0
- package/ui/dist/assets/StepsSimulator-CymGgfbu.js +1 -0
- package/ui/dist/assets/index-BygCiJSb.css +1 -0
- package/ui/dist/assets/{index-BuK0lizt.js → index-DCHqRrwO.js} +9 -9
- package/ui/dist/assets/{markdown-v0F0UEt3.js → markdown-C9tbsVHX.js} +1 -1
- package/ui/dist/assets/react-nrLBr15I.js +28 -0
- package/ui/dist/assets/useEvents-S3Qk1Y_d.js +1 -0
- package/ui/dist/assets/useServerIdentity-B7rI0u3O.js +1 -0
- package/ui/dist/codeyam-mark.svg +4 -0
- package/ui/dist/codeyam-wordmark.svg +5 -0
- package/ui/dist/index.html +4 -4
- package/ui/dist/open-source/codeyam-counter.png +0 -0
- package/ui/dist/open-source/el-carot.png +0 -0
- package/ui/dist/open-source/tabcommand.png +0 -0
- package/ui/dist/assets/ContainerInspector-C8EkH4PP.js +0 -2
- package/ui/dist/assets/EditorShell-tMMdarZD.js +0 -187
- package/ui/dist/assets/ScenarioDataPanel-xWYGZOpo.js +0 -5
- package/ui/dist/assets/ScenarioDataPanelFullPage-5G6KuZgw.js +0 -1
- package/ui/dist/assets/ScenarioRenderer-CSdhX1Ak.js +0 -1
- package/ui/dist/assets/StepsSimulator-CRtmlyNZ.js +0 -1
- package/ui/dist/assets/index-BGqairFV.css +0 -1
- package/ui/dist/assets/react-CSS0HapR.js +0 -28
- package/ui/dist/assets/useEvents-DggWrtHe.js +0 -1
package/npm/scenario-mocks.js
CHANGED
|
@@ -1,45 +1,124 @@
|
|
|
1
|
-
|
|
1
|
+
// Route matcher shared, semantically, with the injected live-preview shim
|
|
2
|
+
// (crates/proxy-http/src/fetch_patch.js::matchUrl / matchPath / matchQuerySpec).
|
|
3
|
+
// This is a VERBATIM port of that shim's matcher — the two interception paths
|
|
4
|
+
// MUST agree on which requests a mock route covers. When they drifted (the
|
|
5
|
+
// shim gained `:param` + query-spec parity but this capture-harness matcher was
|
|
6
|
+
// left doing exact string matching), a parameterized or query-spec'd mock
|
|
7
|
+
// rendered in the Live Preview but escaped Playwright's `page.route` during
|
|
8
|
+
// capture and rendered an empty list. `scenario-mocks.test.js` pins the two to
|
|
9
|
+
// identical verdicts on a shared fixture table so a future divergence is a
|
|
10
|
+
// test failure, not another lost build session.
|
|
11
|
+
//
|
|
12
|
+
// `:param` path segments match any single non-empty segment; a `?k=v` / `?k=*`
|
|
13
|
+
// query-spec suffix constrains the query as a subset match (`k=*` matches any
|
|
14
|
+
// value; an empty spec matches any query). Full-URL patterns (`http://…`) match
|
|
15
|
+
// by prefix on the raw URL. Mirrors crates/mock-engine's server matcher.
|
|
16
|
+
function matchUrl(pattern, url) {
|
|
17
|
+
// Full-URL patterns (external APIs) match by prefix on the raw URL.
|
|
18
|
+
if (pattern.startsWith("http://") || pattern.startsWith("https://")) {
|
|
19
|
+
return url.indexOf(pattern) === 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let reqPath = url;
|
|
23
|
+
let reqQuery = "";
|
|
2
24
|
try {
|
|
3
|
-
const
|
|
4
|
-
|
|
25
|
+
const u = new URL(url);
|
|
26
|
+
reqPath = u.pathname;
|
|
27
|
+
reqQuery = u.search.replace(/^\?/, "");
|
|
5
28
|
} catch {
|
|
6
|
-
|
|
29
|
+
const qi = url.indexOf("?");
|
|
30
|
+
if (qi >= 0) {
|
|
31
|
+
reqPath = url.slice(0, qi);
|
|
32
|
+
reqQuery = url.slice(qi + 1);
|
|
33
|
+
}
|
|
7
34
|
}
|
|
35
|
+
|
|
36
|
+
const patParts = pattern.split("?");
|
|
37
|
+
if (!matchPath(patParts[0], reqPath)) return false;
|
|
38
|
+
return matchQuerySpec(patParts.length > 1 ? patParts[1] : "", reqQuery);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Segment-wise path match with `:param` wildcards. A `:name` segment matches
|
|
42
|
+
// any single non-empty segment; every other segment must be equal, and the
|
|
43
|
+
// segment counts must match — no implicit prefix match, same as the server.
|
|
44
|
+
function matchPath(pattern, path) {
|
|
45
|
+
const pp = pattern.split("/");
|
|
46
|
+
const rp = path.split("/");
|
|
47
|
+
if (pp.length !== rp.length) return false;
|
|
48
|
+
for (let i = 0; i < pp.length; i++) {
|
|
49
|
+
if (pp[i].charAt(0) === ":") {
|
|
50
|
+
if (rp[i] === "") return false;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (pp[i] !== rp[i]) return false;
|
|
54
|
+
}
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Query-spec match. An empty spec matches any query (a path-only route still
|
|
59
|
+
// matches a request that carries query params). Otherwise every `k=v` pair in
|
|
60
|
+
// the spec must be present in the request query; `k=*` matches any value.
|
|
61
|
+
function matchQuerySpec(spec, query) {
|
|
62
|
+
if (!spec) return true;
|
|
63
|
+
const want = new URLSearchParams(spec);
|
|
64
|
+
const have = new URLSearchParams(query);
|
|
65
|
+
let ok = true;
|
|
66
|
+
want.forEach((v, k) => {
|
|
67
|
+
const got = have.get(k);
|
|
68
|
+
if (got === null) {
|
|
69
|
+
ok = false;
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (v !== "*" && got !== v) ok = false;
|
|
73
|
+
});
|
|
74
|
+
return ok;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Split a mock key (`"<METHOD> <route>"`, e.g. `"GET /api/plans"`) into its
|
|
78
|
+
// method and route pattern. Returns null for a malformed key with no separator.
|
|
79
|
+
function splitMockKey(key) {
|
|
80
|
+
const spaceIdx = key.indexOf(" ");
|
|
81
|
+
if (spaceIdx === -1) return null;
|
|
82
|
+
return { method: key.slice(0, spaceIdx), route: key.slice(spaceIdx + 1) };
|
|
8
83
|
}
|
|
9
84
|
|
|
10
85
|
function findHttpMock(httpMocks, request) {
|
|
11
86
|
const method = request.method().toUpperCase();
|
|
12
|
-
const
|
|
13
|
-
for (const
|
|
14
|
-
const
|
|
15
|
-
if (
|
|
16
|
-
|
|
17
|
-
|
|
87
|
+
const url = request.url();
|
|
88
|
+
for (const [key, mock] of Object.entries(httpMocks)) {
|
|
89
|
+
const parsed = splitMockKey(key);
|
|
90
|
+
if (!parsed) continue;
|
|
91
|
+
// Method stays an exact check; only the route is matched by pattern.
|
|
92
|
+
if (parsed.method.toUpperCase() !== method) continue;
|
|
93
|
+
if (matchUrl(parsed.route, url)) return mock;
|
|
18
94
|
}
|
|
19
95
|
return null;
|
|
20
96
|
}
|
|
21
97
|
|
|
22
|
-
// The set of path/URL
|
|
23
|
-
// `"<METHOD> <
|
|
98
|
+
// The set of path/URL route patterns declared by the mock keys. A key is
|
|
99
|
+
// `"<METHOD> <route>"` (e.g. `"GET /api/plans"`); we strip the method so the
|
|
24
100
|
// route matcher can decide whether a request *could* match any mock without
|
|
25
101
|
// knowing the method (the handler re-checks method via findHttpMock).
|
|
26
102
|
function mockedTargets(httpMocks) {
|
|
27
103
|
const targets = new Set();
|
|
28
104
|
for (const key of Object.keys(httpMocks)) {
|
|
29
|
-
const
|
|
30
|
-
if (
|
|
31
|
-
targets.add(
|
|
105
|
+
const parsed = splitMockKey(key);
|
|
106
|
+
if (!parsed) continue;
|
|
107
|
+
targets.add(parsed.route);
|
|
32
108
|
}
|
|
33
109
|
return targets;
|
|
34
110
|
}
|
|
35
111
|
|
|
36
|
-
// True when a request URL matches one of the declared mock
|
|
37
|
-
//
|
|
112
|
+
// True when a request URL matches one of the declared mock route patterns under
|
|
113
|
+
// the shared route matcher (`:param` + query-spec parity), not exact string
|
|
114
|
+
// equality. Accepts either a string or a WHATWG URL (Playwright's URL-matcher
|
|
115
|
+
// passes a URL).
|
|
38
116
|
function requestTargetsMock(targets, url) {
|
|
39
117
|
const href = typeof url === "string" ? url : url.href;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
118
|
+
for (const target of targets) {
|
|
119
|
+
if (matchUrl(target, href)) return true;
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
43
122
|
}
|
|
44
123
|
|
|
45
124
|
async function attachHttpMocks(page, httpMocks) {
|
|
@@ -98,10 +177,54 @@ async function attachHttpMocks(page, httpMocks) {
|
|
|
98
177
|
});
|
|
99
178
|
}
|
|
100
179
|
|
|
180
|
+
|
|
181
|
+
// True when a console "Failed to load resource" error at `url` corresponds to
|
|
182
|
+
// a mock this scenario DECLARED with an error status (>= 400). An intentional
|
|
183
|
+
// error-state scenario (e.g. a History tab mocking `GET /api/history` -> 500)
|
|
184
|
+
// must not fail its own capture on the console noise its mock deliberately
|
|
185
|
+
// produces. Console errors carry no HTTP method, so any method's mock on a
|
|
186
|
+
// matching target counts.
|
|
187
|
+
function isDeclaredErrorMock(httpMocks, url) {
|
|
188
|
+
for (const [key, mock] of Object.entries(httpMocks || {})) {
|
|
189
|
+
const parsed = splitMockKey(key);
|
|
190
|
+
if (!parsed) continue;
|
|
191
|
+
// Method-agnostic on purpose: console errors carry no HTTP method, so any
|
|
192
|
+
// method's error mock on a matching route counts. Route matching uses the
|
|
193
|
+
// shared matcher so a `:param`/query-spec error mock is recognised too.
|
|
194
|
+
if (!matchUrl(parsed.route, url)) continue;
|
|
195
|
+
if ((mock.status || 200) >= 400) return true;
|
|
196
|
+
}
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Given a same-origin response's method/url/status and the scenario's declared
|
|
201
|
+
// mocks, return the `{method, path, status}` to record as an unmocked route, or
|
|
202
|
+
// `null` if it should be ignored: a sub-4xx response, or one already covered by
|
|
203
|
+
// a declared error mock (status >= 400, whose 4xx is the mock's intended
|
|
204
|
+
// behavior). The caller applies the same-origin and `expectedConsoleErrors`
|
|
205
|
+
// gates before calling. `path` is the URL pathname — the route half of the
|
|
206
|
+
// `"<METHOD> <path>"` stub-mock key; a malformed URL falls back to the raw
|
|
207
|
+
// string so the key is still well-formed.
|
|
208
|
+
function unmockedRouteFrom(method, url, status, httpMocks) {
|
|
209
|
+
if (status < 400) return null;
|
|
210
|
+
if (isDeclaredErrorMock(httpMocks, url)) return null;
|
|
211
|
+
let path = url;
|
|
212
|
+
try {
|
|
213
|
+
path = new URL(url).pathname;
|
|
214
|
+
} catch {
|
|
215
|
+
/* malformed URL — fall back to the raw string for the stub key */
|
|
216
|
+
}
|
|
217
|
+
return { method: String(method).toUpperCase(), path, status };
|
|
218
|
+
}
|
|
219
|
+
|
|
101
220
|
module.exports = {
|
|
102
|
-
|
|
221
|
+
matchUrl,
|
|
222
|
+
matchPath,
|
|
223
|
+
matchQuerySpec,
|
|
103
224
|
findHttpMock,
|
|
104
225
|
mockedTargets,
|
|
105
226
|
requestTargetsMock,
|
|
106
227
|
attachHttpMocks,
|
|
228
|
+
isDeclaredErrorMock,
|
|
229
|
+
unmockedRouteFrom,
|
|
107
230
|
};
|