@platforma-sdk/block-tools 2.6.43 → 2.6.45
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/README.md +16 -9
- package/bin/dev.js +4 -4
- package/bin/run.js +3 -3
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +16 -6
- package/dist/cli.mjs.map +1 -1
- package/dist/cmd/index.d.ts +8 -8
- package/dist/cmd/mark-stable.d.ts +1 -1
- package/dist/cmd/publish.d.ts +1 -1
- package/dist/cmd/restore-overview-from-snapshot.d.ts +1 -1
- package/dist/{config-DKBY0B2u.mjs → config-Cc8_zV3b.mjs} +48 -17
- package/dist/config-Cc8_zV3b.mjs.map +1 -0
- package/dist/config-Ycas5fbX.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6 -4
- package/dist/index.mjs.map +1 -1
- package/dist/registry_v1/config_schema.d.ts +7 -7
- package/dist/registry_v1/v1_repo_schema.d.ts +1 -1
- package/dist/v2/model/block_components.d.ts +19 -19
- package/dist/v2/model/block_description.d.ts +102 -102
- package/dist/v2/model/block_meta.d.ts +20 -20
- package/dist/v2/model/content_conversion.d.ts +2 -2
- package/dist/v2/registry/registry.d.ts +1 -1
- package/dist/v2/source_package.d.ts +1 -1
- package/package.json +31 -29
- package/src/cmd/build-meta.ts +15 -15
- package/src/cmd/build-model.ts +23 -26
- package/src/cmd/index.ts +20 -20
- package/src/cmd/list-overview-snapshots.ts +12 -12
- package/src/cmd/mark-stable.ts +30 -33
- package/src/cmd/pack.ts +15 -15
- package/src/cmd/publish.ts +46 -34
- package/src/cmd/refresh-registry.ts +15 -15
- package/src/cmd/restore-overview-from-snapshot.ts +27 -25
- package/src/cmd/update-deps.ts +8 -8
- package/src/cmd/upload-package-v1.ts +33 -33
- package/src/common_types.ts +1 -1
- package/src/io/folder_reader.test.ts +13 -13
- package/src/io/folder_reader.ts +18 -20
- package/src/io/index.ts +2 -2
- package/src/io/storage.test.ts +48 -48
- package/src/io/storage.ts +20 -15
- package/src/lib.ts +3 -3
- package/src/registry_v1/config.ts +11 -11
- package/src/registry_v1/config_schema.ts +5 -5
- package/src/registry_v1/flags.ts +4 -4
- package/src/registry_v1/index.ts +3 -3
- package/src/registry_v1/registry.test.ts +54 -54
- package/src/registry_v1/registry.ts +29 -25
- package/src/registry_v1/v1_repo_schema.ts +3 -3
- package/src/util.ts +6 -9
- package/src/v2/build_dist.test.ts +8 -9
- package/src/v2/build_dist.ts +10 -13
- package/src/v2/index.ts +4 -4
- package/src/v2/model/block_components.ts +5 -5
- package/src/v2/model/block_description.ts +12 -8
- package/src/v2/model/block_meta.ts +4 -5
- package/src/v2/model/content_conversion.ts +44 -44
- package/src/v2/model/index.ts +4 -4
- package/src/v2/registry/index.ts +3 -3
- package/src/v2/registry/registry.test.ts +223 -197
- package/src/v2/registry/registry.ts +93 -66
- package/src/v2/registry/registry_reader.test.ts +15 -15
- package/src/v2/registry/registry_reader.ts +29 -27
- package/src/v2/registry/schema_internal.ts +11 -10
- package/src/v2/registry/schema_public.ts +56 -47
- package/src/v2/source_package.test.ts +15 -15
- package/src/v2/source_package.ts +33 -26
- package/dist/config-DKBY0B2u.mjs.map +0 -1
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import { test, expect } from
|
|
2
|
-
import { RegistryStorage, storageByUrl } from
|
|
3
|
-
import { randomUUID } from
|
|
4
|
-
import path from
|
|
5
|
-
import fsp from
|
|
6
|
-
import { BlockRegistryV2 } from
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { OverviewSnapshotsPrefix } from './schema_internal';
|
|
1
|
+
import { test, expect } from "vitest";
|
|
2
|
+
import { RegistryStorage, storageByUrl } from "../../io";
|
|
3
|
+
import { randomUUID } from "crypto";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import fsp from "fs/promises";
|
|
6
|
+
import { BlockRegistryV2 } from "./registry";
|
|
7
|
+
import { UpdateSuggestions, BlockPackManifest } from "@milaboratories/pl-model-middle-layer";
|
|
8
|
+
import { inferUpdateSuggestions } from "./registry_reader";
|
|
9
|
+
import { OverviewSnapshotsPrefix } from "./schema_internal";
|
|
11
10
|
|
|
12
11
|
type TestStorageInstance = {
|
|
13
12
|
storage: RegistryStorage;
|
|
@@ -19,265 +18,292 @@ type TestStorageTarget = {
|
|
|
19
18
|
};
|
|
20
19
|
const testStorages: TestStorageTarget[] = [
|
|
21
20
|
{
|
|
22
|
-
name:
|
|
21
|
+
name: "local",
|
|
23
22
|
storageProvider: () => {
|
|
24
23
|
const uuid = randomUUID().toString();
|
|
25
|
-
const tmp = path.resolve(
|
|
24
|
+
const tmp = path.resolve("tmp");
|
|
26
25
|
const storagePath = path.resolve(tmp, uuid);
|
|
27
|
-
const storage = storageByUrl(
|
|
26
|
+
const storage = storageByUrl("file://" + storagePath);
|
|
28
27
|
return {
|
|
29
28
|
storage,
|
|
30
29
|
teardown: async () => {
|
|
31
30
|
await fsp.rm(storagePath, { recursive: true, force: true });
|
|
32
|
-
}
|
|
31
|
+
},
|
|
33
32
|
};
|
|
34
|
-
}
|
|
35
|
-
}
|
|
33
|
+
},
|
|
34
|
+
},
|
|
36
35
|
];
|
|
37
36
|
|
|
38
37
|
const testS3Address = process.env.TEST_S3_ADDRESS;
|
|
39
38
|
if (testS3Address !== undefined) {
|
|
40
39
|
testStorages.push({
|
|
41
|
-
name:
|
|
40
|
+
name: "s3",
|
|
42
41
|
storageProvider: () => {
|
|
43
42
|
const uuid = randomUUID().toString();
|
|
44
43
|
const testS3AddressURL = new URL(testS3Address!);
|
|
45
|
-
testS3AddressURL.pathname = `${testS3AddressURL.pathname.replace(/\/$/,
|
|
44
|
+
testS3AddressURL.pathname = `${testS3AddressURL.pathname.replace(/\/$/, "")}/${uuid}`;
|
|
46
45
|
const storage = storageByUrl(testS3AddressURL.toString());
|
|
47
46
|
return {
|
|
48
47
|
storage,
|
|
49
48
|
teardown: async () => {
|
|
50
|
-
const allFiles = await storage.listFiles(
|
|
51
|
-
console.log(
|
|
49
|
+
const allFiles = await storage.listFiles("");
|
|
50
|
+
console.log("Deleting: ", allFiles);
|
|
52
51
|
await storage.deleteFiles(...allFiles);
|
|
53
|
-
}
|
|
52
|
+
},
|
|
54
53
|
};
|
|
55
|
-
}
|
|
54
|
+
},
|
|
56
55
|
});
|
|
57
56
|
}
|
|
58
57
|
|
|
59
|
-
test.each(testStorages)(
|
|
58
|
+
test.each(testStorages)("registry snapshots test with $name", async ({ storageProvider }) => {
|
|
60
59
|
const { storage, teardown } = storageProvider();
|
|
61
60
|
const registry = new BlockRegistryV2(storage);
|
|
62
|
-
|
|
61
|
+
|
|
63
62
|
try {
|
|
64
63
|
// Force an update to trigger snapshot creation (even with empty registry)
|
|
65
|
-
await registry.updateIfNeeded(
|
|
66
|
-
|
|
64
|
+
await registry.updateIfNeeded("force");
|
|
65
|
+
|
|
67
66
|
// Check that snapshot files actually exist in storage
|
|
68
67
|
const snapshotFiles = await storage.listFiles(OverviewSnapshotsPrefix);
|
|
69
68
|
expect(snapshotFiles.length).toBeGreaterThan(0);
|
|
70
|
-
|
|
69
|
+
|
|
71
70
|
// Check that snapshots were created
|
|
72
71
|
const snapshots = await registry.listGlobalOverviewSnapshots();
|
|
73
72
|
expect(snapshots.length).toBeGreaterThan(0);
|
|
74
|
-
expect(snapshots[0]).toHaveProperty(
|
|
75
|
-
expect(snapshots[0]).toHaveProperty(
|
|
73
|
+
expect(snapshots[0]).toHaveProperty("timestamp");
|
|
74
|
+
expect(snapshots[0]).toHaveProperty("path");
|
|
76
75
|
expect(snapshots[0].path).toMatch(/^_overview_snapshots_v2\/global\/.*\.json\.gz$/);
|
|
77
|
-
|
|
76
|
+
|
|
78
77
|
// Test that global overview files exist (should be empty initially)
|
|
79
78
|
const globalOverview = await registry.getGlobalOverview();
|
|
80
79
|
expect(globalOverview).toBeDefined();
|
|
81
80
|
expect(globalOverview?.packages).toHaveLength(0);
|
|
82
|
-
|
|
81
|
+
|
|
83
82
|
// Test restore functionality
|
|
84
83
|
const snapshotId = snapshots[0].timestamp;
|
|
85
84
|
await registry.restoreGlobalOverviewFromSnapshot(snapshotId);
|
|
86
|
-
|
|
85
|
+
|
|
87
86
|
// Verify restored overview is still valid
|
|
88
87
|
const restoredOverview = await registry.getGlobalOverview();
|
|
89
88
|
expect(restoredOverview).toBeDefined();
|
|
90
89
|
expect(restoredOverview?.packages).toHaveLength(0);
|
|
91
|
-
|
|
92
90
|
} finally {
|
|
93
91
|
await teardown();
|
|
94
92
|
}
|
|
95
93
|
});
|
|
96
94
|
|
|
97
|
-
test.each(testStorages)(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
// Force an update which would normally create snapshots
|
|
103
|
-
await registry.updateIfNeeded('force');
|
|
104
|
-
|
|
105
|
-
// Check that no snapshots were created
|
|
106
|
-
const snapshots = await registry.listGlobalOverviewSnapshots();
|
|
107
|
-
expect(snapshots).toHaveLength(0);
|
|
108
|
-
|
|
109
|
-
const snapshotFiles = await storage.listFiles(OverviewSnapshotsPrefix);
|
|
110
|
-
expect(snapshotFiles).toHaveLength(0);
|
|
111
|
-
|
|
112
|
-
} finally {
|
|
113
|
-
await teardown();
|
|
114
|
-
}
|
|
115
|
-
});
|
|
95
|
+
test.each(testStorages)(
|
|
96
|
+
"registry snapshots disabled test with $name",
|
|
97
|
+
async ({ storageProvider }) => {
|
|
98
|
+
const { storage, teardown } = storageProvider();
|
|
99
|
+
const registry = new BlockRegistryV2(storage, undefined, { skipSnapshotCreation: true });
|
|
116
100
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
101
|
+
try {
|
|
102
|
+
// Force an update which would normally create snapshots
|
|
103
|
+
await registry.updateIfNeeded("force");
|
|
104
|
+
|
|
105
|
+
// Check that no snapshots were created
|
|
106
|
+
const snapshots = await registry.listGlobalOverviewSnapshots();
|
|
107
|
+
expect(snapshots).toHaveLength(0);
|
|
108
|
+
|
|
109
|
+
const snapshotFiles = await storage.listFiles(OverviewSnapshotsPrefix);
|
|
110
|
+
expect(snapshotFiles).toHaveLength(0);
|
|
111
|
+
} finally {
|
|
112
|
+
await teardown();
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
test.each(testStorages)(
|
|
118
|
+
"force mode removes deleted packages and versions with $name",
|
|
119
|
+
async ({ storageProvider }) => {
|
|
120
|
+
const { storage, teardown } = storageProvider();
|
|
121
|
+
const registry = new BlockRegistryV2(storage);
|
|
122
|
+
|
|
123
|
+
try {
|
|
124
|
+
// Create mock manifests for testing
|
|
125
|
+
const createMockManifest = (
|
|
126
|
+
org: string,
|
|
127
|
+
name: string,
|
|
128
|
+
version: string,
|
|
129
|
+
): BlockPackManifest => ({
|
|
130
|
+
schema: "v2",
|
|
131
|
+
description: {
|
|
132
|
+
id: { organization: org, name: name, version: version },
|
|
135
133
|
title: `Test ${name}`,
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
134
|
+
summary: "Test package",
|
|
135
|
+
components: {
|
|
136
|
+
workflow: { type: "workflow-v1", main: { type: "relative", path: "workflow.json" } },
|
|
137
|
+
model: { type: "relative", path: "model.json" },
|
|
138
|
+
ui: { type: "relative", path: "ui.json" },
|
|
140
139
|
},
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
140
|
+
meta: {
|
|
141
|
+
title: `Test ${name}`,
|
|
142
|
+
description: "Test package description",
|
|
143
|
+
organization: {
|
|
144
|
+
name: "Test Organization",
|
|
145
|
+
url: "https://test.com",
|
|
146
|
+
},
|
|
147
|
+
tags: [],
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
files: [
|
|
151
|
+
{
|
|
152
|
+
name: "model.json",
|
|
153
|
+
size: 13,
|
|
154
|
+
sha256: "6FD977DB9B2AFE87A9CEEE48432881299A6AAF83D935FBBE83007660287F9C2E",
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
const mockFileReader = async (fileName: string) => {
|
|
160
|
+
if (fileName === "model.json") {
|
|
161
|
+
return Buffer.from('{"test":true}');
|
|
149
162
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
163
|
+
throw new Error(`Unknown file: ${fileName}`);
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
// 1. Publish multiple packages and versions
|
|
167
|
+
const pkg1v1 = createMockManifest("testorg", "pkg1", "1.0.0");
|
|
168
|
+
const pkg1v2 = createMockManifest("testorg", "pkg1", "2.0.0");
|
|
169
|
+
const pkg2v1 = createMockManifest("testorg", "pkg2", "1.0.0");
|
|
170
|
+
const pkg3v1 = createMockManifest("anotherorg", "pkg3", "1.0.0");
|
|
171
|
+
|
|
172
|
+
await registry.publishPackage(pkg1v1, mockFileReader);
|
|
173
|
+
await registry.publishPackage(pkg1v2, mockFileReader);
|
|
174
|
+
await registry.publishPackage(pkg2v1, mockFileReader);
|
|
175
|
+
await registry.publishPackage(pkg3v1, mockFileReader);
|
|
176
|
+
|
|
177
|
+
// Update registry to create overviews
|
|
178
|
+
await registry.updateIfNeeded("normal");
|
|
179
|
+
|
|
180
|
+
// Verify initial state
|
|
181
|
+
let globalOverview = await registry.getGlobalOverview();
|
|
182
|
+
expect(globalOverview?.packages).toHaveLength(3); // testorg:pkg1, testorg:pkg2, anotherorg:pkg3
|
|
183
|
+
|
|
184
|
+
let pkg1Overview = await registry.getPackageOverview({
|
|
185
|
+
organization: "testorg",
|
|
186
|
+
name: "pkg1",
|
|
187
|
+
});
|
|
188
|
+
expect(pkg1Overview?.versions).toHaveLength(2); // v1.0.0 and v2.0.0
|
|
189
|
+
|
|
190
|
+
let pkg2Overview = await registry.getPackageOverview({
|
|
191
|
+
organization: "testorg",
|
|
192
|
+
name: "pkg2",
|
|
193
|
+
});
|
|
194
|
+
expect(pkg2Overview?.versions).toHaveLength(1); // v1.0.0
|
|
195
|
+
|
|
196
|
+
let pkg3Overview = await registry.getPackageOverview({
|
|
197
|
+
organization: "anotherorg",
|
|
198
|
+
name: "pkg3",
|
|
199
|
+
});
|
|
200
|
+
expect(pkg3Overview?.versions).toHaveLength(1); // v1.0.0
|
|
201
|
+
|
|
202
|
+
// 2. Manually delete some packages/versions from storage (simulating external deletion)
|
|
203
|
+
// Delete pkg1 v1.0.0
|
|
204
|
+
await storage.deleteFiles(
|
|
205
|
+
"v2/testorg/pkg1/1.0.0/manifest.json",
|
|
206
|
+
"v2/testorg/pkg1/1.0.0/model.json",
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
// Delete entire pkg2
|
|
210
|
+
await storage.deleteFiles(
|
|
211
|
+
"v2/testorg/pkg2/1.0.0/manifest.json",
|
|
212
|
+
"v2/testorg/pkg2/1.0.0/model.json",
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
// Leave pkg1 v2.0.0 and pkg3 v1.0.0 intact
|
|
216
|
+
|
|
217
|
+
// 3. Count snapshots before force mode
|
|
218
|
+
const initialSnapshots = await storage.listFiles("_overview_snapshots_v2/");
|
|
219
|
+
|
|
220
|
+
// 4. Run force mode - should create pre-write snapshots and rebuild from scratch
|
|
221
|
+
await registry.updateIfNeeded("force");
|
|
222
|
+
|
|
223
|
+
// 5. Verify pre-write snapshots were created
|
|
224
|
+
const finalSnapshots = await storage.listFiles("_overview_snapshots_v2/");
|
|
225
|
+
expect(finalSnapshots.length).toBeGreaterThan(initialSnapshots.length);
|
|
226
|
+
|
|
227
|
+
// Check for pre-write snapshots (should contain "-prewrite-" in filename)
|
|
228
|
+
const preWriteSnapshots = finalSnapshots.filter((s) => s.includes("-prewrite-"));
|
|
229
|
+
expect(preWriteSnapshots.length).toBeGreaterThan(0);
|
|
230
|
+
|
|
231
|
+
// 6. Verify overviews now only reflect what exists in storage
|
|
232
|
+
globalOverview = await registry.getGlobalOverview();
|
|
233
|
+
expect(globalOverview?.packages).toHaveLength(2); // Only testorg:pkg1 and anotherorg:pkg3 should remain
|
|
234
|
+
|
|
235
|
+
const remainingPackageNames = globalOverview?.packages
|
|
236
|
+
.map((p) => `${p.id.organization}:${p.id.name}`)
|
|
237
|
+
.sort();
|
|
238
|
+
expect(remainingPackageNames).toEqual(["anotherorg:pkg3", "testorg:pkg1"]);
|
|
239
|
+
|
|
240
|
+
// 7. Verify pkg1 now only has v2.0.0
|
|
241
|
+
pkg1Overview = await registry.getPackageOverview({ organization: "testorg", name: "pkg1" });
|
|
242
|
+
expect(pkg1Overview?.versions).toHaveLength(1);
|
|
243
|
+
expect(pkg1Overview?.versions[0].description.id.version).toBe("2.0.0");
|
|
244
|
+
|
|
245
|
+
// 8. Verify pkg2 overview is unchanged (since pkg2 was completely deleted,
|
|
246
|
+
// force mode doesn't process it, so the old overview file remains)
|
|
247
|
+
pkg2Overview = await registry.getPackageOverview({ organization: "testorg", name: "pkg2" });
|
|
248
|
+
expect(pkg2Overview?.versions).toHaveLength(1); // Old overview remains
|
|
249
|
+
|
|
250
|
+
// 9. Verify pkg3 is unchanged
|
|
251
|
+
pkg3Overview = await registry.getPackageOverview({
|
|
252
|
+
organization: "anotherorg",
|
|
253
|
+
name: "pkg3",
|
|
254
|
+
});
|
|
255
|
+
expect(pkg3Overview?.versions).toHaveLength(1);
|
|
256
|
+
expect(pkg3Overview?.versions[0].description.id.version).toBe("1.0.0");
|
|
257
|
+
} finally {
|
|
258
|
+
await teardown();
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
);
|
|
236
262
|
|
|
237
263
|
test.each([
|
|
238
264
|
{
|
|
239
|
-
name:
|
|
240
|
-
current:
|
|
241
|
-
available: [
|
|
265
|
+
name: "test1",
|
|
266
|
+
current: "1.2.3",
|
|
267
|
+
available: ["1.1.2", "1.2.3", "1.2.4", "1.2.5", "1.3.4", "1.3.5", "3.4.1", "3.4.2"],
|
|
242
268
|
expected: [
|
|
243
|
-
{ type:
|
|
244
|
-
{ type:
|
|
245
|
-
{ type:
|
|
246
|
-
]
|
|
269
|
+
{ type: "patch", update: "1.2.5" },
|
|
270
|
+
{ type: "minor", update: "1.3.5" },
|
|
271
|
+
{ type: "major", update: "3.4.2" },
|
|
272
|
+
],
|
|
247
273
|
},
|
|
248
274
|
{
|
|
249
|
-
name:
|
|
250
|
-
current:
|
|
251
|
-
available: [
|
|
275
|
+
name: "test2",
|
|
276
|
+
current: "1.2.3",
|
|
277
|
+
available: ["1.1.2", "1.2.3", "1.3.4", "1.3.5", "3.4.1", "3.4.2"],
|
|
252
278
|
expected: [
|
|
253
|
-
{ type:
|
|
254
|
-
{ type:
|
|
255
|
-
]
|
|
279
|
+
{ type: "minor", update: "1.3.5" },
|
|
280
|
+
{ type: "major", update: "3.4.2" },
|
|
281
|
+
],
|
|
256
282
|
},
|
|
257
283
|
{
|
|
258
|
-
name:
|
|
259
|
-
current:
|
|
260
|
-
available: [
|
|
284
|
+
name: "test3",
|
|
285
|
+
current: "1.2.3",
|
|
286
|
+
available: ["1.1.2", "1.2.3", "1.2.4", "1.2.5", "3.4.1", "3.4.2"],
|
|
261
287
|
expected: [
|
|
262
|
-
{ type:
|
|
263
|
-
{ type:
|
|
264
|
-
]
|
|
288
|
+
{ type: "patch", update: "1.2.5" },
|
|
289
|
+
{ type: "major", update: "3.4.2" },
|
|
290
|
+
],
|
|
265
291
|
},
|
|
266
292
|
{
|
|
267
|
-
name:
|
|
268
|
-
current:
|
|
269
|
-
available: [
|
|
293
|
+
name: "test4",
|
|
294
|
+
current: "1.2.3",
|
|
295
|
+
available: ["1.1.2", "1.2.3", "1.2.4", "1.3.0", "2.0.0"],
|
|
270
296
|
expected: [
|
|
271
|
-
{ type:
|
|
272
|
-
{ type:
|
|
273
|
-
{ type:
|
|
274
|
-
]
|
|
275
|
-
}
|
|
297
|
+
{ type: "patch", update: "1.2.4" },
|
|
298
|
+
{ type: "minor", update: "1.3.0" },
|
|
299
|
+
{ type: "major", update: "2.0.0" },
|
|
300
|
+
],
|
|
301
|
+
},
|
|
276
302
|
] as { name: string; current: string; available: string[]; expected: UpdateSuggestions<string> }[])(
|
|
277
|
-
|
|
303
|
+
"infer updates test $name",
|
|
278
304
|
({ current, available, expected }) => {
|
|
279
305
|
const a = [...available];
|
|
280
306
|
a.reverse();
|
|
281
307
|
expect(inferUpdateSuggestions(current, a)).toStrictEqual(expected);
|
|
282
|
-
}
|
|
308
|
+
},
|
|
283
309
|
);
|