@coldtea/pr-lens-schema 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/LICENSE +21 -0
- package/README.md +150 -0
- package/dist/apply.d.ts +42 -0
- package/dist/apply.d.ts.map +1 -0
- package/dist/apply.js +315 -0
- package/dist/apply.js.map +1 -0
- package/dist/config.d.ts +58 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +61 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +24 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +12 -0
- package/dist/errors.js.map +1 -0
- package/dist/examples/baseline.d.ts +18 -0
- package/dist/examples/baseline.d.ts.map +1 -0
- package/dist/examples/baseline.js +433 -0
- package/dist/examples/baseline.js.map +1 -0
- package/dist/examples/index.d.ts +1194 -0
- package/dist/examples/index.d.ts.map +1 -0
- package/dist/examples/index.js +20 -0
- package/dist/examples/index.js.map +1 -0
- package/dist/examples/minimal.d.ts +4 -0
- package/dist/examples/minimal.d.ts.map +1 -0
- package/dist/examples/minimal.js +25 -0
- package/dist/examples/minimal.js.map +1 -0
- package/dist/examples/postmark-refactor.d.ts +16 -0
- package/dist/examples/postmark-refactor.d.ts.map +1 -0
- package/dist/examples/postmark-refactor.js +468 -0
- package/dist/examples/postmark-refactor.js.map +1 -0
- package/dist/graph.d.ts +568 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +266 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/integrity.d.ts +20 -0
- package/dist/integrity.d.ts.map +1 -0
- package/dist/integrity.js +167 -0
- package/dist/integrity.js.map +1 -0
- package/dist/manifest.d.ts +65 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +60 -0
- package/dist/manifest.js.map +1 -0
- package/dist/patch.d.ts +824 -0
- package/dist/patch.d.ts.map +1 -0
- package/dist/patch.js +84 -0
- package/dist/patch.js.map +1 -0
- package/dist/primitives.d.ts +92 -0
- package/dist/primitives.d.ts.map +1 -0
- package/dist/primitives.js +120 -0
- package/dist/primitives.js.map +1 -0
- package/dist/utils.d.ts +6 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +8 -0
- package/dist/utils.js.map +1 -0
- package/dist/validate.d.ts +18 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +95 -0
- package/dist/validate.js.map +1 -0
- package/dist/version.d.ts +21 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +24 -0
- package/dist/version.js.map +1 -0
- package/examples/broadcast-baseline.graph.json +289 -0
- package/examples/broadcast-baseline.patch.json +321 -0
- package/examples/minimal.graph.json +45 -0
- package/examples/postmark-refactor.graph.json +580 -0
- package/examples/postmark-refactor.render-manifest.json +67 -0
- package/examples/pr-lens.config.json +32 -0
- package/json-schema/config.schema.json +153 -0
- package/json-schema/graph-doc.schema.json +1032 -0
- package/json-schema/patch-doc.schema.json +1383 -0
- package/json-schema/render-manifest.schema.json +183 -0
- package/package.json +66 -0
- package/src/apply.ts +399 -0
- package/src/config.ts +69 -0
- package/src/errors.ts +34 -0
- package/src/examples/baseline.ts +437 -0
- package/src/examples/index.ts +25 -0
- package/src/examples/minimal.ts +26 -0
- package/src/examples/postmark-refactor.ts +480 -0
- package/src/graph.ts +331 -0
- package/src/index.ts +82 -0
- package/src/integrity.ts +216 -0
- package/src/manifest.ts +64 -0
- package/src/patch.ts +100 -0
- package/src/primitives.ts +146 -0
- package/src/utils.ts +7 -0
- package/src/validate.ts +132 -0
- package/src/version.ts +31 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch.d.ts","sourceRoot":"","sources":["../src/patch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;GAKG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;kBAAoC,CAAC;AAC3D,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAyC,CAAC;AAChE,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAyC,CAAC;AAChE,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAoC,CAAC;AAE3D;;;;;;;GAOG;AACH,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAoBsC,CAAC;AAC3D,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAC;AAE9C,eAAO,MAAM,SAAS,YACpB,UAAU,EACV,aAAa,EACb,aAAa,EACb,UAAU,EACV,aAAa,EACb,aAAa,EACb,UAAU,EACV,aAAa,EACb,aAAa,EACb,UAAU,EACV,aAAa,EACb,aAAa,EACb,WAAW,CACH,CAAC;AAEX;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,WAAY;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf,KAAG,OAA0C,CAAC;AAE/C,+DAA+D;AAC/D,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAqBmB,CAAC;AACzC,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC;AAChD,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC"}
|
package/dist/patch.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { Flow, GraphEdge, GraphNode, Lane, Stats } from "./graph.js";
|
|
3
|
+
import { FullSha, Id, SchemaVersionField, Summary } from "./primitives.js";
|
|
4
|
+
/**
|
|
5
|
+
* Update payloads are the element minus its id: a patch never renames the
|
|
6
|
+
* thing it addresses. Every field is optional and only the supplied fields
|
|
7
|
+
* are written, so two producers can patch different facets of one element
|
|
8
|
+
* without clobbering each other.
|
|
9
|
+
*/
|
|
10
|
+
export const LanePatch = Lane.omit({ id: true }).partial();
|
|
11
|
+
export const NodePatch = GraphNode.omit({ id: true }).partial();
|
|
12
|
+
export const EdgePatch = GraphEdge.omit({ id: true }).partial();
|
|
13
|
+
export const FlowPatch = Flow.omit({ id: true }).partial();
|
|
14
|
+
/**
|
|
15
|
+
* Operations that evolve a stored graph — in practice the baseline map, which
|
|
16
|
+
* is updated by each merged pull request rather than re-extracted wholesale.
|
|
17
|
+
*
|
|
18
|
+
* `remove_*` deletes the element from the map. That is a different statement
|
|
19
|
+
* from `delta: "removed"`, which says an element still exists in the map but
|
|
20
|
+
* is being deleted by the change under review.
|
|
21
|
+
*/
|
|
22
|
+
export const PatchOp = z
|
|
23
|
+
.discriminatedUnion("op", [
|
|
24
|
+
z.strictObject({ op: z.literal("add_lane"), lane: Lane }),
|
|
25
|
+
z.strictObject({ op: z.literal("update_lane"), id: Id, patch: LanePatch }),
|
|
26
|
+
z.strictObject({ op: z.literal("remove_lane"), id: Id }),
|
|
27
|
+
z.strictObject({ op: z.literal("add_node"), node: GraphNode }),
|
|
28
|
+
z.strictObject({ op: z.literal("update_node"), id: Id, patch: NodePatch }),
|
|
29
|
+
z.strictObject({ op: z.literal("remove_node"), id: Id }),
|
|
30
|
+
z.strictObject({ op: z.literal("add_edge"), edge: GraphEdge }),
|
|
31
|
+
z.strictObject({ op: z.literal("update_edge"), id: Id, patch: EdgePatch }),
|
|
32
|
+
z.strictObject({ op: z.literal("remove_edge"), id: Id }),
|
|
33
|
+
z.strictObject({ op: z.literal("add_flow"), flow: Flow }),
|
|
34
|
+
z.strictObject({ op: z.literal("update_flow"), id: Id, patch: FlowPatch }),
|
|
35
|
+
z.strictObject({ op: z.literal("remove_flow"), id: Id }),
|
|
36
|
+
z.strictObject({ op: z.literal("set_stats"), stats: Stats }),
|
|
37
|
+
])
|
|
38
|
+
.describe("A single change to a stored graph document.");
|
|
39
|
+
export const PATCH_OPS = [
|
|
40
|
+
"add_lane",
|
|
41
|
+
"update_lane",
|
|
42
|
+
"remove_lane",
|
|
43
|
+
"add_node",
|
|
44
|
+
"update_node",
|
|
45
|
+
"remove_node",
|
|
46
|
+
"add_edge",
|
|
47
|
+
"update_edge",
|
|
48
|
+
"remove_edge",
|
|
49
|
+
"add_flow",
|
|
50
|
+
"update_flow",
|
|
51
|
+
"remove_flow",
|
|
52
|
+
"set_stats",
|
|
53
|
+
];
|
|
54
|
+
/**
|
|
55
|
+
* A patch has to move the map: the same commit at both ends describes no
|
|
56
|
+
* transition, and such a patch could be applied over and over.
|
|
57
|
+
*
|
|
58
|
+
* The rule lives here as a predicate because a zod refinement does not
|
|
59
|
+
* survive into the inferred type — a caller holding a `PatchDoc` it built
|
|
60
|
+
* itself has to be held to the same rule as one that came from a parser.
|
|
61
|
+
*/
|
|
62
|
+
export const targetDescribesATransition = (target) => target.fromSha !== target.toSha;
|
|
63
|
+
/** An ordered batch of operations against one stored graph. */
|
|
64
|
+
export const PatchDoc = z
|
|
65
|
+
.strictObject({
|
|
66
|
+
schemaVersion: SchemaVersionField,
|
|
67
|
+
kind: z.literal("patch"),
|
|
68
|
+
generatedAt: z.iso.datetime().optional(),
|
|
69
|
+
summary: Summary.optional().describe("Why the map is changing, in prose."),
|
|
70
|
+
target: z
|
|
71
|
+
.strictObject({
|
|
72
|
+
graphId: Id.describe("Id of the stored graph being patched."),
|
|
73
|
+
fromSha: FullSha.describe("Commit the stored graph reflects before the operations run."),
|
|
74
|
+
toSha: FullSha.describe("Commit it reflects once they have."),
|
|
75
|
+
})
|
|
76
|
+
.refine(targetDescribesATransition, {
|
|
77
|
+
message: "a patch has to move the map to a different commit",
|
|
78
|
+
path: ["toSha"],
|
|
79
|
+
})
|
|
80
|
+
.describe("Which stored graph these operations belong to, and which commits they carry it between. All three are required, and the commits must differ: they are what stops a patch landing on the wrong map, on a stale one, or twice."),
|
|
81
|
+
ops: z.array(PatchOp).min(1).max(512).describe("Applied in array order."),
|
|
82
|
+
})
|
|
83
|
+
.describe("A PR Lens patch document.");
|
|
84
|
+
//# sourceMappingURL=patch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch.js","sourceRoot":"","sources":["../src/patch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Identifiers are authored by an extraction model, so they are constrained to
|
|
4
|
+
* a shape that survives being embedded in an SVG id, a URL fragment and a
|
|
5
|
+
* GitHub comment anchor without escaping.
|
|
6
|
+
*/
|
|
7
|
+
export declare const Id: z.ZodString;
|
|
8
|
+
export type Id = z.infer<typeof Id>;
|
|
9
|
+
/**
|
|
10
|
+
* The loose shape is checked here and the supported range is checked by the
|
|
11
|
+
* parser, which can say which version it implements. The exported JSON
|
|
12
|
+
* Schemas carry the range instead, since they have no parser behind them.
|
|
13
|
+
*/
|
|
14
|
+
export declare const SchemaVersionField: z.ZodString;
|
|
15
|
+
/** Non-empty single-line label rendered on a card, lane header or edge. */
|
|
16
|
+
export declare const Label: z.ZodString;
|
|
17
|
+
/** Prose shown in drill-down bodies; kept short enough to stay scannable. */
|
|
18
|
+
export declare const Summary: z.ZodString;
|
|
19
|
+
export declare const Sha: z.ZodString;
|
|
20
|
+
/**
|
|
21
|
+
* Abbreviations are fine for something a human reads, but not for deciding
|
|
22
|
+
* whether two records mean the same commit: two abbreviations of different
|
|
23
|
+
* lengths compare unequal, and a short one can collide as a repository grows.
|
|
24
|
+
* Anything a machine compares uses the full name.
|
|
25
|
+
*/
|
|
26
|
+
export declare const FullSha: z.ZodString;
|
|
27
|
+
/**
|
|
28
|
+
* The two lenses PR Lens ships. The enum is additive: a future contract
|
|
29
|
+
* version may introduce further lenses, and consumers must treat an unknown
|
|
30
|
+
* lens as "skip this view" rather than as a hard failure.
|
|
31
|
+
*/
|
|
32
|
+
export declare const Lens: z.ZodEnum<{
|
|
33
|
+
architecture: "architecture";
|
|
34
|
+
"data-flow": "data-flow";
|
|
35
|
+
}>;
|
|
36
|
+
export type Lens = z.infer<typeof Lens>;
|
|
37
|
+
export declare const LENSES: ("architecture" | "data-flow")[];
|
|
38
|
+
/** The two renders that make a `<picture>` pair. */
|
|
39
|
+
export declare const Theme: z.ZodEnum<{
|
|
40
|
+
dark: "dark";
|
|
41
|
+
light: "light";
|
|
42
|
+
}>;
|
|
43
|
+
export type Theme = z.infer<typeof Theme>;
|
|
44
|
+
export declare const THEMES: ("dark" | "light")[];
|
|
45
|
+
/**
|
|
46
|
+
* A render is one asset per view per theme, so these two caps are one rule
|
|
47
|
+
* rather than two numbers that happen to sit near each other: a document with
|
|
48
|
+
* more views than a manifest can carry at every theme is one whose full
|
|
49
|
+
* render could never be described, however well formed it looks.
|
|
50
|
+
*
|
|
51
|
+
* Deriving the view cap from the asset budget keeps the relationship in one
|
|
52
|
+
* place — raise the budget, or add a theme, and the other end moves with it
|
|
53
|
+
* instead of every surface rediscovering the arithmetic.
|
|
54
|
+
*
|
|
55
|
+
* The cap is deliberately the worst case, every theme rendered, rather than
|
|
56
|
+
* what some particular render would emit. A renderer asked for one theme
|
|
57
|
+
* could describe twice as many views, but then whether a document is
|
|
58
|
+
* renderable would depend on how it was asked to be rendered, and the promise
|
|
59
|
+
* this package exists to make — if it parses, it renders — would need a
|
|
60
|
+
* second rule at a second boundary to stay true.
|
|
61
|
+
*/
|
|
62
|
+
export declare const MAX_RENDER_ASSETS = 256;
|
|
63
|
+
export declare const MAX_VIEWS: number;
|
|
64
|
+
/**
|
|
65
|
+
* How an element relates to the base branch. `unchanged` elements are the
|
|
66
|
+
* context a reader needs to judge blast radius, so they are first-class
|
|
67
|
+
* rather than omitted.
|
|
68
|
+
*/
|
|
69
|
+
export declare const Delta: z.ZodEnum<{
|
|
70
|
+
added: "added";
|
|
71
|
+
modified: "modified";
|
|
72
|
+
removed: "removed";
|
|
73
|
+
unchanged: "unchanged";
|
|
74
|
+
}>;
|
|
75
|
+
export type Delta = z.infer<typeof Delta>;
|
|
76
|
+
export declare const DELTAS: ("added" | "modified" | "removed" | "unchanged")[];
|
|
77
|
+
/**
|
|
78
|
+
* A pointer into the head tree, used to build diff permalinks. Line numbers
|
|
79
|
+
* are 1-based and refer to the head revision except on `removed` elements,
|
|
80
|
+
* where they refer to the base revision.
|
|
81
|
+
*/
|
|
82
|
+
export declare const FileRef: z.ZodObject<{
|
|
83
|
+
path: z.ZodString;
|
|
84
|
+
startLine: z.ZodOptional<z.ZodInt>;
|
|
85
|
+
endLine: z.ZodOptional<z.ZodInt>;
|
|
86
|
+
revision: z.ZodOptional<z.ZodEnum<{
|
|
87
|
+
base: "base";
|
|
88
|
+
head: "head";
|
|
89
|
+
}>>;
|
|
90
|
+
}, z.core.$strict>;
|
|
91
|
+
export type FileRef = z.infer<typeof FileRef>;
|
|
92
|
+
//# sourceMappingURL=primitives.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../src/primitives.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;GAIG;AACH,eAAO,MAAM,EAAE,aAQ8D,CAAC;AAC9E,MAAM,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;AAEpC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,aAIkD,CAAC;AAElF,2EAA2E;AAC3E,eAAO,MAAM,KAAK,aAA8D,CAAC;AAEjF,6EAA6E;AAC7E,eAAO,MAAM,OAAO,aAIqD,CAAC;AAE1E,eAAO,MAAM,GAAG,aAGmC,CAAC;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,OAAO,aAGmB,CAAC;AAExC;;;;GAIG;AACH,eAAO,MAAM,IAAI;;;EAAoE,CAAC;AACtF,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;AAExC,eAAO,MAAM,MAAM,kCAAe,CAAC;AAEnC,oDAAoD;AACpD,eAAO,MAAM,KAAK;;;EAA8E,CAAC;AACjG,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,CAAC;AAE1C,eAAO,MAAM,MAAM,sBAAgB,CAAC;AAEpC;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC,eAAO,MAAM,SAAS,QAAoC,CAAC;AAE3D;;;;GAIG;AACH,eAAO,MAAM,KAAK;;;;;EAEsC,CAAC;AACzD,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,CAAC;AAE1C,eAAO,MAAM,MAAM,oDAAgB,CAAC;AASpC;;;;GAIG;AACH,eAAO,MAAM,OAAO;;;;;;;;kBA2B+C,CAAC;AACpE,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { SCHEMA_VERSION, SUPPORTED_VERSION_PATTERN } from "./version.js";
|
|
3
|
+
/**
|
|
4
|
+
* Identifiers are authored by an extraction model, so they are constrained to
|
|
5
|
+
* a shape that survives being embedded in an SVG id, a URL fragment and a
|
|
6
|
+
* GitHub comment anchor without escaping.
|
|
7
|
+
*/
|
|
8
|
+
export const Id = z
|
|
9
|
+
.string()
|
|
10
|
+
.min(1)
|
|
11
|
+
.max(128)
|
|
12
|
+
.regex(/^[A-Za-z0-9][A-Za-z0-9._:/-]*$/, "must start alphanumeric and contain only letters, digits and . _ : / -")
|
|
13
|
+
.describe("Stable identifier, unique within its collection in a document.");
|
|
14
|
+
/**
|
|
15
|
+
* The loose shape is checked here and the supported range is checked by the
|
|
16
|
+
* parser, which can say which version it implements. The exported JSON
|
|
17
|
+
* Schemas carry the range instead, since they have no parser behind them.
|
|
18
|
+
*/
|
|
19
|
+
export const SchemaVersionField = z
|
|
20
|
+
.string()
|
|
21
|
+
.regex(/^\d+\.\d+\.\d+$/, "must be a semver string, e.g. 0.1.0")
|
|
22
|
+
.meta({ pattern: SUPPORTED_VERSION_PATTERN })
|
|
23
|
+
.describe(`Contract version the document targets. Current: ${SCHEMA_VERSION}.`);
|
|
24
|
+
/** Non-empty single-line label rendered on a card, lane header or edge. */
|
|
25
|
+
export const Label = z.string().min(1).max(120).describe("Short display label.");
|
|
26
|
+
/** Prose shown in drill-down bodies; kept short enough to stay scannable. */
|
|
27
|
+
export const Summary = z
|
|
28
|
+
.string()
|
|
29
|
+
.min(1)
|
|
30
|
+
.max(2000)
|
|
31
|
+
.describe("One or two sentences of plain prose. No markdown headings.");
|
|
32
|
+
export const Sha = z
|
|
33
|
+
.string()
|
|
34
|
+
.regex(/^[0-9a-f]{7,40}$/, "must be a lowercase hex git object name")
|
|
35
|
+
.describe("Git commit sha, abbreviated or full.");
|
|
36
|
+
/**
|
|
37
|
+
* Abbreviations are fine for something a human reads, but not for deciding
|
|
38
|
+
* whether two records mean the same commit: two abbreviations of different
|
|
39
|
+
* lengths compare unequal, and a short one can collide as a repository grows.
|
|
40
|
+
* Anything a machine compares uses the full name.
|
|
41
|
+
*/
|
|
42
|
+
export const FullSha = z
|
|
43
|
+
.string()
|
|
44
|
+
.regex(/^[0-9a-f]{40}$/, "must be a full 40-character lowercase hex git object name")
|
|
45
|
+
.describe("Git commit sha, in full.");
|
|
46
|
+
/**
|
|
47
|
+
* The two lenses PR Lens ships. The enum is additive: a future contract
|
|
48
|
+
* version may introduce further lenses, and consumers must treat an unknown
|
|
49
|
+
* lens as "skip this view" rather than as a hard failure.
|
|
50
|
+
*/
|
|
51
|
+
export const Lens = z.enum(["architecture", "data-flow"]).describe("Rendering lens.");
|
|
52
|
+
export const LENSES = Lens.options;
|
|
53
|
+
/** The two renders that make a `<picture>` pair. */
|
|
54
|
+
export const Theme = z.enum(["light", "dark"]).describe("Which colour scheme a render targets.");
|
|
55
|
+
export const THEMES = Theme.options;
|
|
56
|
+
/**
|
|
57
|
+
* A render is one asset per view per theme, so these two caps are one rule
|
|
58
|
+
* rather than two numbers that happen to sit near each other: a document with
|
|
59
|
+
* more views than a manifest can carry at every theme is one whose full
|
|
60
|
+
* render could never be described, however well formed it looks.
|
|
61
|
+
*
|
|
62
|
+
* Deriving the view cap from the asset budget keeps the relationship in one
|
|
63
|
+
* place — raise the budget, or add a theme, and the other end moves with it
|
|
64
|
+
* instead of every surface rediscovering the arithmetic.
|
|
65
|
+
*
|
|
66
|
+
* The cap is deliberately the worst case, every theme rendered, rather than
|
|
67
|
+
* what some particular render would emit. A renderer asked for one theme
|
|
68
|
+
* could describe twice as many views, but then whether a document is
|
|
69
|
+
* renderable would depend on how it was asked to be rendered, and the promise
|
|
70
|
+
* this package exists to make — if it parses, it renders — would need a
|
|
71
|
+
* second rule at a second boundary to stay true.
|
|
72
|
+
*/
|
|
73
|
+
export const MAX_RENDER_ASSETS = 256;
|
|
74
|
+
export const MAX_VIEWS = MAX_RENDER_ASSETS / THEMES.length;
|
|
75
|
+
/**
|
|
76
|
+
* How an element relates to the base branch. `unchanged` elements are the
|
|
77
|
+
* context a reader needs to judge blast radius, so they are first-class
|
|
78
|
+
* rather than omitted.
|
|
79
|
+
*/
|
|
80
|
+
export const Delta = z
|
|
81
|
+
.enum(["added", "modified", "removed", "unchanged"])
|
|
82
|
+
.describe("Change state relative to the base commit.");
|
|
83
|
+
export const DELTAS = Delta.options;
|
|
84
|
+
/**
|
|
85
|
+
* One rule both representations share: no absolute path in any spelling a
|
|
86
|
+
* platform recognises, and no `..` segment. A path that breaks it cannot
|
|
87
|
+
* produce a diff permalink, whatever else it might mean.
|
|
88
|
+
*/
|
|
89
|
+
const REPOSITORY_PATH = /^(?!\/)(?![A-Za-z]:)(?!.*\\)(?!.*(?:^|\/)\.\.(?:\/|$)).+$/;
|
|
90
|
+
/**
|
|
91
|
+
* A pointer into the head tree, used to build diff permalinks. Line numbers
|
|
92
|
+
* are 1-based and refer to the head revision except on `removed` elements,
|
|
93
|
+
* where they refer to the base revision.
|
|
94
|
+
*/
|
|
95
|
+
export const FileRef = z
|
|
96
|
+
.strictObject({
|
|
97
|
+
path: z
|
|
98
|
+
.string()
|
|
99
|
+
.min(1)
|
|
100
|
+
.max(1024)
|
|
101
|
+
.regex(REPOSITORY_PATH, "must be a repository-relative POSIX path, without a drive letter, a backslash or a '..' segment")
|
|
102
|
+
.describe("Repository-relative path, POSIX separators."),
|
|
103
|
+
startLine: z.int().min(1).optional().describe("1-based first line."),
|
|
104
|
+
endLine: z.int().min(1).optional().describe("1-based last line, inclusive."),
|
|
105
|
+
revision: z
|
|
106
|
+
.enum(["head", "base"])
|
|
107
|
+
.optional()
|
|
108
|
+
.describe("Which side of the diff the lines refer to. Defaults to head."),
|
|
109
|
+
})
|
|
110
|
+
.meta({ dependentRequired: { endLine: ["startLine"] } })
|
|
111
|
+
.refine((f) => f.endLine === undefined || f.startLine !== undefined, {
|
|
112
|
+
message: "endLine requires startLine",
|
|
113
|
+
path: ["endLine"],
|
|
114
|
+
})
|
|
115
|
+
.refine((f) => f.endLine === undefined || f.startLine === undefined || f.endLine >= f.startLine, {
|
|
116
|
+
message: "endLine must be greater than or equal to startLine",
|
|
117
|
+
path: ["endLine"],
|
|
118
|
+
})
|
|
119
|
+
.describe("A file (and optional line range) backing an element.");
|
|
120
|
+
//# sourceMappingURL=primitives.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitives.js","sourceRoot":"","sources":["../src/primitives.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAEzE;;;;GAIG;AACH,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;KAChB,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,CAAC;KACN,GAAG,CAAC,GAAG,CAAC;KACR,KAAK,CACJ,gCAAgC,EAChC,wEAAwE,CACzE;KACA,QAAQ,CAAC,gEAAgE,CAAC,CAAC;AAG9E;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC;KAChC,MAAM,EAAE;KACR,KAAK,CAAC,iBAAiB,EAAE,qCAAqC,CAAC;KAC/D,IAAI,CAAC,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC;KAC5C,QAAQ,CAAC,mDAAmD,cAAc,GAAG,CAAC,CAAC;AAElF,2EAA2E;AAC3E,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC;AAEjF,6EAA6E;AAC7E,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC;KACrB,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,CAAC;KACN,GAAG,CAAC,IAAI,CAAC;KACT,QAAQ,CAAC,4DAA4D,CAAC,CAAC;AAE1E,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC;KACjB,MAAM,EAAE;KACR,KAAK,CAAC,kBAAkB,EAAE,yCAAyC,CAAC;KACpE,QAAQ,CAAC,sCAAsC,CAAC,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC;KACrB,MAAM,EAAE;KACR,KAAK,CAAC,gBAAgB,EAAE,2DAA2D,CAAC;KACpF,QAAQ,CAAC,0BAA0B,CAAC,CAAC;AAExC;;;;GAIG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;AAGtF,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;AAEnC,oDAAoD;AACpD,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,uCAAuC,CAAC,CAAC;AAGjG,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC;AAEpC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAErC,MAAM,CAAC,MAAM,SAAS,GAAG,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC;AAE3D;;;;GAIG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC;KACnB,IAAI,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;KACnD,QAAQ,CAAC,2CAA2C,CAAC,CAAC;AAGzD,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC;AAEpC;;;;GAIG;AACH,MAAM,eAAe,GAAG,2DAA2D,CAAC;AAEpF;;;;GAIG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC;KACrB,YAAY,CAAC;IACZ,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,IAAI,CAAC;SACT,KAAK,CACJ,eAAe,EACf,iGAAiG,CAClG;SACA,QAAQ,CAAC,6CAA6C,CAAC;IAC1D,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC;IACpE,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;IAC5E,QAAQ,EAAE,CAAC;SACR,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SACtB,QAAQ,EAAE;SACV,QAAQ,CAAC,8DAA8D,CAAC;CAC5E,CAAC;KACD,IAAI,CAAC,EAAE,iBAAiB,EAAE,EAAE,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC;KACvD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,EAAE;IACnE,OAAO,EAAE,4BAA4B;IACrC,IAAI,EAAE,CAAC,SAAS,CAAC;CAClB,CAAC;KACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,SAAS,EAAE;IAC/F,OAAO,EAAE,oDAAoD;IAC7D,IAAI,EAAE,CAAC,SAAS,CAAC;CAClB,CAAC;KACD,QAAQ,CAAC,sDAAsD,CAAC,CAAC"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ends a switch over a closed set. Adding a variant then fails to compile at
|
|
3
|
+
* every consumer instead of silently falling through at runtime.
|
|
4
|
+
*/
|
|
5
|
+
export declare const assertNever: (value: never, message?: string) => never;
|
|
6
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,WAAW,UAAW,KAAK,uBAAkC,KAEzE,CAAC"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ends a switch over a closed set. Adding a variant then fails to compile at
|
|
3
|
+
* every consumer instead of silently falling through at runtime.
|
|
4
|
+
*/
|
|
5
|
+
export const assertNever = (value, message = "Unhandled variant") => {
|
|
6
|
+
throw new Error(`${message}: ${JSON.stringify(value)}`);
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAY,EAAE,OAAO,GAAG,mBAAmB,EAAS,EAAE;IAChF,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Config } from "./config.js";
|
|
2
|
+
import { type Parsed } from "./errors.js";
|
|
3
|
+
import { GraphDoc } from "./graph.js";
|
|
4
|
+
import { RenderManifest } from "./manifest.js";
|
|
5
|
+
import { PatchDoc } from "./patch.js";
|
|
6
|
+
/**
|
|
7
|
+
* Structure, contract version and referential integrity in one pass. A
|
|
8
|
+
* document that survives this is safe to render without further checking.
|
|
9
|
+
*/
|
|
10
|
+
export declare const safeParseGraphDoc: (input: unknown) => Parsed<GraphDoc>;
|
|
11
|
+
export declare const parseGraphDoc: (input: unknown) => GraphDoc;
|
|
12
|
+
export declare const safeParsePatchDoc: (input: unknown) => Parsed<PatchDoc>;
|
|
13
|
+
export declare const parsePatchDoc: (input: unknown) => PatchDoc;
|
|
14
|
+
export declare const safeParseConfig: (input: unknown) => Parsed<Config>;
|
|
15
|
+
export declare const parseConfig: (input: unknown) => Config;
|
|
16
|
+
export declare const safeParseRenderManifest: (input: unknown) => Parsed<RenderManifest>;
|
|
17
|
+
export declare const parseRenderManifest: (input: unknown) => RenderManifest;
|
|
18
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAmC,KAAK,MAAM,EAAoB,MAAM,aAAa,CAAC;AAC7F,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AA6FtC;;;GAGG;AACH,eAAO,MAAM,iBAAiB,UAAW,OAAO,KAAG,MAAM,CAAC,QAAQ,CAI9D,CAAC;AAEL,eAAO,MAAM,aAAa,UAAW,OAAO,KAAG,QAA4C,CAAC;AAE5F,eAAO,MAAM,iBAAiB,UAAW,OAAO,KAAG,MAAM,CAAC,QAAQ,CAG/D,CAAC;AAEJ,eAAO,MAAM,aAAa,UAAW,OAAO,KAAG,QAA4C,CAAC;AAE5F,eAAO,MAAM,eAAe,UAAW,OAAO,KAAG,MAAM,CAAC,MAAM,CAG3D,CAAC;AAEJ,eAAO,MAAM,WAAW,UAAW,OAAO,KAAG,MAAwC,CAAC;AAEtF,eAAO,MAAM,uBAAuB,UAAW,OAAO,KAAG,MAAM,CAAC,cAAc,CAG3E,CAAC;AAEJ,eAAO,MAAM,mBAAmB,UAAW,OAAO,KAAG,cACb,CAAC"}
|
package/dist/validate.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Config } from "./config.js";
|
|
2
|
+
import { formatIssues, PrLensSchemaError } from "./errors.js";
|
|
3
|
+
import { GraphDoc } from "./graph.js";
|
|
4
|
+
import { graphIntegrityIssues } from "./integrity.js";
|
|
5
|
+
import { RenderManifest } from "./manifest.js";
|
|
6
|
+
import { PatchDoc } from "./patch.js";
|
|
7
|
+
import { isSupportedVersion, SCHEMA_VERSION } from "./version.js";
|
|
8
|
+
const formatPath = (path) => path.reduce((acc, segment) => {
|
|
9
|
+
if (typeof segment === "number")
|
|
10
|
+
return `${acc}[${segment}]`;
|
|
11
|
+
return acc === "" ? String(segment) : `${acc}.${String(segment)}`;
|
|
12
|
+
}, "");
|
|
13
|
+
const toIssues = (error) => error.issues.map((issue) => ({
|
|
14
|
+
code: "INVALID_DOCUMENT",
|
|
15
|
+
path: formatPath(issue.path),
|
|
16
|
+
message: issue.message,
|
|
17
|
+
}));
|
|
18
|
+
const versionIssues = (version, path) => isSupportedVersion(version)
|
|
19
|
+
? []
|
|
20
|
+
: [
|
|
21
|
+
{
|
|
22
|
+
code: "UNSUPPORTED_SCHEMA_VERSION",
|
|
23
|
+
path,
|
|
24
|
+
message: `document targets schema version ${version}; this package implements ${SCHEMA_VERSION}`,
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
const fail = (label, issues) => {
|
|
28
|
+
const first = issues[0];
|
|
29
|
+
return new PrLensSchemaError(first ? first.code : "INVALID_DOCUMENT", `invalid ${label}:\n${formatIssues(issues)}`, issues);
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Validating a recursive structure recurses, so a document nested deeply
|
|
33
|
+
* enough exhausts the stack while zod is still walking it — before any check
|
|
34
|
+
* of ours can count anything. A `safeParse` that throws would be a worse
|
|
35
|
+
* failure than the document it was handed, so the stack running out is
|
|
36
|
+
* reported as what it is: a document too deep to read.
|
|
37
|
+
*
|
|
38
|
+
* Every `RangeError` is read that way, not only the ones provoked by depth.
|
|
39
|
+
* That is deliberate: failing closed keeps the promise that these functions
|
|
40
|
+
* return a verdict rather than throwing one, and nesting is the only way a
|
|
41
|
+
* document is known to provoke one. Narrowing this to rethrow would trade
|
|
42
|
+
* that promise for a diagnosis.
|
|
43
|
+
*/
|
|
44
|
+
const attemptParse = (schema, input) => {
|
|
45
|
+
try {
|
|
46
|
+
const result = schema.safeParse(input);
|
|
47
|
+
return result.success
|
|
48
|
+
? { read: true, value: result.data }
|
|
49
|
+
: { read: false, issues: toIssues(result.error) };
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
if (!(error instanceof RangeError))
|
|
53
|
+
throw error;
|
|
54
|
+
return {
|
|
55
|
+
read: false,
|
|
56
|
+
issues: [
|
|
57
|
+
{
|
|
58
|
+
code: "INVALID_DOCUMENT",
|
|
59
|
+
path: "",
|
|
60
|
+
message: "document nests too deeply to read",
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const parseDocument = (schema, label, input, extraIssues) => {
|
|
67
|
+
const result = attemptParse(schema, input);
|
|
68
|
+
if (!result.read)
|
|
69
|
+
return { ok: false, error: fail(label, result.issues) };
|
|
70
|
+
const issues = extraIssues(result.value);
|
|
71
|
+
if (issues.length > 0)
|
|
72
|
+
return { ok: false, error: fail(label, issues) };
|
|
73
|
+
return { ok: true, value: result.value };
|
|
74
|
+
};
|
|
75
|
+
const unwrap = (parsed) => {
|
|
76
|
+
if (parsed.ok)
|
|
77
|
+
return parsed.value;
|
|
78
|
+
throw parsed.error;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Structure, contract version and referential integrity in one pass. A
|
|
82
|
+
* document that survives this is safe to render without further checking.
|
|
83
|
+
*/
|
|
84
|
+
export const safeParseGraphDoc = (input) => parseDocument(GraphDoc, "graph document", input, (doc) => [
|
|
85
|
+
...versionIssues(doc.schemaVersion, "schemaVersion"),
|
|
86
|
+
...graphIntegrityIssues(doc),
|
|
87
|
+
]);
|
|
88
|
+
export const parseGraphDoc = (input) => unwrap(safeParseGraphDoc(input));
|
|
89
|
+
export const safeParsePatchDoc = (input) => parseDocument(PatchDoc, "patch document", input, (doc) => versionIssues(doc.schemaVersion, "schemaVersion"));
|
|
90
|
+
export const parsePatchDoc = (input) => unwrap(safeParsePatchDoc(input));
|
|
91
|
+
export const safeParseConfig = (input) => parseDocument(Config, "config", input, (config) => versionIssues(config.schemaVersion, "schemaVersion"));
|
|
92
|
+
export const parseConfig = (input) => unwrap(safeParseConfig(input));
|
|
93
|
+
export const safeParseRenderManifest = (input) => parseDocument(RenderManifest, "render manifest", input, (manifest) => versionIssues(manifest.schemaVersion, "schemaVersion"));
|
|
94
|
+
export const parseRenderManifest = (input) => unwrap(safeParseRenderManifest(input));
|
|
95
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version of the PR Lens document contract.
|
|
3
|
+
*
|
|
4
|
+
* Every document carries this string so a consumer can refuse, migrate, or
|
|
5
|
+
* degrade gracefully when it meets a document it was not built for. Bumped
|
|
6
|
+
* with semver semantics: patch/minor releases only ever add optional fields
|
|
7
|
+
* or widen an enum, a major release may remove or retype a field.
|
|
8
|
+
*/
|
|
9
|
+
export declare const SCHEMA_VERSION: "0.1.0";
|
|
10
|
+
export type SchemaVersion = typeof SCHEMA_VERSION;
|
|
11
|
+
/**
|
|
12
|
+
* Which versions this package reads, as a pattern so the rule can be carried
|
|
13
|
+
* into the exported JSON Schemas rather than restated there.
|
|
14
|
+
*
|
|
15
|
+
* Below 1.0 a minor bump is allowed to break, so only the exact major.minor
|
|
16
|
+
* is accepted; from 1.0 on, the major must match and a newer minor is
|
|
17
|
+
* readable because minor releases only add optional fields.
|
|
18
|
+
*/
|
|
19
|
+
export declare const SUPPORTED_VERSION_PATTERN: string;
|
|
20
|
+
export declare const isSupportedVersion: (version: string) => boolean;
|
|
21
|
+
//# sourceMappingURL=version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,EAAG,OAAgB,CAAC;AAE/C,MAAM,MAAM,aAAa,GAAG,OAAO,cAAc,CAAC;AAMlD;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,QAG0B,CAAC;AAEjE,eAAO,MAAM,kBAAkB,YAAa,MAAM,KAAG,OACA,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version of the PR Lens document contract.
|
|
3
|
+
*
|
|
4
|
+
* Every document carries this string so a consumer can refuse, migrate, or
|
|
5
|
+
* degrade gracefully when it meets a document it was not built for. Bumped
|
|
6
|
+
* with semver semantics: patch/minor releases only ever add optional fields
|
|
7
|
+
* or widen an enum, a major release may remove or retype a field.
|
|
8
|
+
*/
|
|
9
|
+
export const SCHEMA_VERSION = "0.1.0";
|
|
10
|
+
const [currentMajor = "0", currentMinor = "0"] = SCHEMA_VERSION.split(".");
|
|
11
|
+
const readableMinors = Array.from({ length: Number(currentMinor) + 1 }, (_, minor) => minor);
|
|
12
|
+
/**
|
|
13
|
+
* Which versions this package reads, as a pattern so the rule can be carried
|
|
14
|
+
* into the exported JSON Schemas rather than restated there.
|
|
15
|
+
*
|
|
16
|
+
* Below 1.0 a minor bump is allowed to break, so only the exact major.minor
|
|
17
|
+
* is accepted; from 1.0 on, the major must match and a newer minor is
|
|
18
|
+
* readable because minor releases only add optional fields.
|
|
19
|
+
*/
|
|
20
|
+
export const SUPPORTED_VERSION_PATTERN = currentMajor === "0"
|
|
21
|
+
? `^0\\.${currentMinor}\\.\\d+$`
|
|
22
|
+
: `^${currentMajor}\\.(${readableMinors.join("|")})\\.\\d+$`;
|
|
23
|
+
export const isSupportedVersion = (version) => new RegExp(SUPPORTED_VERSION_PATTERN).test(version);
|
|
24
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,OAAgB,CAAC;AAI/C,MAAM,CAAC,YAAY,GAAG,GAAG,EAAE,YAAY,GAAG,GAAG,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAE3E,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;AAE7F;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,yBAAyB,GACpC,YAAY,KAAK,GAAG;IAClB,CAAC,CAAC,QAAQ,YAAY,UAAU;IAChC,CAAC,CAAC,IAAI,YAAY,OAAO,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC;AAEjE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,OAAe,EAAW,EAAE,CAC7D,IAAI,MAAM,CAAC,yBAAyB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC"}
|