vite-plugin-decap-cms 0.3.1 → 0.4.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.js CHANGED
@@ -30,11 +30,12 @@ var __objRest = (source, exclude) => {
30
30
  return target;
31
31
  };
32
32
 
33
- // src/index.ts
34
- import { exec } from "child_process";
33
+ // src/update.ts
34
+ import { mkdir, writeFile } from "fs/promises";
35
+ import { resolve, isAbsolute, sep } from "path";
35
36
  import { stringify } from "yaml";
36
37
 
37
- // src/util.ts
38
+ // src/utils/git.ts
38
39
  import { execSync } from "child_process";
39
40
  function getGitData() {
40
41
  const executeGit = (command) => {
@@ -52,6 +53,299 @@ function getGitData() {
52
53
  }
53
54
  };
54
55
  }
56
+
57
+ // src/utils/object.ts
58
+ var objToSnakeCase = (obj) => {
59
+ const ignoredKeys = ["i18n"];
60
+ const camelToSnakeCase = (str) => str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
61
+ return Object.fromEntries(
62
+ Object.entries(obj).map(([k, v]) => [ignoredKeys.includes(k) ? k : camelToSnakeCase(k), v])
63
+ );
64
+ };
65
+ var keyof = (obj) => Object.keys(obj);
66
+ function filterUndefined(item) {
67
+ return item != void 0;
68
+ }
69
+ function omit(obj, keys) {
70
+ if (!obj) return {};
71
+ const validEntries = Object.entries(obj).filter(([key]) => !keys.includes(key));
72
+ return Object.fromEntries(validEntries);
73
+ }
74
+ function pick(obj, keys) {
75
+ if (!obj) return {};
76
+ const validEntries = Object.entries(obj).filter(([key]) => keys.includes(key));
77
+ return Object.fromEntries(validEntries);
78
+ }
79
+
80
+ // src/files/config.ts
81
+ function getBooleanFromEnv(value, command) {
82
+ return value === "dev" ? command === "serve" : value === "prod" ? command === "build" : value != null ? value : false;
83
+ }
84
+ function resolveBackend(options, command) {
85
+ const _a = options, { local, name } = _a, backend = __objRest(_a, ["local", "name"]);
86
+ const git = getGitData();
87
+ const branch = "useCurrentBranch" in options && getBooleanFromEnv(options.useCurrentBranch, command) ? git.getBranch() : "branch" in backend ? backend.branch : void 0;
88
+ delete backend.useCurrentBranch;
89
+ const resolved = {
90
+ local_backend: typeof local === "object" ? objToSnakeCase(local) : getBooleanFromEnv(local, command),
91
+ backend: __spreadProps(__spreadValues({}, objToSnakeCase(backend)), {
92
+ branch,
93
+ name
94
+ })
95
+ };
96
+ return resolved;
97
+ }
98
+ function createConfigFile(config, command, log) {
99
+ const _a = config, { backend, collections } = _a, options = __objRest(_a, ["backend", "collections"]);
100
+ return __spreadProps(__spreadValues(__spreadValues({}, resolveBackend(backend, command)), objToSnakeCase(options)), {
101
+ collections: collections.map((col) => {
102
+ if ("fields" in col) {
103
+ const _a2 = col, { fields } = _a2, data = __objRest(_a2, ["fields"]);
104
+ return __spreadProps(__spreadValues({}, objToSnakeCase(data)), {
105
+ fields: fields.map(objToSnakeCase)
106
+ });
107
+ } else if ("files" in col) {
108
+ const _b = col, { files } = _b, data = __objRest(_b, ["files"]);
109
+ return __spreadProps(__spreadValues({}, objToSnakeCase(data)), {
110
+ files: files.map((file) => {
111
+ const _a3 = file, { fields } = _a3, _data = __objRest(_a3, ["fields"]);
112
+ return __spreadProps(__spreadValues({}, objToSnakeCase(_data)), {
113
+ fields: fields.map(objToSnakeCase)
114
+ });
115
+ })
116
+ });
117
+ } else log("config", "stderr", "Missing either fields or files property in collection");
118
+ })
119
+ });
120
+ }
121
+
122
+ // src/script.ts
123
+ function createCmsFunction(method, items, createParams, options) {
124
+ var _a;
125
+ const create = (params) => {
126
+ var _a2;
127
+ return `${(_a2 = options == null ? void 0 : options.base) != null ? _a2 : "CMS"}.${method}(${params})`;
128
+ };
129
+ return (items != null ? items : []).map((item) => {
130
+ const params = createParams(item);
131
+ if (!params) return null;
132
+ else return create(params);
133
+ }).filter(Boolean).join((_a = options == null ? void 0 : options.joinChar) != null ? _a : "\n");
134
+ }
135
+ function createScript(options) {
136
+ const _a = options, {
137
+ useManualInitialization,
138
+ markdownEditorComponents,
139
+ formatters,
140
+ previewStylesheets,
141
+ onGenerated: onGenerated,
142
+ onInitialized
143
+ } = _a, eventHooks = __objRest(_a, [
144
+ "useManualInitialization",
145
+ "markdownEditorComponents",
146
+ "formatters",
147
+ "previewStylesheets",
148
+ // previewTemplates,
149
+ // widgets,
150
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
151
+ "onGenerated",
152
+ "onInitialized"
153
+ ]);
154
+ const events = createCmsFunction("registerEventListener", Object.keys(eventHooks), (hookName) => {
155
+ const hook = eventHooks[hookName];
156
+ if (!hook) return null;
157
+ else {
158
+ const name = hookName.slice(2)[0].toLowerCase() + hookName.slice(3);
159
+ return `{ name: '${name}', handler: data => { function ${hook.toString()}; ${hookName}({ app: CMS, ...data }) } }`;
160
+ }
161
+ });
162
+ const customFormatters = createCmsFunction("registerCustomFormat", formatters, ({ name, extension, formatter }) => {
163
+ return `'${name}', '${extension}', ${formatter.toString()}`;
164
+ });
165
+ const customStyles = createCmsFunction("registerPreviewStyle", previewStylesheets, (style) => {
166
+ return typeof style === "string" ? style : `${style.style}, { raw: ${style.options.raw} }`;
167
+ });
168
+ const editorComponents = createCmsFunction("registerEditorComponent", markdownEditorComponents, (item) => {
169
+ const _a2 = item, { pattern, toPreview, toBlock, fromBlock } = _a2, component = __objRest(_a2, ["pattern", "toPreview", "toBlock", "fromBlock"]);
170
+ return `{ pattern: ${pattern}, toPreview: ${toPreview.toString()}, toBlock: ${toBlock.toString()}, fromBlock: ${fromBlock.toString()}, ...${JSON.stringify(component)}}`;
171
+ });
172
+ return `
173
+ <script>
174
+ ${useManualInitialization ? "window.CMS_MANUAL_INIT = true;" : ""}
175
+ ${onInitialized != void 0 ? `window.onload = () => { function ${onInitialized.toString()}; onInitialized({ app: CMS }) }` : ""}
176
+ ${customFormatters}
177
+ ${customStyles}
178
+ ${events}
179
+ ${editorComponents}
180
+ </script>`;
181
+ }
182
+
183
+ // src/files/index.ts
184
+ var defaultDecapCmsCdnVersion = "3.1.11";
185
+ var defaultNetlifyIdentityVersion = "1";
186
+ var addSlash = (path, slash = "/") => path.endsWith(slash) ? path : path + slash;
187
+ function resolveCdnRoute(options) {
188
+ const getUrl = (host = "https://unpkg.com/", version = defaultDecapCmsCdnVersion) => {
189
+ return `${addSlash(host)}decap-cms@^${version}/dist/decap-cms.js`;
190
+ };
191
+ return typeof options === "boolean" ? options ? getUrl() : void 0 : typeof options === "string" ? options : options != void 0 ? getUrl(options.base, options.version) : void 0;
192
+ }
193
+ function resolveHead(head) {
194
+ return head.reduce((output, config) => {
195
+ if (typeof config === "string") return output.concat(config);
196
+ if ("skip" in config) {
197
+ if (config.skip) return output;
198
+ if (typeof config.head === "string") return output.concat(config.head);
199
+ }
200
+ const item = "head" in config ? config.head : config;
201
+ let str = `<${item[0]}`;
202
+ for (const key in item[1]) {
203
+ str += ` ${key}="${item[1][key]}"`;
204
+ }
205
+ str += item[0] === "meta" ? "/>" : ">";
206
+ if (item[2] == void 0) return output.concat(str);
207
+ str += item[2] + `</${item[0]}>`;
208
+ return output.concat(str);
209
+ }, []);
210
+ }
211
+ function getIndexFeatures(config, loadOptions) {
212
+ var _a;
213
+ const configRoute = config.dir ? addSlash(config.dir) + "config.yml" : void 0;
214
+ return {
215
+ cdn_route: resolveCdnRoute(loadOptions == void 0 || loadOptions.method === "cdn" ? (_a = loadOptions == null ? void 0 : loadOptions.options) != null ? _a : true : void 0),
216
+ custom_logo: "logoUrl" in config ? config.logoUrl != void 0 : "logo_url" in config ? config.logo_url != void 0 : false,
217
+ head: (options) => {
218
+ var _a2, _b, _c;
219
+ return resolveHead([
220
+ ["meta", { charset: "utf-8" }],
221
+ ["meta", { name: "viewport", content: "width=device-width, initial-scale=1.0" }],
222
+ ["meta", { name: "robots", content: "noindex" }],
223
+ ...(_a2 = options == null ? void 0 : options.head) != null ? _a2 : [],
224
+ ["title", {}, (_b = options == null ? void 0 : options.title) != null ? _b : "Content Manager"],
225
+ {
226
+ head: ["link", { rel: "favicon", ref: (_c = options == null ? void 0 : options.icon) != null ? _c : "" }],
227
+ skip: (options == null ? void 0 : options.icon) == void 0
228
+ },
229
+ {
230
+ head: ["script", { src: `https://identity.netlify.com/v${defaultNetlifyIdentityVersion}/netlify-identity-widget.js` }],
231
+ skip: config.backend.name !== "git-gateway"
232
+ },
233
+ {
234
+ head: ["link", { type: "text/yaml", rel: "cms-config-url", href: configRoute }],
235
+ skip: configRoute == void 0
236
+ }
237
+ ]);
238
+ }
239
+ };
240
+ }
241
+ function createIndexFile(pluginOptions) {
242
+ var _a, _b;
243
+ const { config, load, login: options, script } = pluginOptions;
244
+ if (options == null ? void 0 : options.html) return options.html;
245
+ const features = getIndexFeatures(config, load);
246
+ return `<!DOCTYPE html>
247
+ <html>
248
+ <head>
249
+ ${features.head(options).join("\n" + " ".repeat(8))}
250
+ </head>
251
+ <body>
252
+ ${features.cdn_route ? `<script src="${features.cdn_route}"></script>` : ""}
253
+ ${script ? createScript(script) : ""}
254
+ ${((_a = pluginOptions.login) == null ? void 0 : _a.additionalHtml) ? `${(_b = pluginOptions.login) == null ? void 0 : _b.additionalHtml}
255
+
256
+ <div id="nc-root"></div>` : ""}
257
+ </body>
258
+ </html>${features.custom_logo ? `
259
+
260
+ <style>
261
+ span[class*='CustomIconWrapper'] {
262
+ width: auto;
263
+ }
264
+ </style>` : ""}`;
265
+ }
266
+
267
+ // src/proxy.ts
268
+ import { exec } from "child_process";
269
+ function runProxy(options, log) {
270
+ var _a, _b, _c, _d, _e;
271
+ const port = ((_a = options == null ? void 0 : options.port) != null ? _a : 8081).toString();
272
+ log("proxy", "debug", `Starting decap-server on port ${port}`);
273
+ const proxy = exec("npx decap-server", __spreadProps(__spreadValues({}, (_b = options == null ? void 0 : options.process) != null ? _b : {}), {
274
+ env: __spreadValues({
275
+ PORT: port,
276
+ MODE: options == null ? void 0 : options.mode,
277
+ LOG_LEVEL: options == null ? void 0 : options.logLevel,
278
+ GIT_REPO_DIRECTORY: options == null ? void 0 : options.gitRepoDirectory
279
+ }, (_d = (_c = options == null ? void 0 : options.process) == null ? void 0 : _c.env) != null ? _d : {})
280
+ }));
281
+ if (log("proxy", "stdout")) (_e = proxy.stdout) == null ? void 0 : _e.pipe(process.stdout);
282
+ proxy.on("error", (err) => {
283
+ if ("code" in err && err.code === "EADDRINUSE") {
284
+ log("proxy", "stderr", `Port ${port} for decap-server is already used by another process`);
285
+ } else throw err;
286
+ });
287
+ process.on("beforeExit", () => proxy.kill());
288
+ }
289
+
290
+ // src/update.ts
291
+ function resolveDir(publicDir, dir) {
292
+ return dir ? isAbsolute(dir) ? dir : resolve(dir) : publicDir;
293
+ }
294
+ async function writeToFolder(folder, options) {
295
+ const dir = folder + (options.subfolder ? sep + options.subfolder : "");
296
+ await mkdir(dir, { recursive: true });
297
+ for (const file of options.files.filter((f) => !f.skip)) {
298
+ await writeFile(dir + sep + file.name, file.content, {
299
+ encoding: "utf-8"
300
+ });
301
+ }
302
+ }
303
+ function validateLoadOptions(options, log) {
304
+ var _a;
305
+ const valid = ["npm", "cdn"].includes((_a = options == null ? void 0 : options.method) != null ? _a : "cdn");
306
+ if (!valid) log("config", "stderr", "Invalid load options for decap-cms provided");
307
+ }
308
+ async function updateConfig(options, config, log) {
309
+ var _a, _b, _c, _d, _e, _f, _g, _h;
310
+ validateLoadOptions(options.load, log);
311
+ const configFile = createConfigFile(options.config, config.command, log);
312
+ await writeToFolder(
313
+ resolveDir(config.publicDir, options.dir),
314
+ {
315
+ subfolder: "admin",
316
+ files: [
317
+ { name: "index.html", content: createIndexFile(options) },
318
+ { name: "config.yml", content: stringify(configFile, (_a = options.yml) == null ? void 0 : _a.replacer, (_b = options.yml) == null ? void 0 : _b.options) }
319
+ // { name: 'npm.js', content: createCustomScript(), skip: options.load?.method !== 'npm' },
320
+ ]
321
+ }
322
+ );
323
+ if (config.command === "serve" && configFile.local_backend !== false && ((_d = (_c = options.proxy) == null ? void 0 : _c.enabled) != null ? _d : true)) {
324
+ runProxy(options.proxy, log);
325
+ }
326
+ await ((_f = (_e = options.script) == null ? void 0 : _e.onConfigUpdated) == null ? void 0 : _f.call(_e));
327
+ if (config.command === "build") {
328
+ await ((_h = (_g = options.script) == null ? void 0 : _g.onGenerated) == null ? void 0 : _h.call(_g));
329
+ }
330
+ }
331
+
332
+ // src/utils/log.ts
333
+ function createLogger(options) {
334
+ return function(type, pipe, ...data) {
335
+ if (options == void 0 || options === false) {
336
+ if (!data.length) return false;
337
+ else return;
338
+ }
339
+ if (!data.length) return true;
340
+ const fn = pipe === "stderr" ? "error" : pipe === "debug" ? "debug" : "log";
341
+ const pipeDefined = ["debug", "stdout", "stderr"].includes(pipe);
342
+ for (const msg of pipeDefined ? data : [pipe, ...data]) {
343
+ console[fn](`[Vite Decap] - [${type.toUpperCase()}] ` + msg);
344
+ }
345
+ };
346
+ }
347
+
348
+ // src/utils/collection.ts
55
349
  function createField(widget, data) {
56
350
  return __spreadProps(__spreadValues({}, data), {
57
351
  widget
@@ -66,6 +360,52 @@ function createFile(data) {
66
360
  function createFileCollection(data) {
67
361
  return data;
68
362
  }
363
+ function fieldToSnakeCase(field) {
364
+ return objToSnakeCase(field);
365
+ }
366
+ function createSharedCollectionOptions(shared, options) {
367
+ return function(collection) {
368
+ const isSharedOptions = (value) => {
369
+ return value != void 0 && typeof value === "object" && "value" in value && !("field" in value);
370
+ };
371
+ const combinedWithShared = keyof(collection).reduce((output, key) => {
372
+ var _a, _b;
373
+ const collectionValue = collection[key];
374
+ const sharedValue = shared[key];
375
+ if (sharedValue != void 0) {
376
+ if (isSharedOptions(sharedValue)) {
377
+ const sharedOptions = sharedValue;
378
+ const action = (_b = (_a = sharedOptions.action) != null ? _a : options == null ? void 0 : options.action) != null ? _b : "overwrite";
379
+ if (action === "overwrite") {
380
+ output[key] = collectionValue;
381
+ return output;
382
+ } else if (action === "append") {
383
+ if (typeof collectionValue === "string") {
384
+ output[key] = sharedOptions.value + collectionValue;
385
+ } else if (Array.isArray(collectionValue)) {
386
+ output[key] = sharedOptions.value.concat(collectionValue);
387
+ }
388
+ return output;
389
+ }
390
+ }
391
+ }
392
+ output[key] = collectionValue;
393
+ return output;
394
+ }, {});
395
+ const sharedRaw = keyof(shared).reduce((output, key) => {
396
+ const value = shared[key];
397
+ if (isSharedOptions(value)) {
398
+ output[key] = value.value;
399
+ } else {
400
+ output[key] = value;
401
+ }
402
+ return output;
403
+ }, {});
404
+ return __spreadValues(__spreadValues({}, sharedRaw), combinedWithShared);
405
+ };
406
+ }
407
+
408
+ // src/utils/overwrites.ts
69
409
  function createOverwriteableField(widget, data, overwrites) {
70
410
  if (overwrites != void 0) {
71
411
  const toAdd = (key) => {
@@ -83,13 +423,31 @@ function createOverwriteableField(widget, data, overwrites) {
83
423
  widget
84
424
  });
85
425
  }
86
- function filterUndefined(item) {
87
- return item != void 0;
88
- }
89
- function omit(obj, keys) {
90
- if (!obj) return void 0;
91
- const validEntries = Object.entries(obj).filter(([key]) => !keys.includes(key));
92
- return Object.fromEntries(validEntries);
426
+
427
+ // src/vitepress.ts
428
+ var overwriteKeys = [
429
+ "comment",
430
+ "deleted",
431
+ "hidden",
432
+ "hint",
433
+ "label",
434
+ "media_folder",
435
+ "i18n",
436
+ "pattern",
437
+ "public_folder",
438
+ "required"
439
+ ];
440
+ function mergeOverwrites(main, parent) {
441
+ var _a;
442
+ if (parent == void 0) return main != null ? main : {};
443
+ else if (main == void 0) return (_a = pick(parent != null ? parent : {}, overwriteKeys)) != null ? _a : {};
444
+ else {
445
+ return overwriteKeys.reduce((combined, key) => {
446
+ if ((main == null ? void 0 : main[key]) != void 0) combined[key] = main[key];
447
+ else if ((parent == null ? void 0 : parent[key]) != void 0) combined[key] = parent[key];
448
+ return combined;
449
+ }, {});
450
+ }
93
451
  }
94
452
  var VitePress = class {
95
453
  /**
@@ -115,50 +473,50 @@ var VitePress = class {
115
473
  name: "layout",
116
474
  label: "Layout",
117
475
  required: false
118
- }),
476
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.layout, overwrites)),
119
477
  createOverwriteableField("boolean", {
120
478
  name: "navbar",
121
479
  label: "Whether to display the navbar",
122
480
  required: false
123
- }, overwrites == null ? void 0 : overwrites.navbar),
481
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.navbar, overwrites)),
124
482
  createOverwriteableField("boolean", {
125
483
  name: "sidebar",
126
484
  label: "Whether to display the sidebar",
127
485
  required: false
128
- }, overwrites == null ? void 0 : overwrites.sidebar),
486
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.sidebar, overwrites)),
129
487
  // TODO: add aside 'left' option
130
488
  createOverwriteableField("boolean", {
131
489
  name: "aside",
132
490
  label: "Whether to display the aside container",
133
491
  required: false
134
- }, overwrites == null ? void 0 : overwrites.aside),
492
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.aside, overwrites)),
135
493
  // TODO: add support for [number, number] | 'deep' | false
136
494
  createOverwriteableField("number", {
137
495
  name: "outline",
138
496
  label: "The header levels in the outline",
139
497
  required: false
140
- }, overwrites == null ? void 0 : overwrites.outline),
498
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.outline, overwrites)),
141
499
  // TODO: add support for Date
142
500
  createOverwriteableField("boolean", {
143
501
  name: "lastUpdated",
144
502
  label: "Whether to display last updated text",
145
503
  required: false
146
- }, overwrites == null ? void 0 : overwrites.lastUpdated),
504
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.lastUpdated, overwrites)),
147
505
  createOverwriteableField("boolean", {
148
506
  name: "editLink",
149
507
  label: "Whether to display edit link text",
150
508
  required: false
151
- }, overwrites == null ? void 0 : overwrites.editLink),
509
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.editLink, overwrites)),
152
510
  createOverwriteableField("boolean", {
153
511
  name: "footer",
154
512
  label: "Whether to display footer text",
155
513
  required: false
156
- }, overwrites == null ? void 0 : overwrites.footer),
514
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.footer, overwrites)),
157
515
  createOverwriteableField("string", {
158
516
  name: "pageClass",
159
517
  label: "Page class",
160
518
  required: false
161
- }, overwrites == null ? void 0 : overwrites.pageClass)
519
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.pageClass, overwrites))
162
520
  ].filter(filterUndefined);
163
521
  }
164
522
  /**
@@ -167,36 +525,37 @@ var VitePress = class {
167
525
  * - titleTemplate
168
526
  * - description
169
527
  * - head
528
+ * - body (field for writing the markdown in the file)
170
529
  * @param options.overwrites Overwrite data, such as labels, for the fields
171
530
  * @see https://vitepress.dev/reference/frontmatter-config
172
531
  */
173
532
  static createDefaultPageFields(options) {
174
- var _a, _b;
533
+ var _a, _b, _c;
175
534
  const { additionalFields, overwrites } = options != null ? options : {};
176
535
  const fields = [
177
536
  createOverwriteableField("string", {
178
537
  name: "title",
179
538
  label: "Title"
180
- }, overwrites == null ? void 0 : overwrites.title),
539
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.title, overwrites)),
181
540
  createOverwriteableField("string", {
182
541
  name: "titleTemplate",
183
542
  label: "Title template",
184
543
  required: false
185
- }, overwrites == null ? void 0 : overwrites.titleTemplate),
544
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.titleTemplate, overwrites)),
186
545
  createOverwriteableField("text", {
187
546
  name: "description",
188
547
  label: "Description",
189
548
  required: false
190
- }, overwrites == null ? void 0 : overwrites.description),
549
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.description, overwrites)),
191
550
  createOverwriteableField("list", {
192
551
  name: "head",
193
552
  label: "Head"
194
- }, overwrites == null ? void 0 : overwrites.head)
553
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.head, overwrites))
195
554
  ].filter(filterUndefined);
