@milaboratories/pl-middle-layer 1.69.2 → 1.71.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/dist/index.cjs +0 -2
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -2
- package/dist/middle_layer/build_stamp.cjs +1 -1
- package/dist/middle_layer/build_stamp.js +1 -1
- package/dist/middle_layer/middle_layer.cjs +14 -45
- package/dist/middle_layer/middle_layer.cjs.map +1 -1
- package/dist/middle_layer/middle_layer.d.ts +8 -15
- package/dist/middle_layer/middle_layer.d.ts.map +1 -1
- package/dist/middle_layer/middle_layer.js +14 -45
- package/dist/middle_layer/middle_layer.js.map +1 -1
- package/dist/middle_layer/template_list.cjs.map +1 -1
- package/dist/middle_layer/template_list.d.ts +1 -6
- package/dist/middle_layer/template_list.d.ts.map +1 -1
- package/dist/middle_layer/template_list.js.map +1 -1
- package/dist/model/index.cjs +0 -2
- package/dist/model/index.d.ts +1 -2
- package/dist/model/index.js +1 -2
- package/dist/model/template_export.cjs +5 -1
- package/dist/model/template_export.cjs.map +1 -1
- package/dist/model/template_export.d.ts +3 -0
- package/dist/model/template_export.d.ts.map +1 -1
- package/dist/model/template_export.js +5 -1
- package/dist/model/template_export.js.map +1 -1
- package/dist/model/template_serializer.cjs +2 -0
- package/dist/model/template_serializer.cjs.map +1 -1
- package/dist/model/template_serializer.d.ts.map +1 -1
- package/dist/model/template_serializer.js +2 -0
- package/dist/model/template_serializer.js.map +1 -1
- package/package.json +13 -13
- package/src/middle_layer/middle_layer.ts +21 -57
- package/src/middle_layer/template_list.ts +2 -5
- package/src/middle_layer/templates.test.ts +11 -20
- package/src/model/index.ts +0 -1
- package/src/model/template_export.test.ts +41 -5
- package/src/model/template_export.ts +11 -3
- package/src/model/template_serializer.test.ts +26 -3
- package/src/model/template_serializer.ts +2 -0
- package/dist/model/template_share.cjs +0 -42
- package/dist/model/template_share.cjs.map +0 -1
- package/dist/model/template_share.d.ts +0 -27
- package/dist/model/template_share.d.ts.map +0 -1
- package/dist/model/template_share.js +0 -42
- package/dist/model/template_share.js.map +0 -1
- package/src/model/template_share.test.ts +0 -78
- package/src/model/template_share.ts +0 -52
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "vitest";
|
|
2
|
-
import type {
|
|
3
|
-
BlockKindSelectorReference,
|
|
4
|
-
BlockPackLocationReference,
|
|
5
|
-
ProjectTemplateV1,
|
|
6
|
-
ProjectTemplateV1Entry,
|
|
7
|
-
} from "@milaboratories/pl-model-common";
|
|
8
|
-
import { PROJECT_TEMPLATE_SCHEMA_V1 } from "@milaboratories/pl-model-common";
|
|
9
|
-
import { unshareableTemplateEntries } from "./template_share";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Whether a stored template may travel to another machine.
|
|
13
|
-
*
|
|
14
|
-
* A function of the document alone, which is why it is asked both when a share is attempted
|
|
15
|
-
* and when a template is merely displayed — the refusal has to be visible on the template
|
|
16
|
-
* itself, not only after the user tries.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
const KIND = "@platforma-open/milaboratories.demo.kind@^1.0.0" as BlockKindSelectorReference;
|
|
20
|
-
|
|
21
|
-
const entry = (id: string, location?: string): ProjectTemplateV1Entry => ({
|
|
22
|
-
id,
|
|
23
|
-
kind: KIND,
|
|
24
|
-
params: {},
|
|
25
|
-
...(location !== undefined ? { location: location as BlockPackLocationReference } : {}),
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
const documentOf = (...blocks: ProjectTemplateV1Entry[]): ProjectTemplateV1 => ({
|
|
29
|
-
schema: PROJECT_TEMPLATE_SCHEMA_V1,
|
|
30
|
-
blocks,
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
describe("unshareableTemplateEntries", () => {
|
|
34
|
-
test("a template whose entries name no place at all can be shared", () => {
|
|
35
|
-
// The common case: every entry resolves through its kind, which means the same thing
|
|
36
|
-
// on the recipient's machine as it does here.
|
|
37
|
-
expect(unshareableTemplateEntries(documentOf(entry("a"), entry("b")))).toStrictEqual([]);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
test("an entry installed from a folder on this machine refuses the share, and says which folder", () => {
|
|
41
|
-
const problems = unshareableTemplateEntries(
|
|
42
|
-
documentOf(entry("a"), entry("b", "file:///Users/dev/blocks/demo/block")),
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
expect(problems.map((p) => p.entryId)).toStrictEqual(["b"]);
|
|
46
|
-
expect(problems[0].error).toContain("file:///Users/dev/blocks/demo/block");
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
test("every offending entry is reported, not only the first", () => {
|
|
50
|
-
// A UI names each block once instead of sending its user round the loop per entry.
|
|
51
|
-
const problems = unshareableTemplateEntries(
|
|
52
|
-
documentOf(
|
|
53
|
-
entry("a", "file:///blocks/a"),
|
|
54
|
-
entry("b"),
|
|
55
|
-
entry("c", "FILE:///blocks/c"), // the scheme is case-insensitive
|
|
56
|
-
),
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
expect(problems.map((p) => p.entryId)).toStrictEqual(["a", "c"]);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
test("a location whose scheme cannot be read is refused too", () => {
|
|
63
|
-
// Nothing can resolve it anywhere, here included — so the reason differs from the
|
|
64
|
-
// `file:` one, and the message says so rather than blaming the recipient's machine.
|
|
65
|
-
const problems = unshareableTemplateEntries(documentOf(entry("a", "/blocks/a")));
|
|
66
|
-
|
|
67
|
-
expect(problems.map((p) => p.entryId)).toStrictEqual(["a"]);
|
|
68
|
-
expect(problems[0].error).toContain("nothing can resolve");
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
test("a location naming a place both machines can reach is not refused", () => {
|
|
72
|
-
// The rule is about a place that means something different elsewhere, not about
|
|
73
|
-
// locations as such.
|
|
74
|
-
expect(
|
|
75
|
-
unshareableTemplateEntries(documentOf(entry("a", "https://blocks.example.org/demo"))),
|
|
76
|
-
).toStrictEqual([]);
|
|
77
|
-
});
|
|
78
|
-
});
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import type { ProjectTemplateV1 } from "@milaboratories/pl-model-common";
|
|
2
|
-
import { parseBlockPackLocation } from "@milaboratories/pl-model-common";
|
|
3
|
-
|
|
4
|
-
/** One template entry standing in the way of sharing the template, and why. */
|
|
5
|
-
export type TemplateShareProblem = {
|
|
6
|
-
/** The template-local id of the entry the problem belongs to; on an exported template it is
|
|
7
|
-
* the block's project-local uuid. */
|
|
8
|
-
readonly entryId: string;
|
|
9
|
-
readonly error: string;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Every entry of a template that cannot travel to another machine, or an empty list for a
|
|
14
|
-
* template that can be shared.
|
|
15
|
-
*
|
|
16
|
-
* An entry's `location` names a place rather than a name, and a `file:` place is a folder on
|
|
17
|
-
* the author's own disk: a recipient resolving it finds nothing, or worse finds something
|
|
18
|
-
* else. Such a template stays perfectly usable where it was made, so it is stored and applied
|
|
19
|
-
* as normal — only sharing it is refused.
|
|
20
|
-
*
|
|
21
|
-
* A location whose scheme cannot be read is refused for the same reason: nothing can resolve
|
|
22
|
-
* it anywhere, here included.
|
|
23
|
-
*
|
|
24
|
-
* Every offending entry is reported, not only the first, so a UI can name each block instead
|
|
25
|
-
* of sending its user round the loop once per entry.
|
|
26
|
-
*/
|
|
27
|
-
export function unshareableTemplateEntries(
|
|
28
|
-
document: ProjectTemplateV1,
|
|
29
|
-
): readonly TemplateShareProblem[] {
|
|
30
|
-
const problems: TemplateShareProblem[] = [];
|
|
31
|
-
for (const entry of document.blocks) {
|
|
32
|
-
if (entry.location === undefined) continue;
|
|
33
|
-
let scheme: string;
|
|
34
|
-
try {
|
|
35
|
-
scheme = parseBlockPackLocation(entry.location).scheme;
|
|
36
|
-
} catch (e) {
|
|
37
|
-
problems.push({
|
|
38
|
-
entryId: entry.id,
|
|
39
|
-
error: `Block is installed from a location nothing can resolve: ${e instanceof Error ? e.message : String(e)}`,
|
|
40
|
-
});
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
if (scheme === "file")
|
|
44
|
-
problems.push({
|
|
45
|
-
entryId: entry.id,
|
|
46
|
-
error:
|
|
47
|
-
`Block is installed from ${entry.location}, a folder on this machine — it resolves ` +
|
|
48
|
-
"to nothing on the recipient's, so this template cannot be shared",
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
return problems;
|
|
52
|
-
}
|