@tightknitai/slack-block-kit-validator 0.1.0-alpha.1 → 0.1.7-alpha.1
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 +42 -15
- package/dist/format-ajv-errors.d.ts +26 -0
- package/dist/format-ajv-errors.d.ts.map +1 -0
- package/dist/format-ajv-errors.js +249 -0
- package/dist/format-ajv-errors.js.map +1 -0
- package/dist/helpers/check-response-url-enabled-context.d.ts.map +1 -1
- package/dist/helpers/check-response-url-enabled-context.js +5 -0
- package/dist/helpers/check-response-url-enabled-context.js.map +1 -1
- package/dist/helpers.d.ts +9 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +12 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +1 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -8
- package/dist/index.js.map +1 -1
- package/dist/schema.d.ts +2 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +7 -0
- package/dist/schema.js.map +1 -0
- package/dist/standalone-validator.d.ts +20 -0
- package/dist/standalone-validator.js +18854 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.generated.d.ts +1818 -0
- package/dist/types.generated.d.ts.map +1 -0
- package/dist/types.generated.js +6 -0
- package/dist/types.generated.js.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/validate-block-kit.d.ts.map +1 -1
- package/dist/validate-block-kit.js +30 -6
- package/dist/validate-block-kit.js.map +1 -1
- package/package.json +68 -18
package/README.md
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
# slack-block-kit-validator
|
|
2
2
|
|
|
3
3
|
[](https://github.com/TightknitAI/slack-block-kit-validator/actions/workflows/ci.yml)
|
|
4
|
+
[](https://codecov.io/gh/TightknitAI/slack-block-kit-validator)
|
|
4
5
|
[](https://www.npmjs.com/package/@tightknitai/slack-block-kit-validator)
|
|
6
|
+
[](https://bundlejs.com/?q=%40tightknitai%2Fslack-block-kit-validator)
|
|
7
|
+
[](https://json-schema.org/draft/2020-12/release-notes)
|
|
5
8
|
[](https://opensource.org/licenses/MIT)
|
|
6
9
|
|
|
7
10
|
JSON Schema (draft 2020-12) and validation helpers for Slack Block Kit JSON. Catches invalid block payloads before Slack silently swallows them.
|
|
8
11
|
|
|
12
|
+
**Try it live:** <https://block-kit-validator.tightknit.dev> — paste any payload, see every error in your browser.
|
|
13
|
+
|
|
9
14
|
## Why this exists
|
|
10
15
|
|
|
11
16
|
Slack's API returns `200 OK` when you send malformed Block Kit JSON — the metadata is dropped and the message renders as plain text (or a modal opens blank). The only way to find out is to eyeball a real Slack channel. Slack hasn't open-sourced their validator.
|
|
12
17
|
|
|
13
18
|
This package compiles every rule in <https://docs.slack.dev/reference/block-kit> into a single JSON Schema, plus a handful of helpers for the cross-payload rules JSON Schema can't express (duplicate `block_id`, cumulative markdown length, one-table-per-message, `focus_on_load` uniqueness, surface compatibility).
|
|
14
19
|
|
|
20
|
+
> Prefer an API call or an MCP server over an npm install? The repo also ships a Cloudflare Worker that exposes this package as a public, rate-limited HTTP endpoint plus a remote MCP server — see [`worker/`](./worker).
|
|
21
|
+
|
|
15
22
|
## Install
|
|
16
23
|
|
|
17
24
|
```sh
|
|
@@ -48,7 +55,7 @@ When `target` is `modal` or `home`, the surface-compatibility check is enforced
|
|
|
48
55
|
|
|
49
56
|
```ts
|
|
50
57
|
validateBlockKit(blocks, { surface: "message" });
|
|
51
|
-
// rejects
|
|
58
|
+
// rejects alert/file on messages, markdown/table on modals, etc.
|
|
52
59
|
```
|
|
53
60
|
|
|
54
61
|
### Example output
|
|
@@ -117,7 +124,7 @@ The schema uses `$defs` for every block, element, composition object, rich-text
|
|
|
117
124
|
| `checkCumulativeMarkdownLength` | `(blocks) => string[]` | Sum of all `markdown` block text > 12,000 chars. |
|
|
118
125
|
| `checkSingleTableBlock` | `(blocks) => string[]` | More than one `table` block per payload. |
|
|
119
126
|
| `checkFocusOnLoadUniqueness` | `(blocks) => string[]` | More than one element with `focus_on_load: true` in a view (walks nested elements + accessories). |
|
|
120
|
-
| `checkSurfaceCompatibility` | `(blocks, surface) => string[]` | Blocks not allowed on the target surface (e.g. `
|
|
127
|
+
| `checkSurfaceCompatibility` | `(blocks, surface) => string[]` | Blocks not allowed on the target surface (e.g. `alert` on message, `markdown` on modal, `file_input` outside modals). |
|
|
121
128
|
| `checkCardActionsMax` | `(blocks) => string[]` | More than `CARD_ACTIONS_MAX` action buttons on a card block. |
|
|
122
129
|
| `checkNumberInputBounds` | `(blocks) => string[]` | `number_input` element with `min_value > max_value`. |
|
|
123
130
|
| `checkResponseUrlEnabledContext` | `(blocks, surface?) => string[]` | `response_url_enabled` set in contexts that don't support it. |
|
|
@@ -155,27 +162,47 @@ Server-side rules that need app-config context or deep equality checks the schem
|
|
|
155
162
|
|
|
156
163
|
`validateBlockKit` strips properties whose value is `undefined` before running Ajv. `JSON.stringify` drops these before the payload reaches Slack, so common builder patterns like `value: foo ?? undefined` are no-ops on the wire but would otherwise trip the schema's `additionalProperties: false`. Explicit `null` values are preserved — they survive `JSON.stringify` and may legitimately fail the schema.
|
|
157
164
|
|
|
158
|
-
##
|
|
165
|
+
## Entry points
|
|
159
166
|
|
|
160
|
-
|
|
167
|
+
The package ships several entry points so you only pay for what you use:
|
|
161
168
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
169
|
+
| Entry | Pulls Ajv? | Use when |
|
|
170
|
+
|---|---|---|
|
|
171
|
+
| `@tightknitai/slack-block-kit-validator` | yes | The full wrapper. `validateBlockKit`, helpers, schema, types. |
|
|
172
|
+
| `@tightknitai/slack-block-kit-validator/helpers` | no | Just the pure helpers — compose with Zod, TypeBox, your own validator. |
|
|
173
|
+
| `@tightknitai/slack-block-kit-validator/schema` | no | Just `slackBlockKitSchema` as a JS module. |
|
|
174
|
+
| `@tightknitai/slack-block-kit-validator/schema.json` | no | The raw JSON Schema file (for non-JS consumers). |
|
|
175
|
+
| `@tightknitai/slack-block-kit-validator/standalone` | no — precompiled | Self-contained validators for environments where Ajv is too heavy (Cloudflare Workers, Deno deploy). Exports `validateBlocks`, `validateModal`, `validateHome`. |
|
|
176
|
+
| `@tightknitai/slack-block-kit-validator/types` | no — types only | TypeScript types generated from the schema. `Block`, `SectionBlock`, `ModalView`, etc. |
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
// Worker-friendly: no Ajv at runtime
|
|
180
|
+
import { validateBlocks } from "@tightknitai/slack-block-kit-validator/standalone";
|
|
181
|
+
|
|
182
|
+
// Types straight from the schema (always in sync with what the validator accepts)
|
|
183
|
+
import type { Block, SectionBlock } from "@tightknitai/slack-block-kit-validator/types";
|
|
166
184
|
```
|
|
167
185
|
|
|
186
|
+
## Runtime & bundle considerations
|
|
187
|
+
|
|
188
|
+
The wrapper entry pulls in Ajv v8 + ajv-formats. The standalone entry has no runtime dependencies (its Ajv usage is fully inlined at build time) but is larger as a single bundle.
|
|
189
|
+
|
|
168
190
|
For most apps the recommended pattern is **validate in tests only** — use `validateBlockKit` in unit tests next to your block builders, and let CI catch regressions before they hit production.
|
|
169
191
|
|
|
170
|
-
##
|
|
192
|
+
## Hosted API & MCP
|
|
193
|
+
|
|
194
|
+
For when you'd rather call an endpoint than install the package:
|
|
195
|
+
|
|
196
|
+
- **`POST /v1/validate`** — JSON in / JSON out. Same return shape as `validateBlockKit`. OpenAPI 3.1 spec at `/openapi.json`.
|
|
197
|
+
- **Remote MCP server** — exposes a `validate_block_kit` tool over Streamable HTTP (`/mcp`) and SSE (`/sse`). Connects to Claude Code, Claude Desktop, and other MCP clients.
|
|
198
|
+
|
|
199
|
+
Hosted on Cloudflare Workers, rate-limited per IP via the Workers Rate Limiting binding. Source in [`worker/`](./worker); deployment + MCP client setup in [`worker/README.md`](./worker/README.md). For the interactive UI, the [live playground](https://block-kit-validator.tightknit.dev) covers that.
|
|
200
|
+
|
|
201
|
+
The published npm package is unaffected by the worker — install it directly for production / high-volume use to skip the network hop entirely.
|
|
171
202
|
|
|
172
|
-
|
|
203
|
+
## Contributing
|
|
173
204
|
|
|
174
|
-
|
|
175
|
-
2. Add or amend the relevant `$defs/*` entry, including required / optional / maxLength / enum.
|
|
176
|
-
3. For new top-level blocks, add to `$defs/block.oneOf` and the `modal_view` / `home_view` inner arrays if applicable.
|
|
177
|
-
4. For new elements, add to the relevant parent-container whitelist (`actions_block_element`, `section_accessory_element`, `input_block_element`, `context_block_element`, or `context_actions_block_element`).
|
|
178
|
-
5. Add fixtures to `test/` covering both valid and invalid payloads.
|
|
205
|
+
See [MAINTAINING.md](./MAINTAINING.md) for how to keep the schema in sync with Slack's docs.
|
|
179
206
|
|
|
180
207
|
## License
|
|
181
208
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ErrorObject, ValidateFunction } from "ajv/dist/2020.js";
|
|
2
|
+
/**
|
|
3
|
+
* Look-aside validators keyed by `block.type`. Populated by the caller
|
|
4
|
+
* (validate-block-kit.ts) with one compiled validator per block def, so we
|
|
5
|
+
* can re-validate a misbehaving block against just its discriminator-matched
|
|
6
|
+
* branch and report focused errors instead of the full oneOf cascade.
|
|
7
|
+
*/
|
|
8
|
+
export type FocusValidators = ReadonlyMap<string, ValidateFunction>;
|
|
9
|
+
/**
|
|
10
|
+
* Format AJV errors with normalized paths and friendly per-keyword messages.
|
|
11
|
+
*
|
|
12
|
+
* When a block fails its `oneOf` evaluation, AJV reports a failure against
|
|
13
|
+
* every branch (~80 errors for a single typo). We collapse this by
|
|
14
|
+
* re-validating each offending block against just the schema branch matching
|
|
15
|
+
* its declared `type`, replacing the union noise with the real reason that
|
|
16
|
+
* specific block didn't validate. Blocks whose `type` isn't a recognized block
|
|
17
|
+
* kind fall back to the raw (deduplicated) AJV output.
|
|
18
|
+
*
|
|
19
|
+
* @param errors - the raw `validator.errors` array from AJV
|
|
20
|
+
* @param root - the (normalized) input AJV ran against — used to read each
|
|
21
|
+
* block's `type` so we can pick the focused branch validator
|
|
22
|
+
* @param target - validation target, controls path-normalization rooting
|
|
23
|
+
* @param focusValidators - per-block-type compiled validators
|
|
24
|
+
*/
|
|
25
|
+
export declare function formatAjvErrors(errors: readonly ErrorObject[], root: unknown, target: "blocks" | "modal" | "home", focusValidators: FocusValidators): string[];
|
|
26
|
+
//# sourceMappingURL=format-ajv-errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-ajv-errors.d.ts","sourceRoot":"","sources":["../src/format-ajv-errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAgHtE;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAuDpE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,EACnC,eAAe,EAAE,eAAe,GAC/B,MAAM,EAAE,CAwFV"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a JSON-pointer instancePath into the user-facing `blocks[N].field`
|
|
3
|
+
* path the cross-payload helpers also use. RFC 6901 segment decoding is applied
|
|
4
|
+
* so `~1` / `~0` round-trip correctly.
|
|
5
|
+
*
|
|
6
|
+
* - target = "blocks": root is the blocks array → `/0/text` → `blocks[0].text`
|
|
7
|
+
* - target = "modal"/"home": root is the view → `/blocks/2/element` → `blocks[2].element`
|
|
8
|
+
*/
|
|
9
|
+
const normalizePath = (instancePath, target) => {
|
|
10
|
+
if (!instancePath) {
|
|
11
|
+
return "(root)";
|
|
12
|
+
}
|
|
13
|
+
const segments = instancePath.split("/").slice(1).map(decodePointerSegment);
|
|
14
|
+
if (target === "blocks") {
|
|
15
|
+
if (segments.length === 0) {
|
|
16
|
+
return "(root)";
|
|
17
|
+
}
|
|
18
|
+
const head = segments[0];
|
|
19
|
+
const rest = segments.slice(1);
|
|
20
|
+
const idx = Number(head);
|
|
21
|
+
if (Number.isInteger(idx) && head !== "") {
|
|
22
|
+
return `blocks[${idx}]${formatTail(rest)}`;
|
|
23
|
+
}
|
|
24
|
+
return head + formatTail(rest);
|
|
25
|
+
}
|
|
26
|
+
if (segments.length === 0) {
|
|
27
|
+
return "(root)";
|
|
28
|
+
}
|
|
29
|
+
if (segments[0] === "blocks" && segments.length >= 2) {
|
|
30
|
+
const idx = Number(segments[1]);
|
|
31
|
+
if (Number.isInteger(idx) && segments[1] !== "") {
|
|
32
|
+
return `blocks[${idx}]${formatTail(segments.slice(2))}`;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return segments[0] + formatTail(segments.slice(1));
|
|
36
|
+
};
|
|
37
|
+
const decodePointerSegment = (seg) => seg.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
38
|
+
const formatTail = (rest) => {
|
|
39
|
+
let out = "";
|
|
40
|
+
for (const seg of rest) {
|
|
41
|
+
const idx = Number(seg);
|
|
42
|
+
if (Number.isInteger(idx) && seg !== "") {
|
|
43
|
+
out += `[${idx}]`;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
out += `.${seg}`;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return out;
|
|
50
|
+
};
|
|
51
|
+
const lookupAt = (root, instancePath) => {
|
|
52
|
+
let node = root;
|
|
53
|
+
const segments = instancePath.split("/").slice(1).map(decodePointerSegment);
|
|
54
|
+
for (const seg of segments) {
|
|
55
|
+
if (node == null || typeof node !== "object") {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
if (Array.isArray(node)) {
|
|
59
|
+
const idx = Number(seg);
|
|
60
|
+
if (!Number.isInteger(idx)) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
node = node[idx];
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
node = node[seg];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return node;
|
|
70
|
+
};
|
|
71
|
+
const formatSingle = (err, path) => {
|
|
72
|
+
const params = (err.params ?? {});
|
|
73
|
+
switch (err.keyword) {
|
|
74
|
+
case "required":
|
|
75
|
+
return `${path}: missing required property '${String(params.missingProperty)}'`;
|
|
76
|
+
case "additionalProperties":
|
|
77
|
+
return `${path}: unknown property '${String(params.additionalProperty)}'`;
|
|
78
|
+
case "type":
|
|
79
|
+
return `${path}: expected ${String(params.type)}`;
|
|
80
|
+
case "const":
|
|
81
|
+
return `${path}: expected ${JSON.stringify(params.allowedValue)}`;
|
|
82
|
+
case "enum": {
|
|
83
|
+
const values = Array.isArray(params.allowedValues) ? params.allowedValues : [];
|
|
84
|
+
return `${path}: expected one of [${values.map((v) => JSON.stringify(v)).join(", ")}]`;
|
|
85
|
+
}
|
|
86
|
+
case "maxLength":
|
|
87
|
+
return `${path}: longer than ${String(params.limit)} characters`;
|
|
88
|
+
case "minLength":
|
|
89
|
+
return `${path}: shorter than ${String(params.limit)} characters`;
|
|
90
|
+
case "maxItems":
|
|
91
|
+
return `${path}: more than ${String(params.limit)} items`;
|
|
92
|
+
case "minItems":
|
|
93
|
+
return `${path}: fewer than ${String(params.limit)} items`;
|
|
94
|
+
case "minimum":
|
|
95
|
+
return `${path}: below minimum ${String(params.limit)}`;
|
|
96
|
+
case "maximum":
|
|
97
|
+
return `${path}: above maximum ${String(params.limit)}`;
|
|
98
|
+
case "pattern":
|
|
99
|
+
return `${path}: does not match ${String(params.pattern)}`;
|
|
100
|
+
case "format":
|
|
101
|
+
return `${path}: not a valid ${String(params.format)}`;
|
|
102
|
+
default:
|
|
103
|
+
return `${path}: ${err.message ?? "failed validation"}`;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Identify the canonical block-rooted path (`/N` for bare blocks, `/blocks/N`
|
|
108
|
+
* for views) for an error. Returns null for errors that aren't scoped to a
|
|
109
|
+
* particular block — they're emitted as-is.
|
|
110
|
+
*/
|
|
111
|
+
const blockPathOf = (instancePath, target) => {
|
|
112
|
+
const segs = instancePath.split("/").slice(1);
|
|
113
|
+
if (target === "blocks") {
|
|
114
|
+
if (segs.length >= 1 && Number.isInteger(Number(segs[0])) && segs[0] !== "") {
|
|
115
|
+
return `/${segs[0]}`;
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
if (segs.length >= 2 && segs[0] === "blocks" && Number.isInteger(Number(segs[1])) && segs[1] !== "") {
|
|
120
|
+
return `/blocks/${segs[1]}`;
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Apply umbrella `oneOf`/`anyOf` suppression and emit focused errors with
|
|
126
|
+
* their instancePath rewritten back into the original payload's coordinate
|
|
127
|
+
* space (`bp` is the block's `/N` or `/blocks/N` path). The umbrella keywords
|
|
128
|
+
* are dropped when other errors at the same instancePath (or deeper) are
|
|
129
|
+
* already in the bucket — those underlying errors say everything the umbrella
|
|
130
|
+
* does, with more detail.
|
|
131
|
+
*/
|
|
132
|
+
const META_KEYWORDS = new Set(["oneOf", "anyOf", "if", "not"]);
|
|
133
|
+
const pushFocusedErrors = (focused, bp, target, push) => {
|
|
134
|
+
const detailedPaths = new Set();
|
|
135
|
+
for (const err of focused) {
|
|
136
|
+
if (!META_KEYWORDS.has(err.keyword)) {
|
|
137
|
+
detailedPaths.add(err.instancePath);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
for (const err of focused) {
|
|
141
|
+
if (META_KEYWORDS.has(err.keyword)) {
|
|
142
|
+
const suppress = [...detailedPaths].some((p) => p === err.instancePath || p.startsWith(`${err.instancePath}/`));
|
|
143
|
+
if (suppress) {
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const rewrittenPath = `${bp}${err.instancePath}`;
|
|
148
|
+
push(formatSingle({ ...err, instancePath: rewrittenPath }, normalizePath(rewrittenPath, target)));
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* Format AJV errors with normalized paths and friendly per-keyword messages.
|
|
153
|
+
*
|
|
154
|
+
* When a block fails its `oneOf` evaluation, AJV reports a failure against
|
|
155
|
+
* every branch (~80 errors for a single typo). We collapse this by
|
|
156
|
+
* re-validating each offending block against just the schema branch matching
|
|
157
|
+
* its declared `type`, replacing the union noise with the real reason that
|
|
158
|
+
* specific block didn't validate. Blocks whose `type` isn't a recognized block
|
|
159
|
+
* kind fall back to the raw (deduplicated) AJV output.
|
|
160
|
+
*
|
|
161
|
+
* @param errors - the raw `validator.errors` array from AJV
|
|
162
|
+
* @param root - the (normalized) input AJV ran against — used to read each
|
|
163
|
+
* block's `type` so we can pick the focused branch validator
|
|
164
|
+
* @param target - validation target, controls path-normalization rooting
|
|
165
|
+
* @param focusValidators - per-block-type compiled validators
|
|
166
|
+
*/
|
|
167
|
+
export function formatAjvErrors(errors, root, target, focusValidators) {
|
|
168
|
+
// Group errors by block path so we can replace each block's union cascade
|
|
169
|
+
// with its focused-branch errors. Errors not scoped to a block (e.g. on the
|
|
170
|
+
// root array itself, or on the view's title) are kept as-is.
|
|
171
|
+
const byBlock = new Map();
|
|
172
|
+
const standalone = [];
|
|
173
|
+
for (const err of errors) {
|
|
174
|
+
const bp = blockPathOf(err.instancePath, target);
|
|
175
|
+
if (bp == null) {
|
|
176
|
+
standalone.push(err);
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
let bucket = byBlock.get(bp);
|
|
180
|
+
if (!bucket) {
|
|
181
|
+
bucket = [];
|
|
182
|
+
byBlock.set(bp, bucket);
|
|
183
|
+
}
|
|
184
|
+
bucket.push(err);
|
|
185
|
+
}
|
|
186
|
+
const out = [];
|
|
187
|
+
const seen = new Set();
|
|
188
|
+
const push = (msg) => {
|
|
189
|
+
if (!seen.has(msg)) {
|
|
190
|
+
seen.add(msg);
|
|
191
|
+
out.push(msg);
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
for (const err of standalone) {
|
|
195
|
+
push(formatSingle(err, normalizePath(err.instancePath, target)));
|
|
196
|
+
}
|
|
197
|
+
for (const [bp, bucket] of byBlock) {
|
|
198
|
+
const block = lookupAt(root, bp);
|
|
199
|
+
const blockType = block != null && typeof block === "object" && !Array.isArray(block)
|
|
200
|
+
? block.type
|
|
201
|
+
: undefined;
|
|
202
|
+
const focus = typeof blockType === "string" ? focusValidators.get(blockType) : undefined;
|
|
203
|
+
if (focus) {
|
|
204
|
+
focus(block);
|
|
205
|
+
const focusedErrors = focus.errors ?? [];
|
|
206
|
+
pushFocusedErrors(focusedErrors, bp, target, push);
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
// No focus available — block.type is missing, non-string, or not a known
|
|
210
|
+
// kind. AJV will have emitted dozens of per-branch errors (each branch's
|
|
211
|
+
// const-on-type plus its own required fields). Collapse those into a
|
|
212
|
+
// single useful message keyed on what we know about block.type.
|
|
213
|
+
const blockPath = normalizePath(bp, target);
|
|
214
|
+
if (block != null && typeof block === "object" && !Array.isArray(block) && !("type" in block)) {
|
|
215
|
+
push(`${blockPath}: missing required property 'type'`);
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
if (typeof blockType === "string") {
|
|
219
|
+
// type is a string but isn't one of the 18 kinds we map.
|
|
220
|
+
push(`${blockPath}.type: '${blockType}' is not a recognized block kind`);
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
if (block != null && typeof block === "object" && !Array.isArray(block)) {
|
|
224
|
+
// type is present but the wrong shape.
|
|
225
|
+
const actual = blockType === null ? "null" : typeof blockType;
|
|
226
|
+
push(`${blockPath}.type: expected string, got ${actual}`);
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
// Block itself isn't an object — fall back to whatever shape errors AJV
|
|
230
|
+
// emitted (e.g. "expected object"), but skip meta-keyword umbrellas.
|
|
231
|
+
const concretePaths = new Set();
|
|
232
|
+
for (const err of bucket) {
|
|
233
|
+
if (!META_KEYWORDS.has(err.keyword)) {
|
|
234
|
+
concretePaths.add(err.instancePath);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
for (const err of bucket) {
|
|
238
|
+
if (META_KEYWORDS.has(err.keyword)) {
|
|
239
|
+
const suppress = [...concretePaths].some((p) => p === err.instancePath || p.startsWith(`${err.instancePath}/`));
|
|
240
|
+
if (suppress) {
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
push(formatSingle(err, normalizePath(err.instancePath, target)));
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return out;
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=format-ajv-errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-ajv-errors.js","sourceRoot":"","sources":["../src/format-ajv-errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-response-url-enabled-context.d.ts","sourceRoot":"","sources":["../../src/helpers/check-response-url-enabled-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAEhE,KAAK,UAAU,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AACpE,KAAK,SAAS,GAAG;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;CACzB,CAAC;AAUF;;;;;;;;;;GAUG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"check-response-url-enabled-context.d.ts","sourceRoot":"","sources":["../../src/helpers/check-response-url-enabled-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAEhE,KAAK,UAAU,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AACpE,KAAK,SAAS,GAAG;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;CACzB,CAAC;AAUF;;;;;;;;;;GAUG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,EAAE,CAqCnH"}
|
|
@@ -17,6 +17,11 @@ const hasResponseUrlEnabled = (node) => !!node &&
|
|
|
17
17
|
export function checkResponseUrlEnabledContext(blocks, surface) {
|
|
18
18
|
const errors = [];
|
|
19
19
|
blocks.forEach((block, i) => {
|
|
20
|
+
// Normalization can leave `null` in array slots (matching JSON.stringify
|
|
21
|
+
// semantics) — guard before any property access.
|
|
22
|
+
if (block == null) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
20
25
|
// Section accessory — never a valid host.
|
|
21
26
|
if (hasResponseUrlEnabled(block.accessory)) {
|
|
22
27
|
errors.push(`blocks[${i}].accessory sets response_url_enabled — only valid on select menus inside input blocks in modals`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-response-url-enabled-context.js","sourceRoot":"","sources":["../../src/helpers/check-response-url-enabled-context.ts"],"names":[],"mappings":"AAUA,MAAM,8BAA8B,GAAG,IAAI,GAAG,CAAC,CAAC,sBAAsB,EAAE,iBAAiB,CAAC,CAAC,CAAC;AAE5F,MAAM,qBAAqB,GAAG,CAAC,IAA4B,EAAW,EAAE,CACtE,CAAC,CAAC,IAAI;IACN,IAAI,CAAC,oBAAoB,KAAK,IAAI;IAClC,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;IAC7B,8BAA8B,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEhD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,8BAA8B,CAAC,MAA4B,EAAE,OAA4B;IACvG,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QAC1B,0CAA0C;QAC1C,IAAI,qBAAqB,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3C,MAAM,CAAC,IAAI,CACT,UAAU,CAAC,kGAAkG,CAC9G,CAAC;QACJ,CAAC;QACD,+CAA+C;QAC/C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;gBAC/B,IAAI,qBAAqB,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC9B,MAAM,CAAC,IAAI,CACT,UAAU,CAAC,cAAc,CAAC,wFAAwF,CACnH,CAAC;gBACJ,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QACD,uEAAuE;QACvE,qEAAqE;QACrE,yEAAyE;QACzE,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,qBAAqB,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YAC1F,MAAM,YAAY,GAAG,OAAO,IAAI,aAAa,CAAC;YAC9C,MAAM,CAAC,IAAI,CACT,UAAU,CAAC,mDAAmD,YAAY,mDAAmD,CAC9H,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
1
|
+
{"version":3,"file":"check-response-url-enabled-context.js","sourceRoot":"","sources":["../../src/helpers/check-response-url-enabled-context.ts"],"names":[],"mappings":"AAUA,MAAM,8BAA8B,GAAG,IAAI,GAAG,CAAC,CAAC,sBAAsB,EAAE,iBAAiB,CAAC,CAAC,CAAC;AAE5F,MAAM,qBAAqB,GAAG,CAAC,IAA4B,EAAW,EAAE,CACtE,CAAC,CAAC,IAAI;IACN,IAAI,CAAC,oBAAoB,KAAK,IAAI;IAClC,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;IAC7B,8BAA8B,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEhD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,8BAA8B,CAAC,MAA4B,EAAE,OAA4B;IACvG,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QAC1B,yEAAyE;QACzE,iDAAiD;QACjD,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QACD,0CAA0C;QAC1C,IAAI,qBAAqB,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3C,MAAM,CAAC,IAAI,CACT,UAAU,CAAC,kGAAkG,CAC9G,CAAC;QACJ,CAAC;QACD,+CAA+C;QAC/C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;gBAC/B,IAAI,qBAAqB,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC9B,MAAM,CAAC,IAAI,CACT,UAAU,CAAC,cAAc,CAAC,wFAAwF,CACnH,CAAC;gBACJ,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QACD,uEAAuE;QACvE,qEAAqE;QACrE,yEAAyE;QACzE,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,qBAAqB,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YAC1F,MAAM,YAAY,GAAG,OAAO,IAAI,aAAa,CAAC;YAC9C,MAAM,CAAC,IAAI,CACT,UAAU,CAAC,mDAAmD,YAAY,mDAAmD,CAC9H,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "./helpers/check-card-actions-max.js";
|
|
2
|
+
export * from "./helpers/check-cumulative-markdown-length.js";
|
|
3
|
+
export * from "./helpers/check-focus-on-load-uniqueness.js";
|
|
4
|
+
export * from "./helpers/check-number-input-bounds.js";
|
|
5
|
+
export * from "./helpers/check-response-url-enabled-context.js";
|
|
6
|
+
export * from "./helpers/check-single-table-block.js";
|
|
7
|
+
export * from "./helpers/check-surface-compatibility.js";
|
|
8
|
+
export * from "./helpers/find-duplicate-block-ids.js";
|
|
9
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAIA,cAAc,qCAAqC,CAAC;AACpD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,wCAAwC,CAAC;AACvD,cAAc,iDAAiD,CAAC;AAChE,cAAc,uCAAuC,CAAC;AACtD,cAAc,0CAA0C,CAAC;AACzD,cAAc,uCAAuC,CAAC"}
|
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Pure helper entry point: `@tightknitai/slack-block-kit-validator/helpers`.
|
|
2
|
+
// No Ajv at runtime — these helpers cover the cross-payload rules JSON Schema
|
|
3
|
+
// can't express, and can be composed with any other validator.
|
|
4
|
+
export * from "./helpers/check-card-actions-max.js";
|
|
5
|
+
export * from "./helpers/check-cumulative-markdown-length.js";
|
|
6
|
+
export * from "./helpers/check-focus-on-load-uniqueness.js";
|
|
7
|
+
export * from "./helpers/check-number-input-bounds.js";
|
|
8
|
+
export * from "./helpers/check-response-url-enabled-context.js";
|
|
9
|
+
export * from "./helpers/check-single-table-block.js";
|
|
10
|
+
export * from "./helpers/check-surface-compatibility.js";
|
|
11
|
+
export * from "./helpers/find-duplicate-block-ids.js";
|
|
12
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,8EAA8E;AAC9E,+DAA+D;AAE/D,cAAc,qCAAqC,CAAC;AACpD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,wCAAwC,CAAC;AACvD,cAAc,iDAAiD,CAAC;AAChE,cAAc,uCAAuC,CAAC;AACtD,cAAc,0CAA0C,CAAC;AACzD,cAAc,uCAAuC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
export * from "./helpers
|
|
2
|
-
export * from "./helpers/check-cumulative-markdown-length.js";
|
|
3
|
-
export * from "./helpers/check-focus-on-load-uniqueness.js";
|
|
4
|
-
export * from "./helpers/check-number-input-bounds.js";
|
|
5
|
-
export * from "./helpers/check-response-url-enabled-context.js";
|
|
6
|
-
export * from "./helpers/check-single-table-block.js";
|
|
7
|
-
export * from "./helpers/check-surface-compatibility.js";
|
|
8
|
-
export * from "./helpers/find-duplicate-block-ids.js";
|
|
1
|
+
export * from "./helpers.js";
|
|
9
2
|
export { default as slackBlockKitSchema } from "./slack-block-kit.schema.json";
|
|
10
3
|
export * from "./validate-block-kit.js";
|
|
11
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,+BAA+B,CAAuB;AACrG,cAAc,yBAAyB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export * from "./helpers
|
|
1
|
+
// Default entry point: `@tightknitai/slack-block-kit-validator`.
|
|
2
|
+
// Re-exports the full surface — Ajv-backed wrapper + helpers + raw schema.
|
|
3
|
+
// Tree-shake friendlier alternatives:
|
|
4
|
+
// - `/helpers` (pure helpers, no Ajv)
|
|
5
|
+
// - `/schema` (JSON schema only, no Ajv)
|
|
6
|
+
// - `/standalone` (precompiled validators, no Ajv at runtime)
|
|
7
|
+
// - `/types` (types only, generated from the schema)
|
|
8
|
+
export * from "./helpers.js";
|
|
9
9
|
export { default as slackBlockKitSchema } from "./slack-block-kit.schema.json" with { type: "json" };
|
|
10
10
|
export * from "./validate-block-kit.js";
|
|
11
11
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,2EAA2E;AAC3E,sCAAsC;AACtC,wCAAwC;AACxC,2CAA2C;AAC3C,gEAAgE;AAChE,uDAAuD;AAEvD,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,+BAA+B,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACrG,cAAc,yBAAyB,CAAC"}
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,+BAA+B,CAAuB"}
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Schema-only entry: `@tightknitai/slack-block-kit-validator/schema`.
|
|
2
|
+
// Loads no Ajv runtime — for consumers wiring the schema into their own
|
|
3
|
+
// validator (TypeBox, Zod, another Ajv config, OpenAPI tooling, etc.).
|
|
4
|
+
// For non-JS consumers, the raw JSON is also available at
|
|
5
|
+
// `@tightknitai/slack-block-kit-validator/schema.json`.
|
|
6
|
+
export { default as slackBlockKitSchema } from "./slack-block-kit.schema.json" with { type: "json" };
|
|
7
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,wEAAwE;AACxE,uEAAuE;AACvE,0DAA0D;AAC1D,wDAAwD;AAExD,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,+BAA+B,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// AUTO-GENERATED — DO NOT EDIT BY HAND.
|
|
2
|
+
|
|
3
|
+
export type StandaloneValidateFunction = ((data: unknown) => boolean) & {
|
|
4
|
+
errors?:
|
|
5
|
+
| {
|
|
6
|
+
instancePath: string;
|
|
7
|
+
schemaPath: string;
|
|
8
|
+
keyword: string;
|
|
9
|
+
params: Record<string, unknown>;
|
|
10
|
+
message?: string;
|
|
11
|
+
}[]
|
|
12
|
+
| null;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/** Validates a bare blocks array. */
|
|
16
|
+
export const validateBlocks: StandaloneValidateFunction;
|
|
17
|
+
/** Validates a modal view envelope. */
|
|
18
|
+
export const validateModal: StandaloneValidateFunction;
|
|
19
|
+
/** Validates a home view envelope. */
|
|
20
|
+
export const validateHome: StandaloneValidateFunction;
|