@valbuild/shared 0.136.10 → 0.138.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.
@@ -1496,6 +1496,28 @@ var GenericError = z.object({
1496
1496
  message: z.string()
1497
1497
  });
1498
1498
 
1499
+ /**
1500
+ * What answered when one URL was opened.
1501
+ *
1502
+ * The one place the Studio's `ExternalUrlProbeResult` and the server's
1503
+ * `ProbeResult` meet, so the two cannot drift without this failing to parse.
1504
+ */
1505
+ var ExternalUrlProbeResult = z.union([z.object({
1506
+ kind: z.literal("answered"),
1507
+ code: z.number(),
1508
+ finalUrl: z.string(),
1509
+ ms: z.number()
1510
+ }), z.object({
1511
+ kind: z.literal("unreachable"),
1512
+ message: z.string()
1513
+ }), z.object({
1514
+ kind: z.literal("timeout"),
1515
+ ms: z.number()
1516
+ }), z.object({
1517
+ kind: z.literal("skipped"),
1518
+ message: z.string()
1519
+ })]);
1520
+
1499
1521
  /**
1500
1522
  * Why a publish cannot happen, in a form the Studio can show.
1501
1523
  *
@@ -1934,6 +1956,13 @@ var Api = {
1934
1956
  * which is the one the Studio has always told.
1935
1957
  */
1936
1958
  sourceMode: z.union([z.literal("managed"), z.literal("connected")]).optional(),
1959
+ /**
1960
+ * A press of Publish is a publish JOB: every managed project,
1961
+ * and a connected one hosted on the platform. Absent from a
1962
+ * server that predates it: managed projects publish as jobs,
1963
+ * connected ones by commit.
1964
+ */
1965
+ publishJobs: z["boolean"]().optional(),
1937
1966
  publishRefusal: PublishRefusal.optional()
1938
1967
  }), z.object({
1939
1968
  type: z.literal("use-websocket"),
@@ -1984,6 +2013,13 @@ var Api = {
1984
2013
  * content service that predates it sends nothing.
1985
2014
  */
1986
2015
  headPatchId: PatchId.nullable().optional(),
2016
+ /**
2017
+ * The version of the chain `headPatchId` was read at, bumped by
2018
+ * every write and delete. `/stat` has more than one caller, so
2019
+ * answers can land out of order; a client keeps the head with the
2020
+ * highest version. Optional, for the same reason `headPatchId` is.
2021
+ */
2022
+ headVersion: z.number().optional(),
1987
2023
  commits: z.array(ValCommit),
1988
2024
  /**
1989
2025
  * The publishes the content service knows about.
@@ -2024,6 +2060,13 @@ var Api = {
2024
2060
  * which is the one the Studio has always told.
2025
2061
  */
2026
2062
  sourceMode: z.union([z.literal("managed"), z.literal("connected")]).optional(),
2063
+ /**
2064
+ * A press of Publish is a publish JOB: every managed project,
2065
+ * and a connected one hosted on the platform. Absent from a
2066
+ * server that predates it: managed projects publish as jobs,
2067
+ * connected ones by commit.
2068
+ */
2069
+ publishJobs: z["boolean"]().optional(),
2027
2070
  publishRefusal: PublishRefusal.optional()
2028
2071
  })])
2029
2072
  })])
@@ -2137,6 +2180,42 @@ var Api = {
2137
2180
  })])
2138
2181
  }
2139
2182
  },
