-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathconfig.ts
154 lines (129 loc) · 4.02 KB
/
config.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import { clientStore, editor } from "$sb/syscalls.ts";
import { readSetting } from "$sb/lib/settings_page.ts";
import { z, ZodError } from "zod";
/**
* The name of this plug.
* TODO: is there a way to get this programatically?
*/
export const PLUG_NAME = "treeview";
export const PLUG_DISPLAY_NAME = "TreeView Plug";
/**
* The key used to save the current enabled state of the treeview.
*/
const ENABLED_STATE_KEY = "enableTreeView";
/**
* The possible position where the treeview can be rendered.
*/
const POSITIONS = ["rhs", "lhs", "bhs", "modal"] as const;
export type Position = typeof POSITIONS[number];
/**
* Defines an exclusion rule based on a regular expression
*/
export const exclusionRuleByRegexSchema = z.object({
type: z.literal("regex"),
rule: z.string(),
negate: z.boolean().optional().default(false),
});
/**
* Defines an exclusion rule based on a list of tags
*/
export const exclusionRuleByTagsSchema = z.object({
type: z.literal("tags"),
tags: z.array(z.string()),
negate: z.boolean().optional().default(false),
attribute: z.enum(["tags", "itags", "tag"]).optional().default("tags"),
});
/**
* Defines an exclusion rule based on a regular expression
*/
export const exclusionRuleByFunctionSchema = z.object({
type: z.literal("space-function"),
name: z.string(),
negate: z.boolean().optional().default(false),
});
/**
* The schema for the tree view configuration read from the SETTINGS page.
*/
const treeViewConfigSchema = z.object({
/**
* Where to position the tree view in the UI.
*/
position: z.enum(POSITIONS).optional().default("lhs"),
/**
* The size of the treeview pane.
*/
size: z.number().gt(0).optional().default(1),
/**
* Drag-and-drop options
*/
dragAndDrop: z.object({
/**
* Whether dragging/dropping functionality is
*/
enabled: z.boolean().optional().default(true),
/**
* True to confirm on rename actions by showing a popup prompt.
*/
confirmOnRename: z.boolean().optional().default(true),
}).optional().default({}),
/**
* @deprecated
*/
pageExcludeRegex: z.string().optional().default(""),
/**
* A list of exclusion rules to apply.
*/
exclusions: z.array(z.discriminatedUnion("type", [
exclusionRuleByRegexSchema,
exclusionRuleByTagsSchema,
exclusionRuleByFunctionSchema,
])).optional(),
});
export type TreeViewConfig = z.infer<typeof treeViewConfigSchema>;
async function showConfigErrorNotification(error: unknown) {
if (configErrorShown) {
return;
}
configErrorShown = true;
let errorMessage = `${typeof error}: ${String(error)}`;
if (error instanceof ZodError) {
const { formErrors, fieldErrors } = error.flatten();
const fieldErrorMessages = Object.keys(fieldErrors).map((field) =>
`\`${field}\` - ${fieldErrors[field]!.join(", ")}`
);
// Not pretty, but we don't have any formatting options available here.
errorMessage = [...formErrors, ...fieldErrorMessages].join("; ");
}
// Some rudimentary notification about an invalid configuration.
// Not pretty, but we can't use html/formatting here.
await editor.flashNotification(
`There was an error with your ${PLUG_NAME} configuration. Check your SETTINGS file: ${errorMessage}`,
"error",
);
}
let configErrorShown = false;
export async function getPlugConfig(): Promise<TreeViewConfig> {
const userConfig = await readSetting(PLUG_NAME);
try {
return treeViewConfigSchema.parse(userConfig || {});
} catch (_err) {
if (!configErrorShown) {
showConfigErrorNotification(_err);
configErrorShown = true;
}
// Fallback to the default configuration
return treeViewConfigSchema.parse({});
}
}
export async function isTreeViewEnabled() {
return !!(await clientStore.get(ENABLED_STATE_KEY));
}
export async function setTreeViewEnabled(value: boolean) {
return await clientStore.set(ENABLED_STATE_KEY, value);
}
export async function getCustomStyles() {
const customStyles = await editor.getUiOption("customStyles") as
| string
| undefined;
return customStyles;
}