@tsdoctor/manifest 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.
@@ -0,0 +1,209 @@
1
+ import { Effect, Schema } from "effect";
2
+
3
+ //#region src/BundleManifest.ts
4
+ /**
5
+ * The registry protocol families this reader knows how to do more than link
6
+ * to. `"npm"` means an npm-compatible registry — install commands and tarball
7
+ * fetching work against any instance of it — and `"jsr"` the jsr protocol.
8
+ *
9
+ * @remarks
10
+ * The manifest's `type` field is deliberately NOT constrained to these
11
+ * values: unknown future types must degrade to link-only rendering, not
12
+ * reject the manifest. Use {@link isKnownRegistryType} to branch.
13
+ *
14
+ * @public
15
+ */
16
+ const KNOWN_REGISTRY_TYPES = ["npm", "jsr"];
17
+ /**
18
+ * Whether a registry `type` value is a protocol family this reader
19
+ * recognizes. `false` means the registry entry should degrade to link-only
20
+ * rendering — it is never a validation failure.
21
+ *
22
+ * @public
23
+ */
24
+ function isKnownRegistryType(type) {
25
+ return KNOWN_REGISTRY_TYPES.includes(type);
26
+ }
27
+ /**
28
+ * One registry the documented package is published to.
29
+ *
30
+ * @remarks
31
+ * `type` is the PROTOCOL FAMILY (`"npm"` covers every npm-compatible
32
+ * registry), `name` the human instance label, `url` the package's page on
33
+ * that instance. Unknown `type` values decode successfully and degrade to
34
+ * link-only rendering (see {@link isKnownRegistryType}).
35
+ *
36
+ * @public
37
+ */
38
+ const RegistryRef = Schema.Struct({
39
+ /** The protocol family, e.g. `"npm"` or `"jsr"`. Unknown values are accepted. */
40
+ type: Schema.String,
41
+ /** The human instance label, e.g. `"npm"` or `"Savvy Web Registry"`. */
42
+ name: Schema.String,
43
+ /** The package's URL on that registry instance. */
44
+ url: Schema.String
45
+ });
46
+ /**
47
+ * One Open Graph image declared by the manifest.
48
+ *
49
+ * @remarks
50
+ * Exactly ONE of `path` (a bundle-relative asset the consuming platform
51
+ * publishes and resolves to a URL) or `url` (an absolute external URL used
52
+ * verbatim) must be present — the schema enforces the XOR. `type` is a MIME
53
+ * type, inferred from the file extension by the resolver when omitted; `alt`
54
+ * has a documented inference chain (tagline → description →
55
+ * `"<name> API documentation"`).
56
+ *
57
+ * @public
58
+ */
59
+ const OpenGraphImage = Schema.Struct({
60
+ /** Bundle-relative asset path. Mutually exclusive with `url`. */
61
+ path: Schema.optionalKey(Schema.String),
62
+ /** Absolute external URL, used verbatim. Mutually exclusive with `path`. */
63
+ url: Schema.optionalKey(Schema.String),
64
+ /** MIME type; inferred from the extension when omitted. */
65
+ type: Schema.optionalKey(Schema.String),
66
+ /** Pixel width; 1200×630 (1.91:1) is the cross-platform safe default. */
67
+ width: Schema.optionalKey(Schema.Int),
68
+ /** Pixel height. */
69
+ height: Schema.optionalKey(Schema.Int),
70
+ /** Alt text; inferred (tagline → description → fallback) when omitted. */
71
+ alt: Schema.optionalKey(Schema.String)
72
+ }).check(Schema.makeFilter((image) => image.path === void 0 !== (image.url === void 0) ? void 0 : "exactly one of \"path\" or \"url\" must be present", { title: "openGraph image source" }));
73
+ /**
74
+ * The manifest's Open Graph block: the asset-ish pieces only — most OG tags
75
+ * are page-level and derive at render time in the consuming platform.
76
+ *
77
+ * @remarks
78
+ * Multiple images follow OG array semantics: the first declared wins, extras
79
+ * are alternates (e.g. a portrait 1000×1500 variant).
80
+ *
81
+ * @public
82
+ */
83
+ const OpenGraphConfig = Schema.Struct({
84
+ /** Declared images, first-wins per OG array semantics. */
85
+ images: Schema.optionalKey(Schema.Array(OpenGraphImage)),
86
+ /** Embed accent color (e.g. Discord), a CSS color string. */
87
+ themeColor: Schema.optionalKey(Schema.String)
88
+ });
89
+ /**
90
+ * A pointer to the bundle's SBOM, computed by the bundler at publish and
91
+ * served as a downloadable static asset.
92
+ *
93
+ * @public
94
+ */
95
+ const SbomRef = Schema.Struct({
96
+ /** Bundle-relative path to the SBOM file. */
97
+ path: Schema.String,
98
+ /** SBOM format label, e.g. `"spdx-json"`. Unknown values are accepted. */
99
+ format: Schema.optionalKey(Schema.String)
100
+ });
101
+ /**
102
+ * The inherited project tier, flattened into the emitted manifest by the
103
+ * bundler (a fetched bundle has no parent directory to walk). Kept nested —
104
+ * structurally distinguishable from the leaf fields — because provenance is
105
+ * load-bearing for override detection.
106
+ *
107
+ * @public
108
+ */
109
+ const ProjectIdentity = Schema.Struct({
110
+ /** The project display name, e.g. `"Effected"` over leaf `@effected/store`. */
111
+ name: Schema.optionalKey(Schema.String),
112
+ /** The project tagline. */
113
+ tagline: Schema.optionalKey(Schema.String)
114
+ });
115
+ /**
116
+ * The versioned `tsdoctor.json` sidecar manifest — bundle layer 3.
117
+ *
118
+ * @remarks
119
+ * `spec` is the only required field; every other field enriches. Unknown
120
+ * top-level fields are ignored on decode (additive fields are minor spec
121
+ * revisions) and unknown enum-ish values (registry `type`, sbom `format`)
122
+ * degrade gracefully instead of rejecting — an old reader must be able to
123
+ * consume a new bundle.
124
+ *
125
+ * @public
126
+ */
127
+ const BundleManifest = Schema.Struct({
128
+ /** The integer spec version. This reader understands spec 1. */
129
+ spec: Schema.Literal(1),
130
+ /** Human display name (the npm name is dry; this one is SEO-friendly). */
131
+ name: Schema.optionalKey(Schema.String),
132
+ /** Short tagline. */
133
+ tagline: Schema.optionalKey(Schema.String),
134
+ /** Long description; overrides the package.json description when present. */
135
+ description: Schema.optionalKey(Schema.String),
136
+ /** The inherited project tier, flattened in at emit time. */
137
+ project: Schema.optionalKey(ProjectIdentity),
138
+ /** Open Graph assets. */
139
+ openGraph: Schema.optionalKey(OpenGraphConfig),
140
+ /** SBOM pointer. */
141
+ sbom: Schema.optionalKey(SbomRef),
142
+ /** Registries the package is published to. */
143
+ registries: Schema.optionalKey(Schema.Array(RegistryRef))
144
+ });
145
+ /**
146
+ * Raised when a present `tsdoctor.json` cannot be parsed or does not satisfy
147
+ * the {@link (BundleManifest:variable)} schema.
148
+ *
149
+ * @remarks
150
+ * Absence of the manifest is NEVER this error — layers enrich, never gate,
151
+ * so a missing sidecar is the normal case and reads as `Option.none()`.
152
+ *
153
+ * @public
154
+ */
155
+ var BundleManifestError = class extends Schema.TaggedError()("BundleManifestError", {
156
+ /** The manifest file path, when the failure is tied to a file on disk. */
157
+ path: Schema.optionalKey(Schema.String),
158
+ /** The underlying failure (JSON syntax or schema decode), preserved structurally. */
159
+ cause: Schema.Defect()
160
+ }) {
161
+ get message() {
162
+ return `Invalid tsdoctor.json manifest${this.path !== void 0 ? ` at ${this.path}` : ""}`;
163
+ }
164
+ };
165
+ /**
166
+ * Decode an unknown value into a {@link (BundleManifest:type)}.
167
+ *
168
+ * @remarks
169
+ * The typed boundary for manifest input that has already been parsed from
170
+ * JSON (plugin options, fetched payloads). File-based reading lives in
171
+ * `readBundle`, which routes through this after parsing.
172
+ *
173
+ * @public
174
+ */
175
+ function decodeBundleManifest(input, path) {
176
+ return Schema.decodeUnknownEffect(BundleManifest)(input).pipe(Effect.mapError((cause) => new BundleManifestError({
177
+ ...path !== void 0 ? { path } : {},
178
+ cause
179
+ })));
180
+ }
181
+ /**
182
+ * The manifest spec version this package reads and writes.
183
+ *
184
+ * @public
185
+ */
186
+ const MANIFEST_SPEC = 1;
187
+ /**
188
+ * The sidecar manifest's file name inside a bundle folder.
189
+ *
190
+ * @public
191
+ */
192
+ const TSDOCTOR_MANIFEST_FILENAME = "tsdoctor.json";
193
+ /**
194
+ * Encode a {@link (BundleManifest:type)} into the JSON-ready value a writer
195
+ * serializes as `tsdoctor.json`.
196
+ *
197
+ * @remarks
198
+ * The writer's boundary. Going through the schema rather than
199
+ * `JSON.stringify` means an emitted file is by construction what
200
+ * {@link decodeBundleManifest} accepts.
201
+ *
202
+ * @public
203
+ */
204
+ function encodeBundleManifest(manifest) {
205
+ return Schema.encodeEffect(BundleManifest)(manifest).pipe(Effect.mapError((cause) => new BundleManifestError({ cause })));
206
+ }
207
+
208
+ //#endregion
209
+ export { BundleManifest, BundleManifestError, KNOWN_REGISTRY_TYPES, MANIFEST_SPEC, OpenGraphConfig, OpenGraphImage, ProjectIdentity, RegistryRef, SbomRef, TSDOCTOR_MANIFEST_FILENAME, decodeBundleManifest, encodeBundleManifest, isKnownRegistryType };
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 C. Spencer Beggs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,38 @@
1
+ import { BundleManifest, BundleManifestError } from "./BundleManifest.js";
2
+ import { Effect, Schema } from "effect";
3
+
4
+ //#region src/ManifestSource.ts
5
+ /**
6
+ * The shape an author checks in as a `tsdoctor.json` SOURCE file, at a
7
+ * package root (the leaf tier) or a workspace root (the project tier).
8
+ *
9
+ * @remarks
10
+ * `BundleManifest` minus `spec` and `project`: a source file never declares
11
+ * its own spec version, and it never declares its inherited tier — the
12
+ * bundler supplies both when it flattens the hierarchy at emit time. Decoded
13
+ * only by writers; readers never see this shape.
14
+ *
15
+ * @public
16
+ */
17
+ const ManifestSource = Schema.Struct({
18
+ name: BundleManifest.fields.name,
19
+ tagline: BundleManifest.fields.tagline,
20
+ description: BundleManifest.fields.description,
21
+ openGraph: BundleManifest.fields.openGraph,
22
+ sbom: BundleManifest.fields.sbom,
23
+ registries: BundleManifest.fields.registries
24
+ });
25
+ /**
26
+ * Decode an unknown value into a {@link (ManifestSource:type)}.
27
+ *
28
+ * @public
29
+ */
30
+ function decodeManifestSource(input, path) {
31
+ return Schema.decodeUnknownEffect(ManifestSource)(input).pipe(Effect.mapError((cause) => new BundleManifestError({
32
+ ...path !== void 0 ? { path } : {},
33
+ cause
34
+ })));
35
+ }
36
+
37
+ //#endregion
38
+ export { ManifestSource, decodeManifestSource };
package/index.d.ts ADDED
@@ -0,0 +1,339 @@
1
+ import { Effect, Schema } from "effect";
2
+ //#region src/BundleManifest.d.ts
3
+ /**
4
+ * The registry protocol families this reader knows how to do more than link
5
+ * to. `"npm"` means an npm-compatible registry — install commands and tarball
6
+ * fetching work against any instance of it — and `"jsr"` the jsr protocol.
7
+ *
8
+ * @remarks
9
+ * The manifest's `type` field is deliberately NOT constrained to these
10
+ * values: unknown future types must degrade to link-only rendering, not
11
+ * reject the manifest. Use {@link isKnownRegistryType} to branch.
12
+ *
13
+ * @public
14
+ */
15
+ declare const KNOWN_REGISTRY_TYPES: readonly ["npm", "jsr"];
16
+ /**
17
+ * A registry protocol family this reader recognizes.
18
+ *
19
+ * @public
20
+ */
21
+ type KnownRegistryType = (typeof KNOWN_REGISTRY_TYPES)[number];
22
+ /**
23
+ * Whether a registry `type` value is a protocol family this reader
24
+ * recognizes. `false` means the registry entry should degrade to link-only
25
+ * rendering — it is never a validation failure.
26
+ *
27
+ * @public
28
+ */
29
+ declare function isKnownRegistryType(type: string): type is KnownRegistryType;
30
+ /**
31
+ * One registry the documented package is published to.
32
+ *
33
+ * @remarks
34
+ * `type` is the PROTOCOL FAMILY (`"npm"` covers every npm-compatible
35
+ * registry), `name` the human instance label, `url` the package's page on
36
+ * that instance. Unknown `type` values decode successfully and degrade to
37
+ * link-only rendering (see {@link isKnownRegistryType}).
38
+ *
39
+ * @public
40
+ */
41
+ declare const RegistryRef: Schema.Struct<{
42
+ /** The protocol family, e.g. `"npm"` or `"jsr"`. Unknown values are accepted. */
43
+ readonly type: Schema.String;
44
+ /** The human instance label, e.g. `"npm"` or `"Savvy Web Registry"`. */
45
+ readonly name: Schema.String;
46
+ /** The package's URL on that registry instance. */
47
+ readonly url: Schema.String;
48
+ }>;
49
+ /**
50
+ * The decoded type of {@link (RegistryRef:variable)}.
51
+ *
52
+ * @public
53
+ */
54
+ type RegistryRef = typeof RegistryRef.Type;
55
+ /**
56
+ * One Open Graph image declared by the manifest.
57
+ *
58
+ * @remarks
59
+ * Exactly ONE of `path` (a bundle-relative asset the consuming platform
60
+ * publishes and resolves to a URL) or `url` (an absolute external URL used
61
+ * verbatim) must be present — the schema enforces the XOR. `type` is a MIME
62
+ * type, inferred from the file extension by the resolver when omitted; `alt`
63
+ * has a documented inference chain (tagline → description →
64
+ * `"<name> API documentation"`).
65
+ *
66
+ * @public
67
+ */
68
+ declare const OpenGraphImage: Schema.Struct<{
69
+ /** Bundle-relative asset path. Mutually exclusive with `url`. */
70
+ readonly path: Schema.optionalKey<Schema.String>;
71
+ /** Absolute external URL, used verbatim. Mutually exclusive with `path`. */
72
+ readonly url: Schema.optionalKey<Schema.String>;
73
+ /** MIME type; inferred from the extension when omitted. */
74
+ readonly type: Schema.optionalKey<Schema.String>;
75
+ /** Pixel width; 1200×630 (1.91:1) is the cross-platform safe default. */
76
+ readonly width: Schema.optionalKey<Schema.Int>;
77
+ /** Pixel height. */
78
+ readonly height: Schema.optionalKey<Schema.Int>;
79
+ /** Alt text; inferred (tagline → description → fallback) when omitted. */
80
+ readonly alt: Schema.optionalKey<Schema.String>;
81
+ }>;
82
+ /**
83
+ * The decoded type of {@link (OpenGraphImage:variable)}.
84
+ *
85
+ * @public
86
+ */
87
+ type OpenGraphImage = typeof OpenGraphImage.Type;
88
+ /**
89
+ * The manifest's Open Graph block: the asset-ish pieces only — most OG tags
90
+ * are page-level and derive at render time in the consuming platform.
91
+ *
92
+ * @remarks
93
+ * Multiple images follow OG array semantics: the first declared wins, extras
94
+ * are alternates (e.g. a portrait 1000×1500 variant).
95
+ *
96
+ * @public
97
+ */
98
+ declare const OpenGraphConfig: Schema.Struct<{
99
+ /** Declared images, first-wins per OG array semantics. */
100
+ readonly images: Schema.optionalKey<Schema.$Array<Schema.Struct<{
101
+ /** Bundle-relative asset path. Mutually exclusive with `url`. */
102
+ readonly path: Schema.optionalKey<Schema.String>;
103
+ /** Absolute external URL, used verbatim. Mutually exclusive with `path`. */
104
+ readonly url: Schema.optionalKey<Schema.String>;
105
+ /** MIME type; inferred from the extension when omitted. */
106
+ readonly type: Schema.optionalKey<Schema.String>;
107
+ /** Pixel width; 1200×630 (1.91:1) is the cross-platform safe default. */
108
+ readonly width: Schema.optionalKey<Schema.Int>;
109
+ /** Pixel height. */
110
+ readonly height: Schema.optionalKey<Schema.Int>;
111
+ /** Alt text; inferred (tagline → description → fallback) when omitted. */
112
+ readonly alt: Schema.optionalKey<Schema.String>;
113
+ }>>>;
114
+ /** Embed accent color (e.g. Discord), a CSS color string. */
115
+ readonly themeColor: Schema.optionalKey<Schema.String>;
116
+ }>;
117
+ /**
118
+ * The decoded type of {@link (OpenGraphConfig:variable)}.
119
+ *
120
+ * @public
121
+ */
122
+ type OpenGraphConfig = typeof OpenGraphConfig.Type;
123
+ /**
124
+ * A pointer to the bundle's SBOM, computed by the bundler at publish and
125
+ * served as a downloadable static asset.
126
+ *
127
+ * @public
128
+ */
129
+ declare const SbomRef: Schema.Struct<{
130
+ /** Bundle-relative path to the SBOM file. */
131
+ readonly path: Schema.String;
132
+ /** SBOM format label, e.g. `"spdx-json"`. Unknown values are accepted. */
133
+ readonly format: Schema.optionalKey<Schema.String>;
134
+ }>;
135
+ /**
136
+ * The decoded type of {@link (SbomRef:variable)}.
137
+ *
138
+ * @public
139
+ */
140
+ type SbomRef = typeof SbomRef.Type;
141
+ /**
142
+ * The inherited project tier, flattened into the emitted manifest by the
143
+ * bundler (a fetched bundle has no parent directory to walk). Kept nested —
144
+ * structurally distinguishable from the leaf fields — because provenance is
145
+ * load-bearing for override detection.
146
+ *
147
+ * @public
148
+ */
149
+ declare const ProjectIdentity: Schema.Struct<{
150
+ /** The project display name, e.g. `"Effected"` over leaf `@effected/store`. */
151
+ readonly name: Schema.optionalKey<Schema.String>;
152
+ /** The project tagline. */
153
+ readonly tagline: Schema.optionalKey<Schema.String>;
154
+ }>;
155
+ /**
156
+ * The decoded type of {@link (ProjectIdentity:variable)}.
157
+ *
158
+ * @public
159
+ */
160
+ type ProjectIdentity = typeof ProjectIdentity.Type;
161
+ /**
162
+ * The versioned `tsdoctor.json` sidecar manifest — bundle layer 3.
163
+ *
164
+ * @remarks
165
+ * `spec` is the only required field; every other field enriches. Unknown
166
+ * top-level fields are ignored on decode (additive fields are minor spec
167
+ * revisions) and unknown enum-ish values (registry `type`, sbom `format`)
168
+ * degrade gracefully instead of rejecting — an old reader must be able to
169
+ * consume a new bundle.
170
+ *
171
+ * @public
172
+ */
173
+ declare const BundleManifest: Schema.Struct<{
174
+ /** The integer spec version. This reader understands spec 1. */
175
+ readonly spec: Schema.Literal<1>;
176
+ /** Human display name (the npm name is dry; this one is SEO-friendly). */
177
+ readonly name: Schema.optionalKey<Schema.String>;
178
+ /** Short tagline. */
179
+ readonly tagline: Schema.optionalKey<Schema.String>;
180
+ /** Long description; overrides the package.json description when present. */
181
+ readonly description: Schema.optionalKey<Schema.String>;
182
+ /** The inherited project tier, flattened in at emit time. */
183
+ readonly project: Schema.optionalKey<Schema.Struct<{
184
+ /** The project display name, e.g. `"Effected"` over leaf `@effected/store`. */
185
+ readonly name: Schema.optionalKey<Schema.String>;
186
+ /** The project tagline. */
187
+ readonly tagline: Schema.optionalKey<Schema.String>;
188
+ }>>;
189
+ /** Open Graph assets. */
190
+ readonly openGraph: Schema.optionalKey<Schema.Struct<{
191
+ /** Declared images, first-wins per OG array semantics. */
192
+ readonly images: Schema.optionalKey<Schema.$Array<Schema.Struct<{
193
+ /** Bundle-relative asset path. Mutually exclusive with `url`. */
194
+ readonly path: Schema.optionalKey<Schema.String>;
195
+ /** Absolute external URL, used verbatim. Mutually exclusive with `path`. */
196
+ readonly url: Schema.optionalKey<Schema.String>;
197
+ /** MIME type; inferred from the extension when omitted. */
198
+ readonly type: Schema.optionalKey<Schema.String>;
199
+ /** Pixel width; 1200×630 (1.91:1) is the cross-platform safe default. */
200
+ readonly width: Schema.optionalKey<Schema.Int>;
201
+ /** Pixel height. */
202
+ readonly height: Schema.optionalKey<Schema.Int>;
203
+ /** Alt text; inferred (tagline → description → fallback) when omitted. */
204
+ readonly alt: Schema.optionalKey<Schema.String>;
205
+ }>>>;
206
+ /** Embed accent color (e.g. Discord), a CSS color string. */
207
+ readonly themeColor: Schema.optionalKey<Schema.String>;
208
+ }>>;
209
+ /** SBOM pointer. */
210
+ readonly sbom: Schema.optionalKey<Schema.Struct<{
211
+ /** Bundle-relative path to the SBOM file. */
212
+ readonly path: Schema.String;
213
+ /** SBOM format label, e.g. `"spdx-json"`. Unknown values are accepted. */
214
+ readonly format: Schema.optionalKey<Schema.String>;
215
+ }>>;
216
+ /** Registries the package is published to. */
217
+ readonly registries: Schema.optionalKey<Schema.$Array<Schema.Struct<{
218
+ /** The protocol family, e.g. `"npm"` or `"jsr"`. Unknown values are accepted. */
219
+ readonly type: Schema.String;
220
+ /** The human instance label, e.g. `"npm"` or `"Savvy Web Registry"`. */
221
+ readonly name: Schema.String;
222
+ /** The package's URL on that registry instance. */
223
+ readonly url: Schema.String;
224
+ }>>>;
225
+ }>;
226
+ /**
227
+ * The decoded type of {@link (BundleManifest:variable)}.
228
+ *
229
+ * @public
230
+ */
231
+ type BundleManifest = typeof BundleManifest.Type;
232
+ declare const BundleManifestError_base: Schema.Class<BundleManifestError, Schema.TaggedStruct<"BundleManifestError", {
233
+ /** The manifest file path, when the failure is tied to a file on disk. */
234
+ readonly path: Schema.optionalKey<Schema.String>;
235
+ /** The underlying failure (JSON syntax or schema decode), preserved structurally. */
236
+ readonly cause: Schema.Defect;
237
+ }>, import("effect/Cause").YieldableError>;
238
+ /**
239
+ * Raised when a present `tsdoctor.json` cannot be parsed or does not satisfy
240
+ * the {@link (BundleManifest:variable)} schema.
241
+ *
242
+ * @remarks
243
+ * Absence of the manifest is NEVER this error — layers enrich, never gate,
244
+ * so a missing sidecar is the normal case and reads as `Option.none()`.
245
+ *
246
+ * @public
247
+ */
248
+ declare class BundleManifestError extends BundleManifestError_base {
249
+ get message(): string;
250
+ }
251
+ /**
252
+ * Decode an unknown value into a {@link (BundleManifest:type)}.
253
+ *
254
+ * @remarks
255
+ * The typed boundary for manifest input that has already been parsed from
256
+ * JSON (plugin options, fetched payloads). File-based reading lives in
257
+ * `readBundle`, which routes through this after parsing.
258
+ *
259
+ * @public
260
+ */
261
+ declare function decodeBundleManifest(input: unknown, path?: string): Effect.Effect<BundleManifest, BundleManifestError>;
262
+ /**
263
+ * The manifest spec version this package reads and writes.
264
+ *
265
+ * @public
266
+ */
267
+ declare const MANIFEST_SPEC: 1;
268
+ /**
269
+ * The sidecar manifest's file name inside a bundle folder.
270
+ *
271
+ * @public
272
+ */
273
+ declare const TSDOCTOR_MANIFEST_FILENAME = "tsdoctor.json";
274
+ /**
275
+ * Encode a {@link (BundleManifest:type)} into the JSON-ready value a writer
276
+ * serializes as `tsdoctor.json`.
277
+ *
278
+ * @remarks
279
+ * The writer's boundary. Going through the schema rather than
280
+ * `JSON.stringify` means an emitted file is by construction what
281
+ * {@link decodeBundleManifest} accepts.
282
+ *
283
+ * @public
284
+ */
285
+ declare function encodeBundleManifest(manifest: BundleManifest): Effect.Effect<unknown, BundleManifestError>;
286
+ //#endregion
287
+ //#region src/ManifestSource.d.ts
288
+ /**
289
+ * The shape an author checks in as a `tsdoctor.json` SOURCE file, at a
290
+ * package root (the leaf tier) or a workspace root (the project tier).
291
+ *
292
+ * @remarks
293
+ * `BundleManifest` minus `spec` and `project`: a source file never declares
294
+ * its own spec version, and it never declares its inherited tier — the
295
+ * bundler supplies both when it flattens the hierarchy at emit time. Decoded
296
+ * only by writers; readers never see this shape.
297
+ *
298
+ * @public
299
+ */
300
+ declare const ManifestSource: Schema.Struct<{
301
+ readonly name: Schema.optionalKey<Schema.String>;
302
+ readonly tagline: Schema.optionalKey<Schema.String>;
303
+ readonly description: Schema.optionalKey<Schema.String>;
304
+ readonly openGraph: Schema.optionalKey<Schema.Struct<{
305
+ readonly images: Schema.optionalKey<Schema.$Array<Schema.Struct<{
306
+ readonly path: Schema.optionalKey<Schema.String>;
307
+ readonly url: Schema.optionalKey<Schema.String>;
308
+ readonly type: Schema.optionalKey<Schema.String>;
309
+ readonly width: Schema.optionalKey<Schema.Int>;
310
+ readonly height: Schema.optionalKey<Schema.Int>;
311
+ readonly alt: Schema.optionalKey<Schema.String>;
312
+ }>>>;
313
+ readonly themeColor: Schema.optionalKey<Schema.String>;
314
+ }>>;
315
+ readonly sbom: Schema.optionalKey<Schema.Struct<{
316
+ readonly path: Schema.String;
317
+ readonly format: Schema.optionalKey<Schema.String>;
318
+ }>>;
319
+ readonly registries: Schema.optionalKey<Schema.$Array<Schema.Struct<{
320
+ readonly type: Schema.String;
321
+ readonly name: Schema.String;
322
+ readonly url: Schema.String;
323
+ }>>>;
324
+ }>;
325
+ /**
326
+ * The decoded type of {@link (ManifestSource:variable)}.
327
+ *
328
+ * @public
329
+ */
330
+ type ManifestSource = typeof ManifestSource.Type;
331
+ /**
332
+ * Decode an unknown value into a {@link (ManifestSource:type)}.
333
+ *
334
+ * @public
335
+ */
336
+ declare function decodeManifestSource(input: unknown, path?: string): Effect.Effect<ManifestSource, BundleManifestError>;
337
+ //#endregion
338
+ export { BundleManifest, BundleManifestError, KNOWN_REGISTRY_TYPES, type KnownRegistryType, MANIFEST_SPEC, ManifestSource, OpenGraphConfig, OpenGraphImage, ProjectIdentity, RegistryRef, SbomRef, TSDOCTOR_MANIFEST_FILENAME, decodeBundleManifest, decodeManifestSource, encodeBundleManifest, isKnownRegistryType };
339
+ //# sourceMappingURL=index.d.ts.map
package/index.js ADDED
@@ -0,0 +1,4 @@
1
+ import { BundleManifest, BundleManifestError, KNOWN_REGISTRY_TYPES, MANIFEST_SPEC, OpenGraphConfig, OpenGraphImage, ProjectIdentity, RegistryRef, SbomRef, TSDOCTOR_MANIFEST_FILENAME, decodeBundleManifest, encodeBundleManifest, isKnownRegistryType } from "./BundleManifest.js";
2
+ import { ManifestSource, decodeManifestSource } from "./ManifestSource.js";
3
+
4
+ export { BundleManifest, BundleManifestError, KNOWN_REGISTRY_TYPES, MANIFEST_SPEC, ManifestSource, OpenGraphConfig, OpenGraphImage, ProjectIdentity, RegistryRef, SbomRef, TSDOCTOR_MANIFEST_FILENAME, decodeBundleManifest, decodeManifestSource, encodeBundleManifest, isKnownRegistryType };
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@tsdoctor/manifest",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "description": "The tsdoctor.json bundle manifest: the spec-1 schema, encode/decode boundaries and the authoring-file shape shared by bundlers that write it and readers that consume it.",
6
+ "keywords": [
7
+ "tsdoctor",
8
+ "manifest",
9
+ "api-extractor",
10
+ "effect"
11
+ ],
12
+ "homepage": "https://github.com/spencerbeggs/tsdoctor#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/spencerbeggs/tsdoctor/issues"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/spencerbeggs/tsdoctor.git",
19
+ "directory": "packages/manifest"
20
+ },
21
+ "license": "MIT",
22
+ "author": {
23
+ "name": "C. Spencer Beggs",
24
+ "email": "spencer@beggs.codes",
25
+ "url": "https://spencerbeg.gs"
26
+ },
27
+ "sideEffects": false,
28
+ "type": "module",
29
+ "exports": {
30
+ ".": {
31
+ "types": "./index.d.ts",
32
+ "import": "./index.js",
33
+ "default": "./index.js"
34
+ },
35
+ "./package.json": "./package.json"
36
+ },
37
+ "peerDependencies": {
38
+ "effect": "4.0.0-rc.109"
39
+ },
40
+ "engines": {
41
+ "node": ">=24.11.0"
42
+ }
43
+ }
@@ -0,0 +1,11 @@
1
+ // This file is read by tools that parse documentation comments conforming to the TSDoc standard.
2
+ // It should be published with your NPM package. It should not be tracked by Git.
3
+ {
4
+ "tsdocVersion": "0.12",
5
+ "toolPackages": [
6
+ {
7
+ "packageName": "@microsoft/api-extractor",
8
+ "packageVersion": "7.59.0"
9
+ }
10
+ ]
11
+ }