2183
+ /**
2184
+ * Open a batch of external URLs and report what answered.
2185
+ *
2186
+ * A batch rather than one URL because the client checks a list, and a POST
2187
+ * rather than a GET because the list is the input and does not belong in a
2188
+ * URL or a cache.
2189
+ *
2190
+ * The server makes outbound requests to addresses this body supplies, which
2191
+ * is SSRF by construction - see `linkCheck/addressGuard.ts` for the deny
2192
+ * list that makes it safe, and `docs/plans/external-page-link-checks.md` for
2193
+ * why it is a deny list on the RESOLVED address.
2194
+ */
2195
+ "/external-urls/check": {
2196
+ POST: {
2197
+ req: {
2198
+ body: z.object({
2199
+ /*
2200
+ * Capped, and the cap is the point rather than a formality: each URL
2201
+ * is an outbound connection, and a body is not allowed to ask this
2202
+ * server to open a thousand of them. The client sends ten at a time.
2203
+ */
2204
+ urls: z.array(z.string()).min(1).max(20)
2205
+ }),
2206
+ cookies: {
2207
+ val_session: z.string().optional()
2208
+ }
2209
+ },
2210
+ res: z.union([unauthorizedResponse, z.object({
2211
+ status: z.literal(200),
2212
+ json: z.object({
2213
+ /** Keyed by the URL exactly as it was asked about. */
2214
+ results: z.record(z.string(), ExternalUrlProbeResult)
2215
+ })
2216
+ })])
2217
+ }
2218
+ },
2140
2219
  "/direct-file-upload-settings": {
2141
2220
  POST: {
2142
2221
  req: {
@@ -2188,7 +2267,14 @@ var Api = {
2188
2267
  * groups, and a client that predates this is deleting correctly,
2189
2268
  * just not repairing.
2190
2269
  */
2191
- unstagePatchIds: z.array(PatchId).optional()
2270
+ unstagePatchIds: z.array(PatchId).optional(),
2271
+ /*
2272
+ * Answer with `{ deleted, headVersion }` rather than the bare id
2273
+ * array. Asked for rather than always sent, because the array is
2274
+ * what a Studio bundle from before this parses — and a tab left
2275
+ * open across a deploy still runs one.
2276
+ */
2277
+ reportHeadVersion: z.literal(true).optional()
2192
2278
  }).optional(),
2193
2279
  cookies: {
2194
2280
  val_session: z.string().optional()
@@ -2202,7 +2288,16 @@ var Api = {
2202
2288
  })
2203
2289
  }), z.object({
2204
2290
  status: z.literal(200),
2205
- json: z.array(PatchId)
2291
+ json: z.union([z.array(PatchId), z.object({
2292
+ deleted: z.array(PatchId),
2293
+ /**
2294
+ * The chain version this delete moved the branch to. Absent when
2295
+ * it moved nothing, or the content service does not version its
2296
+ * chain. Compared with `headVersion` on `/stat`: an answer read
2297
+ * before the delete would put the deleted head back.
2298
+ */
2299
+ headVersion: z.number().optional()
2300
+ })])
2206
2301
  })])
2207
2302
  },
2208
2303
  PUT: {
@@ -2250,7 +2345,14 @@ var Api = {
2250
2345
  json: z.object({
2251
2346
  newPatchIds: z.array(PatchId),
2252
2347
  parentRef: ParentRef,
2253
- patchGroupId: z.string().optional()
2348
+ patchGroupId: z.string().optional(),
2349
+ /**
2350
+ * The chain version the last of these patches made, comparable with
2351
+ * `headVersion` on `/stat`. A client keeps the highest version, so a
2352
+ * stat read before this write does not put its parent back behind
2353
+ * it. Absent in `fs` mode and from an older content service.
2354
+ */
2355
+ headVersion: z.number().optional()
2254
2356
  })
2255
2357
  })])
2256
2358
  },
@@ -2506,39 +2608,49 @@ var Api = {
2506
2608
  })])
2507
2609
  }
2508
2610
  },
