@ololoepepe/controllers 0.4.0 → 0.5.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/CHANGELOG.md CHANGED
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.5.0] - 2026-08-29
11
+
12
+ ### Changed
13
+
14
+ - `Json` accepts readonly arrays: the array member is now `readonly Json[]`. A
15
+ `ReadonlyArray` field, or anything produced by `as const`, could not be a response
16
+ body, because a readonly array is not assignable to a mutable one. Mutable arrays are
17
+ unaffected — they are assignable to readonly ones, so every body that compiled before
18
+ still compiles.
19
+
20
+ Breaking only for code that passes a value typed `Json` on to a JSON type declaring
21
+ its arrays mutable — another library's `JsonValue`, or a copy of this one. The same
22
+ goes for `Extract<Json, unknown[]>`, which now resolves to `never` and fails at the
23
+ use site rather than where it is declared.
24
+
10
25
  ## [0.4.0] - 2026-08-28
11
26
 
12
27
  ### Changed
package/README.md CHANGED
@@ -175,12 +175,15 @@ so you only name it when you name the response as well. It is constrained to
175
175
  `Json` — what JSON can actually hold:
176
176
 
177
177
  ```ts
178
- export type Json = boolean | Json[] | null | number | string | {[key: string]: Json};
178
+ export type Json = boolean | null | number | readonly Json[] | string | {[key: string]: Json};
179
179
  ```
180
180
 
181
181
  That rules out `undefined`, `bigint` (`JSON.stringify` throws on it), `symbol`
182
182
  and functions, and it checks nested fields too.
183
183
 
184
+ Arrays are `readonly`, so a `ReadonlyArray` field or an `as const` value can be a
185
+ body. A mutable array still passes, being assignable to a readonly one.
186
+
184
187
  **Describe response bodies with `type`, not `interface`.** TypeScript does not
185
188
  assign an `interface` to a type with an index signature, so an interface will not
186
189
  satisfy `Json` however JSON-shaped it is — including one nested inside a `type`:
@@ -20,8 +20,11 @@ export interface ControllerRequest {
20
20
  * У объектов проверяются и поля, вглубь. Цена этого в том, что TypeScript не присваивает
21
21
  * `interface` типу с индексной сигнатурой, поэтому тело ответа описывается через `type`, а не
22
22
  * через `interface`.
23
+ *
24
+ * Массив взят `readonly`, чтобы телом ответа могли стать `ReadonlyArray` и результат `as const`.
25
+ * Изменяемый массив подходит и так: он присваивается в `readonly`, обратное неверно.
23
26
  */
24
- export type Json = boolean | Json[] | null | number | string | {
27
+ export type Json = boolean | null | number | readonly Json[] | string | {
25
28
  [key: string]: Json;
26
29
  };
27
30
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ololoepepe/controllers",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Common Express controllers library",
5
5
  "type": "module",
6
6
  "imports": {