@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/configuration.d.mts +16 -11
- package/dist/configuration.d.ts +16 -11
- package/dist/configuration.js +219 -36
- package/dist/configuration.mjs +219 -36
- package/dist/{context-sqbr2o6i.d.mts → context-Dwl3aRX-.d.mts} +29 -0
- package/dist/{context-BbEmsEct.d.ts → context-zLHgu52i.d.ts} +29 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +993 -221
- package/dist/index.mjs +993 -221
- package/dist/llm.d.mts +1 -1
- package/dist/llm.d.ts +1 -1
- package/dist/llm.js +46 -11
- package/dist/llm.mjs +46 -11
- package/dist/signature.js +2 -2
- package/dist/signature.mjs +2 -2
- package/package.json +1 -1
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
|
|
195
|
-
if (
|
|
196
|
-
metadata.caller =
|
|
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/
|
|
342
|
-
|
|
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
|
|
505
|
+
return getGithubContext().sha;
|
|
443
506
|
}
|
|
444
507
|
get runUrl() {
|
|
445
|
-
|
|
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
|
-
|
|
659
|
+
_commandResponsePolicyApplied = false;
|
|
660
|
+
async _updateIssueComment(context, params) {
|
|
539
661
|
if (!this._lastCommentId.issueCommentId) {
|
|
540
|
-
throw
|
|
662
|
+
throw context.logger.error("issueCommentId is missing");
|
|
541
663
|
}
|
|
542
|
-
const commentData = await
|
|
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(
|
|
672
|
+
async _updateReviewComment(context, params) {
|
|
551
673
|
if (!this._lastCommentId.reviewCommentId) {
|
|
552
|
-
throw
|
|
674
|
+
throw context.logger.error("reviewCommentId is missing");
|
|
553
675
|
}
|
|
554
|
-
const commentData = await
|
|
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(
|
|
684
|
+
async _createNewComment(context, params) {
|
|
563
685
|
if (params.commentId) {
|
|
564
|
-
const commentData2 = await
|
|
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
|
|
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(
|
|
584
|
-
if ("issue" in
|
|
585
|
-
if ("pull_request" in
|
|
586
|
-
if ("discussion" in
|
|
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(
|
|
590
|
-
return "pull_request" in
|
|
711
|
+
_getCommentId(context) {
|
|
712
|
+
return "pull_request" in context.payload && "comment" in context.payload ? context.payload.comment.id : void 0;
|
|
591
713
|
}
|
|
592
|
-
|
|
593
|
-
|
|
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(
|
|
723
|
+
const issueNumber = this._getIssueNumber(context);
|
|
597
724
|
if (!issueNumber) return null;
|
|
598
725
|
return {
|
|
599
726
|
issueNumber,
|
|
600
|
-
commentId: this._getCommentId(
|
|
601
|
-
owner:
|
|
602
|
-
repo:
|
|
727
|
+
commentId: this._getCommentId(context),
|
|
728
|
+
owner: context.payload.repository.owner.login,
|
|
729
|
+
repo: context.payload.repository.name
|
|
603
730
|
};
|
|
604
731
|
}
|
|
605
|
-
|
|
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
|
-
|
|
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 ||
|
|
829
|
+
caller: message.metadata.caller || callerMatch?.[1]
|
|
619
830
|
} : { ...message };
|
|
620
831
|
return { metadata, logMessage: message.logMessage };
|
|
621
832
|
}
|
|
622
|
-
_getInstigatorName(
|
|
623
|
-
if ("installation" in
|
|
624
|
-
return
|
|
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
|
|
837
|
+
return context.payload.sender?.login || _CommentHandler.HEADER_NAME;
|
|
627
838
|
}
|
|
628
|
-
_createMetadataContent(
|
|
839
|
+
_createMetadataContent(context, metadata) {
|
|
629
840
|
const jsonPretty = sanitizeMetadata(metadata);
|
|
630
|
-
const instigatorName = this._getInstigatorName(
|
|
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(
|
|
648
|
-
return this._createCommentBody(
|
|
649
|
-
}
|
|
650
|
-
_createCommentBody(
|
|
651
|
-
const { metadata, logMessage } = this._processMessage(
|
|
652
|
-
const
|
|
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(
|
|
660
|
-
|
|
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
|
-
|
|
876
|
+
context.logger.warn("Cannot post comment: missing issue context in payload");
|
|
663
877
|
return null;
|
|
664
878
|
}
|
|
665
|
-
const
|
|
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
|
|
670
|
-
return this._updateIssueComment(
|
|
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
|
|
673
|
-
return this._updateReviewComment(
|
|
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(
|
|
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-----", "").
|
|
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(
|
|
1183
|
+
async function handleError(context, pluginOptions, error) {
|
|
990
1184
|
console.error(error);
|
|
991
|
-
const loggerError = transformError(
|
|
992
|
-
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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(
|
|
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:
|
|
1072
|
-
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
|
|
1090
|
-
if (
|
|
1091
|
-
segments.push(processSegment(md.slice(lastIndex,
|
|
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(
|
|
1094
|
-
lastIndex =
|
|
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 (
|
|
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
|
-
|
|
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(
|
|
1350
|
+
res = await handler(context, () => dispatch(i + 1));
|
|
1159
1351
|
} catch (err) {
|
|
1160
1352
|
if (err instanceof Error && onError) {
|
|
1161
|
-
|
|
1162
|
-
res = await onError(err,
|
|
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 (
|
|
1170
|
-
res = await onNotFound(
|
|
1361
|
+
if (context.finalized === false && onNotFound) {
|
|
1362
|
+
res = await onNotFound(context);
|
|
1171
1363
|
}
|
|
1172
1364
|
}
|
|
1173
|
-
if (res && (
|
|
1174
|
-
|
|
1365
|
+
if (res && (context.finalized === false || isError)) {
|
|
1366
|
+
context.res = res;
|
|
1175
1367
|
}
|
|
1176
|
-
return
|
|
1368
|
+
return context;
|
|
1177
1369
|
}
|
|
1178
1370
|
};
|
|
1179
1371
|
};
|
|
1180
1372
|
|
|
1181
|
-
// ../../node_modules/hono/dist/
|
|
1182
|
-
var
|
|
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, (
|
|
1493
|
+
path = path.replace(/\{[^}]+\}/g, (match2, index) => {
|
|
1269
1494
|
const mark = `@${index}`;
|
|
1270
|
-
groups.push([mark,
|
|
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
|
|
1293
|
-
if (
|
|
1517
|
+
const match2 = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
|
|
1518
|
+
if (match2) {
|
|
1294
1519
|
const cacheKey = `${label}#${next}`;
|
|
1295
1520
|
if (!patternCache[cacheKey]) {
|
|
1296
|
-
if (
|
|
1297
|
-
patternCache[cacheKey] = next && next[0] !== ":" && next[0] !== "*" ? [cacheKey,
|
|
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,
|
|
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, (
|
|
1535
|
+
return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match2) => {
|
|
1311
1536
|
try {
|
|
1312
|
-
return decoder(
|
|
1537
|
+
return decoder(match2);
|
|
1313
1538
|
} catch {
|
|
1314
|
-
return
|
|
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(
|
|
1610
|
+
let keyIndex2 = url.indexOf("?", 8);
|
|
1389
1611
|
if (keyIndex2 === -1) {
|
|
1390
|
-
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
1992
|
-
if (!
|
|
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
|
|
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/
|
|
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,
|
|
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
|
|
2864
|
+
node = this.#children[regexpStr] = new _Node();
|
|
2093
2865
|
if (name !== "") {
|
|
2094
|
-
node.#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
|
|
2883
|
+
node = this.#children[token] = new _Node();
|
|
2112
2884
|
}
|
|
2113
2885
|
}
|
|
2114
|
-
node.insert(restTokens, index, paramMap,
|
|
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
|
|
2340
|
-
|
|
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
|
|
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(
|
|
3393
|
+
async function handleError2(context, pluginOptions, error) {
|
|
2657
3394
|
console.error(error);
|
|
2658
|
-
const loggerError = transformError(
|
|
3395
|
+
const loggerError = transformError(context, error);
|
|
2659
3396
|
if (pluginOptions.postCommentOnError && loggerError) {
|
|
2660
|
-
await
|
|
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
|
|
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(
|
|
3461
|
+
const result = await handler(context);
|
|
2725
3462
|
return ctx.json({ stateId: inputs.stateId, output: result ?? {} });
|
|
2726
3463
|
} catch (error) {
|
|
2727
|
-
await handleError2(
|
|
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)
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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(/^ /,
|
|
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) {
|