2509
- /**
2510
- * The `.val.ts` text of every module that changed since the RUNNING build,
2511
- * with every commit since it applied, for a build made in the browser.
2512
- *
2513
- * A Studio build starts from the source stored with the live build. A commit
2514
- * whose own publish failed -- or the first commit of a project that started
2515
- * as a copy of a template -- is in content and in no stored source, so a build
2516
- * that added only its own save's files shipped without it. Only this server
2517
- * can render those commits back into text: content keeps a managed project's
2518
- * content as Source, not as files.
2519
- *
2520
- * Committed patches only. A pending one is somebody's unpublished work, and
2521
- * is not this build's to ship. 409 where there is nothing to answer with: a
2522
- * project with a repository, or a build that did not embed its source.
2523
- */
2524
- "/built-source": {
2525
- GET: {
2611
+ "/publish-job-prepare": {
2612
+ POST: {
2526
2613
  req: {
2614
+ body: z.object({
2615
+ jobId: z.string().regex(/^[A-Za-z0-9_-]{1,100}$/),
2616
+ tab: z.string().regex(/^[A-Za-z0-9_-]{1,100}$/),
2617
+ /** The job's changes, as content handed them to the tab. */
2618
+ patchIds: z.array(PatchId)
2619
+ }),
2527
2620
  cookies: {
2528
2621
  val_session: z.string().optional()
2529
2622
  }
2530
2623
  },
2531
2624
  res: z.union([unauthorizedResponse, z.object({
2625
+ status: z.literal(400),
2626
+ json: GenericError
2627
+ }), z.object({
2532
2628
  status: z.literal(409),
2533
2629
  json: GenericError
2534
2630
  }), z.object({
2535
2631
  status: z.literal(500),
2536
2632
  json: GenericError
2633
+ }), z.object({
2634
+ status: z.literal(502),
2635
+ json: GenericError
2537
2636
  }), z.object({
2538
2637
  status: z.literal(200),
2539
2638
  json: z.object({
2540
- /** By path, as `/save`'s `sourceFiles`. `null` is a deleted file. */
2541
- files: z.record(z.string(), z.string().nullable())
2639
+ /** The job as content has it now: its next step is the build. */
2640
+ job: z.object({
2641
+ id: z.string(),
2642
+ step: z["enum"](["prepare", "build", "upload"]).nullable(),
2643
+ base: z.string().nullable(),
2644
+ patches: z.array(z.string())
2645
+ }).nullable(),
2646
+ /** Every source file of the job's content, by path. `null` is deleted. */
2647
+ sourceFiles: z.record(z.string(), z.string().nullable()),
2648
+ /** The job's own local binary files, base64, by path. */
2649
+ binaryFiles: z.record(z.string(), z.string()),
2650
+ /** Binary files whose bytes could not be read back. */
2651
+ binaryFilesUnread: z.array(z.string()),
2652
+ /** The branch the job publishes to. */
2653
+ branch: z.string().nullable()
2542
2654
  })
2543
2655
  })])
2544
2656
  }
@@ -2685,7 +2797,14 @@ var Api = {
2685
2797
  patchId: PatchId,
2686
2798
  moduleFilePath: ModuleFilePath,
2687
2799
  message: z.string()
2688
- })).optional()
2800
+ })).optional(),
2801
+ /**
2802
+ * The chain version this publish moved the branch to, where the
2803
+ * content service versions its chain and the publish applied
2804
+ * anything. See `headVersion` on `/stat`: a `/stat` answer read
2805
+ * before the publish would put its patches back to pending.
2806
+ */
2807
+ headVersion: z.number().optional()
2689
2808
  })
2690
2809
  }),
2691
2810
  /*
@@ -7358,6 +7477,54 @@ var projectSourceResponse = z.object({
7358
7477
  */
7359
7478
  publicPaths: z.array(z.string()).nullable().optional()
7360
7479
  });
7480
+ /**
7481
+ * Whether a managed project can be updated onto its template's current seed,
7482
+ * and -- when it is asked with `POST`, the press -- what to build against.
7483
+ *
7484
+ * An update rebuilds the site as it is on newer dependencies. The loader
7485
+ * decides whether there is one; content adds whether the project is managed at
7486
+ * all, and the branch head the rebuild is wired at, because an update
7487
+ * publishes no content of its own.
7488
+ *
7489
+ * `target` is a `/build-target` answer whose project half is the SEED's
7490
+ * dependency layer, already copied into the project so a publish can name it.
7491
+ * Only a `POST` carries it.
7492
+ */
7493
+ var dependencyChange = z.object({
7494
+ name: z.string(),
7495
+ section: z["enum"](["dependencies", "devDependencies"]),
7496
+ /** `null` for a dependency the template added. */
7497
+ from: z.string().nullable(),
7498
+ /** `null` for a dependency the template dropped: it leaves `package.json`. */
7499
+ to: z.string().nullable()
7500
+ });
7501
+ var updateTargetResponse = z.discriminatedUnion("status", [z.object({
7502
+ status: z.literal("current"),
7503
+ template: z.string(),
7504
+ layerRev: z.string()
7505
+ }), z.object({
7506
+ status: z.literal("available"),
7507
+ template: z.string(),
7508
+ /** Empty when only the dependency layer moved, and no version did. */
7509
+ changes: z.array(dependencyChange),
7510
+ layerRev: z.object({
7511
+ from: z.string().nullable(),
7512
+ to: z.string()
7513
+ }),
7514
+ /** The project's `package.json`, rewritten to the seed's versions. */
7515
+ packageJson: z.string(),
7516
+ /** The branch head to build at; `null` for a project with no commits. */
7517
+ commit: z.string().nullable(),
7518
+ branch: z.string(),
7519
+ target: buildTargetResponse.optional()
7520
+ }), z.object({
7521
+ status: z.literal("unavailable"),
7522
+ reason: z.string(),
7523
+ message: z.string()
7524
+ })]);
7525
+ var parseUpdateTarget = function parseUpdateTarget(body) {
7526
+ return parse(updateTargetResponse, body, "/v1/update-target");
7527
+ };
7361
7528
  var parseBuildTarget = function parseBuildTarget(body) {
7362
7529
  return parse(buildTargetResponse, body, "GET /v1/build-target");
7363
7530
  };
