@ubiquity-os/plugin-sdk 3.2.1 → 3.3.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/README.md +57 -1
- package/dist/compression.js +3 -3
- package/dist/compression.mjs +3 -3
- package/dist/index.d.mts +35 -4
- package/dist/index.d.ts +35 -4
- package/dist/index.js +65 -7
- package/dist/index.mjs +64 -7
- package/package.json +1 -3
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ This project provides a software development kit (SDK) for creating plugins usin
|
|
|
5
5
|
- TypeScript
|
|
6
6
|
- Creating a plugin instance
|
|
7
7
|
- Injection of the context
|
|
8
|
-
- Provider with a logger, an authenticated Octokit instance and the event payload
|
|
8
|
+
- Provider with a logger, an authenticated Octokit instance, and the event payload
|
|
9
9
|
|
|
10
10
|
## Key Functions
|
|
11
11
|
|
|
@@ -58,3 +58,59 @@ To start Jest tests, run:
|
|
|
58
58
|
```sh
|
|
59
59
|
bun run test
|
|
60
60
|
```
|
|
61
|
+
|
|
62
|
+
## Markdown Cleaning Utility
|
|
63
|
+
|
|
64
|
+
`cleanMarkdown` removes top-level HTML comments and configured HTML tags while preserving content inside fenced/indented code blocks, inline code spans, and blockquotes.
|
|
65
|
+
|
|
66
|
+
### Import
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import { cleanMarkdown, type CleanMarkdownOptions } from "@ubiquity-os/plugin-sdk/markdown";
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Options (`CleanMarkdownOptions`)
|
|
73
|
+
|
|
74
|
+
| Option | Type | Default | Description |
|
|
75
|
+
| -------------------- | --------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
76
|
+
| `tags` | `(keyof HTMLElementTagNameMap)[]` | `[]` | List of HTML tag names to strip. Whole block tokens that are a single matching root element are removed entirely. Inline self-closing/void-like occurrences (e.g. `<br>`) are also removed. |
|
|
77
|
+
| `collapseEmptyLines` | `boolean` | `false` | Collapses runs of 3+ blank lines down to exactly 2. |
|
|
78
|
+
|
|
79
|
+
### Behavior Summary
|
|
80
|
+
|
|
81
|
+
- Strips HTML comments (`<!-- ... -->`) outside protected contexts:
|
|
82
|
+
- Not inside fenced/indented code blocks
|
|
83
|
+
- Not inside inline code spans
|
|
84
|
+
- Not inside blockquotes (blockquote content is left untouched)
|
|
85
|
+
- Removes entire HTML block tokens consisting of a single root element whose tag is in `tags`.
|
|
86
|
+
- Removes inline occurrences of any tag in `tags` (void/self-closing style).
|
|
87
|
+
- Leaves everything else unchanged to minimize diff noise.
|
|
88
|
+
- Final output is trimmed (no trailing blank lines).
|
|
89
|
+
|
|
90
|
+
### Example
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
const input = `
|
|
94
|
+
<!-- build badge -->
|
|
95
|
+
<details>
|
|
96
|
+
<summary>Info</summary>
|
|
97
|
+
Content inside details
|
|
98
|
+
</details>
|
|
99
|
+
|
|
100
|
+
Paragraph with <br> line break and \`<br>\` in code.
|
|
101
|
+
|
|
102
|
+
\`\`\`ts
|
|
103
|
+
// Code block with <!-- comment --> and <br>
|
|
104
|
+
const x = 1;
|
|
105
|
+
\`\`\`
|
|
106
|
+
|
|
107
|
+
> Blockquote with <!-- preserved comment --> and <br>.
|
|
108
|
+
`;
|
|
109
|
+
|
|
110
|
+
const cleaned = cleanMarkdown(input, {
|
|
111
|
+
tags: ["details", "br"],
|
|
112
|
+
collapseEmptyLines: true,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
console.log(cleaned);
|
|
116
|
+
```
|
package/dist/compression.js
CHANGED
|
@@ -24,15 +24,15 @@ __export(compression_exports, {
|
|
|
24
24
|
decompressString: () => decompressString
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(compression_exports);
|
|
27
|
-
var
|
|
27
|
+
var import_node_zlib = require("zlib");
|
|
28
28
|
function compressString(str) {
|
|
29
29
|
const input = Buffer.from(str, "utf8");
|
|
30
|
-
const compressed = (0,
|
|
30
|
+
const compressed = (0, import_node_zlib.brotliCompressSync)(input);
|
|
31
31
|
return Buffer.from(compressed).toString("base64");
|
|
32
32
|
}
|
|
33
33
|
function decompressString(compressed) {
|
|
34
34
|
const buffer = Buffer.from(compressed, "base64");
|
|
35
|
-
const decompressed = (0,
|
|
35
|
+
const decompressed = (0, import_node_zlib.brotliDecompressSync)(buffer);
|
|
36
36
|
return Buffer.from(decompressed).toString("utf8");
|
|
37
37
|
}
|
|
38
38
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/compression.mjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// src/helpers/compression.ts
|
|
2
|
-
import {
|
|
2
|
+
import { brotliCompressSync, brotliDecompressSync } from "node:zlib";
|
|
3
3
|
function compressString(str) {
|
|
4
4
|
const input = Buffer.from(str, "utf8");
|
|
5
|
-
const compressed =
|
|
5
|
+
const compressed = brotliCompressSync(input);
|
|
6
6
|
return Buffer.from(compressed).toString("base64");
|
|
7
7
|
}
|
|
8
8
|
function decompressString(compressed) {
|
|
9
9
|
const buffer = Buffer.from(compressed, "base64");
|
|
10
|
-
const decompressed =
|
|
10
|
+
const decompressed = brotliDecompressSync(buffer);
|
|
11
11
|
return Buffer.from(decompressed).toString("utf8");
|
|
12
12
|
}
|
|
13
13
|
export {
|
package/dist/index.d.mts
CHANGED
|
@@ -116,7 +116,7 @@ interface Context<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSuppor
|
|
|
116
116
|
type Return = Record<string, unknown> | undefined | void;
|
|
117
117
|
type HandlerReturn = Promise<Return> | Return;
|
|
118
118
|
|
|
119
|
-
interface Options {
|
|
119
|
+
interface Options$1 {
|
|
120
120
|
kernelPublicKey?: string;
|
|
121
121
|
logLevel?: LogLevel;
|
|
122
122
|
postCommentOnError?: boolean;
|
|
@@ -127,10 +127,41 @@ interface Options {
|
|
|
127
127
|
* @deprecated This disables signature verification - only for local development
|
|
128
128
|
*/
|
|
129
129
|
bypassSignatureVerification?: boolean;
|
|
130
|
+
returnDataToKernel?: boolean;
|
|
130
131
|
}
|
|
131
132
|
|
|
132
|
-
declare function createActionsPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, options?: Options): Promise<void>;
|
|
133
|
+
declare function createActionsPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, options?: Options$1): Promise<void>;
|
|
133
134
|
|
|
134
|
-
declare function createPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, manifest: Manifest, options?: Options): Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
|
|
135
|
+
declare function createPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, manifest: Manifest, options?: Options$1): Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
|
|
135
136
|
|
|
136
|
-
|
|
137
|
+
/**
|
|
138
|
+
* Options for cleanMarkdown.
|
|
139
|
+
*
|
|
140
|
+
* tags:
|
|
141
|
+
* A single list of HTML tag names (keyof HTMLElementTagNameMap) to remove.
|
|
142
|
+
* Behavior per tag:
|
|
143
|
+
* 1. If an HTML block token consists solely of a single root element whose tag matches, the entire block (its content) is removed.
|
|
144
|
+
* (e.g. <details> ... </details> when "details" is in tags).
|
|
145
|
+
* 2. Standalone inline occurrences of that tag treated as void/self-closing (e.g. <br>) are stripped.
|
|
146
|
+
*
|
|
147
|
+
* collapseEmptyLines:
|
|
148
|
+
* If true, collapses sequences of 3+ blank lines down to exactly 2, preserving paragraph spacing while shrinking payload size.
|
|
149
|
+
*/
|
|
150
|
+
type Options = {
|
|
151
|
+
tags?: string[];
|
|
152
|
+
shouldCollapseEmptyLines?: boolean;
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Cleans a GitHub-flavored markdown string by:
|
|
156
|
+
* - Removing top‑level HTML comments (<!-- ... -->) (outside code / inline code / blockquote context)
|
|
157
|
+
* - Removing blocks for configured tags when the entire html token is a single element of that tag
|
|
158
|
+
* - Removing inline occurrences of configured tags treated as void (e.g. \<br\>) outside fenced / inline code
|
|
159
|
+
* - Preserving comments and tags inside:
|
|
160
|
+
* * fenced or indented code blocks
|
|
161
|
+
* * inline code spans
|
|
162
|
+
* * blockquotes (their contents unchanged)
|
|
163
|
+
* - Optionally collapsing excessive blank lines
|
|
164
|
+
*/
|
|
165
|
+
declare function cleanMarkdown(md: string, options?: Options): string;
|
|
166
|
+
|
|
167
|
+
export { CommentHandler, type Context, type Options$1 as Options, cleanMarkdown, createActionsPlugin, createPlugin };
|
package/dist/index.d.ts
CHANGED
|
@@ -116,7 +116,7 @@ interface Context<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSuppor
|
|
|
116
116
|
type Return = Record<string, unknown> | undefined | void;
|
|
117
117
|
type HandlerReturn = Promise<Return> | Return;
|
|
118
118
|
|
|
119
|
-
interface Options {
|
|
119
|
+
interface Options$1 {
|
|
120
120
|
kernelPublicKey?: string;
|
|
121
121
|
logLevel?: LogLevel;
|
|
122
122
|
postCommentOnError?: boolean;
|
|
@@ -127,10 +127,41 @@ interface Options {
|
|
|
127
127
|
* @deprecated This disables signature verification - only for local development
|
|
128
128
|
*/
|
|
129
129
|
bypassSignatureVerification?: boolean;
|
|
130
|
+
returnDataToKernel?: boolean;
|
|
130
131
|
}
|
|
131
132
|
|
|
132
|
-
declare function createActionsPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, options?: Options): Promise<void>;
|
|
133
|
+
declare function createActionsPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, options?: Options$1): Promise<void>;
|
|
133
134
|
|
|
134
|
-
declare function createPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, manifest: Manifest, options?: Options): Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
|
|
135
|
+
declare function createPlugin<TConfig = unknown, TEnv = unknown, TCommand = unknown, TSupportedEvents extends EmitterWebhookEventName = EmitterWebhookEventName>(handler: (context: Context<TConfig, TEnv, TCommand, TSupportedEvents>) => HandlerReturn, manifest: Manifest, options?: Options$1): Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
|
|
135
136
|
|
|
136
|
-
|
|
137
|
+
/**
|
|
138
|
+
* Options for cleanMarkdown.
|
|
139
|
+
*
|
|
140
|
+
* tags:
|
|
141
|
+
* A single list of HTML tag names (keyof HTMLElementTagNameMap) to remove.
|
|
142
|
+
* Behavior per tag:
|
|
143
|
+
* 1. If an HTML block token consists solely of a single root element whose tag matches, the entire block (its content) is removed.
|
|
144
|
+
* (e.g. <details> ... </details> when "details" is in tags).
|
|
145
|
+
* 2. Standalone inline occurrences of that tag treated as void/self-closing (e.g. <br>) are stripped.
|
|
146
|
+
*
|
|
147
|
+
* collapseEmptyLines:
|
|
148
|
+
* If true, collapses sequences of 3+ blank lines down to exactly 2, preserving paragraph spacing while shrinking payload size.
|
|
149
|
+
*/
|
|
150
|
+
type Options = {
|
|
151
|
+
tags?: string[];
|
|
152
|
+
shouldCollapseEmptyLines?: boolean;
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Cleans a GitHub-flavored markdown string by:
|
|
156
|
+
* - Removing top‑level HTML comments (<!-- ... -->) (outside code / inline code / blockquote context)
|
|
157
|
+
* - Removing blocks for configured tags when the entire html token is a single element of that tag
|
|
158
|
+
* - Removing inline occurrences of configured tags treated as void (e.g. \<br\>) outside fenced / inline code
|
|
159
|
+
* - Preserving comments and tags inside:
|
|
160
|
+
* * fenced or indented code blocks
|
|
161
|
+
* * inline code spans
|
|
162
|
+
* * blockquotes (their contents unchanged)
|
|
163
|
+
* - Optionally collapsing excessive blank lines
|
|
164
|
+
*/
|
|
165
|
+
declare function cleanMarkdown(md: string, options?: Options): string;
|
|
166
|
+
|
|
167
|
+
export { CommentHandler, type Context, type Options$1 as Options, cleanMarkdown, createActionsPlugin, createPlugin };
|
package/dist/index.js
CHANGED
|
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
33
|
CommentHandler: () => CommentHandler,
|
|
34
|
+
cleanMarkdown: () => cleanMarkdown,
|
|
34
35
|
createActionsPlugin: () => createActionsPlugin,
|
|
35
36
|
createPlugin: () => createPlugin
|
|
36
37
|
});
|
|
@@ -161,7 +162,8 @@ function getPluginOptions(options) {
|
|
|
161
162
|
envSchema: options?.envSchema,
|
|
162
163
|
commandSchema: options?.commandSchema,
|
|
163
164
|
// eslint-disable-next-line sonarjs/deprecation
|
|
164
|
-
bypassSignatureVerification: options?.bypassSignatureVerification || false
|
|
165
|
+
bypassSignatureVerification: options?.bypassSignatureVerification || false,
|
|
166
|
+
returnDataToKernel: options?.returnDataToKernel ?? true
|
|
165
167
|
};
|
|
166
168
|
}
|
|
167
169
|
|
|
@@ -354,15 +356,15 @@ function getCommand(inputs, pluginOptions) {
|
|
|
354
356
|
}
|
|
355
357
|
|
|
356
358
|
// src/helpers/compression.ts
|
|
357
|
-
var
|
|
359
|
+
var import_node_zlib = require("zlib");
|
|
358
360
|
function compressString(str) {
|
|
359
361
|
const input = Buffer.from(str, "utf8");
|
|
360
|
-
const compressed = (0,
|
|
362
|
+
const compressed = (0, import_node_zlib.brotliCompressSync)(input);
|
|
361
363
|
return Buffer.from(compressed).toString("base64");
|
|
362
364
|
}
|
|
363
365
|
function decompressString(compressed) {
|
|
364
366
|
const buffer = Buffer.from(compressed, "base64");
|
|
365
|
-
const decompressed = (0,
|
|
367
|
+
const decompressed = (0, import_node_zlib.brotliDecompressSync)(buffer);
|
|
366
368
|
return Buffer.from(decompressed).toString("utf8");
|
|
367
369
|
}
|
|
368
370
|
|
|
@@ -436,9 +438,9 @@ var commandCallSchema = import_typebox.Type.Union([import_typebox.Type.Null(), i
|
|
|
436
438
|
// src/types/util.ts
|
|
437
439
|
var import_typebox2 = require("@sinclair/typebox");
|
|
438
440
|
var import_value2 = require("@sinclair/typebox/value");
|
|
439
|
-
function jsonType(type,
|
|
441
|
+
function jsonType(type, decompress = false) {
|
|
440
442
|
return import_typebox2.Type.Transform(import_typebox2.Type.String()).Decode((value) => {
|
|
441
|
-
const parsed = JSON.parse(
|
|
443
|
+
const parsed = JSON.parse(decompress ? decompressString(value) : value);
|
|
442
444
|
return import_value2.Value.Decode(type, import_value2.Value.Default(type, parsed));
|
|
443
445
|
}).Encode((value) => JSON.stringify(value));
|
|
444
446
|
}
|
|
@@ -527,7 +529,9 @@ async function createActionsPlugin(handler, options) {
|
|
|
527
529
|
try {
|
|
528
530
|
const result = await handler(context2);
|
|
529
531
|
core.setOutput("result", result);
|
|
530
|
-
|
|
532
|
+
if (pluginOptions?.returnDataToKernel) {
|
|
533
|
+
await returnDataToKernel(pluginGithubToken, inputs.stateId, result);
|
|
534
|
+
}
|
|
531
535
|
} catch (error) {
|
|
532
536
|
await handleError(context2, pluginOptions, error);
|
|
533
537
|
}
|
|
@@ -625,9 +629,63 @@ function createPlugin(handler, manifest, options) {
|
|
|
625
629
|
});
|
|
626
630
|
return app;
|
|
627
631
|
}
|
|
632
|
+
|
|
633
|
+
// src/markdown.ts
|
|
634
|
+
var VOID_TAGS = /* @__PURE__ */ new Set(["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"]);
|
|
635
|
+
function cleanMarkdown(md, options = {}) {
|
|
636
|
+
const codeBlockRegex = /(```[\s\S]*?```|~~~[\s\S]*?~~~)/g;
|
|
637
|
+
const { tags = [], shouldCollapseEmptyLines = false } = options;
|
|
638
|
+
const segments = [];
|
|
639
|
+
let lastIndex = 0;
|
|
640
|
+
const matches = [...md.matchAll(codeBlockRegex)];
|
|
641
|
+
for (const match of matches) {
|
|
642
|
+
if (match.index > lastIndex) {
|
|
643
|
+
segments.push(processSegment(md.slice(lastIndex, match.index), tags, shouldCollapseEmptyLines));
|
|
644
|
+
}
|
|
645
|
+
segments.push(match[0]);
|
|
646
|
+
lastIndex = match.index + match[0].length;
|
|
647
|
+
}
|
|
648
|
+
if (lastIndex < md.length) {
|
|
649
|
+
segments.push(processSegment(md.slice(lastIndex), tags, shouldCollapseEmptyLines));
|
|
650
|
+
}
|
|
651
|
+
return segments.join("");
|
|
652
|
+
}
|
|
653
|
+
function processSegment(segment, extraTags, shouldCollapseEmptyLines) {
|
|
654
|
+
const inlineCodeRegex = /`[^`]*`/g;
|
|
655
|
+
const inlineCodes = [];
|
|
656
|
+
let s = segment.replace(inlineCodeRegex, (m) => {
|
|
657
|
+
inlineCodes.push(m);
|
|
658
|
+
return `__INLINE_CODE_${inlineCodes.length - 1}__`;
|
|
659
|
+
});
|
|
660
|
+
s = s.replace(/<!--[\s\S]*?-->/g, "");
|
|
661
|
+
for (const raw of extraTags) {
|
|
662
|
+
if (!raw) continue;
|
|
663
|
+
const tag = raw.toLowerCase().trim().replace(/[^\w:-]/g, "");
|
|
664
|
+
if (!tag) continue;
|
|
665
|
+
if (VOID_TAGS.has(tag)) {
|
|
666
|
+
const voidRe = new RegExp(`<${tag}\\b[^>]*\\/?>`, "gi");
|
|
667
|
+
s = s.replace(voidRe, "");
|
|
668
|
+
continue;
|
|
669
|
+
}
|
|
670
|
+
const pairRe = new RegExp(`<${tag}\\b[^>]*>[\\s\\S]*?<\\/${tag}>`, "gi");
|
|
671
|
+
let prev;
|
|
672
|
+
do {
|
|
673
|
+
prev = s;
|
|
674
|
+
s = s.replace(pairRe, "");
|
|
675
|
+
} while (s !== prev);
|
|
676
|
+
const openCloseRe = new RegExp(`<\\/?${tag}\\b[^>]*>`, "gi");
|
|
677
|
+
s = s.replace(openCloseRe, "");
|
|
678
|
+
}
|
|
679
|
+
s = s.replace(/__INLINE_CODE_(\d+)__/g, (str, idx) => inlineCodes[+idx]);
|
|
680
|
+
if (shouldCollapseEmptyLines) {
|
|
681
|
+
s = s.replace(/[ \t]+$/gm, "").replace(/\n{3,}/g, "\n\n");
|
|
682
|
+
}
|
|
683
|
+
return s;
|
|
684
|
+
}
|
|
628
685
|
// Annotate the CommonJS export names for ESM import in node:
|
|
629
686
|
0 && (module.exports = {
|
|
630
687
|
CommentHandler,
|
|
688
|
+
cleanMarkdown,
|
|
631
689
|
createActionsPlugin,
|
|
632
690
|
createPlugin
|
|
633
691
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -123,7 +123,8 @@ function getPluginOptions(options) {
|
|
|
123
123
|
envSchema: options?.envSchema,
|
|
124
124
|
commandSchema: options?.commandSchema,
|
|
125
125
|
// eslint-disable-next-line sonarjs/deprecation
|
|
126
|
-
bypassSignatureVerification: options?.bypassSignatureVerification || false
|
|
126
|
+
bypassSignatureVerification: options?.bypassSignatureVerification || false,
|
|
127
|
+
returnDataToKernel: options?.returnDataToKernel ?? true
|
|
127
128
|
};
|
|
128
129
|
}
|
|
129
130
|
|
|
@@ -316,15 +317,15 @@ function getCommand(inputs, pluginOptions) {
|
|
|
316
317
|
}
|
|
317
318
|
|
|
318
319
|
// src/helpers/compression.ts
|
|
319
|
-
import {
|
|
320
|
+
import { brotliCompressSync, brotliDecompressSync } from "node:zlib";
|
|
320
321
|
function compressString(str) {
|
|
321
322
|
const input = Buffer.from(str, "utf8");
|
|
322
|
-
const compressed =
|
|
323
|
+
const compressed = brotliCompressSync(input);
|
|
323
324
|
return Buffer.from(compressed).toString("base64");
|
|
324
325
|
}
|
|
325
326
|
function decompressString(compressed) {
|
|
326
327
|
const buffer = Buffer.from(compressed, "base64");
|
|
327
|
-
const decompressed =
|
|
328
|
+
const decompressed = brotliDecompressSync(buffer);
|
|
328
329
|
return Buffer.from(decompressed).toString("utf8");
|
|
329
330
|
}
|
|
330
331
|
|
|
@@ -398,9 +399,9 @@ var commandCallSchema = T.Union([T.Null(), T.Object({ name: T.String(), paramete
|
|
|
398
399
|
// src/types/util.ts
|
|
399
400
|
import { Type } from "@sinclair/typebox";
|
|
400
401
|
import { Value as Value2 } from "@sinclair/typebox/value";
|
|
401
|
-
function jsonType(type,
|
|
402
|
+
function jsonType(type, decompress = false) {
|
|
402
403
|
return Type.Transform(Type.String()).Decode((value) => {
|
|
403
|
-
const parsed = JSON.parse(
|
|
404
|
+
const parsed = JSON.parse(decompress ? decompressString(value) : value);
|
|
404
405
|
return Value2.Decode(type, Value2.Default(type, parsed));
|
|
405
406
|
}).Encode((value) => JSON.stringify(value));
|
|
406
407
|
}
|
|
@@ -489,7 +490,9 @@ async function createActionsPlugin(handler, options) {
|
|
|
489
490
|
try {
|
|
490
491
|
const result = await handler(context2);
|
|
491
492
|
core.setOutput("result", result);
|
|
492
|
-
|
|
493
|
+
if (pluginOptions?.returnDataToKernel) {
|
|
494
|
+
await returnDataToKernel(pluginGithubToken, inputs.stateId, result);
|
|
495
|
+
}
|
|
493
496
|
} catch (error) {
|
|
494
497
|
await handleError(context2, pluginOptions, error);
|
|
495
498
|
}
|
|
@@ -587,8 +590,62 @@ function createPlugin(handler, manifest, options) {
|
|
|
587
590
|
});
|
|
588
591
|
return app;
|
|
589
592
|
}
|
|
593
|
+
|
|
594
|
+
// src/markdown.ts
|
|
595
|
+
var VOID_TAGS = /* @__PURE__ */ new Set(["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"]);
|
|
596
|
+
function cleanMarkdown(md, options = {}) {
|
|
597
|
+
const codeBlockRegex = /(```[\s\S]*?```|~~~[\s\S]*?~~~)/g;
|
|
598
|
+
const { tags = [], shouldCollapseEmptyLines = false } = options;
|
|
599
|
+
const segments = [];
|
|
600
|
+
let lastIndex = 0;
|
|
601
|
+
const matches = [...md.matchAll(codeBlockRegex)];
|
|
602
|
+
for (const match of matches) {
|
|
603
|
+
if (match.index > lastIndex) {
|
|
604
|
+
segments.push(processSegment(md.slice(lastIndex, match.index), tags, shouldCollapseEmptyLines));
|
|
605
|
+
}
|
|
606
|
+
segments.push(match[0]);
|
|
607
|
+
lastIndex = match.index + match[0].length;
|
|
608
|
+
}
|
|
609
|
+
if (lastIndex < md.length) {
|
|
610
|
+
segments.push(processSegment(md.slice(lastIndex), tags, shouldCollapseEmptyLines));
|
|
611
|
+
}
|
|
612
|
+
return segments.join("");
|
|
613
|
+
}
|
|
614
|
+
function processSegment(segment, extraTags, shouldCollapseEmptyLines) {
|
|
615
|
+
const inlineCodeRegex = /`[^`]*`/g;
|
|
616
|
+
const inlineCodes = [];
|
|
617
|
+
let s = segment.replace(inlineCodeRegex, (m) => {
|
|
618
|
+
inlineCodes.push(m);
|
|
619
|
+
return `__INLINE_CODE_${inlineCodes.length - 1}__`;
|
|
620
|
+
});
|
|
621
|
+
s = s.replace(/<!--[\s\S]*?-->/g, "");
|
|
622
|
+
for (const raw of extraTags) {
|
|
623
|
+
if (!raw) continue;
|
|
624
|
+
const tag = raw.toLowerCase().trim().replace(/[^\w:-]/g, "");
|
|
625
|
+
if (!tag) continue;
|
|
626
|
+
if (VOID_TAGS.has(tag)) {
|
|
627
|
+
const voidRe = new RegExp(`<${tag}\\b[^>]*\\/?>`, "gi");
|
|
628
|
+
s = s.replace(voidRe, "");
|
|
629
|
+
continue;
|
|
630
|
+
}
|
|
631
|
+
const pairRe = new RegExp(`<${tag}\\b[^>]*>[\\s\\S]*?<\\/${tag}>`, "gi");
|
|
632
|
+
let prev;
|
|
633
|
+
do {
|
|
634
|
+
prev = s;
|
|
635
|
+
s = s.replace(pairRe, "");
|
|
636
|
+
} while (s !== prev);
|
|
637
|
+
const openCloseRe = new RegExp(`<\\/?${tag}\\b[^>]*>`, "gi");
|
|
638
|
+
s = s.replace(openCloseRe, "");
|
|
639
|
+
}
|
|
640
|
+
s = s.replace(/__INLINE_CODE_(\d+)__/g, (str, idx) => inlineCodes[+idx]);
|
|
641
|
+
if (shouldCollapseEmptyLines) {
|
|
642
|
+
s = s.replace(/[ \t]+$/gm, "").replace(/\n{3,}/g, "\n\n");
|
|
643
|
+
}
|
|
644
|
+
return s;
|
|
645
|
+
}
|
|
590
646
|
export {
|
|
591
647
|
CommentHandler,
|
|
648
|
+
cleanMarkdown,
|
|
592
649
|
createActionsPlugin,
|
|
593
650
|
createPlugin
|
|
594
651
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ubiquity-os/plugin-sdk",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"description": "SDK for plugin support.",
|
|
5
5
|
"author": "Ubiquity DAO",
|
|
6
6
|
"license": "MIT",
|
|
@@ -103,7 +103,6 @@
|
|
|
103
103
|
"@octokit/types": "^13.8.0",
|
|
104
104
|
"@octokit/webhooks": "^13.7.4",
|
|
105
105
|
"@ubiquity-os/ubiquity-os-logger": "^1.4.0",
|
|
106
|
-
"brotli": "^1.3.3",
|
|
107
106
|
"dotenv": "^16.4.5",
|
|
108
107
|
"hono": "^4.6.9"
|
|
109
108
|
},
|
|
@@ -119,7 +118,6 @@
|
|
|
119
118
|
"@eslint/js": "^9.14.0",
|
|
120
119
|
"@jest/globals": "^29.7.0",
|
|
121
120
|
"@mswjs/data": "0.16.1",
|
|
122
|
-
"@types/brotli": "^1.3.4",
|
|
123
121
|
"@types/node": "^20.11.19",
|
|
124
122
|
"@ubiquity-os/eslint-plugin-no-empty-strings": "^1.0.3",
|
|
125
123
|
"cross-env": "^7.0.3",
|