@answerable-kit/core 0.1.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 +15 -0
- package/dist/category.d.ts +34 -0
- package/dist/category.d.ts.map +1 -0
- package/dist/category.js +39 -0
- package/dist/category.js.map +1 -0
- package/dist/check.d.ts +83 -0
- package/dist/check.d.ts.map +1 -0
- package/dist/check.js +30 -0
- package/dist/check.js.map +1 -0
- package/dist/errors.d.ts +27 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +40 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/severity.d.ts +18 -0
- package/dist/severity.d.ts.map +1 -0
- package/dist/severity.js +19 -0
- package/dist/severity.js.map +1 -0
- package/dist/url.d.ts +23 -0
- package/dist/url.d.ts.map +1 -0
- package/dist/url.js +36 -0
- package/dist/url.js.map +1 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# @answerable-kit/core
|
|
2
|
+
|
|
3
|
+
Shared types, utilities, and error classes for the [Answerable](https://github.com/Anuj7411/answerable) SEO toolkit.
|
|
4
|
+
|
|
5
|
+
> **Pre-alpha.** This package is a placeholder. Real exports land in Phase 1.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @answerable-kit/core
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## License
|
|
14
|
+
|
|
15
|
+
[MIT](../../LICENSE) © 2026 Anuj Ojha
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* The six audit categories defined in AUDIT-FRAMEWORK.md.
|
|
4
|
+
* Stored as kebab-case for use in config files; the public-facing
|
|
5
|
+
* single-letter prefix (A/B/C/D/E/F) lives on each check's `id`.
|
|
6
|
+
*/
|
|
7
|
+
export declare const CategorySchema: z.ZodEnum<["meta-and-technical", "content-structure", "structured-data", "eeat-and-authority", "offsite-citations", "og-and-social"]>;
|
|
8
|
+
export type Category = z.infer<typeof CategorySchema>;
|
|
9
|
+
/**
|
|
10
|
+
* Maps each category to the single-letter prefix used in check IDs.
|
|
11
|
+
* Example: `B5` → `content-structure`.
|
|
12
|
+
*/
|
|
13
|
+
export declare const CATEGORY_ID_PREFIX: {
|
|
14
|
+
readonly 'meta-and-technical': "A";
|
|
15
|
+
readonly 'content-structure': "B";
|
|
16
|
+
readonly 'structured-data': "C";
|
|
17
|
+
readonly 'eeat-and-authority': "D";
|
|
18
|
+
readonly 'offsite-citations': "E";
|
|
19
|
+
readonly 'og-and-social': "F";
|
|
20
|
+
};
|
|
21
|
+
export type CategoryIdPrefix = (typeof CATEGORY_ID_PREFIX)[Category];
|
|
22
|
+
/**
|
|
23
|
+
* Per-category point budget. Sums to exactly 100.
|
|
24
|
+
* Source: docs/internal/AUDIT-FRAMEWORK.md §1.
|
|
25
|
+
*/
|
|
26
|
+
export declare const CATEGORY_POINT_BUDGET: {
|
|
27
|
+
readonly 'meta-and-technical': 20;
|
|
28
|
+
readonly 'content-structure': 20;
|
|
29
|
+
readonly 'structured-data': 18;
|
|
30
|
+
readonly 'eeat-and-authority': 22;
|
|
31
|
+
readonly 'offsite-citations': 12;
|
|
32
|
+
readonly 'og-and-social': 8;
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=category.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"category.d.ts","sourceRoot":"","sources":["../src/category.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AACH,eAAO,MAAM,cAAc,uIAOzB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;;;;;CAOc,CAAC;AAE9C,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,QAAQ,CAAC,CAAC;AAErE;;;GAGG;AACH,eAAO,MAAM,qBAAqB;;;;;;;CAOW,CAAC"}
|
package/dist/category.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* The six audit categories defined in AUDIT-FRAMEWORK.md.
|
|
4
|
+
* Stored as kebab-case for use in config files; the public-facing
|
|
5
|
+
* single-letter prefix (A/B/C/D/E/F) lives on each check's `id`.
|
|
6
|
+
*/
|
|
7
|
+
export const CategorySchema = z.enum([
|
|
8
|
+
'meta-and-technical',
|
|
9
|
+
'content-structure',
|
|
10
|
+
'structured-data',
|
|
11
|
+
'eeat-and-authority',
|
|
12
|
+
'offsite-citations',
|
|
13
|
+
'og-and-social',
|
|
14
|
+
]);
|
|
15
|
+
/**
|
|
16
|
+
* Maps each category to the single-letter prefix used in check IDs.
|
|
17
|
+
* Example: `B5` → `content-structure`.
|
|
18
|
+
*/
|
|
19
|
+
export const CATEGORY_ID_PREFIX = {
|
|
20
|
+
'meta-and-technical': 'A',
|
|
21
|
+
'content-structure': 'B',
|
|
22
|
+
'structured-data': 'C',
|
|
23
|
+
'eeat-and-authority': 'D',
|
|
24
|
+
'offsite-citations': 'E',
|
|
25
|
+
'og-and-social': 'F',
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Per-category point budget. Sums to exactly 100.
|
|
29
|
+
* Source: docs/internal/AUDIT-FRAMEWORK.md §1.
|
|
30
|
+
*/
|
|
31
|
+
export const CATEGORY_POINT_BUDGET = {
|
|
32
|
+
'meta-and-technical': 20,
|
|
33
|
+
'content-structure': 20,
|
|
34
|
+
'structured-data': 18,
|
|
35
|
+
'eeat-and-authority': 22,
|
|
36
|
+
'offsite-citations': 12,
|
|
37
|
+
'og-and-social': 8,
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=category.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"category.js","sourceRoot":"","sources":["../src/category.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC;IACnC,oBAAoB;IACpB,mBAAmB;IACnB,iBAAiB;IACjB,oBAAoB;IACpB,mBAAmB;IACnB,eAAe;CAChB,CAAC,CAAC;AAGH;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,oBAAoB,EAAE,GAAG;IACzB,mBAAmB,EAAE,GAAG;IACxB,iBAAiB,EAAE,GAAG;IACtB,oBAAoB,EAAE,GAAG;IACzB,mBAAmB,EAAE,GAAG;IACxB,eAAe,EAAE,GAAG;CACuB,CAAC;AAI9C;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,oBAAoB,EAAE,EAAE;IACxB,mBAAmB,EAAE,EAAE;IACvB,iBAAiB,EAAE,EAAE;IACrB,oBAAoB,EAAE,EAAE;IACxB,mBAAmB,EAAE,EAAE;IACvB,eAAe,EAAE,CAAC;CACyB,CAAC"}
|
package/dist/check.d.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { Category } from './category.js';
|
|
2
|
+
import type { Severity } from './severity.js';
|
|
3
|
+
import type { AbsoluteUrl } from './url.js';
|
|
4
|
+
/**
|
|
5
|
+
* Input handed to a check's `run` function by the audit engine.
|
|
6
|
+
*
|
|
7
|
+
* Generic over `TDom` so engines built on different parsers (cheerio,
|
|
8
|
+
* playwright, JSDOM) can supply their own typed handle without forcing
|
|
9
|
+
* `@answerable-kit/core` to depend on a parser.
|
|
10
|
+
*/
|
|
11
|
+
export interface CheckInput<TDom = unknown> {
|
|
12
|
+
readonly url: AbsoluteUrl;
|
|
13
|
+
readonly html: string;
|
|
14
|
+
readonly dom: TDom;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Outcome of a single check run.
|
|
18
|
+
*/
|
|
19
|
+
export interface CheckResult {
|
|
20
|
+
readonly status: 'pass' | 'fail' | 'warn' | 'skip';
|
|
21
|
+
/** Concrete evidence from the page (snippet, count, attribute value). */
|
|
22
|
+
readonly evidence?: string | undefined;
|
|
23
|
+
/** Human-readable next step for the developer. */
|
|
24
|
+
readonly fixRecommendation?: string | undefined;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Context passed to `autoFix` when the engine writes changes back into
|
|
28
|
+
* the user's project. Filled out further as auto-fix capabilities land.
|
|
29
|
+
*/
|
|
30
|
+
export interface ProjectContext {
|
|
31
|
+
readonly cwd: string;
|
|
32
|
+
readonly framework: 'nextjs-app' | 'unknown';
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A single audit check. The full set of 50 checks Phase 1 ships with
|
|
36
|
+
* is enumerated in docs/internal/AUDIT-FRAMEWORK.md.
|
|
37
|
+
*/
|
|
38
|
+
export interface Check<TDom = unknown> {
|
|
39
|
+
/** Stable ID, e.g. `B5`. Part of the public API — never renumbered. */
|
|
40
|
+
readonly id: string;
|
|
41
|
+
readonly category: Category;
|
|
42
|
+
readonly severity: Severity;
|
|
43
|
+
/** Point weight toward the 100-point total. */
|
|
44
|
+
readonly points: number;
|
|
45
|
+
/** One-sentence summary shown in console reports. */
|
|
46
|
+
readonly description: string;
|
|
47
|
+
/** Long-form explanation of why this check matters. */
|
|
48
|
+
readonly rationale: string;
|
|
49
|
+
/** URL to the doc page explaining this check. */
|
|
50
|
+
readonly docsUrl: string;
|
|
51
|
+
/** Runs the check against a parsed page. */
|
|
52
|
+
run: (input: CheckInput<TDom>) => CheckResult | Promise<CheckResult>;
|
|
53
|
+
/** Optional auto-fix that patches the user's project. */
|
|
54
|
+
autoFix?: ((project: ProjectContext) => Promise<void>) | undefined;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Identity helper that gives TypeScript a chance to infer the generic
|
|
58
|
+
* parameter on `Check` and surface type errors at definition time.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* import { defineCheck } from '@answerable-kit/core';
|
|
63
|
+
*
|
|
64
|
+
* export const titlePresent = defineCheck({
|
|
65
|
+
* id: 'A1',
|
|
66
|
+
* category: 'meta-and-technical',
|
|
67
|
+
* severity: 'critical',
|
|
68
|
+
* points: 3,
|
|
69
|
+
* description: '<title> present, 30-60 chars',
|
|
70
|
+
* rationale: 'Search and AI engines surface the title verbatim.',
|
|
71
|
+
* docsUrl: 'https://answerable.dev/docs/checks/A1',
|
|
72
|
+
* run: ({ html }) => {
|
|
73
|
+
* const match = html.match(/<title>([^<]*)<\/title>/i);
|
|
74
|
+
* if (!match) return { status: 'fail', fixRecommendation: 'Add a <title> tag.' };
|
|
75
|
+
* const len = (match[1] ?? '').trim().length;
|
|
76
|
+
* if (len < 30 || len > 60) return { status: 'warn', evidence: `Length: ${len}` };
|
|
77
|
+
* return { status: 'pass' };
|
|
78
|
+
* },
|
|
79
|
+
* });
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export declare function defineCheck<TDom = unknown>(check: Check<TDom>): Check<TDom>;
|
|
83
|
+
//# sourceMappingURL=check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,WAAW,UAAU,CAAC,IAAI,GAAG,OAAO;IACxC,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACnD,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,kDAAkD;IAClD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACjD;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,YAAY,GAAG,SAAS,CAAC;CAC9C;AAED;;;GAGG;AACH,MAAM,WAAW,KAAK,CAAC,IAAI,GAAG,OAAO;IACnC,uEAAuE;IACvE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,+CAA+C;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,uDAAuD;IACvD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,iDAAiD;IACjD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,4CAA4C;IAC5C,GAAG,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACrE,yDAAyD;IACzD,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC;CACpE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,WAAW,CAAC,IAAI,GAAG,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAE3E"}
|
package/dist/check.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity helper that gives TypeScript a chance to infer the generic
|
|
3
|
+
* parameter on `Check` and surface type errors at definition time.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { defineCheck } from '@answerable-kit/core';
|
|
8
|
+
*
|
|
9
|
+
* export const titlePresent = defineCheck({
|
|
10
|
+
* id: 'A1',
|
|
11
|
+
* category: 'meta-and-technical',
|
|
12
|
+
* severity: 'critical',
|
|
13
|
+
* points: 3,
|
|
14
|
+
* description: '<title> present, 30-60 chars',
|
|
15
|
+
* rationale: 'Search and AI engines surface the title verbatim.',
|
|
16
|
+
* docsUrl: 'https://answerable.dev/docs/checks/A1',
|
|
17
|
+
* run: ({ html }) => {
|
|
18
|
+
* const match = html.match(/<title>([^<]*)<\/title>/i);
|
|
19
|
+
* if (!match) return { status: 'fail', fixRecommendation: 'Add a <title> tag.' };
|
|
20
|
+
* const len = (match[1] ?? '').trim().length;
|
|
21
|
+
* if (len < 30 || len > 60) return { status: 'warn', evidence: `Length: ${len}` };
|
|
22
|
+
* return { status: 'pass' };
|
|
23
|
+
* },
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export function defineCheck(check) {
|
|
28
|
+
return check;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AA4DA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,WAAW,CAAiB,KAAkB;IAC5D,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base class for all errors thrown by Answerable packages.
|
|
3
|
+
*
|
|
4
|
+
* Subclasses set a stable `code` string so consumers can branch on error
|
|
5
|
+
* kind without relying on `instanceof` (which breaks across realms /
|
|
6
|
+
* bundler boundaries).
|
|
7
|
+
*/
|
|
8
|
+
export declare class AnswerableError extends Error {
|
|
9
|
+
readonly code: string;
|
|
10
|
+
constructor(code: string, message: string, options?: ErrorOptions);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Thrown when a value that claimed to be a URL fails validation.
|
|
14
|
+
*/
|
|
15
|
+
export declare class InvalidUrlError extends AnswerableError {
|
|
16
|
+
readonly input: string;
|
|
17
|
+
constructor(input: string, reason?: string, options?: ErrorOptions);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Thrown when a schema (zod, JSON-LD, etc.) fails validation.
|
|
21
|
+
* The full list of individual issues is preserved on `issues`.
|
|
22
|
+
*/
|
|
23
|
+
export declare class SchemaValidationError extends AnswerableError {
|
|
24
|
+
readonly issues: readonly string[];
|
|
25
|
+
constructor(issues: readonly string[], options?: ErrorOptions);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAKlE;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,eAAe;IAClD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAEX,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAMnE;AAED;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,eAAe;IACxD,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;gBAEvB,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,YAAY;CAS9D"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base class for all errors thrown by Answerable packages.
|
|
3
|
+
*
|
|
4
|
+
* Subclasses set a stable `code` string so consumers can branch on error
|
|
5
|
+
* kind without relying on `instanceof` (which breaks across realms /
|
|
6
|
+
* bundler boundaries).
|
|
7
|
+
*/
|
|
8
|
+
export class AnswerableError extends Error {
|
|
9
|
+
code;
|
|
10
|
+
constructor(code, message, options) {
|
|
11
|
+
super(message, options);
|
|
12
|
+
this.code = code;
|
|
13
|
+
this.name = 'AnswerableError';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Thrown when a value that claimed to be a URL fails validation.
|
|
18
|
+
*/
|
|
19
|
+
export class InvalidUrlError extends AnswerableError {
|
|
20
|
+
input;
|
|
21
|
+
constructor(input, reason, options) {
|
|
22
|
+
const detail = reason ? `: ${reason}` : '';
|
|
23
|
+
super('ANSWERABLE_INVALID_URL', `Invalid URL "${input}"${detail}`, options);
|
|
24
|
+
this.input = input;
|
|
25
|
+
this.name = 'InvalidUrlError';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Thrown when a schema (zod, JSON-LD, etc.) fails validation.
|
|
30
|
+
* The full list of individual issues is preserved on `issues`.
|
|
31
|
+
*/
|
|
32
|
+
export class SchemaValidationError extends AnswerableError {
|
|
33
|
+
issues;
|
|
34
|
+
constructor(issues, options) {
|
|
35
|
+
super('ANSWERABLE_SCHEMA_VALIDATION', `Schema validation failed:\n - ${issues.join('\n - ')}`, options);
|
|
36
|
+
this.issues = issues;
|
|
37
|
+
this.name = 'SchemaValidationError';
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAC/B,IAAI,CAAS;IAEtB,YAAY,IAAY,EAAE,OAAe,EAAE,OAAsB;QAC/D,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,eAAgB,SAAQ,eAAe;IACzC,KAAK,CAAS;IAEvB,YAAY,KAAa,EAAE,MAAe,EAAE,OAAsB;QAChE,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,KAAK,CAAC,wBAAwB,EAAE,gBAAgB,KAAK,IAAI,MAAM,EAAE,EAAE,OAAO,CAAC,CAAC;QAC5E,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,qBAAsB,SAAQ,eAAe;IAC/C,MAAM,CAAoB;IAEnC,YAAY,MAAyB,EAAE,OAAsB;QAC3D,KAAK,CACH,8BAA8B,EAC9B,kCAAkC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EACzD,OAAO,CACR,CAAC;QACF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACtC,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @answerable-kit/core — shared types, utilities, and error classes
|
|
3
|
+
* used across the Answerable SEO toolkit.
|
|
4
|
+
*/
|
|
5
|
+
export declare const VERSION = "0.0.0";
|
|
6
|
+
export { AnswerableError, InvalidUrlError, SchemaValidationError } from './errors.js';
|
|
7
|
+
export { SEVERITY_ORDER, SeveritySchema, severityRank, type Severity } from './severity.js';
|
|
8
|
+
export { CATEGORY_ID_PREFIX, CATEGORY_POINT_BUDGET, CategorySchema, type Category, type CategoryIdPrefix, } from './category.js';
|
|
9
|
+
export { AbsoluteUrlSchema, parseAbsoluteUrl, tryParseAbsoluteUrl, URLStringSchema, type AbsoluteUrl, type URLString, } from './url.js';
|
|
10
|
+
export { defineCheck, type Check, type CheckInput, type CheckResult, type ProjectContext, } from './check.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEtF,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE5F,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,cAAc,EACd,KAAK,QAAQ,EACb,KAAK,gBAAgB,GACtB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,SAAS,GACf,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,WAAW,EACX,KAAK,KAAK,EACV,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,cAAc,GACpB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @answerable-kit/core — shared types, utilities, and error classes
|
|
3
|
+
* used across the Answerable SEO toolkit.
|
|
4
|
+
*/
|
|
5
|
+
export const VERSION = '0.0.0';
|
|
6
|
+
export { AnswerableError, InvalidUrlError, SchemaValidationError } from './errors.js';
|
|
7
|
+
export { SEVERITY_ORDER, SeveritySchema, severityRank } from './severity.js';
|
|
8
|
+
export { CATEGORY_ID_PREFIX, CATEGORY_POINT_BUDGET, CategorySchema, } from './category.js';
|
|
9
|
+
export { AbsoluteUrlSchema, parseAbsoluteUrl, tryParseAbsoluteUrl, URLStringSchema, } from './url.js';
|
|
10
|
+
export { defineCheck, } from './check.js';
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEtF,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAiB,MAAM,eAAe,CAAC;AAE5F,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,cAAc,GAGf,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,GAGhB,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,WAAW,GAKZ,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* The four severity levels every audit check ships with.
|
|
4
|
+
* Independent of point weight: a low-point check can still be critical.
|
|
5
|
+
*/
|
|
6
|
+
export declare const SeveritySchema: z.ZodEnum<["critical", "high", "medium", "low"]>;
|
|
7
|
+
export type Severity = z.infer<typeof SeveritySchema>;
|
|
8
|
+
/**
|
|
9
|
+
* Severities in descending order of urgency (most severe first).
|
|
10
|
+
* Stable order — relied on by reporters and CI summaries.
|
|
11
|
+
*/
|
|
12
|
+
export declare const SEVERITY_ORDER: readonly Severity[];
|
|
13
|
+
/**
|
|
14
|
+
* Numeric rank for sorting. Lower number = more severe.
|
|
15
|
+
* `critical` → 0, `low` → 3.
|
|
16
|
+
*/
|
|
17
|
+
export declare function severityRank(s: Severity): number;
|
|
18
|
+
//# sourceMappingURL=severity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"severity.d.ts","sourceRoot":"","sources":["../src/severity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,cAAc,kDAAgD,CAAC;AAC5E,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,QAAQ,EAA0C,CAAC;AAEzF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM,CAEhD"}
|
package/dist/severity.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* The four severity levels every audit check ships with.
|
|
4
|
+
* Independent of point weight: a low-point check can still be critical.
|
|
5
|
+
*/
|
|
6
|
+
export const SeveritySchema = z.enum(['critical', 'high', 'medium', 'low']);
|
|
7
|
+
/**
|
|
8
|
+
* Severities in descending order of urgency (most severe first).
|
|
9
|
+
* Stable order — relied on by reporters and CI summaries.
|
|
10
|
+
*/
|
|
11
|
+
export const SEVERITY_ORDER = ['critical', 'high', 'medium', 'low'];
|
|
12
|
+
/**
|
|
13
|
+
* Numeric rank for sorting. Lower number = more severe.
|
|
14
|
+
* `critical` → 0, `low` → 3.
|
|
15
|
+
*/
|
|
16
|
+
export function severityRank(s) {
|
|
17
|
+
return SEVERITY_ORDER.indexOf(s);
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=severity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"severity.js","sourceRoot":"","sources":["../src/severity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;AAG5E;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;AAEzF;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,CAAW;IACtC,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACnC,CAAC"}
|
package/dist/url.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* A URL string that has passed zod's URL validation (any scheme).
|
|
4
|
+
* Branded so `string` literals can't accidentally substitute.
|
|
5
|
+
*/
|
|
6
|
+
export declare const URLStringSchema: z.ZodBranded<z.ZodString, "URLString">;
|
|
7
|
+
export type URLString = z.infer<typeof URLStringSchema>;
|
|
8
|
+
/**
|
|
9
|
+
* An absolute http(s) URL — the strictest form, used wherever Answerable
|
|
10
|
+
* fetches or audits a target site.
|
|
11
|
+
*/
|
|
12
|
+
export declare const AbsoluteUrlSchema: z.ZodBranded<z.ZodEffects<z.ZodString, string, string>, "AbsoluteUrl">;
|
|
13
|
+
export type AbsoluteUrl = z.infer<typeof AbsoluteUrlSchema>;
|
|
14
|
+
/**
|
|
15
|
+
* Parse an input string into an AbsoluteUrl. Throws `InvalidUrlError`
|
|
16
|
+
* on failure with the original zod issue preserved on `.cause`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function parseAbsoluteUrl(input: string): AbsoluteUrl;
|
|
19
|
+
/**
|
|
20
|
+
* Non-throwing variant of `parseAbsoluteUrl`. Returns `null` on failure.
|
|
21
|
+
*/
|
|
22
|
+
export declare function tryParseAbsoluteUrl(input: string): AbsoluteUrl | null;
|
|
23
|
+
//# sourceMappingURL=url.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../src/url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;GAGG;AACH,eAAO,MAAM,eAAe,wCAAwC,CAAC;AACrE,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,wEAIL,CAAC;AAC1B,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAO3D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAGrE"}
|
package/dist/url.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { InvalidUrlError } from './errors.js';
|
|
3
|
+
/**
|
|
4
|
+
* A URL string that has passed zod's URL validation (any scheme).
|
|
5
|
+
* Branded so `string` literals can't accidentally substitute.
|
|
6
|
+
*/
|
|
7
|
+
export const URLStringSchema = z.string().url().brand();
|
|
8
|
+
/**
|
|
9
|
+
* An absolute http(s) URL — the strictest form, used wherever Answerable
|
|
10
|
+
* fetches or audits a target site.
|
|
11
|
+
*/
|
|
12
|
+
export const AbsoluteUrlSchema = z
|
|
13
|
+
.string()
|
|
14
|
+
.url()
|
|
15
|
+
.refine((s) => /^https?:\/\//i.test(s), { message: 'must use http or https' })
|
|
16
|
+
.brand();
|
|
17
|
+
/**
|
|
18
|
+
* Parse an input string into an AbsoluteUrl. Throws `InvalidUrlError`
|
|
19
|
+
* on failure with the original zod issue preserved on `.cause`.
|
|
20
|
+
*/
|
|
21
|
+
export function parseAbsoluteUrl(input) {
|
|
22
|
+
const result = AbsoluteUrlSchema.safeParse(input);
|
|
23
|
+
if (!result.success) {
|
|
24
|
+
const reason = result.error.issues.map((i) => i.message).join('; ');
|
|
25
|
+
throw new InvalidUrlError(input, reason, { cause: result.error });
|
|
26
|
+
}
|
|
27
|
+
return result.data;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Non-throwing variant of `parseAbsoluteUrl`. Returns `null` on failure.
|
|
31
|
+
*/
|
|
32
|
+
export function tryParseAbsoluteUrl(input) {
|
|
33
|
+
const result = AbsoluteUrlSchema.safeParse(input);
|
|
34
|
+
return result.success ? result.data : null;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=url.js.map
|
package/dist/url.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url.js","sourceRoot":"","sources":["../src/url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,EAAe,CAAC;AAGrE;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC;KAC/B,MAAM,EAAE;KACR,GAAG,EAAE;KACL,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,wBAAwB,EAAE,CAAC;KAC7E,KAAK,EAAiB,CAAC;AAG1B;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAClD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpE,MAAM,IAAI,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAClD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7C,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@answerable-kit/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Shared types, utilities, and error classes for the Answerable SEO toolkit.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Anuj Ojha",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/Anuj7411/answerable.git",
|
|
10
|
+
"directory": "packages/core"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/Anuj7411/answerable/tree/main/packages/core#readme",
|
|
13
|
+
"bugs": "https://github.com/Anuj7411/answerable/issues",
|
|
14
|
+
"type": "module",
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"files": ["dist", "README.md"],
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsc -p tsconfig.build.json",
|
|
30
|
+
"test": "vitest run",
|
|
31
|
+
"test:watch": "vitest",
|
|
32
|
+
"typecheck": "tsc --noEmit",
|
|
33
|
+
"clean": "rimraf dist .tsbuildinfo"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"zod": "^3.23.8"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"rimraf": "^6.0.1",
|
|
40
|
+
"typescript": "^5.7.3",
|
|
41
|
+
"vitest": "^3.0.5"
|
|
42
|
+
}
|
|
43
|
+
}
|