@geekity/cms 0.24.0 → 0.26.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.
Files changed (182) hide show
  1. package/README.md +96 -160
  2. package/admin/pages/documents/editor.njk +48 -0
  3. package/admin/pages/federation/settings.njk +1 -59
  4. package/admin/pages/plugins/installed.njk +113 -0
  5. package/admin/pages/plugins/screen.njk +129 -0
  6. package/admin/static/admin.css +144 -4
  7. package/admin/static/editor-actions.js +202 -0
  8. package/dist/admin/accounts.d.ts +18 -39
  9. package/dist/admin/accounts.d.ts.map +1 -1
  10. package/dist/admin/accounts.js +19 -48
  11. package/dist/admin/accounts.js.map +1 -1
  12. package/dist/admin/documents.d.ts +5 -0
  13. package/dist/admin/documents.d.ts.map +1 -1
  14. package/dist/admin/documents.js +17 -8
  15. package/dist/admin/documents.js.map +1 -1
  16. package/dist/admin/editor-actions.d.ts +35 -0
  17. package/dist/admin/editor-actions.d.ts.map +1 -0
  18. package/dist/admin/editor-actions.js +187 -0
  19. package/dist/admin/editor-actions.js.map +1 -0
  20. package/dist/admin/federation.d.ts +4 -5
  21. package/dist/admin/federation.d.ts.map +1 -1
  22. package/dist/admin/federation.js +4 -5
  23. package/dist/admin/federation.js.map +1 -1
  24. package/dist/admin/index.d.ts +1 -1
  25. package/dist/admin/index.d.ts.map +1 -1
  26. package/dist/admin/index.js +1 -1
  27. package/dist/admin/index.js.map +1 -1
  28. package/dist/admin/menu.d.ts +1 -1
  29. package/dist/admin/menu.d.ts.map +1 -1
  30. package/dist/admin/menu.js +10 -3
  31. package/dist/admin/menu.js.map +1 -1
  32. package/dist/admin/plugins.d.ts +24 -0
  33. package/dist/admin/plugins.d.ts.map +1 -0
  34. package/dist/admin/plugins.js +312 -0
  35. package/dist/admin/plugins.js.map +1 -0
  36. package/dist/admin/routes.d.ts.map +1 -1
  37. package/dist/admin/routes.js +5 -1
  38. package/dist/admin/routes.js.map +1 -1
  39. package/dist/admin/settings-federation.d.ts +0 -25
  40. package/dist/admin/settings-federation.d.ts.map +1 -1
  41. package/dist/admin/settings-federation.js +1 -54
  42. package/dist/admin/settings-federation.js.map +1 -1
  43. package/dist/admin/settings.d.ts +2 -14
  44. package/dist/admin/settings.d.ts.map +1 -1
  45. package/dist/admin/settings.js +1 -21
  46. package/dist/admin/settings.js.map +1 -1
  47. package/dist/admin/store.d.ts +8 -1
  48. package/dist/admin/store.d.ts.map +1 -1
  49. package/dist/admin/store.js +7 -3
  50. package/dist/admin/store.js.map +1 -1
  51. package/dist/admin/templates.d.ts +2 -0
  52. package/dist/admin/templates.d.ts.map +1 -1
  53. package/dist/admin/templates.js +2 -0
  54. package/dist/admin/templates.js.map +1 -1
  55. package/dist/cli.d.ts +2 -3
  56. package/dist/cli.d.ts.map +1 -1
  57. package/dist/cli.js +278 -212
  58. package/dist/cli.js.map +1 -1
  59. package/dist/config.d.ts +20 -0
  60. package/dist/config.d.ts.map +1 -1
  61. package/dist/config.js +6 -0
  62. package/dist/config.js.map +1 -1
  63. package/dist/content/store.d.ts +6 -0
  64. package/dist/content/store.d.ts.map +1 -1
  65. package/dist/content/store.js +3 -0
  66. package/dist/content/store.js.map +1 -1
  67. package/dist/drain.d.ts +28 -0
  68. package/dist/drain.d.ts.map +1 -0
  69. package/dist/drain.js +106 -0
  70. package/dist/drain.js.map +1 -0
  71. package/dist/env.d.ts +11 -0
  72. package/dist/env.d.ts.map +1 -1
  73. package/dist/federation/federation.d.ts +4 -2
  74. package/dist/federation/federation.d.ts.map +1 -1
  75. package/dist/federation/federation.js +16 -21
  76. package/dist/federation/federation.js.map +1 -1
  77. package/dist/federation/inbox.d.ts +23 -3
  78. package/dist/federation/inbox.d.ts.map +1 -1
  79. package/dist/federation/inbox.js +63 -1
  80. package/dist/federation/inbox.js.map +1 -1
  81. package/dist/federation/index.d.ts +0 -4
  82. package/dist/federation/index.d.ts.map +1 -1
  83. package/dist/federation/index.js +0 -2
  84. package/dist/federation/index.js.map +1 -1
  85. package/dist/federation/mount.d.ts +6 -12
  86. package/dist/federation/mount.d.ts.map +1 -1
  87. package/dist/federation/mount.js +3 -50
  88. package/dist/federation/mount.js.map +1 -1
  89. package/dist/federation/queue.d.ts +22 -0
  90. package/dist/federation/queue.d.ts.map +1 -0
  91. package/dist/federation/queue.js +58 -0
  92. package/dist/federation/queue.js.map +1 -0
  93. package/dist/files/atomic.d.ts +13 -0
  94. package/dist/files/atomic.d.ts.map +1 -1
  95. package/dist/files/atomic.js +45 -0
  96. package/dist/files/atomic.js.map +1 -1
  97. package/dist/index.d.ts +30 -3
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +156 -79
  100. package/dist/index.js.map +1 -1
  101. package/dist/plugin.d.ts +524 -0
  102. package/dist/plugin.d.ts.map +1 -0
  103. package/dist/plugin.js +23 -0
  104. package/dist/plugin.js.map +1 -0
  105. package/dist/plugins/enabled.d.ts +23 -0
  106. package/dist/plugins/enabled.d.ts.map +1 -0
  107. package/dist/plugins/enabled.js +49 -0
  108. package/dist/plugins/enabled.js.map +1 -0
  109. package/dist/plugins/federation.d.ts +26 -0
  110. package/dist/plugins/federation.d.ts.map +1 -0
  111. package/dist/plugins/federation.js +114 -0
  112. package/dist/plugins/federation.js.map +1 -0
  113. package/dist/plugins/fetch.d.ts +15 -0
  114. package/dist/plugins/fetch.d.ts.map +1 -0
  115. package/dist/plugins/fetch.js +33 -0
  116. package/dist/plugins/fetch.js.map +1 -0
  117. package/dist/plugins/folder.d.ts +50 -0
  118. package/dist/plugins/folder.d.ts.map +1 -0
  119. package/dist/plugins/folder.js +171 -0
  120. package/dist/plugins/folder.js.map +1 -0
  121. package/dist/plugins/install.d.ts +45 -0
  122. package/dist/plugins/install.d.ts.map +1 -0
  123. package/dist/plugins/install.js +275 -0
  124. package/dist/plugins/install.js.map +1 -0
  125. package/dist/plugins/mount.d.ts +17 -0
  126. package/dist/plugins/mount.d.ts.map +1 -0
  127. package/dist/plugins/mount.js +44 -0
  128. package/dist/plugins/mount.js.map +1 -0
  129. package/dist/plugins/registry.d.ts +110 -0
  130. package/dist/plugins/registry.d.ts.map +1 -0
  131. package/dist/plugins/registry.js +447 -0
  132. package/dist/plugins/registry.js.map +1 -0
  133. package/dist/plugins/settings.d.ts +64 -0
  134. package/dist/plugins/settings.d.ts.map +1 -0
  135. package/dist/plugins/settings.js +219 -0
  136. package/dist/plugins/settings.js.map +1 -0
  137. package/dist/plugins/site.d.ts +17 -0
  138. package/dist/plugins/site.d.ts.map +1 -0
  139. package/dist/plugins/site.js +67 -0
  140. package/dist/plugins/site.js.map +1 -0
  141. package/dist/supervisor/primary.d.ts +47 -0
  142. package/dist/supervisor/primary.d.ts.map +1 -0
  143. package/dist/supervisor/primary.js +208 -0
  144. package/dist/supervisor/primary.js.map +1 -0
  145. package/dist/supervisor/protocol.d.ts +37 -0
  146. package/dist/supervisor/protocol.d.ts.map +1 -0
  147. package/dist/supervisor/protocol.js +29 -0
  148. package/dist/supervisor/protocol.js.map +1 -0
  149. package/dist/supervisor/supervision.d.ts +25 -0
  150. package/dist/supervisor/supervision.d.ts.map +1 -0
  151. package/dist/supervisor/supervision.js +7 -0
  152. package/dist/supervisor/supervision.js.map +1 -0
  153. package/dist/supervisor/worker.d.ts +29 -0
  154. package/dist/supervisor/worker.d.ts.map +1 -0
  155. package/dist/supervisor/worker.js +97 -0
  156. package/dist/supervisor/worker.js.map +1 -0
  157. package/dist/web/maintenance.d.ts +2 -2
  158. package/dist/web/maintenance.js +2 -2
  159. package/dist/web/negotiate.d.ts +4 -3
  160. package/dist/web/negotiate.d.ts.map +1 -1
  161. package/dist/web/negotiate.js +4 -3
  162. package/dist/web/negotiate.js.map +1 -1
  163. package/dist/web/routes.d.ts.map +1 -1
  164. package/dist/web/routes.js +33 -14
  165. package/dist/web/routes.js.map +1 -1
  166. package/package.json +10 -1
  167. package/dist/comments/conversation.d.ts +0 -29
  168. package/dist/comments/conversation.d.ts.map +0 -1
  169. package/dist/comments/conversation.js +0 -60
  170. package/dist/comments/conversation.js.map +0 -1
  171. package/dist/federation/import-wordpress.d.ts +0 -128
  172. package/dist/federation/import-wordpress.d.ts.map +0 -1
  173. package/dist/federation/import-wordpress.js +0 -426
  174. package/dist/federation/import-wordpress.js.map +0 -1
  175. package/dist/federation/wordpress.d.ts +0 -131
  176. package/dist/federation/wordpress.d.ts.map +0 -1
  177. package/dist/federation/wordpress.js +0 -342
  178. package/dist/federation/wordpress.js.map +0 -1
  179. package/dist/web/comments.d.ts +0 -60
  180. package/dist/web/comments.d.ts.map +0 -1
  181. package/dist/web/comments.js +0 -207
  182. package/dist/web/comments.js.map +0 -1
