@remit/data-ports 0.0.11 → 0.0.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remit/data-ports",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -28,11 +28,15 @@
28
28
  "./wellknown": {
29
29
  "types": "./src/wellknown.ts",
30
30
  "default": "./src/wellknown.ts"
31
+ },
32
+ "./update-manifest": {
33
+ "types": "./src/update-manifest.ts",
34
+ "default": "./src/update-manifest.ts"
31
35
  }
32
36
  },
33
37
  "scripts": {
34
38
  "test:typecheck": "tsgo --noEmit",
35
- "test:run": "node --import tsx --test 'src/**/*.test.ts'"
39
+ "test:run": "node --import tsx --experimental-test-coverage --test-coverage-include='src/**' --test-coverage-exclude='src/**/*.test.ts' --test-coverage-exclude='src/**/*.test.tsx' --test-coverage-lines=50 --test 'src/**/*.test.ts'"
36
40
  },
37
41
  "dependencies": {
38
42
  "@remit/domain-enums": "*",
@@ -0,0 +1,100 @@
1
+ import assert from "node:assert/strict";
2
+ import { describe, it } from "node:test";
3
+ import { UpdateManifestSchema } from "./update-manifest.js";
4
+
5
+ const GOOD_MANIFEST = {
6
+ version: "v1.5.0",
7
+ publishedAt: "2026-07-18T09:00:00Z",
8
+ summary: "Faster search and a fix for attachments over 25 MB.",
9
+ releaseNotesUrl: "https://github.com/remit-mail/reader/releases/tag/v1.5.0",
10
+ registry: "ghcr.io/remit-mail/reader",
11
+ };
12
+
13
+ describe("UpdateManifestSchema", () => {
14
+ it("accepts the documented manifest shape", () => {
15
+ assert.deepEqual(UpdateManifestSchema.parse(GOOD_MANIFEST), GOOD_MANIFEST);
16
+ });
17
+
18
+ it("rejects a version that is not vX.Y.Z", () => {
19
+ assert.throws(() =>
20
+ UpdateManifestSchema.parse({ ...GOOD_MANIFEST, version: "1.5.0" }),
21
+ );
22
+ assert.throws(() =>
23
+ UpdateManifestSchema.parse({ ...GOOD_MANIFEST, version: "v1.5" }),
24
+ );
25
+ assert.throws(() =>
26
+ UpdateManifestSchema.parse({ ...GOOD_MANIFEST, version: "v1.5.0-rc1" }),
27
+ );
28
+ });
29
+
30
+ it("rejects a publishedAt that is not ISO 8601", () => {
31
+ assert.throws(() =>
32
+ UpdateManifestSchema.parse({
33
+ ...GOOD_MANIFEST,
34
+ publishedAt: "18 July 2026",
35
+ }),
36
+ );
37
+ });
38
+
39
+ it("rejects an empty summary", () => {
40
+ assert.throws(() =>
41
+ UpdateManifestSchema.parse({ ...GOOD_MANIFEST, summary: "" }),
42
+ );
43
+ });
44
+
45
+ it("rejects a summary over 140 characters", () => {
46
+ assert.throws(() =>
47
+ UpdateManifestSchema.parse({
48
+ ...GOOD_MANIFEST,
49
+ summary: "x".repeat(141),
50
+ }),
51
+ );
52
+ });
53
+
54
+ it("accepts a summary at exactly 140 characters", () => {
55
+ const summary = "x".repeat(140);
56
+ assert.equal(
57
+ UpdateManifestSchema.parse({ ...GOOD_MANIFEST, summary }).summary,
58
+ summary,
59
+ );
60
+ });
61
+
62
+ it("rejects a releaseNotesUrl that is not a URL", () => {
63
+ assert.throws(() =>
64
+ UpdateManifestSchema.parse({
65
+ ...GOOD_MANIFEST,
66
+ releaseNotesUrl: "not-a-url",
67
+ }),
68
+ );
69
+ });
70
+
71
+ it("rejects a releaseNotesUrl that is not https", () => {
72
+ assert.throws(() =>
73
+ UpdateManifestSchema.parse({
74
+ ...GOOD_MANIFEST,
75
+ releaseNotesUrl:
76
+ "http://github.com/remit-mail/reader/releases/tag/v1.5.0",
77
+ }),
78
+ );
79
+ });
80
+
81
+ it("rejects a releaseNotesUrl using a non-http(s) scheme", () => {
82
+ assert.throws(() =>
83
+ UpdateManifestSchema.parse({
84
+ ...GOOD_MANIFEST,
85
+ releaseNotesUrl: "javascript:alert(1)",
86
+ }),
87
+ );
88
+ });
89
+
90
+ it("rejects an empty registry", () => {
91
+ assert.throws(() =>
92
+ UpdateManifestSchema.parse({ ...GOOD_MANIFEST, registry: "" }),
93
+ );
94
+ });
95
+
96
+ it("rejects a manifest missing a required field", () => {
97
+ const { summary, ...rest } = GOOD_MANIFEST;
98
+ assert.throws(() => UpdateManifestSchema.parse(rest));
99
+ });
100
+ });
@@ -0,0 +1,18 @@
1
+ import { z } from "zod";
2
+
3
+ export const SUMMARY_MAX_LENGTH = 140;
4
+
5
+ export const UpdateManifestSchema = z.object({
6
+ version: z.string().regex(/^v\d+\.\d+\.\d+$/),
7
+ publishedAt: z.string().datetime(),
8
+ summary: z.string().min(1).max(SUMMARY_MAX_LENGTH),
9
+ releaseNotesUrl: z
10
+ .string()
11
+ .url()
12
+ .refine((url) => url.startsWith("https://"), {
13
+ message: "releaseNotesUrl must be an https:// URL",
14
+ }),
15
+ registry: z.string().min(1),
16
+ });
17
+
18
+ export type UpdateManifest = z.infer<typeof UpdateManifestSchema>;