@@ -7365,6 +7532,88 @@ var parseProjectSource = function parseProjectSource(body) {
7365
7532
  return parse(projectSourceResponse, body, "GET /v1/project-source");
7366
7533
  };
7367
7534
 
7535
+ // ------------------------------------------------------ publish jobs
7536
+
7537
+ /*
7538
+ * Publishing as a queued job (valbuild/home docs/app-mode.md, "Publishing is a
7539
+ * queued job"): a press is a request, the tab builds and uploads the job it is
7540
+ * given, and content runs verify and the seal. Each parser is typed against
7541
+ * the copy in `contentApi.ts`, so a copy brought up to date fails to compile
7542
+ * here until these follow it.
7543
+ */
7544
+
7545
+ var requestStatus = z.union([z.object({
7546
+ kind: z.literal("queued")
7547
+ }), z.object({
7548
+ kind: z.literal("publishing")
7549
+ }), z.object({
7550
+ kind: z.literal("live"),
7551
+ commit: z.string()
7552
+ }), z.object({
7553
+ kind: z.literal("failed"),
7554
+ message: z.string(),
7555
+ actions: z.array(z["enum"](["try-again", "discard", "re-run-build"])),
7556
+ job: z.string()
7557
+ }), z.object({
7558
+ kind: z.literal("cancelled")
7559
+ }), z.object({
7560
+ kind: z.literal("nothing-to-publish")
7561
+ })]);
7562
+ var tabJob = z.object({
7563
+ id: z.string(),
7564
+ step: z["enum"](["prepare", "build", "upload"]).nullable(),
7565
+ base: z.string().nullable(),
7566
+ patches: z.array(z.string())
7567
+ });
7568
+ var pressResponse = z.object({
7569
+ request: requestStatus,
7570
+ job: tabJob.nullable()
7571
+ });
7572
+ var requestStatusResponse = z.object({
7573
+ request: requestStatus
7574
+ });
7575
+ // `/next`, `/prepare` and `/steps` all answer with the job as it now is.
7576
+ var jobResponse = z.object({
7577
+ job: tabJob.nullable()
7578
+ });
7579
+ var renewResponse = z.object({
7580
+ renewed: z["boolean"]()
7581
+ });
7582
+ var cancelResponse = z.object({
7583
+ cancelled: z["boolean"]()
7584
+ });
7585
+ var discardResponse = z.object({
7586
+ stillHeld: z.array(z.string())
7587
+ });
7588
+ var parsePress = function parsePress(body, call) {
7589
+ return parse(pressResponse, body, call);
7590
+ };
7591
+ var parseRequestStatus = function parseRequestStatus(body) {
7592
+ return parse(requestStatusResponse, body, "GET /v1/publish-requests/{id}");
7593
+ };
7594
+ var parseJob = function parseJob(body, call) {
7595
+ return parse(jobResponse, body, call);
7596
+ };
7597
+ var parseRenew = function parseRenew(body) {
7598
+ return parse(renewResponse, body, "POST /v1/publish-jobs/{id}/renew");
7599
+ };
7600
+ var parseCancel = function parseCancel(body) {
7601
+ return parse(cancelResponse, body, "POST /v1/publish-jobs/{id}/cancel");
7602
+ };
7603
+ var parseDiscard = function parseDiscard(body) {
7604
+ return parse(discardResponse, body, "POST /v1/publish-jobs/{id}/discard");
7605
+ };
7606
+ var newestCiRunResponse = z.object({
7607
+ run: z.object({
7608
+ commit: z.string(),
7609
+ status: z["enum"](["failed", "succeeded"]),
7610
+ url: z.string().nullable()
7611
+ }).nullable()
7612
+ });
7613
+ var parseNewestCiRun = function parseNewestCiRun(body) {
7614
+ return parse(newestCiRunResponse, body, "GET /v1/ci-runs/newest");
7615
+ };
7616
+
7368
7617
  /**
7369
7618
  * The `details` of a refusal, when it carries a list of problems.
7370
7619
  *
@@ -7386,4 +7635,4 @@ function parse(schema, body, call) {
7386
7635
  return parsed.data;
7387
7636
  }
7388
7637
 
7389
- export { AA_LARGE, AA_TEXT, Api, BRAND_CONTRAST_PAIRS, BinaryFileRef, CodeOptions, ColorOptions, DEFAULT_ERROR_MESSAGE, DateOptions, ENCODE_DEFAULTS, ENCODE_MIME_TYPE_OF, FileOptions, HistoricalCommit, HistoricalModule, HistoricalPatchSet, HistoryError, ImageEncodeOption, ImageOptions, JSONValue, JSON_ENTRIES_BATCH_MAX, ModuleComparison, NEVER_ENCODED, ParentRef$1 as ParentRef, Patch, PatchBlock, PatchGroup, PatchId, PatchJSON, PublishProtocolError, RAMP_STEPS, RemirrorBr, RemirrorBulletList, RemirrorHeading, RemirrorImage, RemirrorJSON, RemirrorLinkMark, RemirrorListItem, RemirrorOrderedList, RemirrorParagraph, RemirrorText, RemirrorTextMark, RestoreVerdict, RichTextOptions, SCHEMA_SOURCE_FIXES, SerializedArraySchema, SerializedBooleanSchema, SerializedCodeSchema, SerializedColorSchema, SerializedDateSchema, SerializedDateTimeSchema, SerializedDiscriminatedUnionSchema, SerializedEnumSchema, SerializedFileSchema, SerializedImageSchema, SerializedKeyOfSchema, SerializedLiteralSchema, SerializedLocaleSchema, SerializedNumberSchema, SerializedObjectSchema, SerializedRecordSchema, SerializedRichTextSchema, SerializedRouteSchema, SerializedSchema, SerializedSettingsSchema, SerializedStringSchema, SerializedValViewSchema, SharedValConfig, VAL_ENABLE_COOKIE_NAME, VAL_GREEN_RAMP, VAL_SESSION_COOKIE, VAL_STATE_COOKIE, ValCommit, ValDeployment, accentRamp, buildDuplicatePatch, buildEmptyAtPathPatch, buildFileRefValue, buildImageGalleryPatch, buildRemoveImageGalleryEntryPatch, buildSearchIndex, chainHeadOf, checkCompatibility, chooseEncoded, concatModulePath, contrastRatio, createRegExpFromPattern, createSearchIndex, createValClient, declaredLocales, describeContainerAtPath, emptyOf, explainIncompatible, filterBlockingValidationErrors, filterRoutesByPatterns, findSimilar, fitWithin, flattenRichText, getErrorMessageFromUnknownJson, getFilenameFromRef, getInlineImgInfo, getKeyOfRecordAt, getRefParts, getRoutesOf, getRoutesWithModulePaths, getSourceAt, indexModule, isMimeTypeAccepted, isRemoteSchema, isSchemaSourceFixError, isSkippedSource, keyOfRecordPath, levenshtein, localeAt, memoizePerRequest, newestCommitSha, parseArtifacts, parseBuildTarget, parseDeclare, parseProblems, parseProjectSource, parsePromote, parsePublishToken, parseStatus, parseVerify, partitionValidationErrors, performSearch, relativeLuminance, remirrorToRichTextSource, removeModule, resolveEncodeSettings, resolvePairGround, resolveSchemaSourceFixForError, resolveSchemaSourceFixes, resolveSerializedSchemaAtPath, richTextToRemirror, safeParsePatch, sourcePathOfChild, themeCustomProperties, toolNames, traverseSchemaSource, urlOf, validateRoutePatterns, withExtension };
7638
+ export { AA_LARGE, AA_TEXT, Api, BRAND_CONTRAST_PAIRS, BinaryFileRef, CodeOptions, ColorOptions, DEFAULT_ERROR_MESSAGE, DateOptions, ENCODE_DEFAULTS, ENCODE_MIME_TYPE_OF, FileOptions, HistoricalCommit, HistoricalModule, HistoricalPatchSet, HistoryError, ImageEncodeOption, ImageOptions, JSONValue, JSON_ENTRIES_BATCH_MAX, ModuleComparison, NEVER_ENCODED, ParentRef$1 as ParentRef, Patch, PatchBlock, PatchGroup, PatchId, PatchJSON, PublishProtocolError, RAMP_STEPS, RemirrorBr, RemirrorBulletList, RemirrorHeading, RemirrorImage, RemirrorJSON, RemirrorLinkMark, RemirrorListItem, RemirrorOrderedList, RemirrorParagraph, RemirrorText, RemirrorTextMark, RestoreVerdict, RichTextOptions, SCHEMA_SOURCE_FIXES, SerializedArraySchema, SerializedBooleanSchema, SerializedCodeSchema, SerializedColorSchema, SerializedDateSchema, SerializedDateTimeSchema, SerializedDiscriminatedUnionSchema, SerializedEnumSchema, SerializedFileSchema, SerializedImageSchema, SerializedKeyOfSchema, SerializedLiteralSchema, SerializedLocaleSchema, SerializedNumberSchema, SerializedObjectSchema, SerializedRecordSchema, SerializedRichTextSchema, SerializedRouteSchema, SerializedSchema, SerializedSettingsSchema, SerializedStringSchema, SerializedValViewSchema, SharedValConfig, VAL_ENABLE_COOKIE_NAME, VAL_GREEN_RAMP, VAL_SESSION_COOKIE, VAL_STATE_COOKIE, ValCommit, ValDeployment, accentRamp, buildDuplicatePatch, buildEmptyAtPathPatch, buildFileRefValue, buildImageGalleryPatch, buildRemoveImageGalleryEntryPatch, buildSearchIndex, chainHeadOf, checkCompatibility, chooseEncoded, concatModulePath, contrastRatio, createRegExpFromPattern, createSearchIndex, createValClient, declaredLocales, describeContainerAtPath, emptyOf, explainIncompatible, filterBlockingValidationErrors, filterRoutesByPatterns, findSimilar, fitWithin, flattenRichText, getErrorMessageFromUnknownJson, getFilenameFromRef, getInlineImgInfo, getKeyOfRecordAt, getRefParts, getRoutesOf, getRoutesWithModulePaths, getSourceAt, indexModule, isMimeTypeAccepted, isRemoteSchema, isSchemaSourceFixError, isSkippedSource, keyOfRecordPath, levenshtein, localeAt, memoizePerRequest, newestCommitSha, parseArtifacts, parseBuildTarget, parseCancel, parseDeclare, parseDiscard, parseJob, parseNewestCiRun, parsePress, parseProblems, parseProjectSource, parsePromote, parsePublishToken, parseRenew, parseRequestStatus, parseStatus, parseUpdateTarget, parseVerify, partitionValidationErrors, performSearch, relativeLuminance, remirrorToRichTextSource, removeModule, resolveEncodeSettings, resolvePairGround, resolveSchemaSourceFixForError, resolveSchemaSourceFixes, resolveSerializedSchemaAtPath, richTextToRemirror, safeParsePatch, sourcePathOfChild, themeCustomProperties, toolNames, traverseSchemaSource, urlOf, validateRoutePatterns, withExtension };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@valbuild/shared",
3
- "version": "0.136.10",
3
+ "version": "0.138.0",
4
4
  "private": false,
5
5
  "description": "Val shared types and utilities",
6
6
  "repository": {
@@ -37,7 +37,7 @@
37
37
  "flexsearch": "^0.8.212",
38
38
  "zod": "^4.4.3",
39
39
  "zod-validation-error": "^5.0.0",
40
- "@valbuild/core": "0.136.8"
40
+ "@valbuild/core": "0.138.0"
41
41
  },
42
42
  "files": [
43
43
  "CHANGELOG.md",