milieu-cli 0.1.0 → 0.1.6
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 +52 -6
- package/dist/bridges/reachability/index.d.ts.map +1 -1
- package/dist/bridges/reachability/index.js +2 -0
- package/dist/bridges/reachability/index.js.map +1 -1
- package/dist/bridges/separation/api-presence.d.ts +6 -5
- package/dist/bridges/separation/api-presence.d.ts.map +1 -1
- package/dist/bridges/separation/api-presence.js +9 -5
- package/dist/bridges/separation/api-presence.js.map +1 -1
- package/dist/bridges/separation/index.d.ts.map +1 -1
- package/dist/bridges/separation/index.js +9 -2
- package/dist/bridges/separation/index.js.map +1 -1
- package/dist/bridges/separation/webhook-support.d.ts +25 -12
- package/dist/bridges/separation/webhook-support.d.ts.map +1 -1
- package/dist/bridges/separation/webhook-support.js +100 -12
- package/dist/bridges/separation/webhook-support.js.map +1 -1
- package/dist/bridges/standards/graphql.d.ts +20 -0
- package/dist/bridges/standards/graphql.d.ts.map +1 -0
- package/dist/bridges/standards/graphql.js +174 -0
- package/dist/bridges/standards/graphql.js.map +1 -0
- package/dist/bridges/standards/index.d.ts +10 -5
- package/dist/bridges/standards/index.d.ts.map +1 -1
- package/dist/bridges/standards/index.js +32 -13
- package/dist/bridges/standards/index.js.map +1 -1
- package/dist/bridges/standards/openapi.d.ts +8 -1
- package/dist/bridges/standards/openapi.d.ts.map +1 -1
- package/dist/bridges/standards/openapi.js +49 -2
- package/dist/bridges/standards/openapi.js.map +1 -1
- package/dist/bridges/standards/sitemap.d.ts +21 -0
- package/dist/bridges/standards/sitemap.d.ts.map +1 -0
- package/dist/bridges/standards/sitemap.js +174 -0
- package/dist/bridges/standards/sitemap.js.map +1 -0
- package/dist/cli/index.js +0 -0
- package/dist/core/explanations.d.ts.map +1 -1
- package/dist/core/explanations.js +14 -2
- package/dist/core/explanations.js.map +1 -1
- package/dist/utils/http-client.d.ts +9 -4
- package/dist/utils/http-client.d.ts.map +1 -1
- package/dist/utils/http-client.js +23 -3
- package/dist/utils/http-client.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -4,6 +4,19 @@ The API is the new product UI. Your customers are no longer just humans. They're
|
|
|
4
4
|
|
|
5
5
|
As an industry, we've spent decades perfecting UI & UX design for humans. Now we need the same rigor for the interface AI agents actually see: your product's **milieu**.
|
|
6
6
|
|
|
7
|
+
## Table of contents
|
|
8
|
+
|
|
9
|
+
- [What is milieu?](#what-is-milieu)
|
|
10
|
+
- [Quick start](#quick-start)
|
|
11
|
+
- [The 5 Bridges](#the-5-bridges)
|
|
12
|
+
- [Install](#install)
|
|
13
|
+
- [CI/CD integration](#cicd-integration)
|
|
14
|
+
- [Options](#options)
|
|
15
|
+
- [How scoring works](#how-scoring-works)
|
|
16
|
+
- [Programmatic API](#programmatic-api)
|
|
17
|
+
- [Requirements](#requirements)
|
|
18
|
+
- [License](#license)
|
|
19
|
+
|
|
7
20
|
## What is milieu?
|
|
8
21
|
|
|
9
22
|
*Milieu* is the totality of machine-readable signals that surround your product — the environment an AI agent encounters when it tries to discover, understand, and integrate with what you've built. It's not any single file or endpoint. It's robots.txt and OpenAPI specs and llms.txt and JSON-LD and developer docs and SDK references, all working together. It's the difference between a product that AI agents can use and one they walk past.
|
|
@@ -13,14 +26,47 @@ Good design made products usable for humans. Good milieu design makes products u
|
|
|
13
26
|
milieu-cli measures this. It scans your site and tells you what AI agents can actually see.
|
|
14
27
|
|
|
15
28
|
```bash
|
|
16
|
-
npx milieu-cli scan
|
|
29
|
+
npx milieu-cli scan petstore.swagger.io
|
|
17
30
|
```
|
|
18
31
|
|
|
19
32
|
```bash
|
|
20
33
|
# Gate your pipeline on agent-readiness
|
|
21
|
-
milieu scan api.
|
|
34
|
+
milieu scan api.example.com --threshold 70
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick start
|
|
38
|
+
|
|
39
|
+
Run your first scan in under a minute:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx milieu-cli scan petstore.swagger.io
|
|
22
43
|
```
|
|
23
44
|
|
|
45
|
+
No config, no API keys. You'll get a scored report showing what AI agents can see when they visit that site.
|
|
46
|
+
|
|
47
|
+
### Example sites to try
|
|
48
|
+
|
|
49
|
+
Each of these exercises different parts of the scanner:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# The classic OpenAPI demo — Swagger spec at a well-known path
|
|
53
|
+
npx milieu-cli scan petstore.swagger.io
|
|
54
|
+
|
|
55
|
+
# Rich structured data — JSON-LD and Schema.org markup
|
|
56
|
+
npx milieu-cli scan schema.org
|
|
57
|
+
|
|
58
|
+
# Minimal API service — clean reachability, few standards signals
|
|
59
|
+
npx milieu-cli scan httpbin.org
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Add `--verbose` to any scan to see individual check results and explanations:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx milieu-cli scan petstore.swagger.io --verbose
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Once you've seen how these score, scan your own site and compare.
|
|
69
|
+
|
|
24
70
|
## The 5 Bridges
|
|
25
71
|
|
|
26
72
|
Milieu evaluates your product through five progressive bridges. Each one represents a layer of machine legibility that AI agents need, from "can I reach you?" to "can I trust you?"
|
|
@@ -57,9 +103,9 @@ Each policy is checked individually — you might be allowing Googlebot but bloc
|
|
|
57
103
|
## Install
|
|
58
104
|
|
|
59
105
|
```bash
|
|
60
|
-
npx milieu-cli scan
|
|
61
|
-
npm install -g milieu-cli
|
|
62
|
-
milieu scan
|
|
106
|
+
npx milieu-cli scan petstore.swagger.io # one-off, no install
|
|
107
|
+
npm install -g milieu-cli # global install
|
|
108
|
+
milieu scan petstore.swagger.io # short alias after install
|
|
63
109
|
```
|
|
64
110
|
|
|
65
111
|
> Both `milieu` and `milieu-cli` work as commands after global install.
|
|
@@ -121,7 +167,7 @@ const options: ScanOptions = {
|
|
|
121
167
|
silent: true, // suppress spinner output (recommended for library use)
|
|
122
168
|
};
|
|
123
169
|
|
|
124
|
-
const result = await scan("https://
|
|
170
|
+
const result = await scan("https://petstore.swagger.io", options);
|
|
125
171
|
|
|
126
172
|
console.log(result.overallScore); // number (average of scored bridges)
|
|
127
173
|
console.log(result.overallScoreLabel); // "pass" | "partial" | "fail"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bridges/reachability/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAS,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAyC5E;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bridges/reachability/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAS,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAyC5E;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,YAAY,CAAC,CA2FvB"}
|
|
@@ -70,6 +70,8 @@ export async function runReachabilityBridge(ctx) {
|
|
|
70
70
|
const httpStatusCheck = checkHttpStatus(pageResponse);
|
|
71
71
|
// 4. robots.txt fetch + parse
|
|
72
72
|
const robotsResult = await checkRobotsTxt(ctx.domain, ctx.options.timeout);
|
|
73
|
+
// Store sitemap URLs for Bridge 2 consumption
|
|
74
|
+
ctx.shared.robotsSitemaps = robotsResult.parsed?.sitemaps ?? [];
|
|
73
75
|
// 5. Crawler policies (uses parsed robots.txt data)
|
|
74
76
|
let targetPath;
|
|
75
77
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/bridges/reachability/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/bridges/reachability/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEpE;;;;GAIG;AACH,SAAS,cAAc,CAAC,MAAe;IAIrC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,8EAA8E;QAC9E,IACE,KAAK,CAAC,IAAI;YACT,KAAK,CAAC,IAAgC,CAAC,MAAM,KAAK,MAAM,EACzD,CAAC;YACD,SAAS;QACX,CAAC;QAED,SAAS,IAAI,CAAC,CAAC;QACf,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM;YAAE,MAAM,IAAI,CAAC,CAAC;aACpC,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;YAAE,MAAM,IAAI,GAAG,CAAC;QACnD,4BAA4B;IAC9B,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC;IAC3E,MAAM,UAAU,GACd,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;IAC1D,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AAC/B,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,GAAgB;IAEhB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAEhC,gCAAgC;IAChC,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtE,8BAA8B;IAC9B,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO;YACL,EAAE,EAAE,CAAC;YACL,IAAI,EAAE,cAAc;YACpB,MAAM,EAAE,WAAW;YACnB,KAAK,EAAE,CAAC;YACR,UAAU,EAAE,MAAM;YAClB,MAAM,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC;YAC3B,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;YACjD,KAAK,EAAE,IAAI;YACX,WAAW,EAAE,WAAW,CAAC,WAAW;SACrC,CAAC;IACJ,CAAC;IAED,wCAAwC;IACxC,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE;QAC9C,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO;KAC7B,CAAC,CAAC;IAEH,gEAAgE;IAChE,IAAI,YAAY,CAAC,EAAE,EAAE,CAAC;QACpB,GAAG,CAAC,MAAM,CAAC,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC;QACxC,GAAG,CAAC,MAAM,CAAC,WAAW,GAAG,YAAY,CAAC,OAAO,CAAC;IAChD,CAAC;IAED,2DAA2D;IAC3D,MAAM,eAAe,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC;IAEtD,8BAA8B;IAC9B,MAAM,YAAY,GAAG,MAAM,cAAc,CACvC,GAAG,CAAC,MAAM,EACV,GAAG,CAAC,OAAO,CAAC,OAAO,CACpB,CAAC;IAEF,8CAA8C;IAC9C,GAAG,CAAC,MAAM,CAAC,cAAc,GAAG,YAAY,CAAC,MAAM,EAAE,QAAQ,IAAI,EAAE,CAAC;IAEhE,oDAAoD;IACpD,IAAI,UAAkB,CAAC;IACvB,IAAI,CAAC;QACH,UAAU,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,UAAU,GAAG,GAAG,CAAC;IACnB,CAAC;IACD,MAAM,aAAa,GAAG,uBAAuB,CAC3C,YAAY,CAAC,MAAM,EACnB,UAAU,CACX,CAAC;IAEF,sCAAsC;IACtC,IAAI,eAAsB,CAAC;IAC3B,IAAI,YAAmB,CAAC;IAExB,IAAI,YAAY,CAAC,EAAE,EAAE,CAAC;QACpB,eAAe,GAAG,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACrD,YAAY,GAAG,eAAe,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC;SAAM,CAAC;QACN,8EAA8E;QAC9E,eAAe,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;QACtC,YAAY,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;IACrC,CAAC;IAED,wBAAwB;IACxB,MAAM,MAAM,GAAY;QACtB,WAAW,CAAC,KAAK;QACjB,eAAe;QACf,YAAY,CAAC,KAAK;QAClB,GAAG,aAAa;QAChB,eAAe;QACf,YAAY;KACb,CAAC;IAEF,qBAAqB;IACrB,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAErD,OAAO;QACL,EAAE,EAAE,CAAC;QACL,IAAI,EAAE,cAAc;QACpB,MAAM,EAAE,WAAW;QACnB,KAAK;QACL,UAAU;QACV,MAAM;QACN,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;KAClD,CAAC;AACJ,CAAC"}
|
|
@@ -2,13 +2,14 @@ import type { Check, ContentSource } from "../../core/types.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* Detect API presence via multiple signals across content sources.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Five signal sources:
|
|
6
6
|
* 1. OpenAPI spec detected by Bridge 2 (boolean from ctx.shared.openApiDetected)
|
|
7
|
-
* 2.
|
|
8
|
-
* 3.
|
|
9
|
-
* 4.
|
|
7
|
+
* 2. GraphQL endpoint detected by Bridge 2 (boolean from ctx.shared.graphqlDetected)
|
|
8
|
+
* 3. API-related response headers (X-RateLimit-*, X-Request-Id, etc.)
|
|
9
|
+
* 4. HTML links containing /api/ paths (scanned from all content sources)
|
|
10
|
+
* 5. Markdown links containing /api/ paths (scanned from all content sources)
|
|
10
11
|
*
|
|
11
12
|
* Pure function -- no HTTP calls.
|
|
12
13
|
*/
|
|
13
|
-
export declare function checkApiPresence(openApiDetected: boolean, sources: ContentSource[], headers: Record<string, string
|
|
14
|
+
export declare function checkApiPresence(openApiDetected: boolean, sources: ContentSource[], headers: Record<string, string>, graphqlDetected?: boolean): Check;
|
|
14
15
|
//# sourceMappingURL=api-presence.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-presence.d.ts","sourceRoot":"","sources":["../../../src/bridges/separation/api-presence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AA8ChE
|
|
1
|
+
{"version":3,"file":"api-presence.d.ts","sourceRoot":"","sources":["../../../src/bridges/separation/api-presence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AA8ChE;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,eAAe,EAAE,OAAO,EACxB,OAAO,EAAE,aAAa,EAAE,EACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,eAAe,UAAQ,GACtB,KAAK,CA6CP"}
|
|
@@ -44,21 +44,25 @@ function scanApiLinksMarkdown(text) {
|
|
|
44
44
|
/**
|
|
45
45
|
* Detect API presence via multiple signals across content sources.
|
|
46
46
|
*
|
|
47
|
-
*
|
|
47
|
+
* Five signal sources:
|
|
48
48
|
* 1. OpenAPI spec detected by Bridge 2 (boolean from ctx.shared.openApiDetected)
|
|
49
|
-
* 2.
|
|
50
|
-
* 3.
|
|
51
|
-
* 4.
|
|
49
|
+
* 2. GraphQL endpoint detected by Bridge 2 (boolean from ctx.shared.graphqlDetected)
|
|
50
|
+
* 3. API-related response headers (X-RateLimit-*, X-Request-Id, etc.)
|
|
51
|
+
* 4. HTML links containing /api/ paths (scanned from all content sources)
|
|
52
|
+
* 5. Markdown links containing /api/ paths (scanned from all content sources)
|
|
52
53
|
*
|
|
53
54
|
* Pure function -- no HTTP calls.
|
|
54
55
|
*/
|
|
55
|
-
export function checkApiPresence(openApiDetected, sources, headers) {
|
|
56
|
+
export function checkApiPresence(openApiDetected, sources, headers, graphqlDetected = false) {
|
|
56
57
|
const id = "api_presence";
|
|
57
58
|
const label = "API Presence";
|
|
58
59
|
const signals = [];
|
|
59
60
|
// Signal 1: OpenAPI spec detected by Bridge 2
|
|
60
61
|
if (openApiDetected)
|
|
61
62
|
signals.push("OpenAPI spec");
|
|
63
|
+
// Signal 2: GraphQL endpoint detected by Bridge 2
|
|
64
|
+
if (graphqlDetected)
|
|
65
|
+
signals.push("GraphQL endpoint");
|
|
62
66
|
// Signal 2: API-related response headers
|
|
63
67
|
const apiHeaders = API_HEADERS.filter((h) => headers[h] !== undefined);
|
|
64
68
|
if (apiHeaders.length > 0)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-presence.js","sourceRoot":"","sources":["../../../src/bridges/separation/api-presence.ts"],"names":[],"mappings":"AAEA,gEAAgE;AAChE,MAAM,WAAW,GAAG;IAClB,mBAAmB;IACnB,uBAAuB;IACvB,mBAAmB;IACnB,cAAc;IACd,WAAW;IACX,eAAe;IACf,iBAAiB;IACjB,qBAAqB;IACrB,iBAAiB;CAClB,CAAC;AAEF;;;;GAIG;AACH,SAAS,YAAY,CAAC,IAAY;IAChC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,yDAAyD,CAAC;IACxE,IAAI,KAA6B,CAAC;IAClC,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAAC,IAAY;IACxC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,8CAA8C,CAAC;IAC7D,IAAI,KAA6B,CAAC;IAClC,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"api-presence.js","sourceRoot":"","sources":["../../../src/bridges/separation/api-presence.ts"],"names":[],"mappings":"AAEA,gEAAgE;AAChE,MAAM,WAAW,GAAG;IAClB,mBAAmB;IACnB,uBAAuB;IACvB,mBAAmB;IACnB,cAAc;IACd,WAAW;IACX,eAAe;IACf,iBAAiB;IACjB,qBAAqB;IACrB,iBAAiB;CAClB,CAAC;AAEF;;;;GAIG;AACH,SAAS,YAAY,CAAC,IAAY;IAChC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,yDAAyD,CAAC;IACxE,IAAI,KAA6B,CAAC;IAClC,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAAC,IAAY;IACxC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,8CAA8C,CAAC;IAC7D,IAAI,KAA6B,CAAC;IAClC,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAC9B,eAAwB,EACxB,OAAwB,EACxB,OAA+B,EAC/B,eAAe,GAAG,KAAK;IAEvB,MAAM,EAAE,GAAG,cAAc,CAAC;IAC1B,MAAM,KAAK,GAAG,cAAc,CAAC;IAE7B,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,8CAA8C;IAC9C,IAAI,eAAe;QAAE,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAElD,kDAAkD;IAClD,IAAI,eAAe;QAAE,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAEtD,yCAAyC;IACzC,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;IACvE,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,gBAAgB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEzD,6DAA6D;IAC7D,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,OAAO,EAAE,CAAC;QAClC,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;YACzC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpD,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAEzD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO;YACL,EAAE;YACF,KAAK;YACL,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,kCAAkC;SAC3C,CAAC;IACJ,CAAC;IAED,OAAO;QACL,EAAE;QACF,KAAK;QACL,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,0BAA0B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACtD,IAAI,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE;KACxC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bridges/separation/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAwB,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAM3F;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bridges/separation/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAwB,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAM3F;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,YAAY,CAAC,CA0DvB"}
|
|
@@ -25,6 +25,9 @@ export async function runSeparationBridge(ctx) {
|
|
|
25
25
|
const pageBody = ctx.shared.pageBody ?? "";
|
|
26
26
|
const pageHeaders = ctx.shared.pageHeaders ?? {};
|
|
27
27
|
const openApiDetected = ctx.shared.openApiDetected ?? false;
|
|
28
|
+
const openApiHasWebhooks = ctx.shared.openApiHasWebhooks ?? false;
|
|
29
|
+
const openApiHasCallbacks = ctx.shared.openApiHasCallbacks ?? false;
|
|
30
|
+
const graphqlDetected = ctx.shared.graphqlDetected ?? false;
|
|
28
31
|
const llmsTxtBody = ctx.shared.llmsTxtBody ?? null;
|
|
29
32
|
// Fire async developer docs probe first (non-blocking)
|
|
30
33
|
const devDocsPromise = checkDeveloperDocs(ctx.baseUrl, pageBody, ctx.options.timeout);
|
|
@@ -40,9 +43,13 @@ export async function runSeparationBridge(ctx) {
|
|
|
40
43
|
contentSources.push({ content: llmsTxtBody, source: "llms.txt" });
|
|
41
44
|
contentSources.push(...devDocsResult.pages);
|
|
42
45
|
// Run 3 synchronous pure-function checks with assembled content sources
|
|
43
|
-
const apiPresenceCheck = checkApiPresence(openApiDetected, contentSources, pageHeaders);
|
|
46
|
+
const apiPresenceCheck = checkApiPresence(openApiDetected, contentSources, pageHeaders, graphqlDetected);
|
|
44
47
|
const sdkRefsCheck = checkSdkReferences(contentSources);
|
|
45
|
-
const webhookCheck = checkWebhookSupport(contentSources
|
|
48
|
+
const webhookCheck = checkWebhookSupport(contentSources, {
|
|
49
|
+
pageHeaders,
|
|
50
|
+
openApiHasWebhooks,
|
|
51
|
+
openApiHasCallbacks,
|
|
52
|
+
});
|
|
46
53
|
// Assemble checks array in order
|
|
47
54
|
const checks = [
|
|
48
55
|
apiPresenceCheck,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/bridges/separation/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAgB;IAEhB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAEhC,4CAA4C;IAC5C,MAAM,QAAQ,GAAI,GAAG,CAAC,MAAM,CAAC,QAAmB,IAAI,EAAE,CAAC;IACvD,MAAM,WAAW,GACd,GAAG,CAAC,MAAM,CAAC,WAAsC,IAAI,EAAE,CAAC;IAC3D,MAAM,eAAe,GAAI,GAAG,CAAC,MAAM,CAAC,eAA2B,IAAI,KAAK,CAAC;IACzE,MAAM,WAAW,GAAI,GAAG,CAAC,MAAM,CAAC,WAAkC,IAAI,IAAI,CAAC;IAE3E,uDAAuD;IACvD,MAAM,cAAc,GAAG,kBAAkB,CACvC,GAAG,CAAC,OAAO,EACX,QAAQ,EACR,GAAG,CAAC,OAAO,CAAC,OAAO,CACpB,CAAC;IAEF,qDAAqD;IACrD,MAAM,aAAa,GAAG,MAAM,cAAc,CAAC;IAE3C,gEAAgE;IAChE,GAAG,CAAC,MAAM,CAAC,aAAa,GAAG,aAAa,CAAC,KAAK,CAAC;IAE/C,qDAAqD;IACrD,MAAM,cAAc,GAAoB,EAAE,CAAC;IAC3C,IAAI,QAAQ;QAAE,cAAc,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IAC7E,IAAI,WAAW;QAAE,cAAc,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IACnF,cAAc,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAE5C,wEAAwE;IACxE,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,eAAe,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/bridges/separation/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAgB;IAEhB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAEhC,4CAA4C;IAC5C,MAAM,QAAQ,GAAI,GAAG,CAAC,MAAM,CAAC,QAAmB,IAAI,EAAE,CAAC;IACvD,MAAM,WAAW,GACd,GAAG,CAAC,MAAM,CAAC,WAAsC,IAAI,EAAE,CAAC;IAC3D,MAAM,eAAe,GAAI,GAAG,CAAC,MAAM,CAAC,eAA2B,IAAI,KAAK,CAAC;IACzE,MAAM,kBAAkB,GAAI,GAAG,CAAC,MAAM,CAAC,kBAA8B,IAAI,KAAK,CAAC;IAC/E,MAAM,mBAAmB,GAAI,GAAG,CAAC,MAAM,CAAC,mBAA+B,IAAI,KAAK,CAAC;IACjF,MAAM,eAAe,GAAI,GAAG,CAAC,MAAM,CAAC,eAA2B,IAAI,KAAK,CAAC;IACzE,MAAM,WAAW,GAAI,GAAG,CAAC,MAAM,CAAC,WAAkC,IAAI,IAAI,CAAC;IAE3E,uDAAuD;IACvD,MAAM,cAAc,GAAG,kBAAkB,CACvC,GAAG,CAAC,OAAO,EACX,QAAQ,EACR,GAAG,CAAC,OAAO,CAAC,OAAO,CACpB,CAAC;IAEF,qDAAqD;IACrD,MAAM,aAAa,GAAG,MAAM,cAAc,CAAC;IAE3C,gEAAgE;IAChE,GAAG,CAAC,MAAM,CAAC,aAAa,GAAG,aAAa,CAAC,KAAK,CAAC;IAE/C,qDAAqD;IACrD,MAAM,cAAc,GAAoB,EAAE,CAAC;IAC3C,IAAI,QAAQ;QAAE,cAAc,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IAC7E,IAAI,WAAW;QAAE,cAAc,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IACnF,cAAc,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAE5C,wEAAwE;IACxE,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,eAAe,EAAE,cAAc,EAAE,WAAW,EAAE,eAAe,CAAC,CAAC;IACzG,MAAM,YAAY,GAAG,kBAAkB,CAAC,cAAc,CAAC,CAAC;IACxD,MAAM,YAAY,GAAG,mBAAmB,CAAC,cAAc,EAAE;QACvD,WAAW;QACX,kBAAkB;QAClB,mBAAmB;KACpB,CAAC,CAAC;IAEH,iCAAiC;IACjC,MAAM,MAAM,GAAY;QACtB,gBAAgB;QAChB,aAAa,CAAC,KAAK;QACnB,YAAY;QACZ,YAAY;KACb,CAAC;IAEF,OAAO;QACL,EAAE,EAAE,CAAC;QACL,IAAI,EAAE,YAAY;QAClB,MAAM,EAAE,WAAW;QACnB,KAAK,EAAE,IAAI;QACX,UAAU,EAAE,IAAI;QAChB,MAAM;QACN,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;KAClD,CAAC;AACJ,CAAC"}
|
|
@@ -1,19 +1,32 @@
|
|
|
1
1
|
import type { Check, ContentSource } from "../../core/types.js";
|
|
2
|
+
/** Structured signals passed from upstream bridges */
|
|
3
|
+
export interface WebhookDetectionOptions {
|
|
4
|
+
/** HTTP response headers from the homepage (for WebSub rel="hub") */
|
|
5
|
+
pageHeaders?: Record<string, string>;
|
|
6
|
+
/** OpenAPI 3.1+ top-level `webhooks` key detected in spec */
|
|
7
|
+
openApiHasWebhooks?: boolean;
|
|
8
|
+
/** OpenAPI 3.0+ `callbacks` detected in any spec operation */
|
|
9
|
+
openApiHasCallbacks?: boolean;
|
|
10
|
+
}
|
|
2
11
|
/**
|
|
3
|
-
* Detect webhook support signals
|
|
12
|
+
* Detect webhook support signals using tiered detection:
|
|
4
13
|
*
|
|
5
|
-
*
|
|
6
|
-
* 1
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* 4. Markdown links containing "webhook"
|
|
10
|
-
* 5. Markdown headings containing "webhook"
|
|
11
|
-
* 6. URL paths containing "webhook" in structured data (JSON state, JS config)
|
|
14
|
+
* **Tier 1 (high confidence):** Structured specs
|
|
15
|
+
* - OpenAPI 3.1+ `webhooks` key
|
|
16
|
+
* - OpenAPI 3.0+ `callbacks` in operations
|
|
17
|
+
* - WebSub `rel="hub"` in HTML `<link>` or HTTP Link header
|
|
12
18
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
19
|
+
* **Tier 2 (medium confidence):** Standard-compliant behavioral signals
|
|
20
|
+
* - Standard Webhooks headers (webhook-id, webhook-timestamp, webhook-signature)
|
|
21
|
+
* - Standard Webhooks secret prefix (whsec_)
|
|
22
|
+
* - CloudEvents webhook headers (WebHook-Request-Origin, WebHook-Allowed-Origin)
|
|
15
23
|
*
|
|
16
|
-
*
|
|
24
|
+
* **Tier 3 (low confidence):** Keyword heuristics
|
|
25
|
+
* - HTML links, headings, and link text containing "webhook"
|
|
26
|
+
* - Markdown links and headings containing "webhook"
|
|
27
|
+
* - URL paths containing "webhook" in JSON/JS structured data
|
|
28
|
+
*
|
|
29
|
+
* Pure function — no HTTP calls.
|
|
17
30
|
*/
|
|
18
|
-
export declare function checkWebhookSupport(sources: ContentSource[]): Check;
|
|
31
|
+
export declare function checkWebhookSupport(sources: ContentSource[], options?: WebhookDetectionOptions): Check;
|
|
19
32
|
//# sourceMappingURL=webhook-support.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhook-support.d.ts","sourceRoot":"","sources":["../../../src/bridges/separation/webhook-support.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"webhook-support.d.ts","sourceRoot":"","sources":["../../../src/bridges/separation/webhook-support.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAMhE,sDAAsD;AACtD,MAAM,WAAW,uBAAuB;IACtC,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,6DAA6D;IAC7D,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,8DAA8D;IAC9D,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AA2ED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,aAAa,EAAE,EACxB,OAAO,GAAE,uBAA4B,GACpC,KAAK,CAsHP"}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Tier 3: Keyword heuristic patterns (low confidence)
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
1
4
|
/** HTML patterns for webhook detection */
|
|
2
5
|
const HTML_PATTERNS = [
|
|
3
6
|
{
|
|
@@ -23,27 +26,111 @@ const STRUCTURED_PATTERNS = [
|
|
|
23
26
|
// Matches "/path/webhooks" or "\\u002Fpath\\u002Fwebhooks" in JSON/JS
|
|
24
27
|
{ pattern: /["'](?:\/|\\u002[Ff])[^"']*webhook[^"']*["']/gi, signal: "webhook path" },
|
|
25
28
|
];
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Tier 2: Standard-compliant behavioral patterns (medium confidence)
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
/** Patterns for Standard Webhooks and CloudEvents header references in content */
|
|
33
|
+
const BEHAVIORAL_PATTERNS = [
|
|
34
|
+
// Standard Webhooks headers (https://standardwebhooks.com)
|
|
35
|
+
{ pattern: /webhook-id/i, signal: "standard webhooks headers" },
|
|
36
|
+
{ pattern: /webhook-timestamp/i, signal: "standard webhooks headers" },
|
|
37
|
+
{ pattern: /webhook-signature/i, signal: "standard webhooks headers" },
|
|
38
|
+
{ pattern: /whsec_/i, signal: "standard webhooks secret" },
|
|
39
|
+
// CloudEvents HTTP Webhook headers (https://github.com/cloudevents/spec)
|
|
40
|
+
{ pattern: /WebHook-Request-Origin/i, signal: "cloudevents webhook" },
|
|
41
|
+
{ pattern: /WebHook-Allowed-Origin/i, signal: "cloudevents webhook" },
|
|
42
|
+
];
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// Tier 1 helpers: WebSub discovery
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
/**
|
|
47
|
+
* Check for WebSub hub discovery in HTML content.
|
|
48
|
+
* Looks for `<link rel="hub" href="...">`.
|
|
49
|
+
*/
|
|
50
|
+
function detectWebSubInHtml(html) {
|
|
51
|
+
return /<link\s[^>]*rel=["']hub["'][^>]*>/i.test(html);
|
|
52
|
+
}
|
|
26
53
|
/**
|
|
27
|
-
*
|
|
54
|
+
* Check for WebSub hub discovery in HTTP Link headers.
|
|
55
|
+
* Looks for `Link: <url>; rel="hub"`.
|
|
56
|
+
*/
|
|
57
|
+
function detectWebSubInHeaders(headers) {
|
|
58
|
+
const linkHeader = headers["link"] ?? "";
|
|
59
|
+
return /rel=["']?hub["']?/i.test(linkHeader);
|
|
60
|
+
}
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
// Public API
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
/**
|
|
65
|
+
* Detect webhook support signals using tiered detection:
|
|
66
|
+
*
|
|
67
|
+
* **Tier 1 (high confidence):** Structured specs
|
|
68
|
+
* - OpenAPI 3.1+ `webhooks` key
|
|
69
|
+
* - OpenAPI 3.0+ `callbacks` in operations
|
|
70
|
+
* - WebSub `rel="hub"` in HTML `<link>` or HTTP Link header
|
|
28
71
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* 4. Markdown links containing "webhook"
|
|
34
|
-
* 5. Markdown headings containing "webhook"
|
|
35
|
-
* 6. URL paths containing "webhook" in structured data (JSON state, JS config)
|
|
72
|
+
* **Tier 2 (medium confidence):** Standard-compliant behavioral signals
|
|
73
|
+
* - Standard Webhooks headers (webhook-id, webhook-timestamp, webhook-signature)
|
|
74
|
+
* - Standard Webhooks secret prefix (whsec_)
|
|
75
|
+
* - CloudEvents webhook headers (WebHook-Request-Origin, WebHook-Allowed-Origin)
|
|
36
76
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
77
|
+
* **Tier 3 (low confidence):** Keyword heuristics
|
|
78
|
+
* - HTML links, headings, and link text containing "webhook"
|
|
79
|
+
* - Markdown links and headings containing "webhook"
|
|
80
|
+
* - URL paths containing "webhook" in JSON/JS structured data
|
|
39
81
|
*
|
|
40
|
-
* Pure function
|
|
82
|
+
* Pure function — no HTTP calls.
|
|
41
83
|
*/
|
|
42
|
-
export function checkWebhookSupport(sources) {
|
|
84
|
+
export function checkWebhookSupport(sources, options = {}) {
|
|
43
85
|
const id = "webhook_support";
|
|
44
86
|
const label = "Webhook Support";
|
|
45
87
|
const signals = [];
|
|
46
88
|
const signalSources = [];
|
|
89
|
+
// --- Tier 1: Structured specs (high confidence) ---
|
|
90
|
+
if (options.openApiHasWebhooks) {
|
|
91
|
+
signals.push("openapi webhooks");
|
|
92
|
+
if (!signalSources.includes("openapi spec")) {
|
|
93
|
+
signalSources.push("openapi spec");
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (options.openApiHasCallbacks) {
|
|
97
|
+
signals.push("openapi callbacks");
|
|
98
|
+
if (!signalSources.includes("openapi spec")) {
|
|
99
|
+
signalSources.push("openapi spec");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// WebSub: check HTML content sources and HTTP headers
|
|
103
|
+
if (options.pageHeaders && detectWebSubInHeaders(options.pageHeaders)) {
|
|
104
|
+
signals.push("websub hub");
|
|
105
|
+
if (!signalSources.includes("http headers")) {
|
|
106
|
+
signalSources.push("http headers");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
for (const { content, source } of sources) {
|
|
110
|
+
if (detectWebSubInHtml(content)) {
|
|
111
|
+
if (!signals.includes("websub hub")) {
|
|
112
|
+
signals.push("websub hub");
|
|
113
|
+
}
|
|
114
|
+
if (!signalSources.includes(source)) {
|
|
115
|
+
signalSources.push(source);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// --- Tier 2: Behavioral patterns (medium confidence) ---
|
|
120
|
+
for (const { content, source } of sources) {
|
|
121
|
+
let sourceContributed = false;
|
|
122
|
+
for (const { pattern, signal } of BEHAVIORAL_PATTERNS) {
|
|
123
|
+
pattern.lastIndex = 0;
|
|
124
|
+
if (!signals.includes(signal) && pattern.test(content)) {
|
|
125
|
+
signals.push(signal);
|
|
126
|
+
sourceContributed = true;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (sourceContributed && !signalSources.includes(source)) {
|
|
130
|
+
signalSources.push(source);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// --- Tier 3: Keyword heuristics (low confidence) ---
|
|
47
134
|
for (const { content, source } of sources) {
|
|
48
135
|
let sourceContributed = false;
|
|
49
136
|
// HTML patterns
|
|
@@ -74,6 +161,7 @@ export function checkWebhookSupport(sources) {
|
|
|
74
161
|
signalSources.push(source);
|
|
75
162
|
}
|
|
76
163
|
}
|
|
164
|
+
// --- Result ---
|
|
77
165
|
if (signals.length === 0) {
|
|
78
166
|
return {
|
|
79
167
|
id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhook-support.js","sourceRoot":"","sources":["../../../src/bridges/separation/webhook-support.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"webhook-support.js","sourceRoot":"","sources":["../../../src/bridges/separation/webhook-support.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Check } from "../../core/types.js";
|
|
2
|
+
export interface GraphqlResult {
|
|
3
|
+
check: Check;
|
|
4
|
+
detected: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Probe common GraphQL endpoint paths via POST introspection query.
|
|
8
|
+
*
|
|
9
|
+
* Detection strategy per path:
|
|
10
|
+
* 1. POST introspection query with Content-Type: application/json
|
|
11
|
+
* 2. Parse response:
|
|
12
|
+
* - pass: 200 + valid __schema in response
|
|
13
|
+
* - partial: 200 + errors mentioning "introspection" (disabled)
|
|
14
|
+
* - partial: 401/403 (auth required)
|
|
15
|
+
* - skip: 404, non-JSON, connection error
|
|
16
|
+
*
|
|
17
|
+
* Returns early on first successful detection (highest confidence first).
|
|
18
|
+
*/
|
|
19
|
+
export declare function checkGraphql(baseUrl: string, timeout?: number): Promise<GraphqlResult>;
|
|
20
|
+
//# sourceMappingURL=graphql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphql.d.ts","sourceRoot":"","sources":["../../../src/bridges/standards/graphql.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAOjD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB;AAgFD;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,aAAa,CAAC,CA4GxB"}
|