hyperframes 0.6.47 → 0.6.49

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/dist/cli.js CHANGED
@@ -54,7 +54,7 @@ var VERSION;
54
54
  var init_version = __esm({
55
55
  "src/version.ts"() {
56
56
  "use strict";
57
- VERSION = true ? "0.6.47" : "0.0.0-dev";
57
+ VERSION = true ? "0.6.49" : "0.0.0-dev";
58
58
  }
59
59
  });
60
60
 
@@ -11820,6 +11820,23 @@ function trackInitTemplate(templateId, props) {
11820
11820
  function trackBrowserInstall() {
11821
11821
  trackEvent("browser_install", {});
11822
11822
  }
11823
+ function trackCliError(props) {
11824
+ trackEvent("cli_error", {
11825
+ error_name: props.error_name,
11826
+ error_message: props.error_message.slice(0, 1e3),
11827
+ stack_trace: props.stack_trace?.slice(0, 2e3),
11828
+ command: props.command,
11829
+ kind: props.kind
11830
+ });
11831
+ }
11832
+ function trackCommandResult(props) {
11833
+ trackEvent("cli_command_result", {
11834
+ command: props.command,
11835
+ success: props.success,
11836
+ exit_code: props.exitCode,
11837
+ duration_ms: props.durationMs
11838
+ });
11839
+ }
11823
11840
  var init_events = __esm({
11824
11841
  "src/telemetry/events.ts"() {
11825
11842
  "use strict";
@@ -26579,6 +26596,12 @@ function patchElementInHtml(source, target, operations) {
26579
26596
  }
26580
26597
  return wrappedFragment ? document2.body.innerHTML || "" : document2.toString();
26581
26598
  }
26599
+ function probeElementInSource(source, target) {
26600
+ if (!target.id && !target.selector) return false;
26601
+ const { document: document2 } = parseSourceDocument(source);
26602
+ const el = findTargetElement(document2, target);
26603
+ return el != null && isHTMLElement(el);
26604
+ }
26582
26605
  var ALLOWED_HTML_ATTRS, DANGEROUS_URI_SCHEMES, DANGEROUS_DATA_URI, URI_ATTRS;
26583
26606
  var init_sourceMutation = __esm({
26584
26607
  "../core/src/studio-api/helpers/sourceMutation.ts"() {
@@ -26670,13 +26693,13 @@ import {
26670
26693
  readdirSync as readdirSync4
26671
26694
  } from "fs";
26672
26695
  import { resolve as resolve9, dirname as dirname6, join as join13 } from "path";
26673
- async function resolveProjectFile(c3, adapter2, opts) {
26696
+ async function resolveProjectPath(c3, adapter2, pathPrefix, opts) {
26674
26697
  const id = c3.req.param("id");
26675
26698
  const project = await adapter2.resolveProject(id);
26676
26699
  if (!project) {
26677
26700
  return { error: c3.json({ error: "not found" }, 404) };
26678
26701
  }
26679
- const filePath = decodeURIComponent(c3.req.path.replace(`/projects/${project.id}/files/`, ""));
26702
+ const filePath = decodeURIComponent(c3.req.path.replace(pathPrefix(project.id), ""));
26680
26703
  if (filePath.includes("\0")) {
26681
26704
  return { error: c3.json({ error: "forbidden" }, 403) };
26682
26705
  }
@@ -26689,6 +26712,26 @@ async function resolveProjectFile(c3, adapter2, opts) {
26689
26712
  }
26690
26713
  return { project, filePath, absPath };
26691
26714
  }
26715
+ function resolveProjectFile(c3, adapter2, opts) {
26716
+ return resolveProjectPath(c3, adapter2, (id) => `/projects/${id}/files/`, opts);
26717
+ }
26718
+ function resolveFileMutationContext(c3, adapter2, operation) {
26719
+ return resolveProjectPath(c3, adapter2, (id) => `/projects/${id}/file-mutations/${operation}/`);
26720
+ }
26721
+ function writeIfChanged(c3, absPath, original, next) {
26722
+ if (next === original) {
26723
+ return c3.json({ ok: true, changed: false, content: original });
26724
+ }
26725
+ writeFileSync8(absPath, next, "utf-8");
26726
+ return c3.json({ ok: true, changed: true, content: next });
26727
+ }
26728
+ async function parseMutationBody(c3) {
26729
+ const body = await c3.req.json().catch(() => null);
26730
+ if (!body?.target) {
26731
+ return { error: c3.json({ error: "target required" }, 400) };
26732
+ }
26733
+ return { target: body.target, body };
26734
+ }
26692
26735
  function ensureDir(filePath) {
26693
26736
  const dir = dirname6(filePath);
26694
26737
  if (!existsSync11(dir)) mkdirSync6(dir, { recursive: true });
@@ -26781,64 +26824,55 @@ function registerFileRoutes(api, adapter2) {
26781
26824
  return c3.json({ ok: true });
26782
26825
  });
26783
26826
  api.post("/projects/:id/file-mutations/remove-element/*", async (c3) => {
26784
- const id = c3.req.param("id");
26785
- const project = await adapter2.resolveProject(id);
26786
- if (!project) return c3.json({ error: "not found" }, 404);
26787
- const filePath = decodeURIComponent(
26788
- c3.req.path.replace(`/projects/${project.id}/file-mutations/remove-element/`, "")
26789
- );
26790
- if (filePath.includes("\0")) {
26791
- return c3.json({ error: "forbidden" }, 403);
26792
- }
26793
- const absPath = resolve9(project.dir, filePath);
26794
- if (!isSafePath(project.dir, absPath)) {
26795
- return c3.json({ error: "forbidden" }, 403);
26796
- }
26797
- if (!existsSync11(absPath)) {
26827
+ const ctx = await resolveFileMutationContext(c3, adapter2, "remove-element");
26828
+ if ("error" in ctx) return ctx.error;
26829
+ if (!existsSync11(ctx.absPath)) {
26798
26830
  return c3.json({ error: "not found" }, 404);
26799
26831
  }
26800
- const body = await c3.req.json().catch(() => null);
26801
- if (!body?.target) {
26802
- return c3.json({ error: "target required" }, 400);
26803
- }
26804
- const originalContent = readFileSync12(absPath, "utf-8");
26805
- const patchedContent = removeElementFromHtml2(originalContent, body.target);
26806
- if (patchedContent === originalContent) {
26807
- return c3.json({ ok: true, changed: false, content: originalContent });
26808
- }
26809
- writeFileSync8(absPath, patchedContent, "utf-8");
26810
- return c3.json({ ok: true, changed: true, content: patchedContent });
26832
+ const parsed = await parseMutationBody(c3);
26833
+ if ("error" in parsed) return parsed.error;
26834
+ const originalContent = readFileSync12(ctx.absPath, "utf-8");
26835
+ return writeIfChanged(
26836
+ c3,
26837
+ ctx.absPath,
26838
+ originalContent,
26839
+ removeElementFromHtml2(originalContent, parsed.target)
26840
+ );
26811
26841
  });
26812
26842
  api.post("/projects/:id/file-mutations/patch-element/*", async (c3) => {
26813
- const id = c3.req.param("id");
26814
- const project = await adapter2.resolveProject(id);
26815
- if (!project) return c3.json({ error: "not found" }, 404);
26816
- const filePath = decodeURIComponent(
26817
- c3.req.path.replace(`/projects/${project.id}/file-mutations/patch-element/`, "")
26818
- );
26819
- if (filePath.includes("\0")) {
26820
- return c3.json({ error: "forbidden" }, 403);
26821
- }
26822
- const absPath = resolve9(project.dir, filePath);
26823
- if (!isSafePath(project.dir, absPath)) {
26824
- return c3.json({ error: "forbidden" }, 403);
26825
- }
26826
- const body = await c3.req.json().catch(() => null);
26827
- if (!body?.target || !Array.isArray(body.operations) || body.operations.length === 0) {
26843
+ const ctx = await resolveFileMutationContext(c3, adapter2, "patch-element");
26844
+ if ("error" in ctx) return ctx.error;
26845
+ const parsed = await parseMutationBody(c3);
26846
+ if ("error" in parsed) return parsed.error;
26847
+ if (!Array.isArray(parsed.body.operations) || parsed.body.operations.length === 0) {
26828
26848
  return c3.json({ error: "target and operations required" }, 400);
26829
26849
  }
26830
26850
  let originalContent;
26831
26851
  try {
26832
- originalContent = readFileSync12(absPath, "utf-8");
26852
+ originalContent = readFileSync12(ctx.absPath, "utf-8");
26833
26853
  } catch {
26834
26854
  return c3.json({ error: "not found" }, 404);
26835
26855
  }
26836
- const patchedContent = patchElementInHtml(originalContent, body.target, body.operations);
26837
- if (patchedContent === originalContent) {
26838
- return c3.json({ ok: true, changed: false, content: originalContent });
26856
+ return writeIfChanged(
26857
+ c3,
26858
+ ctx.absPath,
26859
+ originalContent,
26860
+ patchElementInHtml(originalContent, parsed.target, parsed.body.operations)
26861
+ );
26862
+ });
26863
+ api.post("/projects/:id/file-mutations/probe-element/*", async (c3) => {
26864
+ const ctx = await resolveFileMutationContext(c3, adapter2, "probe-element");
26865
+ if ("error" in ctx) return ctx.error;
26866
+ const parsed = await parseMutationBody(c3);
26867
+ if ("error" in parsed) return parsed.error;
26868
+ let content;
26869
+ try {
26870
+ content = readFileSync12(ctx.absPath, "utf-8");
26871
+ } catch {
26872
+ return c3.json({ exists: false });
26839
26873
  }
26840
- writeFileSync8(absPath, patchedContent, "utf-8");
26841
- return c3.json({ ok: true, changed: true, content: patchedContent });
26874
+ const exists = probeElementInSource(content, parsed.target);
26875
+ return c3.json({ exists });
26842
26876
  });
26843
26877
  api.patch("/projects/:id/files/*", async (c3) => {
26844
26878
  const res = await resolveProjectFile(c3, adapter2, { mustExist: true });
@@ -99558,7 +99592,9 @@ __export(telemetry_exports2, {
99558
99592
  shouldTrack: () => shouldTrack,
99559
99593
  showTelemetryNotice: () => showTelemetryNotice,
99560
99594
  trackBrowserInstall: () => trackBrowserInstall,
99595
+ trackCliError: () => trackCliError,
99561
99596
  trackCommand: () => trackCommand,
99597
+ trackCommandResult: () => trackCommandResult,
99562
99598
  trackEvent: () => trackEvent,
99563
99599
  trackInitTemplate: () => trackInitTemplate,
99564
99600
  trackRenderComplete: () => trackRenderComplete,
@@ -100097,11 +100133,15 @@ var command = cliCommandArg && cliCommandArg in subCommands ? cliCommandArg : "u
100097
100133
  var hasJsonFlag = process.argv.includes("--json");
100098
100134
  var _flush;
100099
100135
  var _flushSync;
100136
+ var _trackCliError;
100137
+ var _trackCommandResult;
100100
100138
  var _printUpdateNotice;
100101
100139
  if (!isHelp && command !== "telemetry" && command !== "unknown") {
100102
100140
  Promise.resolve().then(() => (init_telemetry2(), telemetry_exports2)).then((mod) => {
100103
100141
  _flush = mod.flush;
100104
100142
  _flushSync = mod.flushSync;
100143
+ _trackCliError = mod.trackCliError;
100144
+ _trackCommandResult = mod.trackCommandResult;
100105
100145
  mod.showTelemetryNotice();
100106
100146
  mod.trackCommand(command);
100107
100147
  if (mod.shouldTrack()) mod.incrementCommandCount();
@@ -100119,13 +100159,44 @@ if (!isHelp && !hasJsonFlag && command !== "upgrade") {
100119
100159
  }
100120
100160
  });
100121
100161
  }
100162
+ var commandStart = Date.now();
100163
+ var commandFailed = false;
100122
100164
  process.on("beforeExit", () => {
100123
100165
  _flush?.().catch(() => {
100124
100166
  });
100125
100167
  if (!hasJsonFlag) _printUpdateNotice?.();
100126
100168
  });
100127
- process.on("exit", () => {
100169
+ process.on("exit", (code) => {
100170
+ _trackCommandResult?.({
100171
+ command,
100172
+ success: code === 0 && !commandFailed,
100173
+ exitCode: code,
100174
+ durationMs: Date.now() - commandStart
100175
+ });
100176
+ _flushSync?.();
100177
+ });
100178
+ process.on("uncaughtException", (error) => {
100179
+ commandFailed = true;
100180
+ _trackCliError?.({
100181
+ error_name: error.name,
100182
+ error_message: error.message,
100183
+ stack_trace: error.stack,
100184
+ command,
100185
+ kind: "uncaught_exception"
100186
+ });
100128
100187
  _flushSync?.();
100188
+ process.exit(1);
100189
+ });
100190
+ process.on("unhandledRejection", (reason) => {
100191
+ commandFailed = true;
100192
+ const error = reason instanceof Error ? reason : new Error(String(reason));
100193
+ _trackCliError?.({
100194
+ error_name: error.name,
100195
+ error_message: error.message,
100196
+ stack_trace: error.stack,
100197
+ command,
100198
+ kind: "unhandled_rejection"
100199
+ });
100129
100200
  });
100130
100201
  async function showUsage3(cmd, parent) {
100131
100202
  const { showUsage: impl } = await Promise.resolve().then(() => (init_help(), help_exports));