@@ -0,0 +1,447 @@
1
+ /**
2
+ * The plugin registry (decision-33): every installed plugin, registered once
3
+ * at boot, and what the dependency graph says about each.
4
+ *
5
+ * Installed and enabled are separate. Installed is fixed for the life of the
6
+ * process: the plugins handed to `createCms`. Enabled is the `plugins` key of
7
+ * `site.json`, read per request, so every question that depends on it takes
8
+ * the enabled set as an argument rather than holding one.
9
+ */
10
+ import { createRequire } from 'node:module';
11
+ import path from 'node:path';
12
+ import semver from 'semver';
13
+ import { readFileIfPresentSync, updateFileAtomically } from '../files/atomic.js';
14
+ import { HOST_API_VERSION } from '../plugin.js';
15
+ import { pluginFetch } from './fetch.js';
16
+ import { pluginEnvPrefix, pluginFolderPath, resolvePluginSettings, settingFieldsProblem, settingValues, } from './settings.js';
17
+ /** Two installed plugins with one name. */
18
+ export class DuplicatePluginError extends Error {
19
+ constructor(name, first, second) {
20
+ super(`Two plugins are named ${name}: one from ${first} and one from ${second}.`);
21
+ this.name = 'DuplicatePluginError';
22
+ }
23
+ }
24
+ const CORE_PACKAGE = '@geekity/cms';
25
+ const CORE_VERSION = createRequire(import.meta.url)('../../package.json')
26
+ .version;
27
+ /** npm's rule for a package name, scoped or not. */
28
+ export const PACKAGE_NAME = /^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;
29
+ const PACKAGE_NAME_MAX = 214;
30
+ /**
31
+ * Register every installed plugin and resolve the dependency graph. Throws
32
+ * {@link DuplicatePluginError} when two plugins share a name; every other
33
+ * problem leaves that plugin unavailable and the site booting.
34
+ */
35
+ export function createPluginRegistry(installed, options) {
36
+ const bySource = new Map();
37
+ for (const entry of installed) {
38
+ const earlier = bySource.get(entry.plugin.name);
39
+ if (earlier !== undefined) {
40
+ throw new DuplicatePluginError(entry.plugin.name, earlier.source, entry.source);
41
+ }
42
+ bySource.set(entry.plugin.name, entry);
43
+ }
44
+ const own = new Map();
45
+ const contributions = new Map();
46
+ const services = new Map();
47
+ let registered = false;
48
+ const serviceFor = (consumer, dependency) => {
49
+ if (!Object.hasOwn(consumer.requires ?? {}, dependency)) {
50
+ throw new Error(`${consumer.name} uses ${dependency}, which is not in its requires.`);
51
+ }
52
+ if (!registered) {
53
+ throw new Error(`${consumer.name} called use(${JSON.stringify(dependency)}) in its register. Call it when handling a request, a command or a job, once every plugin has registered.`);
54
+ }
55
+ if (!services.has(dependency))
56
+ throw new Error(`${dependency} provides no service.`);
57
+ return services.get(dependency);
58
+ };
59
+ for (const entry of installed) {
60
+ const { problem, declared, service } = entry.problem === undefined
61
+ ? register(entry.plugin, options, serviceFor)
62
+ : { problem: entry.problem, declared: NOTHING_DECLARED, service: undefined };
63
+ own.set(entry.plugin.name, problem);
64
+ contributions.set(entry.plugin.name, declared);
65
+ if (service !== undefined)
66
+ services.set(entry.plugin.name, service.value);
67
+ }
68
+ registered = true;
69
+ const cyclic = cyclicNames(installed.map((entry) => entry.plugin));
70
+ const sharedPrefixes = prefixCollisions(installed.map((entry) => entry.plugin.name));
71
+ const problems = new Map();
72
+ function problem(name) {
73
+ if (problems.has(name))
74
+ return problems.get(name);
75
+ const found = resolveProblem(name);
76
+ problems.set(name, found);
77
+ return found;
78
+ }
79
+ function resolveProblem(name) {
80
+ const entry = bySource.get(name);
81
+ if (entry === undefined)
82
+ return 'It is not installed.';
83
+ const shared = sharedPrefixes.get(name);
84
+ if (shared !== undefined) {
85
+ return `Its environment variables would start ${pluginEnvPrefix(name)}__, as those of ${shared.join(' and ')} would, so none of them loads. Rename one package.`;
86
+ }
87
+ const intrinsic = own.get(name);
88
+ if (intrinsic !== undefined)
89
+ return intrinsic;
90
+ const cycle = cyclic.get(name);
91
+ if (cycle !== undefined)
92
+ return `It is in a dependency cycle: ${cycle.join(' → ')}.`;
93
+ for (const [dependency, range] of Object.entries(entry.peerDependencies ?? {})) {
94
+ const version = dependency === CORE_PACKAGE ? CORE_VERSION : bySource.get(dependency)?.plugin.version;
95
+ if (version === undefined || semver.satisfies(version, range))
96
+ continue;
97
+ return dependency === CORE_PACKAGE
98
+ ? `It needs ${CORE_PACKAGE} ${range}, and this core is ${version}.`
99
+ : `It needs ${dependency} ${range}, and ${version} is installed.`;
100
+ }
101
+ for (const [dependency, range] of requirementsOf(entry.plugin)) {
102
+ if (!bySource.has(dependency)) {
103
+ return `It requires ${dependency} ${range}, which is not installed.`;
104
+ }
105
+ if (problem(dependency) !== undefined) {
106
+ return `It requires ${dependency} ${range}, which is unavailable.`;
107
+ }
108
+ }
109
+ return undefined;
110
+ }
111
+ const plugins = installed.map((entry) => {
112
+ const declared = contributions.get(entry.plugin.name) ?? NOTHING_DECLARED;
113
+ return {
114
+ ...entry,
115
+ ...declared,
116
+ problem: problem(entry.plugin.name),
117
+ settingsPlace: { ...options, name: entry.plugin.name, fields: declared.settings },
118
+ };
119
+ });
120
+ const order = dependencyOrder(plugins.filter((entry) => entry.problem === undefined));
121
+ function active(enabled) {
122
+ const running = new Set();
123
+ for (const entry of order) {
124
+ const { name } = entry.plugin;
125
+ if (!enabled.has(name))
126
+ continue;
127
+ if (requirementsOf(entry.plugin).every(([dependency]) => running.has(dependency))) {
128
+ running.add(name);
129
+ }
130
+ }
131
+ return running;
132
+ }
133
+ const startAttempted = [];
134
+ let closed = false;
135
+ let queue = Promise.resolve();
136
+ function serialized(step) {
137
+ queue = queue.then(step);
138
+ return queue;
139
+ }
140
+ async function stopFrom(shouldStop) {
141
+ for (const entry of [...startAttempted].reverse()) {
142
+ if (!shouldStop(entry.name))
143
+ continue;
144
+ startAttempted.splice(startAttempted.indexOf(entry), 1);
145
+ await lifecycle(entry, 'stop');
146
+ }
147
+ }
148
+ async function attemptStart(plugin) {
149
+ startAttempted.push(plugin);
150
+ await lifecycle(plugin, 'start');
151
+ }
152
+ return {
153
+ plugins,
154
+ find: (name) => plugins.find((entry) => entry.plugin.name === name),
155
+ problem,
156
+ active,
157
+ requirements(name, enabled) {
158
+ const entry = bySource.get(name);
159
+ if (entry === undefined)
160
+ return [];
161
+ const running = active(enabled);
162
+ return requirementsOf(entry.plugin).map(([dependency, range]) => ({
163
+ name: dependency,
164
+ range,
165
+ state: requirementState(dependency, enabled, running),
166
+ }));
167
+ },
168
+ enabledDependents(name, enabled) {
169
+ return plugins
170
+ .filter((entry) => enabled.has(entry.plugin.name))
171
+ .filter((entry) => requirementsOf(entry.plugin).some(([dependency]) => dependency === name))
172
+ .map((entry) => entry.plugin.name);
173
+ },
174
+ reconcile(enabled) {
175
+ return serialized(async () => {
176
+ if (closed)
177
+ return;
178
+ const running = active(enabled);
179
+ await stopFrom((name) => !running.has(name));
180
+ for (const { plugin } of order) {
181
+ if (running.has(plugin.name) && !startAttempted.includes(plugin)) {
182
+ await attemptStart(plugin);
183
+ }
184
+ }
185
+ });
186
+ },
187
+ close() {
188
+ return serialized(async () => {
189
+ closed = true;
190
+ await stopFrom(() => true);
191
+ });
192
+ },
193
+ };
194
+ function requirementState(dependency, enabled, running) {
195
+ if (!bySource.has(dependency))
196
+ return 'missing';
197
+ if (problem(dependency) !== undefined)
198
+ return 'unavailable';
199
+ if (running.has(dependency))
200
+ return 'enabled';
201
+ return enabled.has(dependency) ? 'blocked' : 'disabled';
202
+ }
203
+ }
204
+ const NOTHING_DECLARED = {
205
+ routes: [],
206
+ federation: [],
207
+ screen: undefined,
208
+ commands: [],
209
+ settings: [],
210
+ editorActions: [],
211
+ };
212
+ /**
213
+ * Run a plugin's `register`, returning why it cannot run, if it cannot, what
214
+ * it declared and the service it provided. A plugin whose register fails
215
+ * declares and provides nothing.
216
+ */
217
+ function register(plugin, options, serviceFor) {
218
+ const { name } = plugin;
219
+ if (name.length > PACKAGE_NAME_MAX || !PACKAGE_NAME.test(name)) {
220
+ return {
221
+ problem: `${JSON.stringify(name)} is not an npm package name, which a plugin is named by.`,
222
+ declared: NOTHING_DECLARED,
223
+ };
224
+ }
225
+ if (!Number.isInteger(plugin.hostApi) || plugin.hostApi > HOST_API_VERSION) {
226
+ return {
227
+ problem: `It targets host API version ${String(plugin.hostApi)}, and this core provides version ${String(HOST_API_VERSION)}.`,
228
+ declared: NOTHING_DECLARED,
229
+ };
230
+ }
231
+ const routes = [];
232
+ const federation = [];
233
+ const commands = [];
234
+ const editorActions = [];
235
+ let screen;
236
+ let settings;
237
+ let service;
238
+ let registering = true;
239
+ function declaring(what) {
240
+ if (!registering)
241
+ throw new Error(`${name} declared ${what} after its register returned.`);
242
+ }
243
+ const host = {
244
+ apiVersion: HOST_API_VERSION,
245
+ name,
246
+ data: pluginDataFolder(options.dataDir, name),
247
+ get(path, handler) {
248
+ declaring('a route');
249
+ routes.push({ path, handler });
250
+ },
251
+ federation(middleware) {
252
+ declaring('a federation middleware');
253
+ federation.push(middleware);
254
+ },
255
+ screen(declared) {
256
+ declaring('a screen');
257
+ if (screen !== undefined)
258
+ throw new Error('A plugin has at most one screen.');
259
+ screen = declared;
260
+ },
261
+ command(declared) {
262
+ declaring('a command');
263
+ commands.push(declared);
264
+ },
265
+ editorAction(declared) {
266
+ declaring('an editor action');
267
+ if (!EDITOR_ACTION_ID.test(declared.id)) {
268
+ throw new Error(`${JSON.stringify(declared.id)} is not an editor action id: use lower case words joined by -.`);
269
+ }
270
+ if (editorActions.some((entry) => entry.id === declared.id)) {
271
+ throw new Error(`${name} declares two editor actions with the id ${JSON.stringify(declared.id)}.`);
272
+ }
273
+ editorActions.push(declared);
274
+ },
275
+ siteInfo: () => options.siteInfo(),
276
+ fetch: (url, init = {}) => pluginFetch(url, init, options),
277
+ provide(value) {
278
+ declaring('a service');
279
+ if (service !== undefined) {
280
+ throw new Error(`${name} provides a second service. A plugin provides at most one, named by its package name.`);
281
+ }
282
+ service = { value };
283
+ },
284
+ use: (dependency) => serviceFor(plugin, dependency),
285
+ settings(fields) {
286
+ declaring('its settings');
287
+ if (settings !== undefined)
288
+ throw new Error('A plugin declares its settings once.');
289
+ const problem = settingFieldsProblem(fields);
290
+ if (problem !== undefined)
291
+ throw new Error(problem);
292
+ settings = fields;
293
+ const place = { ...options, name, fields };
294
+ return {
295
+ // Each value is built from its field's type, which is what the mapped
296
+ // type says, but TypeScript cannot follow a map over the fields.
297
+ current: () => settingValues(resolvePluginSettings(place)),
298
+ };
299
+ },
300
+ };
301
+ try {
302
+ plugin.register(host);
303
+ return {
304
+ problem: undefined,
305
+ declared: { routes, federation, screen, commands, settings: settings ?? [], editorActions },
306
+ service,
307
+ };
308
+ }
309
+ catch (error) {
310
+ return {
311
+ problem: `Its register failed: ${error instanceof Error ? error.message : String(error)}`,
312
+ declared: NOTHING_DECLARED,
313
+ };
314
+ }
315
+ finally {
316
+ registering = false;
317
+ }
318
+ }
319
+ /** An editor action's id, which is the last segment of its endpoint's path. */
320
+ const EDITOR_ACTION_ID = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
321
+ /** A file name a plugin may use in its folder: one segment, not hidden. */
322
+ const DATA_FILE_NAME = /^[A-Za-z0-9_-][A-Za-z0-9._-]*$/;
323
+ /** `data/plugins/<package name>/`, which only its plugin reads and writes. */
324
+ export function pluginDataFolder(dataDir, name) {
325
+ const folder = pluginFolderPath(dataDir, name);
326
+ function fileIn(file) {
327
+ if (!DATA_FILE_NAME.test(file)) {
328
+ throw new Error(`${JSON.stringify(file)} is not a file name a plugin can use in its folder.`);
329
+ }
330
+ return path.join(folder, file);
331
+ }
332
+ return {
333
+ path: folder,
334
+ read: (file) => readFileIfPresentSync(fileIn(file)),
335
+ update: (file, change) => updateFileAtomically(fileIn(file), change),
336
+ };
337
+ }
338
+ async function lifecycle(plugin, hook) {
339
+ try {
340
+ await plugin[hook]?.();
341
+ }
342
+ catch (error) {
343
+ const message = error instanceof Error ? error.message : String(error);
344
+ console.warn(`The ${plugin.name} plugin's ${hook} failed: ${message}`);
345
+ }
346
+ }
347
+ /**
348
+ * Each installed name whose environment variable prefix another installed
349
+ * name shares, with those others: `@a/b-c` and `@a-b/c` both make `A_B_C`.
350
+ */
351
+ function prefixCollisions(names) {
352
+ const byPrefix = new Map();
353
+ for (const name of names) {
354
+ const prefix = pluginEnvPrefix(name);
355
+ byPrefix.set(prefix, [...(byPrefix.get(prefix) ?? []), name]);
356
+ }
357
+ const collisions = new Map();
358
+ for (const group of byPrefix.values()) {
359
+ if (group.length < 2)
360
+ continue;
361
+ for (const name of group) {
362
+ collisions.set(name, group.filter((other) => other !== name));
363
+ }
364
+ }
365
+ return collisions;
366
+ }
367
+ function requirementsOf(plugin) {
368
+ return Object.entries(plugin.requires ?? {});
369
+ }
370
+ /**
371
+ * Each plugin that sits in a dependency cycle, with the cycle it is in, found
372
+ * as the strongly connected components (Tarjan) of the installed graph.
373
+ */
374
+ function cyclicNames(plugins) {
375
+ const installed = new Map(plugins.map((plugin) => [plugin.name, plugin]));
376
+ const index = new Map();
377
+ const low = new Map();
378
+ const stack = [];
379
+ const onStack = new Set();
380
+ const cyclic = new Map();
381
+ let next = 0;
382
+ function visit(name) {
383
+ index.set(name, next);
384
+ low.set(name, next);
385
+ next += 1;
386
+ stack.push(name);
387
+ onStack.add(name);
388
+ const plugin = installed.get(name);
389
+ for (const [dependency] of plugin === undefined ? [] : requirementsOf(plugin)) {
390
+ if (!installed.has(dependency))
391
+ continue;
392
+ if (!index.has(dependency)) {
393
+ visit(dependency);
394
+ low.set(name, Math.min(low.get(name) ?? 0, low.get(dependency) ?? 0));
395
+ }
396
+ else if (onStack.has(dependency)) {
397
+ low.set(name, Math.min(low.get(name) ?? 0, index.get(dependency) ?? 0));
398
+ }
399
+ }
400
+ if (low.get(name) !== index.get(name))
401
+ return;
402
+ const component = [];
403
+ let member;
404
+ do {
405
+ member = stack.pop();
406
+ if (member === undefined)
407
+ break;
408
+ onStack.delete(member);
409
+ component.push(member);
410
+ } while (member !== name);
411
+ const selfLoop = Object.hasOwn(plugin?.requires ?? {}, name);
412
+ if (component.length > 1 || selfLoop) {
413
+ const cycle = [...component.reverse(), component[0] ?? name];
414
+ for (const entry of component)
415
+ cyclic.set(entry, cycle);
416
+ }
417
+ }
418
+ for (const plugin of plugins)
419
+ if (!index.has(plugin.name))
420
+ visit(plugin.name);
421
+ return cyclic;
422
+ }
423
+ /**
424
+ * Available plugins with every plugin before the ones that require it. Every
425
+ * requirement of an available plugin is available, so this is a plain
426
+ * depth-first post-order.
427
+ */
428
+ function dependencyOrder(available) {
429
+ const byName = new Map(available.map((entry) => [entry.plugin.name, entry]));
430
+ const ordered = [];
431
+ const seen = new Set();
432
+ function visit(entry) {
433
+ if (seen.has(entry.plugin.name))
434
+ return;
435
+ seen.add(entry.plugin.name);
436
+ for (const [dependency] of requirementsOf(entry.plugin)) {
437
+ const required = byName.get(dependency);
438
+ if (required !== undefined)
439
+ visit(required);
440
+ }
441
+ ordered.push(entry);
442
+ }
443
+ for (const entry of available)
444
+ visit(entry);
445
+ return ordered;
446
+ }
447
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/plugins/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * A plugin's settings (decision-33): the fields it declares, where each value
3
+ * lives, and what a save writes.
4
+ *
5
+ * Public values sit under the plugin's key in `content/_data/site.json`,
6
+ * beside `enabled`. Secrets sit in `secrets.json` in the plugin's data folder,
7
+ * mode 0600, and an environment variable named by the package wins over the
8
+ * file, so a Docker operator can keep a key in `.env`. Every value is read
9
+ * from the files and the environment when it is asked for, so a save or a
10
+ * hand edit takes effect on the next request.
11
+ */
12
+ import type { PluginSettingField } from '../plugin.ts';
13
+ export declare const SECRETS_FILE = "secrets.json";
14
+ /** Where a value came from: nowhere, `site.json`, `secrets.json` or the environment. */
15
+ export type SettingSource = 'default' | 'site' | 'file' | 'environment';
16
+ /** One field and the value it has now. */
17
+ export interface ResolvedSetting {
18
+ readonly field: PluginSettingField;
19
+ readonly value: string | boolean | undefined;
20
+ readonly source: SettingSource;
21
+ /** Why the stored value was set aside for the default, or `undefined`. */
22
+ readonly problem: string | undefined;
23
+ /** A secret's environment variable, `undefined` for a public field. */
24
+ readonly variable: string | undefined;
25
+ }
26
+ /** Where one plugin's settings are read from. */
27
+ export interface PluginSettingsPlace {
28
+ readonly contentDir: string;
29
+ readonly dataDir: string;
30
+ readonly env: Readonly<Record<string, string | undefined>>;
31
+ readonly name: string;
32
+ readonly fields: readonly PluginSettingField[];
33
+ }
34
+ /** A settings form as submitted: each box by key, and the secrets to forget. */
35
+ export interface PluginSettingsSubmission {
36
+ readonly values: Readonly<Record<string, string | undefined>>;
37
+ readonly forget: ReadonlySet<string>;
38
+ }
39
+ /** `data/plugins/<package name>/`. */
40
+ export declare function pluginFolderPath(dataDir: string, name: string): string;
41
+ /**
42
+ * What every environment variable of a package starts with, before `__`:
43
+ * `GEEKITY_PLUGIN_LLM` for `@geekity/plugin-llm`. It never contains `__`, so
44
+ * no plugin variable can shadow a core one.
45
+ */
46
+ export declare function pluginEnvPrefix(name: string): string;
47
+ /** The environment variable that sets one setting, such as `GEEKITY_PLUGIN_LLM__API_KEY`. */
48
+ export declare function pluginVariable(name: string, key: string): string;
49
+ /** Why these fields cannot be stored, or `undefined` when they can. */
50
+ export declare function settingFieldsProblem(fields: readonly PluginSettingField[]): string | undefined;
51
+ /** Every field with its value now, in the order declared. */
52
+ export declare function resolvePluginSettings(place: PluginSettingsPlace): ResolvedSetting[];
53
+ /** The values a plugin is handed, keyed by field key. */
54
+ export declare function settingValues(resolved: readonly ResolvedSetting[]): Record<string, string | boolean | undefined>;
55
+ /**
56
+ * Save a submitted form. A field with a value it does not accept refuses the
57
+ * whole save, named in `problems`, and nothing is written. An empty public
58
+ * box removes the key, so the default applies; an empty secret box keeps the
59
+ * stored secret; a secret the environment sets is never written.
60
+ */
61
+ export declare function savePluginSettings(options: PluginSettingsPlace & PluginSettingsSubmission): Promise<{
62
+ problems: Record<string, string>;
63
+ }>;
64
+ //# sourceMappingURL=settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/plugins/settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGvD,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C,wFAAwF;AACxF,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC;AAExE,0CAA0C;AAC1C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,iDAAiD;AACjD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,CAAC;CAChD;AAED,gFAAgF;AAChF,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAC9D,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACtC;AAED,sCAAsC;AACtC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtE;AASD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,6FAA6F;AAC7F,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhE;AAID,uEAAuE;AACvE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,GAAG,MAAM,GAAG,SAAS,CAqB9F;AAED,6DAA6D;AAC7D,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,mBAAmB,GAAG,eAAe,EAAE,CA6BnF;AAED,yDAAyD;AACzD,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,SAAS,eAAe,EAAE,GACnC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAE9C;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,mBAAmB,GAAG,wBAAwB,GACtD,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,CA2D/C"}