196
- return fields.concat(additionalFields != null ? additionalFields : []).concat((_b = createOverwriteableField("markdown", __spreadProps(__spreadValues({}, (_a = options == null ? void 0 : options.markdownOptions) != null ? _a : {}), {
555
+ return fields.concat((_a = additionalFields == null ? void 0 : additionalFields.map(fieldToSnakeCase)) != null ? _a : []).concat((_c = createOverwriteableField("markdown", __spreadProps(__spreadValues({}, (_b = options == null ? void 0 : options.markdownOptions) != null ? _b : {}), {
197
556
  name: "body",
198
557
  label: "Page content"
199
- }), overwrites == null ? void 0 : overwrites.body)) != null ? _b : []).filter(filterUndefined);
558
+ }), mergeOverwrites(overwrites == null ? void 0 : overwrites.body, overwrites))) != null ? _c : []).filter(filterUndefined);
200
559
  }
201
560
  /**
202
561
  * Create fields for:
@@ -212,7 +571,7 @@ var VitePress = class {
212
571
  const keys = ["hidden", "deleted"];
213
572
  function addAdditionalFields(fields) {
214
573
  var _a2;
215
- return (_a2 = fields == null ? void 0 : fields.map((f) => objToSnakeCase(f))) != null ? _a2 : [];
574
+ return (_a2 = fields == null ? void 0 : fields.map(fieldToSnakeCase)) != null ? _a2 : [];
216
575
  }
217
576
  return [
218
577
  createField("hidden", {
@@ -227,19 +586,19 @@ var VitePress = class {
227
586
  createOverwriteableField("string", {
228
587
  name: "name",
229
588
  required: false
230
- }, overwrites == null ? void 0 : overwrites.heroName),
589
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.heroName, overwrites)),
231
590
  createOverwriteableField("string", {
232
591
  name: "text"
233
- }, overwrites == null ? void 0 : overwrites.heroText),
592
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.heroText, overwrites)),
234
593
  createOverwriteableField("string", {
235
594
  name: "tagline",
236
595
  required: false
237
- }, overwrites == null ? void 0 : overwrites.heroTagline),
596
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.heroTagline, overwrites)),
238
597
  // TODO: add support for object options
239
598
  createOverwriteableField("image", {
240
599
  name: "image",
241
600
  required: false
242
- }, overwrites == null ? void 0 : overwrites.heroImage),
601
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.heroImage, overwrites)),
243
602
  createOverwriteableField("list", {
244
603
  name: "actions",
245
604
  label: "Action buttons",
@@ -248,10 +607,10 @@ var VitePress = class {
248
607
  fields: [
249
608
  createOverwriteableField("string", {
250
609
  name: "text"
251
- }, overwrites == null ? void 0 : overwrites.heroActionText),
610
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.heroActionText, overwrites)),
252
611
  createOverwriteableField("string", {
253
612
  name: "link"
254
- }, overwrites == null ? void 0 : overwrites.heroActionLink),
613
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.heroActionLink, overwrites)),
255
614
  createOverwriteableField("select", {
256
615
  name: "theme",
257
616
  required: false,
@@ -260,21 +619,21 @@ var VitePress = class {
260
619
  "brand",
261
620
  "alt"
262
621
  ]
263
- }, overwrites == null ? void 0 : overwrites.heroActionTheme),
622
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.heroActionTheme, overwrites)),
264
623
  createOverwriteableField("string", {
265
624
  name: "target",
266
625
  required: false
267
- }, overwrites == null ? void 0 : overwrites.heroActionTarget),
626
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.heroActionTarget, overwrites)),
268
627
  createOverwriteableField("string", {
269
628
  name: "rel",
270
629
  required: false
271
- }, overwrites == null ? void 0 : overwrites.heroActionRel),
630
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.heroActionRel, overwrites)),
272
631
  ...addAdditionalFields(options == null ? void 0 : options.additionalHeroActionFields)
273
632
  ].filter(filterUndefined)
274
- }, omit(overwrites == null ? void 0 : overwrites.heroActions, keys)),
633
+ }, omit(mergeOverwrites(overwrites == null ? void 0 : overwrites.heroActions, overwrites), keys)),
275
634
  ...addAdditionalFields(options == null ? void 0 : options.additionalHeroFields)
276
635
  ].filter(filterUndefined)
277
- }, omit(overwrites == null ? void 0 : overwrites.hero, keys)),
636
+ }, omit(mergeOverwrites(overwrites == null ? void 0 : overwrites.hero, overwrites), keys)),
278
637
  createOverwriteableField("list", {
279
638
  name: "features",
280
639
  label: "Features",
@@ -285,38 +644,38 @@ var VitePress = class {
285
644
  createOverwriteableField("string", {
286
645
  name: "title",
287
646
  required: true
288
- }, overwrites == null ? void 0 : overwrites.featuresTitle),
647
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.featuresTitle, overwrites)),
289
648
  createOverwriteableField("string", {
290
649
  name: "details",
291
650
  required: false
292
- }, overwrites == null ? void 0 : overwrites.featuresDetails),
651
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.featuresDetails, overwrites)),
293
652
  // TODO: add support for object options
294
653
  createOverwriteableField("string", {
295
654
  name: "icon",
296
655
  required: false
297
- }, overwrites == null ? void 0 : overwrites.featuresIcon),
656
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.featuresIcon, overwrites)),
298
657
  createOverwriteableField("string", {
299
658
  name: "link",
300
659
  required: false
301
- }, overwrites == null ? void 0 : overwrites.featuresLink),
660
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.featuresLink, overwrites)),
302
661
  createOverwriteableField("string", {
303
662
  name: "linkText",
304
663
  label: "Link text",
305
664
  required: false
306
- }, overwrites == null ? void 0 : overwrites.featuresLinkText),
665
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.featuresLinkText, overwrites)),
307
666
  createOverwriteableField("string", {
308
667
  name: "target",
309
668
  label: "Target",
310
669
  required: false
311
- }, overwrites == null ? void 0 : overwrites.featuresTarget),
670
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.featuresTarget, overwrites)),
312
671
  createOverwriteableField("string", {
313
672
  name: "rel",
314
673
  required: false
315
- }, overwrites == null ? void 0 : overwrites.featuresRel),
674
+ }, mergeOverwrites(overwrites == null ? void 0 : overwrites.featuresRel, overwrites)),
316
675
  ...addAdditionalFields((_a = options == null ? void 0 : options.additionalFeatureFields) != null ? _a : [])
317
676
  ].filter(filterUndefined)
318
- }, omit(overwrites == null ? void 0 : overwrites.features, keys))
319
- ];
677
+ }, omit(mergeOverwrites(overwrites == null ? void 0 : overwrites.features, overwrites), keys))
678
+ ].filter(filterUndefined);
320
679
  }
321
680
  static createDefaultPageFolderCollection(name, folder, options) {
322
681
  const _a = options != null ? options : {}, { collection } = _a, fieldsOptions = __objRest(_a, ["collection"]);
@@ -351,276 +710,20 @@ var VitePress = class {
351
710
  }
352
711
  };
353
712
 
354
- // src/files/config.ts
355
- var objToSnakeCase = (obj) => {
356
- const ignoredKeys = ["i18n"];
357
- const camelToSnakeCase = (str) => str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
358
- return Object.fromEntries(
359
- Object.entries(obj).map(([k, v]) => [ignoredKeys.includes(k) ? k : camelToSnakeCase(k), v])
360
- );
361
- };
362
- function getBooleanFromEnv(value, command) {
363
- return value === "dev" ? command === "serve" : value === "prod" ? command === "build" : value != null ? value : false;
364
- }
365
- function resolveBackend(options, command) {
366
- const _a = options, { local, name } = _a, backend = __objRest(_a, ["local", "name"]);
367
- const git = getGitData();
368
- const branch = "useCurrentBranch" in options && getBooleanFromEnv(options.useCurrentBranch, command) ? git.getBranch() : "branch" in backend ? backend.branch : void 0;
369
- delete backend.useCurrentBranch;
370
- const resolved = {
371
- local_backend: typeof local === "object" ? objToSnakeCase(local) : getBooleanFromEnv(local, command),
372
- backend: __spreadProps(__spreadValues({}, objToSnakeCase(backend)), {
373
- branch,
374
- name
375
- })
376
- };
377
- return resolved;
378
- }
379
- function createConfigFile(config, command) {
380
- const _a = config, { backend, collections } = _a, options = __objRest(_a, ["backend", "collections"]);
381
- return __spreadProps(__spreadValues(__spreadValues({}, resolveBackend(backend, command)), objToSnakeCase(options)), {
382
- collections: collections.map((col) => {
383
- if ("fields" in col) {
384
- const _a2 = col, { fields } = _a2, data = __objRest(_a2, ["fields"]);
385
- return __spreadProps(__spreadValues({}, objToSnakeCase(data)), {
386
- fields: fields.map(objToSnakeCase)
387
- });
388
- } else if ("files" in col) {
389
- const _b = col, { files } = _b, data = __objRest(_b, ["files"]);
390
- return __spreadProps(__spreadValues({}, objToSnakeCase(data)), {
391
- files: files.map((file) => {
392
- const _a3 = file, { fields } = _a3, _data = __objRest(_a3, ["fields"]);
393
- return __spreadProps(__spreadValues({}, objToSnakeCase(_data)), {
394
- fields: fields.map(objToSnakeCase)
395
- });
396
- })
397
- });
398
- } else throw new Error("Missing either fields or files property in collection");
399
- })
400
- });
401
- }
402
-
403
- // src/script.ts
404
- function createCmsFunction(method, items, createParams, options) {
405
- var _a;
406
- const create = (params) => {
407
- var _a2;
408
- return `${(_a2 = options == null ? void 0 : options.base) != null ? _a2 : "CMS"}.${method}(${params})`;
409
- };
410
- return (items != null ? items : []).map((item) => {
411
- const params = createParams(item);
412
- if (!params) return null;
413
- else return create(params);
414
- }).filter(Boolean).join((_a = options == null ? void 0 : options.joinChar) != null ? _a : "\n");
415
- }
416
- function createScript(options) {
417
- const _a = options, {
418
- useManualInitialization,
419
- markdownEditorComponents,
420
- formatters,
421
- previewStylesheets,
422
- onGenerated: onGenerated,
423
- onInitialized
424
- } = _a, eventHooks = __objRest(_a, [
425
- "useManualInitialization",
426
- "markdownEditorComponents",
427
- "formatters",
428
- "previewStylesheets",
429
- // previewTemplates,
430
- // widgets,
431
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
432
- "onGenerated",
433
- "onInitialized"
434
- ]);
435
- const events = createCmsFunction("registerEventListener", Object.keys(eventHooks), (hookName) => {
436
- const hook = eventHooks[hookName];
437
- if (!hook) return null;
438
- else {
439
- const name = hookName.slice(2)[0].toLowerCase() + hookName.slice(3);
440
- return `{ name: '${name}', handler: data => { function ${hook.toString()}; ${hookName}({ app: CMS, ...data }) } }`;
441
- }
442
- });
443
- const customFormatters = createCmsFunction("registerCustomFormat", formatters, ({ name, extension, formatter }) => {
444
- return `'${name}', '${extension}', ${formatter.toString()}`;
445
- });
446
- const customStyles = createCmsFunction("registerPreviewStyle", previewStylesheets, (style) => {
447
- return typeof style === "string" ? style : `${style.style}, { raw: ${style.options.raw} }`;
448
- });
449
- const editorComponents = createCmsFunction("registerEditorComponent", markdownEditorComponents, (item) => {
450
- const _a2 = item, { pattern, toPreview, toBlock, fromBlock } = _a2, component = __objRest(_a2, ["pattern", "toPreview", "toBlock", "fromBlock"]);
451
- return `{ pattern: ${pattern}, toPreview: ${toPreview.toString()}, toBlock: ${toBlock.toString()}, fromBlock: ${fromBlock.toString()}, ...${JSON.stringify(component)}}`;
452
- });
453
- return `
454
- <script>
455
- ${useManualInitialization ? "window.CMS_MANUAL_INIT = true;" : ""}
456
- ${onInitialized != void 0 ? `window.onload = () => { function ${onInitialized.toString()}; onInitialized({ app: CMS }) }` : ""}
457
- ${customFormatters}
458
- ${customStyles}
459
- ${events}
460
- ${editorComponents}
461
- </script>`;
462
- }
463
-
464
- // src/files/index.ts
465
- var defaultDecapCmsCdnVersion = "3.1.11";
466
- var defaultNetlifyIdentityVersion = "1";
467
- var addSlash = (path, slash = "/") => path.endsWith(slash) ? path : path + slash;
468
- function resolveCdnRoute(options) {
469
- const getUrl = (host = "https://unpkg.com/", version = defaultDecapCmsCdnVersion) => {
470
- return `${addSlash(host)}decap-cms@^${version}/dist/decap-cms.js`;
471
- };
472
- return typeof options === "boolean" ? options ? getUrl() : void 0 : typeof options === "string" ? options : options != void 0 ? getUrl(options.base, options.version) : void 0;
473
- }
474
- function resolveHead(head) {
475
- return head.reduce((output, config) => {
476
- if (typeof config === "string") return output.concat(config);
477
- if ("skip" in config) {
478
- if (config.skip) return output;
479
- if (typeof config.head === "string") return output.concat(config.head);
480
- }
481
- const item = "head" in config ? config.head : config;
482
- let str = `<${item[0]}`;
483
- for (const key in item[1]) {
484
- str += ` ${key}="${item[1][key]}"`;
485
- }
486
- str += item[0] === "meta" ? "/>" : ">";
487
- if (item[2] == void 0) return output.concat(str);
488
- str += item[2] + `</${item[0]}>`;
489
- return output.concat(str);
490
- }, []);
491
- }
492
- function getIndexFeatures(config, loadOptions) {
493
- var _a;
494
- const configRoute = config.dir ? addSlash(config.dir) + "config.yml" : void 0;
495
- return {
496
- cdn_route: resolveCdnRoute(loadOptions == void 0 || loadOptions.method === "cdn" ? (_a = loadOptions == null ? void 0 : loadOptions.options) != null ? _a : true : void 0),
497
- custom_logo: "logoUrl" in config ? config.logoUrl != void 0 : "logo_url" in config ? config.logo_url != void 0 : false,
498
- head: (options) => {
499
- var _a2, _b, _c;
500
- return resolveHead([
501
- ["meta", { charset: "utf-8" }],
502
- ["meta", { name: "viewport", content: "width=device-width, initial-scale=1.0" }],
503
- ["meta", { name: "robots", content: "noindex" }],
504
- ...(_a2 = options == null ? void 0 : options.head) != null ? _a2 : [],
505
- ["title", {}, (_b = options == null ? void 0 : options.title) != null ? _b : "Content Manager"],
506
- {
507
- head: ["link", { rel: "favicon", ref: (_c = options == null ? void 0 : options.icon) != null ? _c : "" }],
508
- skip: (options == null ? void 0 : options.icon) == void 0
509
- },
510
- {
511
- head: ["script", { src: `https://identity.netlify.com/v${defaultNetlifyIdentityVersion}/netlify-identity-widget.js` }],
512
- skip: config.backend.name !== "git-gateway"
513
- },
514
- {
515
- head: ["link", { type: "text/yaml", rel: "cms-config-url", href: configRoute }],
516
- skip: configRoute == void 0
517
- }
518
- ]);
519
- }
520
- };
521
- }
522
- function createIndexFile(pluginOptions) {
523
- var _a, _b;
524
- const { config, load, login: options, script } = pluginOptions;
525
- if (options == null ? void 0 : options.html) return options.html;
526
- const features = getIndexFeatures(config, load);
527
- return `<!DOCTYPE html>
528
- <html>
529
- <head>
530
- ${features.head(options).join("\n" + " ".repeat(8))}
531
- </head>
532
- <body>
533
- ${features.cdn_route ? `<script src="${features.cdn_route}"></script>` : ""}
534
- ${script ? createScript(script) : ""}
535
- ${((_a = pluginOptions.login) == null ? void 0 : _a.additionalHtml) ? `${(_b = pluginOptions.login) == null ? void 0 : _b.additionalHtml}
536
-
537
- <div id="nc-root"></div>` : ""}
538
- </body>
539
- </html>${features.custom_logo ? `
540
-
541
- <style>
542
- span[class*='CustomIconWrapper'] {
543
- width: auto;
544
- }
545
- </style>` : ""}`;
546
- }
547
-
548
- // src/files.ts
549
- import { mkdir, writeFile } from "fs/promises";
550
- import { resolve, isAbsolute, sep } from "path";
551
- function resolveDir(publicDir, dir) {
552
- return dir ? isAbsolute(dir) ? dir : resolve(dir) : publicDir;
553
- }
554
- async function writeToFolder(folder, options) {
555
- const dir = folder + (options.subfolder ? sep + options.subfolder : "");
556
- await mkdir(dir, { recursive: true });
557
- for (const file of options.files.filter((f) => !f.skip)) {
558
- await writeFile(dir + sep + file.name, file.content, {
559
- encoding: "utf-8"
560
- });
561
- }
562
- }
563
-
564
713
  // src/index.ts
565
- function validateLoadOptions(options) {
566
- var _a;
567
- const valid = ["npm", "cdn"].includes((_a = options == null ? void 0 : options.method) != null ? _a : "cdn");
568
- if (!valid) throw new Error("Invalid load options for decap-cms provided");
569
- }
570
- function runProxy(options) {
571
- var _a, _b, _c, _d, _e;
572
- const proxy = exec("npx decap-server", __spreadProps(__spreadValues({}, (_a = options == null ? void 0 : options.process) != null ? _a : {}), {
573
- env: __spreadProps(__spreadValues({}, (_c = (_b = options == null ? void 0 : options.process) == null ? void 0 : _b.env) != null ? _c : {}), {
574
- PORT: ((_d = options == null ? void 0 : options.port) != null ? _d : 8081).toString()
575
- })
576
- }));
577
- (_e = proxy.stdout) == null ? void 0 : _e.pipe(process.stdout);
578
- proxy.on("error", (err) => {
579
- if ("code" in err && err.code === "EADDRINUSE") {
580
- console.log("[PROXY] Port is already used");
581
- } else throw err;
582
- });
583
- process.on("beforeExit", () => proxy.kill());
584
- }
585
- async function updateConfig(options, config) {
586
- var _a, _b, _c, _d, _e, _f, _g, _h;
587
- validateLoadOptions(options.load);
588
- const loginFile = createIndexFile(options);
589
- const configFile = createConfigFile(options.config, config.command);
590
- await writeToFolder(
591
- resolveDir(config.publicDir, options.dir),
592
- {
593
- subfolder: "admin",
594
- files: [
595
- { name: "index.html", content: loginFile },
596
- { name: "config.yml", content: stringify(configFile, (_a = options.yml) == null ? void 0 : _a.replacer, (_b = options.yml) == null ? void 0 : _b.options) }
597
- // { name: 'npm.js', content: createCustomScript(), skip: options.load?.method !== 'npm' },
598
- ]
599
- }
600
- );
601
- if (config.command === "serve" && configFile.local_backend !== false && ((_d = (_c = options.proxy) == null ? void 0 : _c.enabled) != null ? _d : true)) {
602
- runProxy(options.proxy);
603
- }
604
- await ((_f = (_e = options.script) == null ? void 0 : _e.onConfigUpdated) == null ? void 0 : _f.call(_e));
605
- if (config.command === "build") {
606
- await ((_h = (_g = options.script) == null ? void 0 : _g.onGenerated) == null ? void 0 : _h.call(_g));
607
- }
608
- }
609
714
  function VitePluginDecapCMS(options) {
610
715
  let stored = null;
611
- const debug = (...str) => {
612
- if (options.debug) console.debug(str);
613
- };
614
716
  return {
615
717
  name: "vite-plugin-decap-cms",
616
718
  async configResolved(config) {
617
- const isUpdated = stored != null ? stored.command !== config.command || stored.publicDir !== config.publicDir : true;
618
- if (isUpdated) {
619
- await updateConfig(options, config);
719
+ const needsUpdate = stored != null ? stored.command !== config.command || stored.publicDir !== config.publicDir : true;
720
+ const log = createLogger(options.debug);
721
+ if (needsUpdate) {
722
+ await updateConfig(options, config, log);
620
723
  stored = config;
621
- debug("\nUpdated Decap CMS configuration");
724
+ log("config", "debug", "Updated Decap CMS configuration files");
622
725
  } else {
623
- debug("\nSkipped updating Decap CMS");
726
+ log("config", "debug", "Skipped updating Decap CMS configuration files");
624
727
  }
625
728
  }
626
729
  };
@@ -631,6 +734,9 @@ export {
631
734
  createFile,
632
735
  createFileCollection,
633
736
  createFolderCollection,
737
+ createOverwriteableField,
738
+ createSharedCollectionOptions,
634
739
  VitePluginDecapCMS as default,
740
+ fieldToSnakeCase,
635
741
  getGitData
636
742
  };