@tsdoctor/bundle 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/Bundle.js +127 -0
- package/BundleDiscovery.js +233 -0
- package/BundleFetch.js +348 -0
- package/BundleHash.js +107 -0
- package/BundleManifest.js +183 -0
- package/BundleResolver.js +167 -0
- package/LICENSE +21 -0
- package/PlatformOverrides.js +48 -0
- package/README.md +65 -0
- package/index.d.ts +885 -0
- package/index.js +9 -0
- package/package.json +55 -0
- package/tsdoc-metadata.json +11 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,885 @@
|
|
|
1
|
+
import { PackageManifest } from "@effected/package-json";
|
|
2
|
+
import { CompilerOptions, ResolvedTsconfig } from "@effected/tsconfig-json";
|
|
3
|
+
import { Effect, FileSystem, Option, Path, Schema } from "effect";
|
|
4
|
+
import { GitHubRelease } from "@effected/github";
|
|
5
|
+
import { NpmRegistry, PackageTarball, RegistryTarget } from "@effected/npm";
|
|
6
|
+
import { Cache } from "@effected/store";
|
|
7
|
+
import { AppDirs } from "@effected/xdg";
|
|
8
|
+
//#region src/BundleManifest.d.ts
|
|
9
|
+
/**
|
|
10
|
+
* The registry protocol families this reader knows how to do more than link
|
|
11
|
+
* to. `"npm"` means an npm-compatible registry — install commands and tarball
|
|
12
|
+
* fetching work against any instance of it — and `"jsr"` the jsr protocol.
|
|
13
|
+
*
|
|
14
|
+
* @remarks
|
|
15
|
+
* The manifest's `type` field is deliberately NOT constrained to these
|
|
16
|
+
* values: unknown future types must degrade to link-only rendering, not
|
|
17
|
+
* reject the manifest. Use {@link isKnownRegistryType} to branch.
|
|
18
|
+
*
|
|
19
|
+
* @public
|
|
20
|
+
*/
|
|
21
|
+
declare const KNOWN_REGISTRY_TYPES: readonly ["npm", "jsr"];
|
|
22
|
+
/**
|
|
23
|
+
* A registry protocol family this reader recognizes.
|
|
24
|
+
*
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
type KnownRegistryType = (typeof KNOWN_REGISTRY_TYPES)[number];
|
|
28
|
+
/**
|
|
29
|
+
* Whether a registry `type` value is a protocol family this reader
|
|
30
|
+
* recognizes. `false` means the registry entry should degrade to link-only
|
|
31
|
+
* rendering — it is never a validation failure.
|
|
32
|
+
*
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
declare function isKnownRegistryType(type: string): type is KnownRegistryType;
|
|
36
|
+
/**
|
|
37
|
+
* One registry the documented package is published to.
|
|
38
|
+
*
|
|
39
|
+
* @remarks
|
|
40
|
+
* `type` is the PROTOCOL FAMILY (`"npm"` covers every npm-compatible
|
|
41
|
+
* registry), `name` the human instance label, `url` the package's page on
|
|
42
|
+
* that instance. Unknown `type` values decode successfully and degrade to
|
|
43
|
+
* link-only rendering (see {@link isKnownRegistryType}).
|
|
44
|
+
*
|
|
45
|
+
* @public
|
|
46
|
+
*/
|
|
47
|
+
declare const RegistryRef: Schema.Struct<{
|
|
48
|
+
/** The protocol family, e.g. `"npm"` or `"jsr"`. Unknown values are accepted. */
|
|
49
|
+
readonly type: Schema.String;
|
|
50
|
+
/** The human instance label, e.g. `"npm"` or `"Savvy Web Registry"`. */
|
|
51
|
+
readonly name: Schema.String;
|
|
52
|
+
/** The package's URL on that registry instance. */
|
|
53
|
+
readonly url: Schema.String;
|
|
54
|
+
}>;
|
|
55
|
+
/**
|
|
56
|
+
* The decoded type of {@link (RegistryRef:variable)}.
|
|
57
|
+
*
|
|
58
|
+
* @public
|
|
59
|
+
*/
|
|
60
|
+
type RegistryRef = typeof RegistryRef.Type;
|
|
61
|
+
/**
|
|
62
|
+
* One Open Graph image declared by the manifest.
|
|
63
|
+
*
|
|
64
|
+
* @remarks
|
|
65
|
+
* Exactly ONE of `path` (a bundle-relative asset the consuming platform
|
|
66
|
+
* publishes and resolves to a URL) or `url` (an absolute external URL used
|
|
67
|
+
* verbatim) must be present — the schema enforces the XOR. `type` is a MIME
|
|
68
|
+
* type, inferred from the file extension by the resolver when omitted; `alt`
|
|
69
|
+
* has a documented inference chain (tagline → description →
|
|
70
|
+
* `"<name> API documentation"`).
|
|
71
|
+
*
|
|
72
|
+
* @public
|
|
73
|
+
*/
|
|
74
|
+
declare const OpenGraphImage: Schema.Struct<{
|
|
75
|
+
/** Bundle-relative asset path. Mutually exclusive with `url`. */
|
|
76
|
+
readonly path: Schema.optionalKey<Schema.String>;
|
|
77
|
+
/** Absolute external URL, used verbatim. Mutually exclusive with `path`. */
|
|
78
|
+
readonly url: Schema.optionalKey<Schema.String>;
|
|
79
|
+
/** MIME type; inferred from the extension when omitted. */
|
|
80
|
+
readonly type: Schema.optionalKey<Schema.String>;
|
|
81
|
+
/** Pixel width; 1200×630 (1.91:1) is the cross-platform safe default. */
|
|
82
|
+
readonly width: Schema.optionalKey<Schema.Int>;
|
|
83
|
+
/** Pixel height. */
|
|
84
|
+
readonly height: Schema.optionalKey<Schema.Int>;
|
|
85
|
+
/** Alt text; inferred (tagline → description → fallback) when omitted. */
|
|
86
|
+
readonly alt: Schema.optionalKey<Schema.String>;
|
|
87
|
+
}>;
|
|
88
|
+
/**
|
|
89
|
+
* The decoded type of {@link (OpenGraphImage:variable)}.
|
|
90
|
+
*
|
|
91
|
+
* @public
|
|
92
|
+
*/
|
|
93
|
+
type OpenGraphImage = typeof OpenGraphImage.Type;
|
|
94
|
+
/**
|
|
95
|
+
* The manifest's Open Graph block: the asset-ish pieces only — most OG tags
|
|
96
|
+
* are page-level and derive at render time in the consuming platform.
|
|
97
|
+
*
|
|
98
|
+
* @remarks
|
|
99
|
+
* Multiple images follow OG array semantics: the first declared wins, extras
|
|
100
|
+
* are alternates (e.g. a portrait 1000×1500 variant).
|
|
101
|
+
*
|
|
102
|
+
* @public
|
|
103
|
+
*/
|
|
104
|
+
declare const OpenGraphConfig: Schema.Struct<{
|
|
105
|
+
/** Declared images, first-wins per OG array semantics. */
|
|
106
|
+
readonly images: Schema.optionalKey<Schema.$Array<Schema.Struct<{
|
|
107
|
+
/** Bundle-relative asset path. Mutually exclusive with `url`. */
|
|
108
|
+
readonly path: Schema.optionalKey<Schema.String>;
|
|
109
|
+
/** Absolute external URL, used verbatim. Mutually exclusive with `path`. */
|
|
110
|
+
readonly url: Schema.optionalKey<Schema.String>;
|
|
111
|
+
/** MIME type; inferred from the extension when omitted. */
|
|
112
|
+
readonly type: Schema.optionalKey<Schema.String>;
|
|
113
|
+
/** Pixel width; 1200×630 (1.91:1) is the cross-platform safe default. */
|
|
114
|
+
readonly width: Schema.optionalKey<Schema.Int>;
|
|
115
|
+
/** Pixel height. */
|
|
116
|
+
readonly height: Schema.optionalKey<Schema.Int>;
|
|
117
|
+
/** Alt text; inferred (tagline → description → fallback) when omitted. */
|
|
118
|
+
readonly alt: Schema.optionalKey<Schema.String>;
|
|
119
|
+
}>>>;
|
|
120
|
+
/** Embed accent color (e.g. Discord), a CSS color string. */
|
|
121
|
+
readonly themeColor: Schema.optionalKey<Schema.String>;
|
|
122
|
+
}>;
|
|
123
|
+
/**
|
|
124
|
+
* The decoded type of {@link (OpenGraphConfig:variable)}.
|
|
125
|
+
*
|
|
126
|
+
* @public
|
|
127
|
+
*/
|
|
128
|
+
type OpenGraphConfig = typeof OpenGraphConfig.Type;
|
|
129
|
+
/**
|
|
130
|
+
* A pointer to the bundle's SBOM, computed by the bundler at publish and
|
|
131
|
+
* served as a downloadable static asset.
|
|
132
|
+
*
|
|
133
|
+
* @public
|
|
134
|
+
*/
|
|
135
|
+
declare const SbomRef: Schema.Struct<{
|
|
136
|
+
/** Bundle-relative path to the SBOM file. */
|
|
137
|
+
readonly path: Schema.String;
|
|
138
|
+
/** SBOM format label, e.g. `"spdx-json"`. Unknown values are accepted. */
|
|
139
|
+
readonly format: Schema.optionalKey<Schema.String>;
|
|
140
|
+
}>;
|
|
141
|
+
/**
|
|
142
|
+
* The decoded type of {@link (SbomRef:variable)}.
|
|
143
|
+
*
|
|
144
|
+
* @public
|
|
145
|
+
*/
|
|
146
|
+
type SbomRef = typeof SbomRef.Type;
|
|
147
|
+
/**
|
|
148
|
+
* The inherited project tier, flattened into the emitted manifest by the
|
|
149
|
+
* bundler (a fetched bundle has no parent directory to walk). Kept nested —
|
|
150
|
+
* structurally distinguishable from the leaf fields — because provenance is
|
|
151
|
+
* load-bearing for override detection.
|
|
152
|
+
*
|
|
153
|
+
* @public
|
|
154
|
+
*/
|
|
155
|
+
declare const ProjectIdentity: Schema.Struct<{
|
|
156
|
+
/** The project display name, e.g. `"Effected"` over leaf `@effected/store`. */
|
|
157
|
+
readonly name: Schema.optionalKey<Schema.String>;
|
|
158
|
+
/** The project tagline. */
|
|
159
|
+
readonly tagline: Schema.optionalKey<Schema.String>;
|
|
160
|
+
}>;
|
|
161
|
+
/**
|
|
162
|
+
* The decoded type of {@link (ProjectIdentity:variable)}.
|
|
163
|
+
*
|
|
164
|
+
* @public
|
|
165
|
+
*/
|
|
166
|
+
type ProjectIdentity = typeof ProjectIdentity.Type;
|
|
167
|
+
/**
|
|
168
|
+
* The versioned `tsdoctor.json` sidecar manifest — bundle layer 3.
|
|
169
|
+
*
|
|
170
|
+
* @remarks
|
|
171
|
+
* `spec` is the only required field; every other field enriches. Unknown
|
|
172
|
+
* top-level fields are ignored on decode (additive fields are minor spec
|
|
173
|
+
* revisions) and unknown enum-ish values (registry `type`, sbom `format`)
|
|
174
|
+
* degrade gracefully instead of rejecting — an old reader must be able to
|
|
175
|
+
* consume a new bundle.
|
|
176
|
+
*
|
|
177
|
+
* @public
|
|
178
|
+
*/
|
|
179
|
+
declare const BundleManifest: Schema.Struct<{
|
|
180
|
+
/** The integer spec version. This reader understands spec 1. */
|
|
181
|
+
readonly spec: Schema.Literal<1>;
|
|
182
|
+
/** Human display name (the npm name is dry; this one is SEO-friendly). */
|
|
183
|
+
readonly name: Schema.optionalKey<Schema.String>;
|
|
184
|
+
/** Short tagline. */
|
|
185
|
+
readonly tagline: Schema.optionalKey<Schema.String>;
|
|
186
|
+
/** Long description; overrides the package.json description when present. */
|
|
187
|
+
readonly description: Schema.optionalKey<Schema.String>;
|
|
188
|
+
/** The inherited project tier, flattened in at emit time. */
|
|
189
|
+
readonly project: Schema.optionalKey<Schema.Struct<{
|
|
190
|
+
/** The project display name, e.g. `"Effected"` over leaf `@effected/store`. */
|
|
191
|
+
readonly name: Schema.optionalKey<Schema.String>;
|
|
192
|
+
/** The project tagline. */
|
|
193
|
+
readonly tagline: Schema.optionalKey<Schema.String>;
|
|
194
|
+
}>>;
|
|
195
|
+
/** Open Graph assets. */
|
|
196
|
+
readonly openGraph: Schema.optionalKey<Schema.Struct<{
|
|
197
|
+
/** Declared images, first-wins per OG array semantics. */
|
|
198
|
+
readonly images: Schema.optionalKey<Schema.$Array<Schema.Struct<{
|
|
199
|
+
/** Bundle-relative asset path. Mutually exclusive with `url`. */
|
|
200
|
+
readonly path: Schema.optionalKey<Schema.String>;
|
|
201
|
+
/** Absolute external URL, used verbatim. Mutually exclusive with `path`. */
|
|
202
|
+
readonly url: Schema.optionalKey<Schema.String>;
|
|
203
|
+
/** MIME type; inferred from the extension when omitted. */
|
|
204
|
+
readonly type: Schema.optionalKey<Schema.String>;
|
|
205
|
+
/** Pixel width; 1200×630 (1.91:1) is the cross-platform safe default. */
|
|
206
|
+
readonly width: Schema.optionalKey<Schema.Int>;
|
|
207
|
+
/** Pixel height. */
|
|
208
|
+
readonly height: Schema.optionalKey<Schema.Int>;
|
|
209
|
+
/** Alt text; inferred (tagline → description → fallback) when omitted. */
|
|
210
|
+
readonly alt: Schema.optionalKey<Schema.String>;
|
|
211
|
+
}>>>;
|
|
212
|
+
/** Embed accent color (e.g. Discord), a CSS color string. */
|
|
213
|
+
readonly themeColor: Schema.optionalKey<Schema.String>;
|
|
214
|
+
}>>;
|
|
215
|
+
/** SBOM pointer. */
|
|
216
|
+
readonly sbom: Schema.optionalKey<Schema.Struct<{
|
|
217
|
+
/** Bundle-relative path to the SBOM file. */
|
|
218
|
+
readonly path: Schema.String;
|
|
219
|
+
/** SBOM format label, e.g. `"spdx-json"`. Unknown values are accepted. */
|
|
220
|
+
readonly format: Schema.optionalKey<Schema.String>;
|
|
221
|
+
}>>;
|
|
222
|
+
/** Registries the package is published to. */
|
|
223
|
+
readonly registries: Schema.optionalKey<Schema.$Array<Schema.Struct<{
|
|
224
|
+
/** The protocol family, e.g. `"npm"` or `"jsr"`. Unknown values are accepted. */
|
|
225
|
+
readonly type: Schema.String;
|
|
226
|
+
/** The human instance label, e.g. `"npm"` or `"Savvy Web Registry"`. */
|
|
227
|
+
readonly name: Schema.String;
|
|
228
|
+
/** The package's URL on that registry instance. */
|
|
229
|
+
readonly url: Schema.String;
|
|
230
|
+
}>>>;
|
|
231
|
+
}>;
|
|
232
|
+
/**
|
|
233
|
+
* The decoded type of {@link (BundleManifest:variable)}.
|
|
234
|
+
*
|
|
235
|
+
* @public
|
|
236
|
+
*/
|
|
237
|
+
type BundleManifest = typeof BundleManifest.Type;
|
|
238
|
+
declare const BundleManifestError_base: Schema.Class<BundleManifestError, Schema.TaggedStruct<"BundleManifestError", {
|
|
239
|
+
/** The manifest file path, when the failure is tied to a file on disk. */
|
|
240
|
+
readonly path: Schema.optionalKey<Schema.String>;
|
|
241
|
+
/** The underlying failure (JSON syntax or schema decode), preserved structurally. */
|
|
242
|
+
readonly cause: Schema.Defect;
|
|
243
|
+
}>, import("effect/Cause").YieldableError>;
|
|
244
|
+
/**
|
|
245
|
+
* Raised when a present `tsdoctor.json` cannot be parsed or does not satisfy
|
|
246
|
+
* the {@link (BundleManifest:variable)} schema.
|
|
247
|
+
*
|
|
248
|
+
* @remarks
|
|
249
|
+
* Absence of the manifest is NEVER this error — layers enrich, never gate,
|
|
250
|
+
* so a missing sidecar is the normal case and reads as `Option.none()`.
|
|
251
|
+
*
|
|
252
|
+
* @public
|
|
253
|
+
*/
|
|
254
|
+
declare class BundleManifestError extends BundleManifestError_base {
|
|
255
|
+
get message(): string;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Decode an unknown value into a {@link (BundleManifest:type)}.
|
|
259
|
+
*
|
|
260
|
+
* @remarks
|
|
261
|
+
* The typed boundary for manifest input that has already been parsed from
|
|
262
|
+
* JSON (plugin options, fetched payloads). File-based reading lives in
|
|
263
|
+
* `readBundle`, which routes through this after parsing.
|
|
264
|
+
*
|
|
265
|
+
* @public
|
|
266
|
+
*/
|
|
267
|
+
declare function decodeBundleManifest(input: unknown, path?: string): Effect.Effect<BundleManifest, BundleManifestError>;
|
|
268
|
+
//#endregion
|
|
269
|
+
//#region src/Bundle.d.ts
|
|
270
|
+
/**
|
|
271
|
+
* The sidecar manifest's file name inside a bundle folder.
|
|
272
|
+
*
|
|
273
|
+
* @public
|
|
274
|
+
*/
|
|
275
|
+
declare const TSDOCTOR_MANIFEST_FILENAME = "tsdoctor.json";
|
|
276
|
+
/**
|
|
277
|
+
* The subset of a `<name>.api.json` model this package reads: the package
|
|
278
|
+
* name from the model's own metadata.
|
|
279
|
+
*
|
|
280
|
+
* @remarks
|
|
281
|
+
* Full model loading (entry points, members, TSDoc) is `@tsdoctor/model`'s
|
|
282
|
+
* job — this package deliberately stays free of
|
|
283
|
+
* `@microsoft/api-extractor-model` and reads only what discovery and
|
|
284
|
+
* resolution need.
|
|
285
|
+
*
|
|
286
|
+
* @public
|
|
287
|
+
*/
|
|
288
|
+
interface ApiModelInfo {
|
|
289
|
+
/** The documented package's npm name, from the model's `name` field. */
|
|
290
|
+
readonly name: string;
|
|
291
|
+
}
|
|
292
|
+
declare const BundleLayerError_base: Schema.Class<BundleLayerError, Schema.TaggedStruct<"BundleLayerError", {
|
|
293
|
+
/** Which bundle layer failed. */
|
|
294
|
+
readonly layer: Schema.Literals<readonly ["apiModel", "packageJson", "tsconfig"]>;
|
|
295
|
+
/** The file that failed. */
|
|
296
|
+
readonly path: Schema.String;
|
|
297
|
+
/** The underlying failure, preserved structurally. */
|
|
298
|
+
readonly cause: Schema.Defect;
|
|
299
|
+
}>, import("effect/Cause").YieldableError>;
|
|
300
|
+
/**
|
|
301
|
+
* Raised when a PRESENT bundle layer file cannot be read, parsed or decoded.
|
|
302
|
+
*
|
|
303
|
+
* @remarks
|
|
304
|
+
* Absence of layers 1–3 is the normal case (layers enrich, never gate) and
|
|
305
|
+
* reads as `Option.none()`, never as this error. A file that exists but is
|
|
306
|
+
* malformed is a real problem worth surfacing, not degrading past. Manifest
|
|
307
|
+
* (layer 3) failures use {@link BundleManifestError} instead, so manifest
|
|
308
|
+
* consumers handle one tag across the file and non-file boundaries.
|
|
309
|
+
*
|
|
310
|
+
* @public
|
|
311
|
+
*/
|
|
312
|
+
declare class BundleLayerError extends BundleLayerError_base {
|
|
313
|
+
get message(): string;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Where a bundle's layer files live: the output of discovery, the input of
|
|
317
|
+
* {@link readBundle}.
|
|
318
|
+
*
|
|
319
|
+
* @remarks
|
|
320
|
+
* `modelPath` is the one required layer; the optional path fields are present
|
|
321
|
+
* iff the corresponding file existed at discovery time. `name` and `version`
|
|
322
|
+
* are pre-parsed during discovery (name from package.json, falling back to
|
|
323
|
+
* the api.json model; version from package.json when present).
|
|
324
|
+
*
|
|
325
|
+
* @public
|
|
326
|
+
*/
|
|
327
|
+
interface BundleDescriptor {
|
|
328
|
+
/** Absolute path to the bundle folder. */
|
|
329
|
+
readonly dir: string;
|
|
330
|
+
/** Last path segment of `dir`, e.g. `"kitchensink"`. */
|
|
331
|
+
readonly dirname: string;
|
|
332
|
+
/** The documented package's npm name. */
|
|
333
|
+
readonly name: string;
|
|
334
|
+
/** The package version from package.json, when present. */
|
|
335
|
+
readonly version?: string;
|
|
336
|
+
/** Absolute path to the layer-0 `*.api.json` model. */
|
|
337
|
+
readonly modelPath: string;
|
|
338
|
+
/** Absolute path to the layer-1 package.json, when present. */
|
|
339
|
+
readonly packageJsonPath?: string;
|
|
340
|
+
/** Absolute path to the layer-2 tsconfig.json, when present. */
|
|
341
|
+
readonly tsconfigPath?: string;
|
|
342
|
+
/** Absolute path to the layer-3 tsdoctor.json manifest, when present. */
|
|
343
|
+
readonly manifestPath?: string;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* A bundle with all four layers read into typed structures. Layers 1–3 are
|
|
347
|
+
* `Option`s because their absence is the normal case.
|
|
348
|
+
*
|
|
349
|
+
* @public
|
|
350
|
+
*/
|
|
351
|
+
interface Bundle {
|
|
352
|
+
/** The descriptor the bundle was read from. */
|
|
353
|
+
readonly descriptor: BundleDescriptor;
|
|
354
|
+
/** Layer 0: the api.json model header (always present). */
|
|
355
|
+
readonly apiModel: ApiModelInfo;
|
|
356
|
+
/** Layer 1: the package.json manifest, presence-lenient. */
|
|
357
|
+
readonly packageJson: Option.Option<PackageManifest>;
|
|
358
|
+
/** Layer 2: the tsconfig, extends-resolved. */
|
|
359
|
+
readonly tsconfig: Option.Option<ResolvedTsconfig>;
|
|
360
|
+
/** Layer 3: the tsdoctor.json sidecar manifest. */
|
|
361
|
+
readonly manifest: Option.Option<BundleManifest>;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Read the layer-0 model header — the package name — from a `*.api.json`
|
|
365
|
+
* file.
|
|
366
|
+
*
|
|
367
|
+
* @remarks
|
|
368
|
+
* Parses the whole file as JSON but validates only the `name` field; see
|
|
369
|
+
* {@link ApiModelInfo} for why nothing more is read here.
|
|
370
|
+
*
|
|
371
|
+
* @public
|
|
372
|
+
*/
|
|
373
|
+
declare function readApiModelInfo(modelPath: string): Effect.Effect<ApiModelInfo, BundleLayerError, FileSystem.FileSystem>;
|
|
374
|
+
/**
|
|
375
|
+
* Read all four layers of a discovered bundle into a {@link Bundle}.
|
|
376
|
+
*
|
|
377
|
+
* @remarks
|
|
378
|
+
* Layer 0 is required; layers 1–3 read to `Option.none()` when the
|
|
379
|
+
* descriptor recorded no file for them. A layer file that is present but
|
|
380
|
+
* malformed fails typed ({@link BundleLayerError}, or
|
|
381
|
+
* {@link BundleManifestError} for the manifest) — lenient about absence,
|
|
382
|
+
* strict about shape. `FileSystem` and `Path` stay in the `R` channel;
|
|
383
|
+
* provide the platform layer once at the application boundary.
|
|
384
|
+
*
|
|
385
|
+
* @public
|
|
386
|
+
*/
|
|
387
|
+
declare function readBundle(descriptor: BundleDescriptor): Effect.Effect<Bundle, BundleLayerError | BundleManifestError, FileSystem.FileSystem | Path.Path>;
|
|
388
|
+
//#endregion
|
|
389
|
+
//#region src/BundleDiscovery.d.ts
|
|
390
|
+
declare const BundleDiscoveryError_base: Schema.Class<BundleDiscoveryError, Schema.TaggedStruct<"BundleDiscoveryError", {
|
|
391
|
+
/** The directory (or file) the failure is about. */
|
|
392
|
+
readonly path: Schema.String;
|
|
393
|
+
/** What went wrong, structurally. */
|
|
394
|
+
readonly reason: Schema.Literals<readonly ["notFound", "notADirectory", "noApiModel", "ambiguousApiModel", "invalidPackageJson", "unreadableDirectory", "notABundleFolder", "emptyParent"]>;
|
|
395
|
+
/** Human context for the failure (candidate lists, offending names). */
|
|
396
|
+
readonly detail: Schema.optionalKey<Schema.String>;
|
|
397
|
+
/** The underlying failure, when one exists, preserved structurally. */
|
|
398
|
+
readonly cause: Schema.optionalKey<Schema.Defect>;
|
|
399
|
+
}>, import("effect/Cause").YieldableError>;
|
|
400
|
+
/**
|
|
401
|
+
* Raised when a directory cannot be resolved into a bundle descriptor.
|
|
402
|
+
*
|
|
403
|
+
* @remarks
|
|
404
|
+
* Discovery failures are USER-facing wiring problems — a missing folder, no
|
|
405
|
+
* model file, an ambiguous model set — so the `reason` is a typed literal a
|
|
406
|
+
* consumer can branch on for actionable messaging.
|
|
407
|
+
*
|
|
408
|
+
* @public
|
|
409
|
+
*/
|
|
410
|
+
declare class BundleDiscoveryError extends BundleDiscoveryError_base {
|
|
411
|
+
get message(): string;
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Overrides for {@link discoverBundle}. Any supplied field wins over
|
|
415
|
+
* discovery.
|
|
416
|
+
*
|
|
417
|
+
* @public
|
|
418
|
+
*/
|
|
419
|
+
interface BundleOverrides {
|
|
420
|
+
/** The package name to use instead of the discovered one. */
|
|
421
|
+
readonly name?: string;
|
|
422
|
+
/** The version to use instead of the discovered one. */
|
|
423
|
+
readonly version?: string;
|
|
424
|
+
/** The model path to use instead of `*.api.json` discovery (resolved against the bundle dir when relative). */
|
|
425
|
+
readonly modelPath?: string;
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Options for {@link discoverBundle}.
|
|
429
|
+
*
|
|
430
|
+
* @public
|
|
431
|
+
*/
|
|
432
|
+
interface DiscoverBundleOptions {
|
|
433
|
+
/** Base for resolving a relative `dir`. When omitted, a relative `dir` resolves per the injected `Path` service. */
|
|
434
|
+
readonly cwd?: string;
|
|
435
|
+
/** Caller-supplied fields that win over discovery. */
|
|
436
|
+
readonly overrides?: BundleOverrides;
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Options for {@link discoverBundles}.
|
|
440
|
+
*
|
|
441
|
+
* @public
|
|
442
|
+
*/
|
|
443
|
+
interface DiscoverBundlesOptions {
|
|
444
|
+
/** Base for resolving a relative `parentDir`. */
|
|
445
|
+
readonly cwd?: string;
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Discover a single bundle folder into a {@link BundleDescriptor}.
|
|
449
|
+
*
|
|
450
|
+
* @remarks
|
|
451
|
+
* Generalizes the RSPress plugin's `api.fromDir` helper, framework-neutral:
|
|
452
|
+
* no route derivation — that stays in the adapter. Layer 0 (`*.api.json`) is
|
|
453
|
+
* required; package.json, tsconfig.json and tsdoctor.json are recorded when
|
|
454
|
+
* present. The package name comes from package.json when it has one, falling
|
|
455
|
+
* back to the api.json model's own name; the version comes from package.json
|
|
456
|
+
* alone. Caller overrides win over discovery. `FileSystem` and `Path` stay
|
|
457
|
+
* in the `R` channel — provide the platform layer at the application
|
|
458
|
+
* boundary.
|
|
459
|
+
*
|
|
460
|
+
* @public
|
|
461
|
+
*/
|
|
462
|
+
declare function discoverBundle(dir: string, options?: DiscoverBundleOptions): Effect.Effect<BundleDescriptor, BundleDiscoveryError | BundleLayerError, FileSystem.FileSystem | Path.Path>;
|
|
463
|
+
/**
|
|
464
|
+
* Strictly scan a parent directory and discover one bundle per subfolder.
|
|
465
|
+
*
|
|
466
|
+
* @remarks
|
|
467
|
+
* Generalizes the RSPress plugin's `apis.fromDir`: every non-dotfile
|
|
468
|
+
* subdirectory MUST be a valid bundle folder (contain at least one
|
|
469
|
+
* `*.api.json`) — a stray subfolder fails discovery with guidance to use
|
|
470
|
+
* {@link discoverBundle} for selective inclusion — and an empty scan is a
|
|
471
|
+
* failure, not an empty array (the models have probably not been built).
|
|
472
|
+
* Subfolders are processed in sorted order.
|
|
473
|
+
*
|
|
474
|
+
* @public
|
|
475
|
+
*/
|
|
476
|
+
declare function discoverBundles(parentDir: string, options?: DiscoverBundlesOptions): Effect.Effect<ReadonlyArray<BundleDescriptor>, BundleDiscoveryError | BundleLayerError, FileSystem.FileSystem | Path.Path>;
|
|
477
|
+
/**
|
|
478
|
+
* Discover and read a single bundle in one call.
|
|
479
|
+
*
|
|
480
|
+
* @public
|
|
481
|
+
*/
|
|
482
|
+
declare function loadBundle(dir: string, options?: DiscoverBundleOptions): Effect.Effect<Bundle, BundleDiscoveryError | BundleLayerError | BundleManifestError, FileSystem.FileSystem | Path.Path>;
|
|
483
|
+
/**
|
|
484
|
+
* Discover and read every bundle under a parent directory in one call.
|
|
485
|
+
*
|
|
486
|
+
* @public
|
|
487
|
+
*/
|
|
488
|
+
declare function loadBundles(parentDir: string, options?: DiscoverBundlesOptions): Effect.Effect<ReadonlyArray<Bundle>, BundleDiscoveryError | BundleLayerError | BundleManifestError, FileSystem.FileSystem | Path.Path>;
|
|
489
|
+
//#endregion
|
|
490
|
+
//#region src/BundleFetch.d.ts
|
|
491
|
+
declare const BundleFetchError_base: Schema.Class<BundleFetchError, Schema.TaggedStruct<"BundleFetchError", {
|
|
492
|
+
/** Which fetcher failed. */
|
|
493
|
+
readonly source: Schema.Literals<readonly ["npm", "github"]>;
|
|
494
|
+
/** What went wrong, structurally. */
|
|
495
|
+
readonly reason: Schema.Literals<readonly ["invalidRef", "versionNotFound", "releaseNotFound", "assetNotFound", "assetAmbiguous", "download", "notABundle", "cache"]>;
|
|
496
|
+
/** The remote coordinate: `name@version` or `owner/repo@tag#asset`. */
|
|
497
|
+
readonly ref: Schema.String;
|
|
498
|
+
/** Human context for the failure. */
|
|
499
|
+
readonly detail: Schema.optionalKey<Schema.String>;
|
|
500
|
+
/** The underlying failure, when one exists, preserved structurally. */
|
|
501
|
+
readonly cause: Schema.optionalKey<Schema.Defect>;
|
|
502
|
+
}>, import("effect/Cause").YieldableError>;
|
|
503
|
+
/**
|
|
504
|
+
* Raised when a remote bundle cannot be fetched into the local cache.
|
|
505
|
+
*
|
|
506
|
+
* @remarks
|
|
507
|
+
* Fetch-plane failures speak in remote terms (`ref` names the coordinate the
|
|
508
|
+
* caller asked for, never a temp directory). Post-fetch READ failures — a
|
|
509
|
+
* fetched artifact whose layer files are malformed — surface as the same
|
|
510
|
+
* typed errors local reads produce (`BundleLayerError`,
|
|
511
|
+
* `BundleManifestError`), so a consumer handles one vocabulary for both.
|
|
512
|
+
*
|
|
513
|
+
* @public
|
|
514
|
+
*/
|
|
515
|
+
declare class BundleFetchError extends BundleFetchError_base {
|
|
516
|
+
get message(): string;
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Options for {@link fetchNpmBundle}.
|
|
520
|
+
*
|
|
521
|
+
* @public
|
|
522
|
+
*/
|
|
523
|
+
interface FetchNpmBundleOptions {
|
|
524
|
+
/** The published package name. */
|
|
525
|
+
readonly name: string;
|
|
526
|
+
/**
|
|
527
|
+
* An exact version or a dist-tag (e.g. `"latest"`). Ranges are not
|
|
528
|
+
* resolved by this fetcher — resolve them upstream.
|
|
529
|
+
*/
|
|
530
|
+
readonly version: string;
|
|
531
|
+
/**
|
|
532
|
+
* The registry to read — any `type: "npm"` (npm-protocol-family) registry,
|
|
533
|
+
* per the manifest's registries semantics. Defaults to the public npm
|
|
534
|
+
* registry.
|
|
535
|
+
*/
|
|
536
|
+
readonly target?: RegistryTarget;
|
|
537
|
+
/** Bypass the cache and refetch. */
|
|
538
|
+
readonly refresh?: boolean;
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Options for {@link fetchGitHubReleaseBundle}.
|
|
542
|
+
*
|
|
543
|
+
* @public
|
|
544
|
+
*/
|
|
545
|
+
interface FetchGitHubReleaseBundleOptions {
|
|
546
|
+
/** The repository owner. */
|
|
547
|
+
readonly owner: string;
|
|
548
|
+
/** The repository name. */
|
|
549
|
+
readonly repo: string;
|
|
550
|
+
/** The release tag. */
|
|
551
|
+
readonly tag: string;
|
|
552
|
+
/**
|
|
553
|
+
* The exact asset file name. When omitted, the release must carry exactly
|
|
554
|
+
* ONE `*.npm.meta.tgz` asset (the bundle release variant) and that asset
|
|
555
|
+
* is used.
|
|
556
|
+
*/
|
|
557
|
+
readonly asset?: string;
|
|
558
|
+
/**
|
|
559
|
+
* Bypass the cache and refetch. Unlike npm versions, a git tag CAN move —
|
|
560
|
+
* the cache treats tags as immutable by default, and this is the escape
|
|
561
|
+
* hatch when one has.
|
|
562
|
+
*/
|
|
563
|
+
readonly refresh?: boolean;
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Fetch one published npm package version as a bundle, through the durable
|
|
567
|
+
* XDG cache.
|
|
568
|
+
*
|
|
569
|
+
* @remarks
|
|
570
|
+
* Works against any npm-protocol-family registry via `target` (the
|
|
571
|
+
* `type: "npm"` semantics of the manifest's registries block). The tarball is
|
|
572
|
+
* downloaded, integrity-verified and extracted by `@effected/npm`'s
|
|
573
|
+
* `PackageTarball`, its bundle layer files are copied into
|
|
574
|
+
* `<xdg-cache>/tsdoctor/bundles/npm/<name>/<version>/`, and the returned
|
|
575
|
+
* {@link Bundle}'s descriptor points at that durable directory. A published
|
|
576
|
+
* npm version is immutable, so a cache hit skips the network entirely;
|
|
577
|
+
* `refresh: true` forces a refetch.
|
|
578
|
+
*
|
|
579
|
+
* Provide the `NpmRegistry`, `PackageTarball`, `Cache` and `AppDirs`
|
|
580
|
+
* services (plus `FileSystem`/`Path`) at the application boundary.
|
|
581
|
+
*
|
|
582
|
+
* @public
|
|
583
|
+
*/
|
|
584
|
+
declare function fetchNpmBundle(options: FetchNpmBundleOptions): Effect.Effect<Bundle, BundleFetchError | BundleLayerError | BundleManifestError, NpmRegistry | PackageTarball | Cache | AppDirs | FileSystem.FileSystem | Path.Path>;
|
|
585
|
+
/**
|
|
586
|
+
* Fetch a bundle attached to a GitHub release as a `*.npm.meta.tgz`-style
|
|
587
|
+
* asset, through the durable XDG cache.
|
|
588
|
+
*
|
|
589
|
+
* @remarks
|
|
590
|
+
* The release is looked up by tag via `@effected/github`'s `GitHubRelease`
|
|
591
|
+
* (the `Repo` context is provided internally from `owner`/`repo`), the chosen
|
|
592
|
+
* asset is downloaded and extracted through the same verified
|
|
593
|
+
* `PackageTarball` path the npm fetcher uses (no integrity is available for
|
|
594
|
+
* release assets, so the download is unverified — the extractor logs this),
|
|
595
|
+
* and the layer files land in
|
|
596
|
+
* `<xdg-cache>/tsdoctor/bundles/github/<owner>/<repo>/<tag>/<asset>/`.
|
|
597
|
+
*
|
|
598
|
+
* A tarball with an npm-style `package/` root and one with its files at the
|
|
599
|
+
* archive root are both accepted. Git tags CAN move; the cache treats them as
|
|
600
|
+
* immutable and `refresh: true` is the escape hatch. Private-repo assets are
|
|
601
|
+
* not supported yet: the asset's browser download URL is fetched directly,
|
|
602
|
+
* which works for public releases only.
|
|
603
|
+
*
|
|
604
|
+
* @public
|
|
605
|
+
*/
|
|
606
|
+
declare function fetchGitHubReleaseBundle(options: FetchGitHubReleaseBundleOptions): Effect.Effect<Bundle, BundleFetchError | BundleLayerError | BundleManifestError, GitHubRelease | PackageTarball | Cache | AppDirs | FileSystem.FileSystem | Path.Path>;
|
|
607
|
+
//#endregion
|
|
608
|
+
//#region src/PlatformOverrides.d.ts
|
|
609
|
+
/**
|
|
610
|
+
* The `manifest.platform` tier: a data-override object a consumer passes
|
|
611
|
+
* through platform options (e.g. `ApiExtractorPlugin(options)`), sitting at
|
|
612
|
+
* the TOP of the tier ranking.
|
|
613
|
+
*
|
|
614
|
+
* @remarks
|
|
615
|
+
* Same field surface as the authored manifest tiers — name, tagline,
|
|
616
|
+
* description, openGraph, sbom, registries — with no `spec` field (it is not
|
|
617
|
+
* a file with an independent version) and no `project` block (it is a single
|
|
618
|
+
* tier, not a flattened hierarchy). Lets a user with ONLY an api.json declare
|
|
619
|
+
* identity/OG/registries declaratively; the resolver does the merging.
|
|
620
|
+
*
|
|
621
|
+
* @public
|
|
622
|
+
*/
|
|
623
|
+
declare const PlatformOverrides: Schema.Struct<{
|
|
624
|
+
/** Human display name override. */
|
|
625
|
+
readonly name: Schema.optionalKey<Schema.String>;
|
|
626
|
+
/** Tagline override. */
|
|
627
|
+
readonly tagline: Schema.optionalKey<Schema.String>;
|
|
628
|
+
/** Description override. */
|
|
629
|
+
readonly description: Schema.optionalKey<Schema.String>;
|
|
630
|
+
/** Open Graph override. */
|
|
631
|
+
readonly openGraph: Schema.optionalKey<Schema.Struct<{
|
|
632
|
+
readonly images: Schema.optionalKey<Schema.$Array<Schema.Struct<{
|
|
633
|
+
readonly path: Schema.optionalKey<Schema.String>;
|
|
634
|
+
readonly url: Schema.optionalKey<Schema.String>;
|
|
635
|
+
readonly type: Schema.optionalKey<Schema.String>;
|
|
636
|
+
readonly width: Schema.optionalKey<Schema.Int>;
|
|
637
|
+
readonly height: Schema.optionalKey<Schema.Int>;
|
|
638
|
+
readonly alt: Schema.optionalKey<Schema.String>;
|
|
639
|
+
}>>>;
|
|
640
|
+
readonly themeColor: Schema.optionalKey<Schema.String>;
|
|
641
|
+
}>>;
|
|
642
|
+
/** SBOM pointer override. */
|
|
643
|
+
readonly sbom: Schema.optionalKey<Schema.Struct<{
|
|
644
|
+
readonly path: Schema.String;
|
|
645
|
+
readonly format: Schema.optionalKey<Schema.String>;
|
|
646
|
+
}>>;
|
|
647
|
+
/** Registries override. */
|
|
648
|
+
readonly registries: Schema.optionalKey<Schema.$Array<Schema.Struct<{
|
|
649
|
+
readonly type: Schema.String;
|
|
650
|
+
readonly name: Schema.String;
|
|
651
|
+
readonly url: Schema.String;
|
|
652
|
+
}>>>;
|
|
653
|
+
}>;
|
|
654
|
+
/**
|
|
655
|
+
* The decoded type of {@link (PlatformOverrides:variable)}.
|
|
656
|
+
*
|
|
657
|
+
* @public
|
|
658
|
+
*/
|
|
659
|
+
type PlatformOverrides = typeof PlatformOverrides.Type;
|
|
660
|
+
/**
|
|
661
|
+
* Decode an unknown value into a {@link (PlatformOverrides:type)}.
|
|
662
|
+
*
|
|
663
|
+
* @remarks
|
|
664
|
+
* For adapters decoding raw platform options. Failures share
|
|
665
|
+
* {@link BundleManifestError} — the platform tier is manifest data by another
|
|
666
|
+
* route, and a caller handles both boundaries with one tag.
|
|
667
|
+
*
|
|
668
|
+
* @public
|
|
669
|
+
*/
|
|
670
|
+
declare function decodePlatformOverrides(input: unknown): Effect.Effect<PlatformOverrides, BundleManifestError>;
|
|
671
|
+
//#endregion
|
|
672
|
+
//#region src/BundleResolver.d.ts
|
|
673
|
+
/**
|
|
674
|
+
* Where a resolved field's value came from, highest-ranked tier first.
|
|
675
|
+
*
|
|
676
|
+
* @remarks
|
|
677
|
+
* The first six values are the spec's tier ladder. `"tsconfig"` is this
|
|
678
|
+
* package's one addition: the spec passes tsconfig compiler options through
|
|
679
|
+
* as a resolved field but its ladder has no source that names the tsconfig
|
|
680
|
+
* layer, so the union carries one.
|
|
681
|
+
*
|
|
682
|
+
* @public
|
|
683
|
+
*/
|
|
684
|
+
type ProvenanceSource = "manifest.platform" | "manifest.leaf" | "manifest.project" | "packageJson" | "apiModel" | "tsconfig" | "inferred";
|
|
685
|
+
/**
|
|
686
|
+
* A resolved value carrying its provenance.
|
|
687
|
+
*
|
|
688
|
+
* @remarks
|
|
689
|
+
* Provenance is load-bearing: a field is user-overridden iff its source
|
|
690
|
+
* outranks the derivation that would otherwise supply it, an `inferred`
|
|
691
|
+
* field tracks upstream changes while an authored field is pinned, and the
|
|
692
|
+
* change-detection fingerprints hash value AND source together so an
|
|
693
|
+
* override flip is a visible diff.
|
|
694
|
+
*
|
|
695
|
+
* @public
|
|
696
|
+
*/
|
|
697
|
+
interface Provenanced<A> {
|
|
698
|
+
/** The resolved value. */
|
|
699
|
+
readonly value: A;
|
|
700
|
+
/** The tier that supplied it. */
|
|
701
|
+
readonly source: ProvenanceSource;
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* One Open Graph image after resolution: authored fields passed through,
|
|
705
|
+
* `type` and `alt` filled by the documented inference rules when absent.
|
|
706
|
+
*
|
|
707
|
+
* @public
|
|
708
|
+
*/
|
|
709
|
+
interface ResolvedOpenGraphImage {
|
|
710
|
+
/** Bundle-relative asset path, when the image is bundle-supplied. */
|
|
711
|
+
readonly path?: string;
|
|
712
|
+
/** Absolute external URL, when the image is external. */
|
|
713
|
+
readonly url?: string;
|
|
714
|
+
/** MIME type — authored, or inferred from the file extension. */
|
|
715
|
+
readonly type?: Provenanced<string>;
|
|
716
|
+
/** Pixel width, as authored. */
|
|
717
|
+
readonly width?: number;
|
|
718
|
+
/** Pixel height, as authored. */
|
|
719
|
+
readonly height?: number;
|
|
720
|
+
/** Alt text — authored, or inferred (tagline → description → `"<name> API documentation"`); never empty. */
|
|
721
|
+
readonly alt: Provenanced<string>;
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* The Open Graph block after resolution.
|
|
725
|
+
*
|
|
726
|
+
* @public
|
|
727
|
+
*/
|
|
728
|
+
interface ResolvedOpenGraph {
|
|
729
|
+
/** Resolved images, first-declared-wins per OG array semantics. */
|
|
730
|
+
readonly images: ReadonlyArray<ResolvedOpenGraphImage>;
|
|
731
|
+
/** Embed accent color, when authored. */
|
|
732
|
+
readonly themeColor?: string;
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* A bundle's manifest data resolved across the six tiers, every field
|
|
736
|
+
* carrying value + provenance.
|
|
737
|
+
*
|
|
738
|
+
* @remarks
|
|
739
|
+
* Fields that no tier supplies are absent — with two floors: `name` always
|
|
740
|
+
* resolves (the api.json model always has one) and every resolved image's
|
|
741
|
+
* `alt` always resolves (the inference chain bottoms out on `name`).
|
|
742
|
+
*
|
|
743
|
+
* @public
|
|
744
|
+
*/
|
|
745
|
+
interface ResolvedBundle {
|
|
746
|
+
/** Display name: platform → leaf manifest → package.json → api.json model. */
|
|
747
|
+
readonly name: Provenanced<string>;
|
|
748
|
+
/** Package version, from package.json. */
|
|
749
|
+
readonly version?: Provenanced<string>;
|
|
750
|
+
/** Tagline: platform → leaf manifest → project tier. */
|
|
751
|
+
readonly tagline?: Provenanced<string>;
|
|
752
|
+
/** Description: platform → leaf manifest → package.json. */
|
|
753
|
+
readonly description?: Provenanced<string>;
|
|
754
|
+
/** The project identity block, when the manifest carries one. */
|
|
755
|
+
readonly project?: Provenanced<ProjectIdentity>;
|
|
756
|
+
/** Open Graph block: platform → leaf manifest, with per-image inference applied. */
|
|
757
|
+
readonly openGraph?: Provenanced<ResolvedOpenGraph>;
|
|
758
|
+
/** SBOM pointer: platform → leaf manifest. */
|
|
759
|
+
readonly sbom?: Provenanced<SbomRef>;
|
|
760
|
+
/** Registries: platform → leaf manifest. */
|
|
761
|
+
readonly registries?: Provenanced<ReadonlyArray<RegistryRef>>;
|
|
762
|
+
/** Runtime dependencies from package.json, key-sorted. Feeds the type registry's rendering scope. */
|
|
763
|
+
readonly dependencies?: Provenanced<Readonly<Record<string, string>>>;
|
|
764
|
+
/** Peer dependencies from package.json, key-sorted. Feeds the type registry's rendering scope. */
|
|
765
|
+
readonly peerDependencies?: Provenanced<Readonly<Record<string, string>>>;
|
|
766
|
+
/** Extends-resolved compiler options from tsconfig.json. Feeds the Twoslash environment. */
|
|
767
|
+
readonly compilerOptions?: Provenanced<CompilerOptions.Type>;
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
* The parsed layers {@link resolveBundle} resolves — plain optional fields,
|
|
771
|
+
* so pure call sites (and tests) need no `Option` wrapping.
|
|
772
|
+
*
|
|
773
|
+
* @public
|
|
774
|
+
*/
|
|
775
|
+
interface ResolveBundleInput {
|
|
776
|
+
/** Layer 0: the model header (required — the one layer a bundle must have). */
|
|
777
|
+
readonly apiModel: ApiModelInfo;
|
|
778
|
+
/** Layer 1: the package.json manifest, when present. */
|
|
779
|
+
readonly packageJson?: PackageManifest;
|
|
780
|
+
/** Layer 2: the extends-resolved tsconfig, when present. */
|
|
781
|
+
readonly tsconfig?: ResolvedTsconfig;
|
|
782
|
+
/** Layer 3: the tsdoctor.json sidecar manifest, when present. */
|
|
783
|
+
readonly manifest?: BundleManifest;
|
|
784
|
+
/** The `manifest.platform` tier, from platform options. */
|
|
785
|
+
readonly platform?: PlatformOverrides;
|
|
786
|
+
}
|
|
787
|
+
/**
|
|
788
|
+
* Resolve a bundle's layers into a {@link ResolvedBundle}, pure.
|
|
789
|
+
*
|
|
790
|
+
* @remarks
|
|
791
|
+
* Highest tier wins per FIELD: `manifest.platform` → `manifest.leaf` →
|
|
792
|
+
* `manifest.project` → `packageJson` → `apiModel` → `inferred`. The project
|
|
793
|
+
* tier participates only in the fields it carries site/project identity for
|
|
794
|
+
* (tagline); the display `name` chain deliberately skips it — a project name
|
|
795
|
+
* outranking every leaf's own name would render each package in a monorepo
|
|
796
|
+
* under the same title, and the spec's `og:title` derivation reads
|
|
797
|
+
* `leaf name/tagline ← package name`. Inference (image `alt` and MIME
|
|
798
|
+
* `type`) runs on the RESOLVED tagline/description, so a tagline change at
|
|
799
|
+
* any tier propagates into inferred alt text.
|
|
800
|
+
*
|
|
801
|
+
* @public
|
|
802
|
+
*/
|
|
803
|
+
declare function resolveBundle(input: ResolveBundleInput): ResolvedBundle;
|
|
804
|
+
/**
|
|
805
|
+
* Resolve a read {@link Bundle}, unwrapping its `Option` layers.
|
|
806
|
+
*
|
|
807
|
+
* @public
|
|
808
|
+
*/
|
|
809
|
+
declare function resolveBundleFrom(bundle: Bundle, platform?: PlatformOverrides): ResolvedBundle;
|
|
810
|
+
//#endregion
|
|
811
|
+
//#region src/BundleHash.d.ts
|
|
812
|
+
/**
|
|
813
|
+
* Serialize a JSON-shaped value canonically: object keys sorted recursively,
|
|
814
|
+
* `undefined`-valued keys dropped, arrays in declared order, no whitespace.
|
|
815
|
+
*
|
|
816
|
+
* @remarks
|
|
817
|
+
* The normalization half of the change-detection discipline: two values that
|
|
818
|
+
* differ only in key order or optional-key presence-as-`undefined` serialize
|
|
819
|
+
* identically, so their hashes match. Non-JSON leaves (functions, symbols)
|
|
820
|
+
* serialize as `null`, matching `JSON.stringify` semantics inside arrays.
|
|
821
|
+
*
|
|
822
|
+
* @public
|
|
823
|
+
*/
|
|
824
|
+
declare function canonicalJson(value: unknown): string;
|
|
825
|
+
/**
|
|
826
|
+
* Normalize text for hashing: CRLF/CR line endings become LF and trailing
|
|
827
|
+
* whitespace at the end of the content is trimmed.
|
|
828
|
+
*
|
|
829
|
+
* @remarks
|
|
830
|
+
* The same file checked out with different line-ending settings must hash
|
|
831
|
+
* identically — coarse layer-hash comparison otherwise reports every file
|
|
832
|
+
* changed on the first cross-platform build.
|
|
833
|
+
*
|
|
834
|
+
* @public
|
|
835
|
+
*/
|
|
836
|
+
declare function normalizeText(text: string): string;
|
|
837
|
+
/**
|
|
838
|
+
* The lowercase hex SHA-256 of a string, UTF-8 encoded.
|
|
839
|
+
*
|
|
840
|
+
* @public
|
|
841
|
+
*/
|
|
842
|
+
declare function sha256Hex(text: string): string;
|
|
843
|
+
/**
|
|
844
|
+
* Hash text content: {@link normalizeText} then {@link sha256Hex}.
|
|
845
|
+
*
|
|
846
|
+
* @public
|
|
847
|
+
*/
|
|
848
|
+
declare function hashText(text: string): string;
|
|
849
|
+
/**
|
|
850
|
+
* Hash a JSON-shaped value: {@link canonicalJson} then {@link sha256Hex}.
|
|
851
|
+
*
|
|
852
|
+
* @public
|
|
853
|
+
*/
|
|
854
|
+
declare function hashJsonValue(value: unknown): string;
|
|
855
|
+
/**
|
|
856
|
+
* Hash one bundle layer file's raw text — the COARSE half of change
|
|
857
|
+
* detection (all layer hashes match → skip resolution entirely).
|
|
858
|
+
*
|
|
859
|
+
* @remarks
|
|
860
|
+
* Total: text that parses as JSON hashes canonically (key order and
|
|
861
|
+
* formatting churn do not read as change); text that does not parse falls
|
|
862
|
+
* back to {@link hashText}, so a broken file still gets a stable hash
|
|
863
|
+
* rather than an error — hashing is bookkeeping, not validation.
|
|
864
|
+
*
|
|
865
|
+
* @public
|
|
866
|
+
*/
|
|
867
|
+
declare function hashLayerText(text: string): string;
|
|
868
|
+
/**
|
|
869
|
+
* Fingerprint every present field of a {@link ResolvedBundle} — the FINE
|
|
870
|
+
* half of change detection, hashing each field's `{ value, source }` pair.
|
|
871
|
+
*
|
|
872
|
+
* @remarks
|
|
873
|
+
* The source participates deliberately: an override flip (a field moving
|
|
874
|
+
* from `inferred` to an authored tier without changing value) is a
|
|
875
|
+
* semantically meaningful change and must read as one. Absent fields carry
|
|
876
|
+
* no fingerprint — their appearance or disappearance is itself the diff.
|
|
877
|
+
* The consuming store maps each key to its invalidation scope (version →
|
|
878
|
+
* version-embedding surfaces, tsconfig → all code blocks, …).
|
|
879
|
+
*
|
|
880
|
+
* @public
|
|
881
|
+
*/
|
|
882
|
+
declare function fingerprintResolvedBundle(resolved: ResolvedBundle): Readonly<Record<string, string>>;
|
|
883
|
+
//#endregion
|
|
884
|
+
export { type ApiModelInfo, type Bundle, type BundleDescriptor, BundleDiscoveryError, BundleFetchError, BundleLayerError, BundleManifest, BundleManifestError, type BundleOverrides, type DiscoverBundleOptions, type DiscoverBundlesOptions, type FetchGitHubReleaseBundleOptions, type FetchNpmBundleOptions, KNOWN_REGISTRY_TYPES, type KnownRegistryType, OpenGraphConfig, OpenGraphImage, PlatformOverrides, ProjectIdentity, type ProvenanceSource, type Provenanced, RegistryRef, type ResolveBundleInput, type ResolvedBundle, type ResolvedOpenGraph, type ResolvedOpenGraphImage, SbomRef, TSDOCTOR_MANIFEST_FILENAME, canonicalJson, decodeBundleManifest, decodePlatformOverrides, discoverBundle, discoverBundles, fetchGitHubReleaseBundle, fetchNpmBundle, fingerprintResolvedBundle, hashJsonValue, hashLayerText, hashText, isKnownRegistryType, loadBundle, loadBundles, normalizeText, readApiModelInfo, readBundle, resolveBundle, resolveBundleFrom, sha256Hex };
|
|
885
|
+
//# sourceMappingURL=index.d.ts.map
|