@ubiquity-os/plugin-sdk 3.6.3 → 3.8.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/dist/index.mjs CHANGED
@@ -1,6 +1,5 @@
1
1
  // src/actions.ts
2
2
  import * as core from "@actions/core";
3
- import * as github2 from "@actions/github";
4
3
  import { Value as Value3 } from "@sinclair/typebox/value";
5
4
 
6
5
  // ../../node_modules/@ubiquity-os/ubiquity-os-logger/dist/index.js
@@ -191,9 +190,9 @@ var Logs = class _Logs {
191
190
  const stackLines = new Error().stack?.split("\n") || [];
192
191
  if (stackLines.length > 3) {
193
192
  const callerLine = stackLines[3];
194
- const match = callerLine.match(/at (\S+)/);
195
- if (match) {
196
- metadata.caller = match[1];
193
+ const match2 = callerLine.match(/at (\S+)/);
194
+ if (match2) {
195
+ metadata.caller = match2[1];
197
196
  }
198
197
  }
199
198
  return metadata;
@@ -338,10 +337,58 @@ var Logs = class _Logs {
338
337
  // src/actions.ts
339
338
  import { config } from "dotenv";
340
339
 
341
- // src/helpers/runtime-info.ts
342
- import github from "@actions/github";
340
+ // src/error.ts
341
+ function getErrorStatus(err) {
342
+ if (!err || typeof err !== "object") return null;
343
+ const candidate = err;
344
+ const directStatus = candidate.status ?? candidate.response?.status;
345
+ if (typeof directStatus === "number" && Number.isFinite(directStatus)) return directStatus;
346
+ if (typeof directStatus === "string" && directStatus.trim()) {
347
+ const parsed = Number.parseInt(directStatus, 10);
348
+ if (Number.isFinite(parsed)) return parsed;
349
+ }
350
+ if (err instanceof Error) {
351
+ const match2 = /LLM API error:\s*(\d{3})/i.exec(err.message);
352
+ if (match2) {
353
+ const parsed = Number.parseInt(match2[1], 10);
354
+ if (Number.isFinite(parsed)) return parsed;
355
+ }
356
+ }
357
+ return null;
358
+ }
359
+ function logByStatus(context, message, metadata) {
360
+ const status = getErrorStatus(metadata.err);
361
+ const payload = { ...metadata, ...status ? { status } : {} };
362
+ if (status && status >= 500) return context.logger.error(message, payload);
363
+ if (status && status >= 400) return context.logger.warn(message, payload);
364
+ if (status && status >= 300) return context.logger.debug(message, payload);
365
+ if (status && status >= 200) return context.logger.ok(message, payload);
366
+ if (status && status >= 100) return context.logger.info(message, payload);
367
+ return context.logger.error(message, payload);
368
+ }
369
+ function transformError(context, error) {
370
+ if (error instanceof LogReturn) {
371
+ return error;
372
+ }
373
+ if (error instanceof AggregateError) {
374
+ const message = error.errors.map((err) => {
375
+ if (err instanceof LogReturn) {
376
+ return err.logMessage.raw;
377
+ }
378
+ if (err instanceof Error) {
379
+ return err.message;
380
+ }
381
+ return String(err);
382
+ }).join("\n\n");
383
+ return logByStatus(context, message, { err: error });
384
+ }
385
+ if (error instanceof Error) {
386
+ return logByStatus(context, error.message, { err: error });
387
+ }
388
+ return logByStatus(context, String(error), { err: error });
389
+ }
343
390
 
344
- // ../../node_modules/hono/dist/helper/adapter/index.js
391
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/helper/adapter/index.js
345
392
  var env = (c, runtime) => {
346
393
  const global = globalThis;
347
394
  const globalEnv = global?.process?.env;
@@ -354,6 +401,7 @@ var env = (c, runtime) => {
354
401
  return Deno.env.toObject();
355
402
  },
356
403
  workerd: () => c.env,
404
+ // On Fastly Compute, you can use the ConfigStore to manage user-defined data.
357
405
  fastly: () => ({}),
358
406
  other: () => ({})
359
407
  };
@@ -391,6 +439,21 @@ var checkUserAgentEquals = (platform) => {
391
439
  return userAgent.startsWith(platform);
392
440
  };
393
441
 
442
+ // src/helpers/github-context.ts
443
+ import * as github from "@actions/github";
444
+ function getGithubContext() {
445
+ const override = globalThis.__UOS_GITHUB_CONTEXT__;
446
+ if (override) {
447
+ return override;
448
+ }
449
+ const module = github;
450
+ const context = module.context ?? module.default?.context;
451
+ if (!context) {
452
+ throw new Error("GitHub context is unavailable.");
453
+ }
454
+ return context;
455
+ }
456
+
394
457
  // src/helpers/runtime-info.ts
395
458
  var PluginRuntimeInfo = class _PluginRuntimeInfo {
396
459
  static _instance = null;
@@ -439,10 +502,11 @@ var CfRuntimeInfo = class extends PluginRuntimeInfo {
439
502
  };
440
503
  var NodeRuntimeInfo = class extends PluginRuntimeInfo {
441
504
  get version() {
442
- return github.context.sha;
505
+ return getGithubContext().sha;
443
506
  }
444
507
  get runUrl() {
445
- return github.context.payload.repository ? `${github.context.payload.repository?.html_url}/actions/runs/${github.context.runId}` : "http://localhost";
508
+ const context = getGithubContext();
509
+ return context.payload.repository ? `${context.payload.repository?.html_url}/actions/runs/${context.runId}` : "http://localhost";
446
510
  }
447
511
  };
448
512
  var DenoRuntimeInfo = class extends PluginRuntimeInfo {
@@ -532,14 +596,72 @@ function getPluginOptions(options) {
532
596
  }
533
597
 
534
598
  // src/comment.ts
599
+ var COMMAND_RESPONSE_KIND = "command-response";
600
+ var COMMAND_RESPONSE_MARKER = `"commentKind": "${COMMAND_RESPONSE_KIND}"`;
601
+ var COMMAND_RESPONSE_COMMENT_LIMIT = 50;
602
+ var RECENT_COMMENTS_QUERY = `
603
+ query($owner: String!, $repo: String!, $number: Int!, $last: Int!) {
604
+ repository(owner: $owner, name: $repo) {
605
+ issueOrPullRequest(number: $number) {
606
+ __typename
607
+ ... on Issue {
608
+ comments(last: $last) {
609
+ nodes {
610
+ id
611
+ body
612
+ isMinimized
613
+ minimizedReason
614
+ author {
615
+ login
616
+ }
617
+ }
618
+ }
619
+ }
620
+ ... on PullRequest {
621
+ comments(last: $last) {
622
+ nodes {
623
+ id
624
+ body
625
+ isMinimized
626
+ minimizedReason
627
+ author {
628
+ login
629
+ }
630
+ }
631
+ }
632
+ }
633
+ }
634
+ }
635
+ }
636
+ `;
637
+ var MINIMIZE_COMMENT_MUTATION = `
638
+ mutation($id: ID!, $classifier: ReportedContentClassifiers!) {
639
+ minimizeComment(input: { subjectId: $id, classifier: $classifier }) {
640
+ minimizedComment {
641
+ isMinimized
642
+ minimizedReason
643
+ }
644
+ }
645
+ }
646
+ `;
647
+ function logByStatus2(logger, message, status, metadata) {
648
+ const payload = { ...metadata, ...status ? { status } : {} };
649
+ if (status && status >= 500) return logger.error(message, payload);
650
+ if (status && status >= 400) return logger.warn(message, payload);
651
+ if (status && status >= 300) return logger.debug(message, payload);
652
+ if (status && status >= 200) return logger.ok(message, payload);
653
+ if (status && status >= 100) return logger.info(message, payload);
654
+ return logger.error(message, payload);
655
+ }
535
656
  var CommentHandler = class _CommentHandler {
536
657
  static HEADER_NAME = "UbiquityOS";
537
658
  _lastCommentId = { reviewCommentId: null, issueCommentId: null };
538
- async _updateIssueComment(context2, params) {
659
+ _commandResponsePolicyApplied = false;
660
+ async _updateIssueComment(context, params) {
539
661
  if (!this._lastCommentId.issueCommentId) {
540
- throw context2.logger.error("issueCommentId is missing");
662
+ throw context.logger.error("issueCommentId is missing");
541
663
  }
542
- const commentData = await context2.octokit.rest.issues.updateComment({
664
+ const commentData = await context.octokit.rest.issues.updateComment({
543
665
  owner: params.owner,
544
666
  repo: params.repo,
545
667
  comment_id: this._lastCommentId.issueCommentId,
@@ -547,11 +669,11 @@ var CommentHandler = class _CommentHandler {
547
669
  });
548
670
  return { ...commentData.data, issueNumber: params.issueNumber };
549
671
  }
550
- async _updateReviewComment(context2, params) {
672
+ async _updateReviewComment(context, params) {
551
673
  if (!this._lastCommentId.reviewCommentId) {
552
- throw context2.logger.error("reviewCommentId is missing");
674
+ throw context.logger.error("reviewCommentId is missing");
553
675
  }
554
- const commentData = await context2.octokit.rest.pulls.updateReviewComment({
676
+ const commentData = await context.octokit.rest.pulls.updateReviewComment({
555
677
  owner: params.owner,
556
678
  repo: params.repo,
557
679
  comment_id: this._lastCommentId.reviewCommentId,
@@ -559,9 +681,9 @@ var CommentHandler = class _CommentHandler {
559
681
  });
560
682
  return { ...commentData.data, issueNumber: params.issueNumber };
561
683
  }
562
- async _createNewComment(context2, params) {
684
+ async _createNewComment(context, params) {
563
685
  if (params.commentId) {
564
- const commentData2 = await context2.octokit.rest.pulls.createReplyForReviewComment({
686
+ const commentData2 = await context.octokit.rest.pulls.createReplyForReviewComment({
565
687
  owner: params.owner,
566
688
  repo: params.repo,
567
689
  pull_number: params.issueNumber,
@@ -571,7 +693,7 @@ var CommentHandler = class _CommentHandler {
571
693
  this._lastCommentId.reviewCommentId = commentData2.data.id;
572
694
  return { ...commentData2.data, issueNumber: params.issueNumber };
573
695
  }
574
- const commentData = await context2.octokit.rest.issues.createComment({
696
+ const commentData = await context.octokit.rest.issues.createComment({
575
697
  owner: params.owner,
576
698
  repo: params.repo,
577
699
  issue_number: params.issueNumber,
@@ -580,54 +702,143 @@ var CommentHandler = class _CommentHandler {
580
702
  this._lastCommentId.issueCommentId = commentData.data.id;
581
703
  return { ...commentData.data, issueNumber: params.issueNumber };
582
704
  }
583
- _getIssueNumber(context2) {
584
- if ("issue" in context2.payload) return context2.payload.issue.number;
585
- if ("pull_request" in context2.payload) return context2.payload.pull_request.number;
586
- if ("discussion" in context2.payload) return context2.payload.discussion.number;
705
+ _getIssueNumber(context) {
706
+ if ("issue" in context.payload) return context.payload.issue.number;
707
+ if ("pull_request" in context.payload) return context.payload.pull_request.number;
708
+ if ("discussion" in context.payload) return context.payload.discussion.number;
587
709
  return void 0;
588
710
  }
589
- _getCommentId(context2) {
590
- return "pull_request" in context2.payload && "comment" in context2.payload ? context2.payload.comment.id : void 0;
711
+ _getCommentId(context) {
712
+ return "pull_request" in context.payload && "comment" in context.payload ? context.payload.comment.id : void 0;
591
713
  }
592
- _extractIssueContext(context2) {
593
- if (!("repository" in context2.payload) || !context2.payload.repository?.owner?.login) {
714
+ _getCommentNodeId(context) {
715
+ const payload = context.payload;
716
+ const nodeId = payload.comment?.node_id;
717
+ return typeof nodeId === "string" && nodeId.trim() ? nodeId : null;
718
+ }
719
+ _extractIssueContext(context) {
720
+ if (!("repository" in context.payload) || !context.payload.repository?.owner?.login) {
594
721
  return null;
595
722
  }
596
- const issueNumber = this._getIssueNumber(context2);
723
+ const issueNumber = this._getIssueNumber(context);
597
724
  if (!issueNumber) return null;
598
725
  return {
599
726
  issueNumber,
600
- commentId: this._getCommentId(context2),
601
- owner: context2.payload.repository.owner.login,
602
- repo: context2.payload.repository.name
727
+ commentId: this._getCommentId(context),
728
+ owner: context.payload.repository.owner.login,
729
+ repo: context.payload.repository.name
603
730
  };
604
731
  }
605
- _processMessage(context2, message) {
732
+ _extractIssueLocator(context) {
733
+ if (!("issue" in context.payload) && !("pull_request" in context.payload)) {
734
+ return null;
735
+ }
736
+ const issueContext = this._extractIssueContext(context);
737
+ if (!issueContext) return null;
738
+ return {
739
+ owner: issueContext.owner,
740
+ repo: issueContext.repo,
741
+ issueNumber: issueContext.issueNumber
742
+ };
743
+ }
744
+ _shouldApplyCommandResponsePolicy(context) {
745
+ const payload = context;
746
+ return Boolean(payload.command);
747
+ }
748
+ _isCommandResponseComment(body) {
749
+ return typeof body === "string" && body.includes(COMMAND_RESPONSE_MARKER);
750
+ }
751
+ _getGraphqlClient(context) {
752
+ const graphql = context.octokit.graphql;
753
+ return typeof graphql === "function" ? graphql : null;
754
+ }
755
+ async _fetchRecentComments(context, locator, last = COMMAND_RESPONSE_COMMENT_LIMIT) {
756
+ const graphql = this._getGraphqlClient(context);
757
+ if (!graphql) return [];
758
+ try {
759
+ const data = await graphql(RECENT_COMMENTS_QUERY, {
760
+ owner: locator.owner,
761
+ repo: locator.repo,
762
+ number: locator.issueNumber,
763
+ last
764
+ });
765
+ const nodes = data.repository?.issueOrPullRequest?.comments?.nodes ?? [];
766
+ return nodes.filter((node) => Boolean(node));
767
+ } catch (error) {
768
+ context.logger.debug("Failed to fetch recent comments (non-fatal)", { err: error });
769
+ return [];
770
+ }
771
+ }
772
+ _findPreviousCommandResponseComment(comments, currentCommentId) {
773
+ for (let idx = comments.length - 1; idx >= 0; idx -= 1) {
774
+ const comment = comments[idx];
775
+ if (!comment) continue;
776
+ if (currentCommentId && comment.id === currentCommentId) continue;
777
+ if (this._isCommandResponseComment(comment.body)) {
778
+ return comment;
779
+ }
780
+ }
781
+ return null;
782
+ }
783
+ async _minimizeComment(context, commentNodeId, classifier = "RESOLVED") {
784
+ const graphql = this._getGraphqlClient(context);
785
+ if (!graphql) return;
786
+ try {
787
+ await graphql(MINIMIZE_COMMENT_MUTATION, {
788
+ id: commentNodeId,
789
+ classifier
790
+ });
791
+ } catch (error) {
792
+ context.logger.debug("Failed to minimize comment (non-fatal)", { err: error, commentNodeId });
793
+ }
794
+ }
795
+ async _applyCommandResponsePolicy(context) {
796
+ if (this._commandResponsePolicyApplied) return;
797
+ this._commandResponsePolicyApplied = true;
798
+ if (!this._shouldApplyCommandResponsePolicy(context)) return;
799
+ const locator = this._extractIssueLocator(context);
800
+ const commentNodeId = this._getCommentNodeId(context);
801
+ const comments = locator ? await this._fetchRecentComments(context, locator) : [];
802
+ const current = commentNodeId ? comments.find((comment) => comment.id === commentNodeId) : null;
803
+ const currentIsMinimized = current?.isMinimized ?? false;
804
+ if (commentNodeId && !currentIsMinimized) {
805
+ await this._minimizeComment(context, commentNodeId);
806
+ }
807
+ const previous = this._findPreviousCommandResponseComment(comments, commentNodeId);
808
+ if (previous && !previous.isMinimized) {
809
+ await this._minimizeComment(context, previous.id);
810
+ }
811
+ }
812
+ _processMessage(context, message) {
606
813
  if (message instanceof Error) {
607
814
  const metadata2 = {
608
815
  message: message.message,
609
816
  name: message.name,
610
817
  stack: message.stack
611
818
  };
612
- return { metadata: metadata2, logMessage: context2.logger.error(message.message).logMessage };
819
+ const status = getErrorStatus(message);
820
+ const logReturn = logByStatus2(context.logger, message.message, status, metadata2);
821
+ return { metadata: { ...metadata2, ...status ? { status } : {} }, logMessage: logReturn.logMessage };
613
822
  }
823
+ const stackLine = message.metadata?.error?.stack?.split("\n")[2];
824
+ const callerMatch = stackLine ? /at (\S+)/.exec(stackLine) : null;
614
825
  const metadata = message.metadata ? {
615
826
  ...message.metadata,
616
827
  message: message.metadata.message,
617
828
  stack: message.metadata.stack || message.metadata.error?.stack,
618
- caller: message.metadata.caller || message.metadata.error?.stack?.split("\n")[2]?.match(/at (\S+)/)?.[1]
829
+ caller: message.metadata.caller || callerMatch?.[1]
619
830
  } : { ...message };
620
831
  return { metadata, logMessage: message.logMessage };
621
832
  }
622
- _getInstigatorName(context2) {
623
- if ("installation" in context2.payload && context2.payload.installation && "account" in context2.payload.installation && context2.payload.installation?.account?.name) {
624
- return context2.payload.installation?.account?.name;
833
+ _getInstigatorName(context) {
834
+ if ("installation" in context.payload && context.payload.installation && "account" in context.payload.installation && context.payload.installation?.account?.name) {
835
+ return context.payload.installation?.account?.name;
625
836
  }
626
- return context2.payload.sender?.login || _CommentHandler.HEADER_NAME;
837
+ return context.payload.sender?.login || _CommentHandler.HEADER_NAME;
627
838
  }
628
- _createMetadataContent(context2, metadata) {
839
+ _createMetadataContent(context, metadata) {
629
840
  const jsonPretty = sanitizeMetadata(metadata);
630
- const instigatorName = this._getInstigatorName(context2);
841
+ const instigatorName = this._getInstigatorName(context);
631
842
  const runUrl = PluginRuntimeInfo.getInstance().runUrl;
632
843
  const version = PluginRuntimeInfo.getInstance().version;
633
844
  const callingFnName = metadata.caller || "anonymous";
@@ -644,63 +855,46 @@ var CommentHandler = class _CommentHandler {
644
855
  /*
645
856
  * Creates the body for the comment, embeds the metadata and the header hidden in the body as well.
646
857
  */
647
- createCommentBody(context2, message, options) {
648
- return this._createCommentBody(context2, message, options);
649
- }
650
- _createCommentBody(context2, message, options) {
651
- const { metadata, logMessage } = this._processMessage(context2, message);
652
- const { header, jsonPretty } = this._createMetadataContent(context2, metadata);
858
+ createCommentBody(context, message, options) {
859
+ return this._createCommentBody(context, message, options);
860
+ }
861
+ _createCommentBody(context, message, options) {
862
+ const { metadata, logMessage } = this._processMessage(context, message);
863
+ const shouldTagCommandResponse = options?.commentKind && typeof metadata === "object" && metadata !== null && !("commentKind" in metadata);
864
+ const metadataWithKind = shouldTagCommandResponse ? { ...metadata, commentKind: options?.commentKind } : metadata;
865
+ const { header, jsonPretty } = this._createMetadataContent(context, metadataWithKind);
653
866
  const metadataContent = this._formatMetadataContent(logMessage, header, jsonPretty);
654
867
  return `${options?.raw ? logMessage?.raw : logMessage?.diff}
655
868
 
656
869
  ${metadataContent}
657
870
  `;
658
871
  }
659
- async postComment(context2, message, options = { updateComment: true, raw: false }) {
660
- const issueContext = this._extractIssueContext(context2);
872
+ async postComment(context, message, options = { updateComment: true, raw: false }) {
873
+ await this._applyCommandResponsePolicy(context);
874
+ const issueContext = this._extractIssueContext(context);
661
875
  if (!issueContext) {
662
- context2.logger.warn("Cannot post comment: missing issue context in payload");
876
+ context.logger.warn("Cannot post comment: missing issue context in payload");
663
877
  return null;
664
878
  }
665
- const body = this._createCommentBody(context2, message, options);
879
+ const shouldTagCommandResponse = this._shouldApplyCommandResponsePolicy(context);
880
+ const body = this._createCommentBody(context, message, {
881
+ ...options,
882
+ commentKind: options.commentKind ?? (shouldTagCommandResponse ? COMMAND_RESPONSE_KIND : void 0)
883
+ });
666
884
  const { issueNumber, commentId, owner, repo } = issueContext;
667
885
  const params = { owner, repo, body, issueNumber };
668
886
  if (options.updateComment) {
669
- if (this._lastCommentId.issueCommentId && !("pull_request" in context2.payload && "comment" in context2.payload)) {
670
- return this._updateIssueComment(context2, params);
887
+ if (this._lastCommentId.issueCommentId && !("pull_request" in context.payload && "comment" in context.payload)) {
888
+ return this._updateIssueComment(context, params);
671
889
  }
672
- if (this._lastCommentId.reviewCommentId && "pull_request" in context2.payload && "comment" in context2.payload) {
673
- return this._updateReviewComment(context2, params);
890
+ if (this._lastCommentId.reviewCommentId && "pull_request" in context.payload && "comment" in context.payload) {
891
+ return this._updateReviewComment(context, params);
674
892
  }
675
893
  }
676
- return this._createNewComment(context2, { ...params, commentId });
894
+ return this._createNewComment(context, { ...params, commentId });
677
895
  }
678
896
  };
679
897
 
680
- // src/error.ts
681
- function transformError(context2, error) {
682
- let loggerError;
683
- if (error instanceof AggregateError) {
684
- loggerError = context2.logger.error(
685
- error.errors.map((err) => {
686
- if (err instanceof LogReturn) {
687
- return err.logMessage.raw;
688
- } else if (err instanceof Error) {
689
- return err.message;
690
- } else {
691
- return err;
692
- }
693
- }).join("\n\n"),
694
- { error }
695
- );
696
- } else if (error instanceof Error || error instanceof LogReturn) {
697
- loggerError = error;
698
- } else {
699
- loggerError = context2.logger.error(String(error));
700
- }
701
- return loggerError;
702
- }
703
-
704
898
  // src/helpers/command.ts
705
899
  import { Value } from "@sinclair/typebox/value";
706
900
  function getCommand(inputs, pluginOptions) {
@@ -933,7 +1127,7 @@ async function verifySignature(publicKeyPem, inputs, signature) {
933
1127
  ref: inputs.ref,
934
1128
  command: inputs.command
935
1129
  };
936
- const pemContents = publicKeyPem.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "").trim();
1130
+ const pemContents = publicKeyPem.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "").replace(/\s+/g, "");
937
1131
  const binaryDer = Uint8Array.from(atob(pemContents), (c) => c.charCodeAt(0));
938
1132
  const publicKey = await crypto.subtle.importKey(
939
1133
  "spki",
@@ -986,16 +1180,12 @@ var inputSchema = T2.Object({
986
1180
 
987
1181
  // src/actions.ts
988
1182
  config();
989
- async function handleError(context2, pluginOptions, error) {
1183
+ async function handleError(context, pluginOptions, error) {
990
1184
  console.error(error);
991
- const loggerError = transformError(context2, error);
992
- if (loggerError instanceof LogReturn) {
993
- core.setFailed(loggerError.logMessage.diff);
994
- } else if (loggerError instanceof Error) {
995
- core.setFailed(loggerError);
996
- }
1185
+ const loggerError = transformError(context, error);
1186
+ core.setFailed(loggerError.logMessage.diff);
997
1187
  if (pluginOptions.postCommentOnError && loggerError) {
998
- await context2.commentHandler.postComment(context2, loggerError);
1188
+ await context.commentHandler.postComment(context, loggerError);
999
1189
  }
1000
1190
  }
1001
1191
  async function createActionsPlugin(handler, options) {
@@ -1005,7 +1195,8 @@ async function createActionsPlugin(handler, options) {
1005
1195
  core.setFailed("Error: PLUGIN_GITHUB_TOKEN env is not set");
1006
1196
  return;
1007
1197
  }
1008
- const body = github2.context.payload.inputs;
1198
+ const githubContext = getGithubContext();
1199
+ const body = githubContext.payload.inputs;
1009
1200
  const inputSchemaErrors = [...Value3.Errors(inputSchema, body)];
1010
1201
  if (inputSchemaErrors.length) {
1011
1202
  console.dir(inputSchemaErrors, { depth: null });
@@ -1043,7 +1234,7 @@ async function createActionsPlugin(handler, options) {
1043
1234
  env2 = process.env;
1044
1235
  }
1045
1236
  const command = getCommand(inputs, pluginOptions);
1046
- const context2 = {
1237
+ const context = {
1047
1238
  eventName: inputs.eventName,
1048
1239
  payload: inputs.eventPayload,
1049
1240
  command,
@@ -1056,20 +1247,21 @@ async function createActionsPlugin(handler, options) {
1056
1247
  commentHandler: new CommentHandler()
1057
1248
  };
1058
1249
  try {
1059
- const result = await handler(context2);
1250
+ const result = await handler(context);
1060
1251
  core.setOutput("result", result);
1061
1252
  if (pluginOptions?.returnDataToKernel) {
1062
1253
  await returnDataToKernel(pluginGithubToken, inputs.stateId, result);
1063
1254
  }
1064
1255
  } catch (error) {
1065
- await handleError(context2, pluginOptions, error);
1256
+ await handleError(context, pluginOptions, error);
1066
1257
  }
1067
1258
  }
1068
1259
  async function returnDataToKernel(repoToken, stateId, output) {
1260
+ const githubContext = getGithubContext();
1069
1261
  const octokit = new customOctokit({ auth: repoToken });
1070
1262
  await octokit.rest.repos.createDispatchEvent({
1071
- owner: github2.context.repo.owner,
1072
- repo: github2.context.repo.repo,
1263
+ owner: githubContext.repo.owner,
1264
+ repo: githubContext.repo.repo,
1073
1265
  event_type: "return-data-to-ubiquity-os-kernel",
1074
1266
  client_payload: {
1075
1267
  state_id: stateId,
@@ -1086,12 +1278,12 @@ function cleanMarkdown(md, options = {}) {
1086
1278
  const segments = [];
1087
1279
  let lastIndex = 0;
1088
1280
  const matches = [...md.matchAll(codeBlockRegex)];
1089
- for (const match of matches) {
1090
- if (match.index > lastIndex) {
1091
- segments.push(processSegment(md.slice(lastIndex, match.index), tags, shouldCollapseEmptyLines));
1281
+ for (const match2 of matches) {
1282
+ if (match2.index > lastIndex) {
1283
+ segments.push(processSegment(md.slice(lastIndex, match2.index), tags, shouldCollapseEmptyLines));
1092
1284
  }
1093
- segments.push(match[0]);
1094
- lastIndex = match.index + match[0].length;
1285
+ segments.push(match2[0]);
1286
+ lastIndex = match2.index + match2[0].length;
1095
1287
  }
1096
1288
  if (lastIndex < md.length) {
1097
1289
  segments.push(processSegment(md.slice(lastIndex), tags, shouldCollapseEmptyLines));
@@ -1134,9 +1326,9 @@ function processSegment(segment, extraTags, shouldCollapseEmptyLines) {
1134
1326
  // src/server.ts
1135
1327
  import { Value as Value4 } from "@sinclair/typebox/value";
1136
1328
 
1137
- // ../../node_modules/hono/dist/compose.js
1329
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/compose.js
1138
1330
  var compose = (middleware, onError, onNotFound) => {
1139
- return (context2, next) => {
1331
+ return (context, next) => {
1140
1332
  let index = -1;
1141
1333
  return dispatch(0);
1142
1334
  async function dispatch(i) {
@@ -1149,39 +1341,72 @@ var compose = (middleware, onError, onNotFound) => {
1149
1341
  let handler;
1150
1342
  if (middleware[i]) {
1151
1343
  handler = middleware[i][0][0];
1152
- context2.req.routeIndex = i;
1344
+ context.req.routeIndex = i;
1153
1345
  } else {
1154
1346
  handler = i === middleware.length && next || void 0;
1155
1347
  }
1156
1348
  if (handler) {
1157
1349
  try {
1158
- res = await handler(context2, () => dispatch(i + 1));
1350
+ res = await handler(context, () => dispatch(i + 1));
1159
1351
  } catch (err) {
1160
1352
  if (err instanceof Error && onError) {
1161
- context2.error = err;
1162
- res = await onError(err, context2);
1353
+ context.error = err;
1354
+ res = await onError(err, context);
1163
1355
  isError = true;
1164
1356
  } else {
1165
1357
  throw err;
1166
1358
  }
1167
1359
  }
1168
1360
  } else {
1169
- if (context2.finalized === false && onNotFound) {
1170
- res = await onNotFound(context2);
1361
+ if (context.finalized === false && onNotFound) {
1362
+ res = await onNotFound(context);
1171
1363
  }
1172
1364
  }
1173
- if (res && (context2.finalized === false || isError)) {
1174
- context2.res = res;
1365
+ if (res && (context.finalized === false || isError)) {
1366
+ context.res = res;
1175
1367
  }
1176
- return context2;
1368
+ return context;
1177
1369
  }
1178
1370
  };
1179
1371
  };
1180
1372
 
1181
- // ../../node_modules/hono/dist/request/constants.js
1182
- var GET_MATCH_RESULT = Symbol();
1373
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/http-exception.js
1374
+ var HTTPException = class extends Error {
1375
+ res;
1376
+ status;
1377
+ /**
1378
+ * Creates an instance of `HTTPException`.
1379
+ * @param status - HTTP status code for the exception. Defaults to 500.
1380
+ * @param options - Additional options for the exception.
1381
+ */
1382
+ constructor(status = 500, options) {
1383
+ super(options?.message, { cause: options?.cause });
1384
+ this.res = options?.res;
1385
+ this.status = status;
1386
+ }
1387
+ /**
1388
+ * Returns the response object associated with the exception.
1389
+ * If a response object is not provided, a new response is created with the error message and status code.
1390
+ * @returns The response object.
1391
+ */
1392
+ getResponse() {
1393
+ if (this.res) {
1394
+ const newResponse = new Response(this.res.body, {
1395
+ status: this.status,
1396
+ headers: this.res.headers
1397
+ });
1398
+ return newResponse;
1399
+ }
1400
+ return new Response(this.message, {
1401
+ status: this.status
1402
+ });
1403
+ }
1404
+ };
1405
+
1406
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/request/constants.js
1407
+ var GET_MATCH_RESULT = /* @__PURE__ */ Symbol();
1183
1408
 
1184
- // ../../node_modules/hono/dist/utils/body.js
1409
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/utils/body.js
1185
1410
  var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {
1186
1411
  const { all = false, dot = false } = options;
1187
1412
  const headers = request instanceof HonoRequest ? request.raw.headers : request.headers;
@@ -1250,7 +1475,7 @@ var handleParsingNestedValues = (form, key, value) => {
1250
1475
  });
1251
1476
  };
1252
1477
 
1253
- // ../../node_modules/hono/dist/utils/url.js
1478
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/utils/url.js
1254
1479
  var splitPath = (path) => {
1255
1480
  const paths = path.split("/");
1256
1481
  if (paths[0] === "") {
@@ -1265,9 +1490,9 @@ var splitRoutingPath = (routePath) => {
1265
1490
  };
1266
1491
  var extractGroupsFromPath = (path) => {
1267
1492
  const groups = [];
1268
- path = path.replace(/\{[^}]+\}/g, (match, index) => {
1493
+ path = path.replace(/\{[^}]+\}/g, (match2, index) => {
1269
1494
  const mark = `@${index}`;
1270
- groups.push([mark, match]);
1495
+ groups.push([mark, match2]);
1271
1496
  return mark;
1272
1497
  });
1273
1498
  return { groups, path };
@@ -1289,14 +1514,14 @@ var getPattern = (label, next) => {
1289
1514
  if (label === "*") {
1290
1515
  return "*";
1291
1516
  }
1292
- const match = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
1293
- if (match) {
1517
+ const match2 = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
1518
+ if (match2) {
1294
1519
  const cacheKey = `${label}#${next}`;
1295
1520
  if (!patternCache[cacheKey]) {
1296
- if (match[2]) {
1297
- patternCache[cacheKey] = next && next[0] !== ":" && next[0] !== "*" ? [cacheKey, match[1], new RegExp(`^${match[2]}(?=/${next})`)] : [label, match[1], new RegExp(`^${match[2]}$`)];
1521
+ if (match2[2]) {
1522
+ patternCache[cacheKey] = next && next[0] !== ":" && next[0] !== "*" ? [cacheKey, match2[1], new RegExp(`^${match2[2]}(?=/${next})`)] : [label, match2[1], new RegExp(`^${match2[2]}$`)];
1298
1523
  } else {
1299
- patternCache[cacheKey] = [label, match[1], true];
1524
+ patternCache[cacheKey] = [label, match2[1], true];
1300
1525
  }
1301
1526
  }
1302
1527
  return patternCache[cacheKey];
@@ -1307,11 +1532,11 @@ var tryDecode = (str, decoder) => {
1307
1532
  try {
1308
1533
  return decoder(str);
1309
1534
  } catch {
1310
- return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match) => {
1535
+ return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match2) => {
1311
1536
  try {
1312
- return decoder(match);
1537
+ return decoder(match2);
1313
1538
  } catch {
1314
- return match;
1539
+ return match2;
1315
1540
  }
1316
1541
  });
1317
1542
  }
@@ -1319,10 +1544,7 @@ var tryDecode = (str, decoder) => {
1319
1544
  var tryDecodeURI = (str) => tryDecode(str, decodeURI);
1320
1545
  var getPath = (request) => {
1321
1546
  const url = request.url;
1322
- const start = url.indexOf(
1323
- "/",
1324
- url.charCodeAt(9) === 58 ? 13 : 8
1325
- );
1547
+ const start = url.indexOf("/", url.indexOf(":") + 4);
1326
1548
  let i = start;
1327
1549
  for (; i < url.length; i++) {
1328
1550
  const charCode = url.charCodeAt(i);
@@ -1385,9 +1607,12 @@ var _decodeURI = (value) => {
1385
1607
  var _getQueryParam = (url, key, multiple) => {
1386
1608
  let encoded;
1387
1609
  if (!multiple && key && !/[%+]/.test(key)) {
1388
- let keyIndex2 = url.indexOf(`?${key}`, 8);
1610
+ let keyIndex2 = url.indexOf("?", 8);
1389
1611
  if (keyIndex2 === -1) {
1390
- keyIndex2 = url.indexOf(`&${key}`, 8);
1612
+ return void 0;
1613
+ }
1614
+ if (!url.startsWith(key, keyIndex2 + 1)) {
1615
+ keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1);
1391
1616
  }
1392
1617
  while (keyIndex2 !== -1) {
1393
1618
  const trailingKeyCode = url.charCodeAt(keyIndex2 + key.length + 1);
@@ -1452,13 +1677,40 @@ var getQueryParams = (url, key) => {
1452
1677
  };
1453
1678
  var decodeURIComponent_ = decodeURIComponent;
1454
1679
 
1455
- // ../../node_modules/hono/dist/request.js
1680
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/request.js
1456
1681
  var tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_);
1457
1682
  var HonoRequest = class {
1683
+ /**
1684
+ * `.raw` can get the raw Request object.
1685
+ *
1686
+ * @see {@link https://hono.dev/docs/api/request#raw}
1687
+ *
1688
+ * @example
1689
+ * ```ts
1690
+ * // For Cloudflare Workers
1691
+ * app.post('/', async (c) => {
1692
+ * const metadata = c.req.raw.cf?.hostMetadata?
1693
+ * ...
1694
+ * })
1695
+ * ```
1696
+ */
1458
1697
  raw;
1459
1698
  #validatedData;
1699
+ // Short name of validatedData
1460
1700
  #matchResult;
1461
1701
  routeIndex = 0;
1702
+ /**
1703
+ * `.path` can get the pathname of the request.
1704
+ *
1705
+ * @see {@link https://hono.dev/docs/api/request#path}
1706
+ *
1707
+ * @example
1708
+ * ```ts
1709
+ * app.get('/about/me', (c) => {
1710
+ * const pathname = c.req.path // `/about/me`
1711
+ * })
1712
+ * ```
1713
+ */
1462
1714
  path;
1463
1715
  bodyCache = {};
1464
1716
  constructor(request, path = "/", matchResult = [[]]) {
@@ -1473,14 +1725,14 @@ var HonoRequest = class {
1473
1725
  #getDecodedParam(key) {
1474
1726
  const paramKey = this.#matchResult[0][this.routeIndex][1][key];
1475
1727
  const param = this.#getParamValue(paramKey);
1476
- return param ? /\%/.test(param) ? tryDecodeURIComponent(param) : param : void 0;
1728
+ return param && /\%/.test(param) ? tryDecodeURIComponent(param) : param;
1477
1729
  }
1478
1730
  #getAllDecodedParams() {
1479
1731
  const decoded = {};
1480
1732
  const keys = Object.keys(this.#matchResult[0][this.routeIndex][1]);
1481
1733
  for (const key of keys) {
1482
1734
  const value = this.#getParamValue(this.#matchResult[0][this.routeIndex][1][key]);
1483
- if (value && typeof value === "string") {
1735
+ if (value !== void 0) {
1484
1736
  decoded[key] = /\%/.test(value) ? tryDecodeURIComponent(value) : value;
1485
1737
  }
1486
1738
  }
@@ -1525,45 +1777,175 @@ var HonoRequest = class {
1525
1777
  }
1526
1778
  return bodyCache[key] = raw2[key]();
1527
1779
  };
1780
+ /**
1781
+ * `.json()` can parse Request body of type `application/json`
1782
+ *
1783
+ * @see {@link https://hono.dev/docs/api/request#json}
1784
+ *
1785
+ * @example
1786
+ * ```ts
1787
+ * app.post('/entry', async (c) => {
1788
+ * const body = await c.req.json()
1789
+ * })
1790
+ * ```
1791
+ */
1528
1792
  json() {
1529
1793
  return this.#cachedBody("text").then((text) => JSON.parse(text));
1530
1794
  }
1795
+ /**
1796
+ * `.text()` can parse Request body of type `text/plain`
1797
+ *
1798
+ * @see {@link https://hono.dev/docs/api/request#text}
1799
+ *
1800
+ * @example
1801
+ * ```ts
1802
+ * app.post('/entry', async (c) => {
1803
+ * const body = await c.req.text()
1804
+ * })
1805
+ * ```
1806
+ */
1531
1807
  text() {
1532
1808
  return this.#cachedBody("text");
1533
1809
  }
1810
+ /**
1811
+ * `.arrayBuffer()` parse Request body as an `ArrayBuffer`
1812
+ *
1813
+ * @see {@link https://hono.dev/docs/api/request#arraybuffer}
1814
+ *
1815
+ * @example
1816
+ * ```ts
1817
+ * app.post('/entry', async (c) => {
1818
+ * const body = await c.req.arrayBuffer()
1819
+ * })
1820
+ * ```
1821
+ */
1534
1822
  arrayBuffer() {
1535
1823
  return this.#cachedBody("arrayBuffer");
1536
1824
  }
1825
+ /**
1826
+ * Parses the request body as a `Blob`.
1827
+ * @example
1828
+ * ```ts
1829
+ * app.post('/entry', async (c) => {
1830
+ * const body = await c.req.blob();
1831
+ * });
1832
+ * ```
1833
+ * @see https://hono.dev/docs/api/request#blob
1834
+ */
1537
1835
  blob() {
1538
1836
  return this.#cachedBody("blob");
1539
1837
  }
1838
+ /**
1839
+ * Parses the request body as `FormData`.
1840
+ * @example
1841
+ * ```ts
1842
+ * app.post('/entry', async (c) => {
1843
+ * const body = await c.req.formData();
1844
+ * });
1845
+ * ```
1846
+ * @see https://hono.dev/docs/api/request#formdata
1847
+ */
1540
1848
  formData() {
1541
1849
  return this.#cachedBody("formData");
1542
1850
  }
1851
+ /**
1852
+ * Adds validated data to the request.
1853
+ *
1854
+ * @param target - The target of the validation.
1855
+ * @param data - The validated data to add.
1856
+ */
1543
1857
  addValidatedData(target, data) {
1544
1858
  this.#validatedData[target] = data;
1545
1859
  }
1546
1860
  valid(target) {
1547
1861
  return this.#validatedData[target];
1548
1862
  }
1863
+ /**
1864
+ * `.url()` can get the request url strings.
1865
+ *
1866
+ * @see {@link https://hono.dev/docs/api/request#url}
1867
+ *
1868
+ * @example
1869
+ * ```ts
1870
+ * app.get('/about/me', (c) => {
1871
+ * const url = c.req.url // `http://localhost:8787/about/me`
1872
+ * ...
1873
+ * })
1874
+ * ```
1875
+ */
1549
1876
  get url() {
1550
1877
  return this.raw.url;
1551
1878
  }
1879
+ /**
1880
+ * `.method()` can get the method name of the request.
1881
+ *
1882
+ * @see {@link https://hono.dev/docs/api/request#method}
1883
+ *
1884
+ * @example
1885
+ * ```ts
1886
+ * app.get('/about/me', (c) => {
1887
+ * const method = c.req.method // `GET`
1888
+ * })
1889
+ * ```
1890
+ */
1552
1891
  get method() {
1553
1892
  return this.raw.method;
1554
1893
  }
1555
1894
  get [GET_MATCH_RESULT]() {
1556
1895
  return this.#matchResult;
1557
1896
  }
1897
+ /**
1898
+ * `.matchedRoutes()` can return a matched route in the handler
1899
+ *
1900
+ * @deprecated
1901
+ *
1902
+ * Use matchedRoutes helper defined in "hono/route" instead.
1903
+ *
1904
+ * @see {@link https://hono.dev/docs/api/request#matchedroutes}
1905
+ *
1906
+ * @example
1907
+ * ```ts
1908
+ * app.use('*', async function logger(c, next) {
1909
+ * await next()
1910
+ * c.req.matchedRoutes.forEach(({ handler, method, path }, i) => {
1911
+ * const name = handler.name || (handler.length < 2 ? '[handler]' : '[middleware]')
1912
+ * console.log(
1913
+ * method,
1914
+ * ' ',
1915
+ * path,
1916
+ * ' '.repeat(Math.max(10 - path.length, 0)),
1917
+ * name,
1918
+ * i === c.req.routeIndex ? '<- respond from here' : ''
1919
+ * )
1920
+ * })
1921
+ * })
1922
+ * ```
1923
+ */
1558
1924
  get matchedRoutes() {
1559
1925
  return this.#matchResult[0].map(([[, route]]) => route);
1560
1926
  }
1927
+ /**
1928
+ * `routePath()` can retrieve the path registered within the handler
1929
+ *
1930
+ * @deprecated
1931
+ *
1932
+ * Use routePath helper defined in "hono/route" instead.
1933
+ *
1934
+ * @see {@link https://hono.dev/docs/api/request#routepath}
1935
+ *
1936
+ * @example
1937
+ * ```ts
1938
+ * app.get('/posts/:id', (c) => {
1939
+ * return c.json({ path: c.req.routePath })
1940
+ * })
1941
+ * ```
1942
+ */
1561
1943
  get routePath() {
1562
1944
  return this.#matchResult[0].map(([[, route]]) => route)[this.routeIndex].path;
1563
1945
  }
1564
1946
  };
1565
1947
 
1566
- // ../../node_modules/hono/dist/utils/html.js
1948
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/utils/html.js
1567
1949
  var HtmlEscapedCallbackPhase = {
1568
1950
  Stringify: 1,
1569
1951
  BeforeStream: 2,
@@ -1575,7 +1957,7 @@ var raw = (value, callbacks) => {
1575
1957
  escapedString.callbacks = callbacks;
1576
1958
  return escapedString;
1577
1959
  };
1578
- var resolveCallback = async (str, phase, preserveCallbacks, context2, buffer) => {
1960
+ var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) => {
1579
1961
  if (typeof str === "object" && !(str instanceof String)) {
1580
1962
  if (!(str instanceof Promise)) {
1581
1963
  str = str.toString();
@@ -1593,9 +1975,9 @@ var resolveCallback = async (str, phase, preserveCallbacks, context2, buffer) =>
1593
1975
  } else {
1594
1976
  buffer = [str];
1595
1977
  }
1596
- const resStr = Promise.all(callbacks.map((c) => c({ phase, buffer, context: context2 }))).then(
1978
+ const resStr = Promise.all(callbacks.map((c) => c({ phase, buffer, context }))).then(
1597
1979
  (res) => Promise.all(
1598
- res.filter(Boolean).map((str2) => resolveCallback(str2, phase, false, context2, buffer))
1980
+ res.filter(Boolean).map((str2) => resolveCallback(str2, phase, false, context, buffer))
1599
1981
  ).then(() => buffer[0])
1600
1982
  );
1601
1983
  if (preserveCallbacks) {
@@ -1605,7 +1987,7 @@ var resolveCallback = async (str, phase, preserveCallbacks, context2, buffer) =>
1605
1987
  }
1606
1988
  };
1607
1989
 
1608
- // ../../node_modules/hono/dist/context.js
1990
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/context.js
1609
1991
  var TEXT_PLAIN = "text/plain; charset=UTF-8";
1610
1992
  var setDefaultContentType = (contentType, headers) => {
1611
1993
  return {
@@ -1616,9 +1998,37 @@ var setDefaultContentType = (contentType, headers) => {
1616
1998
  var Context = class {
1617
1999
  #rawRequest;
1618
2000
  #req;
2001
+ /**
2002
+ * `.env` can get bindings (environment variables, secrets, KV namespaces, D1 database, R2 bucket etc.) in Cloudflare Workers.
2003
+ *
2004
+ * @see {@link https://hono.dev/docs/api/context#env}
2005
+ *
2006
+ * @example
2007
+ * ```ts
2008
+ * // Environment object for Cloudflare Workers
2009
+ * app.get('*', async c => {
2010
+ * const counter = c.env.COUNTER
2011
+ * })
2012
+ * ```
2013
+ */
1619
2014
  env = {};
1620
2015
  #var;
1621
2016
  finalized = false;
2017
+ /**
2018
+ * `.error` can get the error object from the middleware if the Handler throws an error.
2019
+ *
2020
+ * @see {@link https://hono.dev/docs/api/context#error}
2021
+ *
2022
+ * @example
2023
+ * ```ts
2024
+ * app.use('*', async (c, next) => {
2025
+ * await next()
2026
+ * if (c.error) {
2027
+ * // do something...
2028
+ * }
2029
+ * })
2030
+ * ```
2031
+ */
1622
2032
  error;
1623
2033
  #status;
1624
2034
  #executionCtx;
@@ -1629,6 +2039,12 @@ var Context = class {
1629
2039
  #preparedHeaders;
1630
2040
  #matchResult;
1631
2041
  #path;
2042
+ /**
2043
+ * Creates an instance of the Context class.
2044
+ *
2045
+ * @param req - The Request object.
2046
+ * @param options - Optional configuration options for the context.
2047
+ */
1632
2048
  constructor(req, options) {
1633
2049
  this.#rawRequest = req;
1634
2050
  if (options) {
@@ -1639,10 +2055,19 @@ var Context = class {
1639
2055
  this.#matchResult = options.matchResult;
1640
2056
  }
1641
2057
  }
2058
+ /**
2059
+ * `.req` is the instance of {@link HonoRequest}.
2060
+ */
1642
2061
  get req() {
1643
2062
  this.#req ??= new HonoRequest(this.#rawRequest, this.#path, this.#matchResult);
1644
2063
  return this.#req;
1645
2064
  }
2065
+ /**
2066
+ * @see {@link https://hono.dev/docs/api/context#event}
2067
+ * The FetchEvent associated with the current request.
2068
+ *
2069
+ * @throws Will throw an error if the context does not have a FetchEvent.
2070
+ */
1646
2071
  get event() {
1647
2072
  if (this.#executionCtx && "respondWith" in this.#executionCtx) {
1648
2073
  return this.#executionCtx;
@@ -1650,6 +2075,12 @@ var Context = class {
1650
2075
  throw Error("This context has no FetchEvent");
1651
2076
  }
1652
2077
  }
2078
+ /**
2079
+ * @see {@link https://hono.dev/docs/api/context#executionctx}
2080
+ * The ExecutionContext associated with the current request.
2081
+ *
2082
+ * @throws Will throw an error if the context does not have an ExecutionContext.
2083
+ */
1653
2084
  get executionCtx() {
1654
2085
  if (this.#executionCtx) {
1655
2086
  return this.#executionCtx;
@@ -1657,11 +2088,20 @@ var Context = class {
1657
2088
  throw Error("This context has no ExecutionContext");
1658
2089
  }
1659
2090
  }
2091
+ /**
2092
+ * @see {@link https://hono.dev/docs/api/context#res}
2093
+ * The Response object for the current request.
2094
+ */
1660
2095
  get res() {
1661
2096
  return this.#res ||= new Response(null, {
1662
2097
  headers: this.#preparedHeaders ??= new Headers()
1663
2098
  });
1664
2099
  }
2100
+ /**
2101
+ * Sets the Response object for the current request.
2102
+ *
2103
+ * @param _res - The Response object to set.
2104
+ */
1665
2105
  set res(_res) {
1666
2106
  if (this.#res && _res) {
1667
2107
  _res = new Response(_res.body, _res);
@@ -1683,15 +2123,75 @@ var Context = class {
1683
2123
  this.#res = _res;
1684
2124
  this.finalized = true;
1685
2125
  }
2126
+ /**
2127
+ * `.render()` can create a response within a layout.
2128
+ *
2129
+ * @see {@link https://hono.dev/docs/api/context#render-setrenderer}
2130
+ *
2131
+ * @example
2132
+ * ```ts
2133
+ * app.get('/', (c) => {
2134
+ * return c.render('Hello!')
2135
+ * })
2136
+ * ```
2137
+ */
1686
2138
  render = (...args) => {
1687
2139
  this.#renderer ??= (content) => this.html(content);
1688
2140
  return this.#renderer(...args);
1689
2141
  };
2142
+ /**
2143
+ * Sets the layout for the response.
2144
+ *
2145
+ * @param layout - The layout to set.
2146
+ * @returns The layout function.
2147
+ */
1690
2148
  setLayout = (layout) => this.#layout = layout;
2149
+ /**
2150
+ * Gets the current layout for the response.
2151
+ *
2152
+ * @returns The current layout function.
2153
+ */
1691
2154
  getLayout = () => this.#layout;
2155
+ /**
2156
+ * `.setRenderer()` can set the layout in the custom middleware.
2157
+ *
2158
+ * @see {@link https://hono.dev/docs/api/context#render-setrenderer}
2159
+ *
2160
+ * @example
2161
+ * ```tsx
2162
+ * app.use('*', async (c, next) => {
2163
+ * c.setRenderer((content) => {
2164
+ * return c.html(
2165
+ * <html>
2166
+ * <body>
2167
+ * <p>{content}</p>
2168
+ * </body>
2169
+ * </html>
2170
+ * )
2171
+ * })
2172
+ * await next()
2173
+ * })
2174
+ * ```
2175
+ */
1692
2176
  setRenderer = (renderer) => {
1693
2177
  this.#renderer = renderer;
1694
2178
  };
2179
+ /**
2180
+ * `.header()` can set headers.
2181
+ *
2182
+ * @see {@link https://hono.dev/docs/api/context#header}
2183
+ *
2184
+ * @example
2185
+ * ```ts
2186
+ * app.get('/welcome', (c) => {
2187
+ * // Set headers
2188
+ * c.header('X-Message', 'Hello!')
2189
+ * c.header('Content-Type', 'text/plain')
2190
+ *
2191
+ * return c.body('Thank you for coming')
2192
+ * })
2193
+ * ```
2194
+ */
1695
2195
  header = (name, value, options) => {
1696
2196
  if (this.finalized) {
1697
2197
  this.#res = new Response(this.#res.body, this.#res);
@@ -1708,13 +2208,50 @@ var Context = class {
1708
2208
  status = (status) => {
1709
2209
  this.#status = status;
1710
2210
  };
2211
+ /**
2212
+ * `.set()` can set the value specified by the key.
2213
+ *
2214
+ * @see {@link https://hono.dev/docs/api/context#set-get}
2215
+ *
2216
+ * @example
2217
+ * ```ts
2218
+ * app.use('*', async (c, next) => {
2219
+ * c.set('message', 'Hono is hot!!')
2220
+ * await next()
2221
+ * })
2222
+ * ```
2223
+ */
1711
2224
  set = (key, value) => {
1712
2225
  this.#var ??= /* @__PURE__ */ new Map();
1713
2226
  this.#var.set(key, value);
1714
2227
  };
2228
+ /**
2229
+ * `.get()` can use the value specified by the key.
2230
+ *
2231
+ * @see {@link https://hono.dev/docs/api/context#set-get}
2232
+ *
2233
+ * @example
2234
+ * ```ts
2235
+ * app.get('/', (c) => {
2236
+ * const message = c.get('message')
2237
+ * return c.text(`The message is "${message}"`)
2238
+ * })
2239
+ * ```
2240
+ */
1715
2241
  get = (key) => {
1716
2242
  return this.#var ? this.#var.get(key) : void 0;
1717
2243
  };
2244
+ /**
2245
+ * `.var` can access the value of a variable.
2246
+ *
2247
+ * @see {@link https://hono.dev/docs/api/context#var}
2248
+ *
2249
+ * @example
2250
+ * ```ts
2251
+ * const result = c.var.client.oneMethod()
2252
+ * ```
2253
+ */
2254
+ // c.var.propName is a read-only
1718
2255
  get var() {
1719
2256
  if (!this.#var) {
1720
2257
  return {};
@@ -1749,7 +2286,40 @@ var Context = class {
1749
2286
  return new Response(data, { status, headers: responseHeaders });
1750
2287
  }
1751
2288
  newResponse = (...args) => this.#newResponse(...args);
2289
+ /**
2290
+ * `.body()` can return the HTTP response.
2291
+ * You can set headers with `.header()` and set HTTP status code with `.status`.
2292
+ * This can also be set in `.text()`, `.json()` and so on.
2293
+ *
2294
+ * @see {@link https://hono.dev/docs/api/context#body}
2295
+ *
2296
+ * @example
2297
+ * ```ts
2298
+ * app.get('/welcome', (c) => {
2299
+ * // Set headers
2300
+ * c.header('X-Message', 'Hello!')
2301
+ * c.header('Content-Type', 'text/plain')
2302
+ * // Set HTTP status code
2303
+ * c.status(201)
2304
+ *
2305
+ * // Return the response body
2306
+ * return c.body('Thank you for coming')
2307
+ * })
2308
+ * ```
2309
+ */
1752
2310
  body = (data, arg, headers) => this.#newResponse(data, arg, headers);
2311
+ /**
2312
+ * `.text()` can render text as `Content-Type:text/plain`.
2313
+ *
2314
+ * @see {@link https://hono.dev/docs/api/context#text}
2315
+ *
2316
+ * @example
2317
+ * ```ts
2318
+ * app.get('/say', (c) => {
2319
+ * return c.text('Hello!')
2320
+ * })
2321
+ * ```
2322
+ */
1753
2323
  text = (text, arg, headers) => {
1754
2324
  return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text) : this.#newResponse(
1755
2325
  text,
@@ -1757,6 +2327,18 @@ var Context = class {
1757
2327
  setDefaultContentType(TEXT_PLAIN, headers)
1758
2328
  );
1759
2329
  };
2330
+ /**
2331
+ * `.json()` can render JSON as `Content-Type:application/json`.
2332
+ *
2333
+ * @see {@link https://hono.dev/docs/api/context#json}
2334
+ *
2335
+ * @example
2336
+ * ```ts
2337
+ * app.get('/api', (c) => {
2338
+ * return c.json({ message: 'Hello!' })
2339
+ * })
2340
+ * ```
2341
+ */
1760
2342
  json = (object, arg, headers) => {
1761
2343
  return this.#newResponse(
1762
2344
  JSON.stringify(object),
@@ -1768,21 +2350,50 @@ var Context = class {
1768
2350
  const res = (html2) => this.#newResponse(html2, arg, setDefaultContentType("text/html; charset=UTF-8", headers));
1769
2351
  return typeof html === "object" ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res) : res(html);
1770
2352
  };
2353
+ /**
2354
+ * `.redirect()` can Redirect, default status code is 302.
2355
+ *
2356
+ * @see {@link https://hono.dev/docs/api/context#redirect}
2357
+ *
2358
+ * @example
2359
+ * ```ts
2360
+ * app.get('/redirect', (c) => {
2361
+ * return c.redirect('/')
2362
+ * })
2363
+ * app.get('/redirect-permanently', (c) => {
2364
+ * return c.redirect('/', 301)
2365
+ * })
2366
+ * ```
2367
+ */
1771
2368
  redirect = (location, status) => {
1772
2369
  const locationString = String(location);
1773
2370
  this.header(
1774
2371
  "Location",
2372
+ // Multibyes should be encoded
2373
+ // eslint-disable-next-line no-control-regex
1775
2374
  !/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString)
1776
2375
  );
1777
2376
  return this.newResponse(null, status ?? 302);
1778
2377
  };
2378
+ /**
2379
+ * `.notFound()` can return the Not Found Response.
2380
+ *
2381
+ * @see {@link https://hono.dev/docs/api/context#notfound}
2382
+ *
2383
+ * @example
2384
+ * ```ts
2385
+ * app.get('/notfound', (c) => {
2386
+ * return c.notFound()
2387
+ * })
2388
+ * ```
2389
+ */
1779
2390
  notFound = () => {
1780
2391
  this.#notFoundHandler ??= () => new Response();
1781
2392
  return this.#notFoundHandler(this);
1782
2393
  };
1783
2394
  };
1784
2395
 
1785
- // ../../node_modules/hono/dist/router.js
2396
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/router.js
1786
2397
  var METHOD_NAME_ALL = "ALL";
1787
2398
  var METHOD_NAME_ALL_LOWERCASE = "all";
1788
2399
  var METHODS = ["get", "post", "put", "delete", "options", "patch"];
@@ -1790,10 +2401,10 @@ var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is
1790
2401
  var UnsupportedPathError = class extends Error {
1791
2402
  };
1792
2403
 
1793
- // ../../node_modules/hono/dist/utils/constants.js
2404
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/utils/constants.js
1794
2405
  var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
1795
2406
 
1796
- // ../../node_modules/hono/dist/hono-base.js
2407
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/hono-base.js
1797
2408
  var notFoundHandler = (c) => {
1798
2409
  return c.text("404 Not Found", 404);
1799
2410
  };
@@ -1805,7 +2416,7 @@ var errorHandler = (err, c) => {
1805
2416
  console.error(err);
1806
2417
  return c.text("Internal Server Error", 500);
1807
2418
  };
1808
- var Hono = class {
2419
+ var Hono = class _Hono {
1809
2420
  get;
1810
2421
  post;
1811
2422
  put;
@@ -1815,8 +2426,13 @@ var Hono = class {
1815
2426
  all;
1816
2427
  on;
1817
2428
  use;
2429
+ /*
2430
+ This class is like an abstract class and does not have a router.
2431
+ To use it, inherit the class and implement router in the constructor.
2432
+ */
1818
2433
  router;
1819
2434
  getPath;
2435
+ // Cannot use `#` because it requires visibility at JavaScript runtime.
1820
2436
  _basePath = "/";
1821
2437
  #path = "/";
1822
2438
  routes = [];
@@ -1863,7 +2479,7 @@ var Hono = class {
1863
2479
  this.getPath = strict ?? true ? options.getPath ?? getPath : getPathNoStrict;
1864
2480
  }
1865
2481
  #clone() {
1866
- const clone = new Hono({
2482
+ const clone = new _Hono({
1867
2483
  router: this.router,
1868
2484
  getPath: this.getPath
1869
2485
  });
@@ -1873,7 +2489,26 @@ var Hono = class {
1873
2489
  return clone;
1874
2490
  }
1875
2491
  #notFoundHandler = notFoundHandler;
2492
+ // Cannot use `#` because it requires visibility at JavaScript runtime.
1876
2493
  errorHandler = errorHandler;
2494
+ /**
2495
+ * `.route()` allows grouping other Hono instance in routes.
2496
+ *
2497
+ * @see {@link https://hono.dev/docs/api/routing#grouping}
2498
+ *
2499
+ * @param {string} path - base Path
2500
+ * @param {Hono} app - other Hono instance
2501
+ * @returns {Hono} routed Hono instance
2502
+ *
2503
+ * @example
2504
+ * ```ts
2505
+ * const app = new Hono()
2506
+ * const app2 = new Hono()
2507
+ *
2508
+ * app2.get("/user", (c) => c.text("user"))
2509
+ * app.route("/api", app2) // GET /api/user
2510
+ * ```
2511
+ */
1877
2512
  route(path, app) {
1878
2513
  const subApp = this.basePath(path);
1879
2514
  app.routes.map((r) => {
@@ -1888,19 +2523,95 @@ var Hono = class {
1888
2523
  });
1889
2524
  return this;
1890
2525
  }
2526
+ /**
2527
+ * `.basePath()` allows base paths to be specified.
2528
+ *
2529
+ * @see {@link https://hono.dev/docs/api/routing#base-path}
2530
+ *
2531
+ * @param {string} path - base Path
2532
+ * @returns {Hono} changed Hono instance
2533
+ *
2534
+ * @example
2535
+ * ```ts
2536
+ * const api = new Hono().basePath('/api')
2537
+ * ```
2538
+ */
1891
2539
  basePath(path) {
1892
2540
  const subApp = this.#clone();
1893
2541
  subApp._basePath = mergePath(this._basePath, path);
1894
2542
  return subApp;
1895
2543
  }
2544
+ /**
2545
+ * `.onError()` handles an error and returns a customized Response.
2546
+ *
2547
+ * @see {@link https://hono.dev/docs/api/hono#error-handling}
2548
+ *
2549
+ * @param {ErrorHandler} handler - request Handler for error
2550
+ * @returns {Hono} changed Hono instance
2551
+ *
2552
+ * @example
2553
+ * ```ts
2554
+ * app.onError((err, c) => {
2555
+ * console.error(`${err}`)
2556
+ * return c.text('Custom Error Message', 500)
2557
+ * })
2558
+ * ```
2559
+ */
1896
2560
  onError = (handler) => {
1897
2561
  this.errorHandler = handler;
1898
2562
  return this;
1899
2563
  };
2564
+ /**
2565
+ * `.notFound()` allows you to customize a Not Found Response.
2566
+ *
2567
+ * @see {@link https://hono.dev/docs/api/hono#not-found}
2568
+ *
2569
+ * @param {NotFoundHandler} handler - request handler for not-found
2570
+ * @returns {Hono} changed Hono instance
2571
+ *
2572
+ * @example
2573
+ * ```ts
2574
+ * app.notFound((c) => {
2575
+ * return c.text('Custom 404 Message', 404)
2576
+ * })
2577
+ * ```
2578
+ */
1900
2579
  notFound = (handler) => {
1901
2580
  this.#notFoundHandler = handler;
1902
2581
  return this;
1903
2582
  };
2583
+ /**
2584
+ * `.mount()` allows you to mount applications built with other frameworks into your Hono application.
2585
+ *
2586
+ * @see {@link https://hono.dev/docs/api/hono#mount}
2587
+ *
2588
+ * @param {string} path - base Path
2589
+ * @param {Function} applicationHandler - other Request Handler
2590
+ * @param {MountOptions} [options] - options of `.mount()`
2591
+ * @returns {Hono} mounted Hono instance
2592
+ *
2593
+ * @example
2594
+ * ```ts
2595
+ * import { Router as IttyRouter } from 'itty-router'
2596
+ * import { Hono } from 'hono'
2597
+ * // Create itty-router application
2598
+ * const ittyRouter = IttyRouter()
2599
+ * // GET /itty-router/hello
2600
+ * ittyRouter.get('/hello', () => new Response('Hello from itty-router'))
2601
+ *
2602
+ * const app = new Hono()
2603
+ * app.mount('/itty-router', ittyRouter.handle)
2604
+ * ```
2605
+ *
2606
+ * @example
2607
+ * ```ts
2608
+ * const app = new Hono()
2609
+ * // Send the request to another application without modification.
2610
+ * app.mount('/app', anotherApp, {
2611
+ * replaceRequest: (req) => req,
2612
+ * })
2613
+ * ```
2614
+ */
1904
2615
  mount(path, applicationHandler, options) {
1905
2616
  let replaceRequest;
1906
2617
  let optionHandler;
@@ -1988,21 +2699,44 @@ var Hono = class {
1988
2699
  const composed = compose(matchResult[0], this.errorHandler, this.#notFoundHandler);
1989
2700
  return (async () => {
1990
2701
  try {
1991
- const context2 = await composed(c);
1992
- if (!context2.finalized) {
2702
+ const context = await composed(c);
2703
+ if (!context.finalized) {
1993
2704
  throw new Error(
1994
2705
  "Context is not finalized. Did you forget to return a Response object or `await next()`?"
1995
2706
  );
1996
2707
  }
1997
- return context2.res;
2708
+ return context.res;
1998
2709
  } catch (err) {
1999
2710
  return this.#handleError(err, c);
2000
2711
  }
2001
2712
  })();
2002
2713
  }
2714
+ /**
2715
+ * `.fetch()` will be entry point of your app.
2716
+ *
2717
+ * @see {@link https://hono.dev/docs/api/hono#fetch}
2718
+ *
2719
+ * @param {Request} request - request Object of request
2720
+ * @param {Env} Env - env Object
2721
+ * @param {ExecutionContext} - context of execution
2722
+ * @returns {Response | Promise<Response>} response of request
2723
+ *
2724
+ */
2003
2725
  fetch = (request, ...rest) => {
2004
2726
  return this.#dispatch(request, rest[1], rest[0], request.method);
2005
2727
  };
2728
+ /**
2729
+ * `.request()` is a useful method for testing.
2730
+ * You can pass a URL or pathname to send a GET request.
2731
+ * app will return a Response object.
2732
+ * ```ts
2733
+ * test('GET /hello is ok', async () => {
2734
+ * const res = await app.request('/hello')
2735
+ * expect(res.status).toBe(200)
2736
+ * })
2737
+ * ```
2738
+ * @see https://hono.dev/docs/api/hono#request
2739
+ */
2006
2740
  request = (input, requestInit, Env, executionCtx) => {
2007
2741
  if (input instanceof Request) {
2008
2742
  return this.fetch(requestInit ? new Request(input, requestInit) : input, Env, executionCtx);
@@ -2017,6 +2751,23 @@ var Hono = class {
2017
2751
  executionCtx
2018
2752
  );
2019
2753
  };
2754
+ /**
2755
+ * `.fire()` automatically adds a global fetch event listener.
2756
+ * This can be useful for environments that adhere to the Service Worker API, such as non-ES module Cloudflare Workers.
2757
+ * @deprecated
2758
+ * Use `fire` from `hono/service-worker` instead.
2759
+ * ```ts
2760
+ * import { Hono } from 'hono'
2761
+ * import { fire } from 'hono/service-worker'
2762
+ *
2763
+ * const app = new Hono()
2764
+ * // ...
2765
+ * fire(app)
2766
+ * ```
2767
+ * @see https://hono.dev/docs/api/hono#fire
2768
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
2769
+ * @see https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/
2770
+ */
2020
2771
  fire = () => {
2021
2772
  addEventListener("fetch", (event) => {
2022
2773
  event.respondWith(this.#dispatch(event.request, event, void 0, event.request.method));
@@ -2024,11 +2775,32 @@ var Hono = class {
2024
2775
  };
2025
2776
  };
2026
2777
 
2027
- // ../../node_modules/hono/dist/router/reg-exp-router/node.js
2778
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/router/reg-exp-router/matcher.js
2779
+ var emptyParam = [];
2780
+ function match(method, path) {
2781
+ const matchers = this.buildAllMatchers();
2782
+ const match2 = ((method2, path2) => {
2783
+ const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
2784
+ const staticMatch = matcher[2][path2];
2785
+ if (staticMatch) {
2786
+ return staticMatch;
2787
+ }
2788
+ const match3 = path2.match(matcher[0]);
2789
+ if (!match3) {
2790
+ return [[], emptyParam];
2791
+ }
2792
+ const index = match3.indexOf("", 1);
2793
+ return [matcher[1][index], match3];
2794
+ });
2795
+ this.match = match2;
2796
+ return match2(method, path);
2797
+ }
2798
+
2799
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/router/reg-exp-router/node.js
2028
2800
  var LABEL_REG_EXP_STR = "[^/]+";
2029
2801
  var ONLY_WILDCARD_REG_EXP_STR = ".*";
2030
2802
  var TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
2031
- var PATH_ERROR = Symbol();
2803
+ var PATH_ERROR = /* @__PURE__ */ Symbol();
2032
2804
  var regExpMetaChars = new Set(".\\+*[^]$()");
2033
2805
  function compareKey(a, b) {
2034
2806
  if (a.length === 1) {
@@ -2049,11 +2821,11 @@ function compareKey(a, b) {
2049
2821
  }
2050
2822
  return a.length === b.length ? a < b ? -1 : 1 : b.length - a.length;
2051
2823
  }
2052
- var Node = class {
2824
+ var Node = class _Node {
2053
2825
  #index;
2054
2826
  #varIndex;
2055
2827
  #children = /* @__PURE__ */ Object.create(null);
2056
- insert(tokens, index, paramMap, context2, pathErrorCheckOnly) {
2828
+ insert(tokens, index, paramMap, context, pathErrorCheckOnly) {
2057
2829
  if (tokens.length === 0) {
2058
2830
  if (this.#index !== void 0) {
2059
2831
  throw PATH_ERROR;
@@ -2089,9 +2861,9 @@ var Node = class {
2089
2861
  if (pathErrorCheckOnly) {
2090
2862
  return;
2091
2863
  }
2092
- node = this.#children[regexpStr] = new Node();
2864
+ node = this.#children[regexpStr] = new _Node();
2093
2865
  if (name !== "") {
2094
- node.#varIndex = context2.varIndex++;
2866
+ node.#varIndex = context.varIndex++;
2095
2867
  }
2096
2868
  }
2097
2869
  if (!pathErrorCheckOnly && name !== "") {
@@ -2108,10 +2880,10 @@ var Node = class {
2108
2880
  if (pathErrorCheckOnly) {
2109
2881
  return;
2110
2882
  }
2111
- node = this.#children[token] = new Node();
2883
+ node = this.#children[token] = new _Node();
2112
2884
  }
2113
2885
  }
2114
- node.insert(restTokens, index, paramMap, context2, pathErrorCheckOnly);
2886
+ node.insert(restTokens, index, paramMap, context, pathErrorCheckOnly);
2115
2887
  }
2116
2888
  buildRegExpStr() {
2117
2889
  const childKeys = Object.keys(this.#children).sort(compareKey);
@@ -2132,7 +2904,7 @@ var Node = class {
2132
2904
  }
2133
2905
  };
2134
2906
 
2135
- // ../../node_modules/hono/dist/router/reg-exp-router/trie.js
2907
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/router/reg-exp-router/trie.js
2136
2908
  var Trie = class {
2137
2909
  #context = { varIndex: 0 };
2138
2910
  #root = new Node();
@@ -2188,8 +2960,7 @@ var Trie = class {
2188
2960
  }
2189
2961
  };
2190
2962
 
2191
- // ../../node_modules/hono/dist/router/reg-exp-router/router.js
2192
- var emptyParam = [];
2963
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/router/reg-exp-router/router.js
2193
2964
  var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
2194
2965
  var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
2195
2966
  function buildWildcardRegExp(path) {
@@ -2336,30 +3107,14 @@ var RegExpRouter = class {
2336
3107
  });
2337
3108
  }
2338
3109
  }
2339
- match(method, path) {
2340
- clearWildcardRegExpCache();
2341
- const matchers = this.#buildAllMatchers();
2342
- this.match = (method2, path2) => {
2343
- const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
2344
- const staticMatch = matcher[2][path2];
2345
- if (staticMatch) {
2346
- return staticMatch;
2347
- }
2348
- const match = path2.match(matcher[0]);
2349
- if (!match) {
2350
- return [[], emptyParam];
2351
- }
2352
- const index = match.indexOf("", 1);
2353
- return [matcher[1][index], match];
2354
- };
2355
- return this.match(method, path);
2356
- }
2357
- #buildAllMatchers() {
3110
+ match = match;
3111
+ buildAllMatchers() {
2358
3112
  const matchers = /* @__PURE__ */ Object.create(null);
2359
3113
  Object.keys(this.#routes).concat(Object.keys(this.#middleware)).forEach((method) => {
2360
3114
  matchers[method] ||= this.#buildMatcher(method);
2361
3115
  });
2362
3116
  this.#middleware = this.#routes = void 0;
3117
+ clearWildcardRegExpCache();
2363
3118
  return matchers;
2364
3119
  }
2365
3120
  #buildMatcher(method) {
@@ -2384,7 +3139,7 @@ var RegExpRouter = class {
2384
3139
  }
2385
3140
  };
2386
3141
 
2387
- // ../../node_modules/hono/dist/router/smart-router/router.js
3142
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/router/smart-router/router.js
2388
3143
  var SmartRouter = class {
2389
3144
  name = "SmartRouter";
2390
3145
  #routers = [];
@@ -2439,9 +3194,9 @@ var SmartRouter = class {
2439
3194
  }
2440
3195
  };
2441
3196
 
2442
- // ../../node_modules/hono/dist/router/trie-router/node.js
3197
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/router/trie-router/node.js
2443
3198
  var emptyParams = /* @__PURE__ */ Object.create(null);
2444
- var Node2 = class {
3199
+ var Node2 = class _Node2 {
2445
3200
  #methods;
2446
3201
  #children;
2447
3202
  #patterns;
@@ -2474,7 +3229,7 @@ var Node2 = class {
2474
3229
  }
2475
3230
  continue;
2476
3231
  }
2477
- curNode.#children[key] = new Node2();
3232
+ curNode.#children[key] = new _Node2();
2478
3233
  if (pattern) {
2479
3234
  curNode.#patterns.push(pattern);
2480
3235
  possibleKeys.push(pattern[1]);
@@ -2597,7 +3352,7 @@ var Node2 = class {
2597
3352
  }
2598
3353
  };
2599
3354
 
2600
- // ../../node_modules/hono/dist/router/trie-router/router.js
3355
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/router/trie-router/router.js
2601
3356
  var TrieRouter = class {
2602
3357
  name = "TrieRouter";
2603
3358
  #node;
@@ -2619,8 +3374,13 @@ var TrieRouter = class {
2619
3374
  }
2620
3375
  };
2621
3376
 
2622
- // ../../node_modules/hono/dist/hono.js
3377
+ // ../../node_modules/.deno/hono@4.11.3/node_modules/hono/dist/hono.js
2623
3378
  var Hono2 = class extends Hono {
3379
+ /**
3380
+ * Creates an instance of the Hono class.
3381
+ *
3382
+ * @param options - Optional configuration options for the Hono instance.
3383
+ */
2624
3384
  constructor(options = {}) {
2625
3385
  super(options);
2626
3386
  this.router = options.router ?? new SmartRouter({
@@ -2629,35 +3389,12 @@ var Hono2 = class extends Hono {
2629
3389
  }
2630
3390
  };
2631
3391
 
2632
- // ../../node_modules/hono/dist/http-exception.js
2633
- var HTTPException = class extends Error {
2634
- res;
2635
- status;
2636
- constructor(status = 500, options) {
2637
- super(options?.message, { cause: options?.cause });
2638
- this.res = options?.res;
2639
- this.status = status;
2640
- }
2641
- getResponse() {
2642
- if (this.res) {
2643
- const newResponse = new Response(this.res.body, {
2644
- status: this.status,
2645
- headers: this.res.headers
2646
- });
2647
- return newResponse;
2648
- }
2649
- return new Response(this.message, {
2650
- status: this.status
2651
- });
2652
- }
2653
- };
2654
-
2655
3392
  // src/server.ts
2656
- async function handleError2(context2, pluginOptions, error) {
3393
+ async function handleError2(context, pluginOptions, error) {
2657
3394
  console.error(error);
2658
- const loggerError = transformError(context2, error);
3395
+ const loggerError = transformError(context, error);
2659
3396
  if (pluginOptions.postCommentOnError && loggerError) {
2660
- await context2.commentHandler.postComment(context2, loggerError);
3397
+ await context.commentHandler.postComment(context, loggerError);
2661
3398
  }
2662
3399
  throw new HTTPException(500, { message: "Unexpected error" });
2663
3400
  }
@@ -2708,7 +3445,7 @@ function createPlugin(handler, manifest, options) {
2708
3445
  const workerName = new URL(inputs.ref).hostname.split(".")[0];
2709
3446
  PluginRuntimeInfo.getInstance({ ...env2, CLOUDFLARE_WORKER_NAME: workerName });
2710
3447
  const command = getCommand(inputs, pluginOptions);
2711
- const context2 = {
3448
+ const context = {
2712
3449
  eventName: inputs.eventName,
2713
3450
  payload: inputs.eventPayload,
2714
3451
  command,
@@ -2721,10 +3458,10 @@ function createPlugin(handler, manifest, options) {
2721
3458
  commentHandler: new CommentHandler()
2722
3459
  };
2723
3460
  try {
2724
- const result = await handler(context2);
3461
+ const result = await handler(context);
2725
3462
  return ctx.json({ stateId: inputs.stateId, output: result ?? {} });
2726
3463
  } catch (error) {
2727
- await handleError2(context2, pluginOptions, error);
3464
+ await handleError2(context, pluginOptions, error);
2728
3465
  }
2729
3466
  });
2730
3467
  return app;
@@ -2739,6 +3476,14 @@ function normalizeBaseUrl(baseUrl) {
2739
3476
  }
2740
3477
  return normalized;
2741
3478
  }
3479
+ var MAX_LLM_RETRIES = 2;
3480
+ var RETRY_BACKOFF_MS = [250, 750];
3481
+ function getRetryDelayMs(attempt) {
3482
+ return RETRY_BACKOFF_MS[Math.min(attempt, RETRY_BACKOFF_MS.length - 1)] ?? 750;
3483
+ }
3484
+ function sleep(ms) {
3485
+ return new Promise((resolve) => setTimeout(resolve, ms));
3486
+ }
2742
3487
  function getEnvString(name) {
2743
3488
  if (typeof process === "undefined" || !process?.env) return EMPTY_STRING;
2744
3489
  return String(process.env[name] ?? EMPTY_STRING).trim();
@@ -2753,7 +3498,11 @@ function getAiBaseUrl(options) {
2753
3498
  }
2754
3499
  async function callLlm(options, input) {
2755
3500
  const authToken = String(input.authToken ?? EMPTY_STRING).trim();
2756
- if (!authToken) throw new Error("Missing authToken in input");
3501
+ if (!authToken) {
3502
+ const err = new Error("Missing authToken in input");
3503
+ err.status = 401;
3504
+ throw err;
3505
+ }
2757
3506
  const kernelToken = "ubiquityKernelToken" in input ? input.ubiquityKernelToken : void 0;
2758
3507
  const payload = getPayload(input);
2759
3508
  const { owner, repo, installationId } = getRepoMetadata(payload);
@@ -2773,13 +3522,7 @@ async function callLlm(options, input) {
2773
3522
  installationId,
2774
3523
  ubiquityKernelToken: kernelToken
2775
3524
  });
2776
- const response = await fetch(url, { method: "POST", headers, body });
2777
- if (!response.ok) {
2778
- const err = await response.text();
2779
- const error = new Error(`LLM API error: ${response.status} - ${err}`);
2780
- error.status = response.status;
2781
- throw error;
2782
- }
3525
+ const response = await fetchWithRetry(url, { method: "POST", headers, body }, MAX_LLM_RETRIES);
2783
3526
  if (isStream) {
2784
3527
  if (!response.body) {
2785
3528
  throw new Error("LLM API error: missing response body for streaming request");
@@ -2791,17 +3534,46 @@ async function callLlm(options, input) {
2791
3534
  function ensureKernelToken(authToken, kernelToken) {
2792
3535
  const isKernelTokenRequired = authToken.startsWith("gh");
2793
3536
  if (isKernelTokenRequired && !kernelToken) {
2794
- throw new Error("Missing ubiquityKernelToken in input (kernel attestation is required for GitHub auth)");
3537
+ const err = new Error("Missing ubiquityKernelToken in input (kernel attestation is required for GitHub auth)");
3538
+ err.status = 401;
3539
+ throw err;
2795
3540
  }
2796
3541
  }
2797
3542
  function ensureMessages(messages) {
2798
3543
  if (!Array.isArray(messages) || messages.length === 0) {
2799
- throw new Error("messages must be a non-empty array");
3544
+ const err = new Error("messages must be a non-empty array");
3545
+ err.status = 400;
3546
+ throw err;
2800
3547
  }
2801
3548
  }
2802
3549
  function buildAiUrl(options, baseUrl) {
2803
3550
  return `${getAiBaseUrl({ ...options, baseUrl })}/v1/chat/completions`;
2804
3551
  }
3552
+ async function fetchWithRetry(url, options, maxRetries) {
3553
+ let attempt = 0;
3554
+ let lastError;
3555
+ while (attempt <= maxRetries) {
3556
+ try {
3557
+ const response = await fetch(url, options);
3558
+ if (response.ok) return response;
3559
+ const errText = await response.text();
3560
+ if (response.status >= 500 && attempt < maxRetries) {
3561
+ await sleep(getRetryDelayMs(attempt));
3562
+ attempt += 1;
3563
+ continue;
3564
+ }
3565
+ const error = new Error(`LLM API error: ${response.status} - ${errText}`);
3566
+ error.status = response.status;
3567
+ throw error;
3568
+ } catch (error) {
3569
+ lastError = error;
3570
+ if (attempt >= maxRetries) throw error;
3571
+ await sleep(getRetryDelayMs(attempt));
3572
+ attempt += 1;
3573
+ }
3574
+ }
3575
+ throw lastError ?? new Error("LLM API error: request failed after retries");
3576
+ }
2805
3577
  function getPayload(input) {
2806
3578
  if ("payload" in input) {
2807
3579
  return input.payload;
@@ -2863,7 +3635,7 @@ function getEventData(event) {
2863
3635
  if (!event.trim()) return null;
2864
3636
  const dataLines = event.split("\n").filter((line) => line.startsWith("data:"));
2865
3637
  if (!dataLines.length) return null;
2866
- const data = dataLines.map((line) => line.startsWith("data: ") ? line.slice(6) : line.slice(5).replace(/^ /, "")).join("\n");
3638
+ const data = dataLines.map((line) => line.startsWith("data: ") ? line.slice(6) : line.slice(5).replace(/^ /, EMPTY_STRING)).join("\n");
2867
3639
  return data || null;
2868
3640
  }
2869
3641
  function parseEventData(data) {