@elek-io/core 0.9.1 → 0.11.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.
@@ -7,12 +7,14 @@ var __export = (target, all) => {
7
7
  // src/index.node.ts
8
8
  import Fs7 from "fs-extra";
9
9
 
10
+ // package.json
11
+ var version = "0.11.0";
12
+
10
13
  // src/schema/assetSchema.ts
11
- import z3 from "zod";
14
+ import z4 from "zod";
12
15
 
13
16
  // src/schema/baseSchema.ts
14
17
  import z from "zod";
15
- var environmentSchema = z.enum(["production", "development", "test"]);
16
18
  var supportedLanguageSchema = z.enum([
17
19
  /**
18
20
  * Bulgarian
@@ -67,39 +69,6 @@ var supportedLanguageSchema = z.enum([
67
69
  // (Simplified) Chinese
68
70
  ]);
69
71
  var supportedIconSchema = z.enum(["home", "plus", "foobar"]);
70
- var supportedAssetMimeTypeSchema = z.enum([
71
- "image/avif",
72
- "image/gif",
73
- "image/jpeg",
74
- "image/png",
75
- "image/svg+xml",
76
- "image/webp",
77
- "application/pdf",
78
- "application/zip",
79
- "video/mp4",
80
- "video/webm",
81
- "audio/webm",
82
- "audio/flac"
83
- ]);
84
- var supportedAssetExtensionSchema = z.enum([
85
- "avif",
86
- "gif",
87
- "jpg",
88
- "jpeg",
89
- "png",
90
- "svg",
91
- "webp",
92
- "pdf",
93
- "zip",
94
- "mp4",
95
- "webm",
96
- "flac",
97
- "json"
98
- ]);
99
- var supportedAssetTypeSchema = z.object({
100
- extension: supportedAssetExtensionSchema,
101
- mimeType: supportedAssetMimeTypeSchema
102
- });
103
72
  var objectTypeSchema = z.enum([
104
73
  "project",
105
74
  "asset",
@@ -108,6 +77,7 @@ var objectTypeSchema = z.enum([
108
77
  "value",
109
78
  "sharedValue"
110
79
  ]);
80
+ var logLevelSchema = z.enum(["error", "warn", "info", "debug"]);
111
81
  var versionSchema = z.string();
112
82
  var uuidSchema = z.string().uuid("shared.invalidUuid");
113
83
  var translatableStringSchema = z.record(
@@ -129,6 +99,10 @@ function translatableArrayOf(schema) {
129
99
  // src/schema/fileSchema.ts
130
100
  import z2 from "zod";
131
101
  var baseFileSchema = z2.object({
102
+ /**
103
+ * The object type of the file
104
+ */
105
+ objectType: objectTypeSchema.readonly(),
132
106
  /**
133
107
  * The ID of the file
134
108
  *
@@ -144,40 +118,150 @@ var baseFileSchema = z2.object({
144
118
  */
145
119
  updated: z2.string().datetime().nullable()
146
120
  });
147
- var baseFileWithLanguageSchema = baseFileSchema.extend({
121
+ var fileReferenceSchema = z2.object({
122
+ id: uuidSchema,
123
+ extension: z2.string().optional()
124
+ });
125
+
126
+ // src/schema/gitSchema.ts
127
+ import { z as z3 } from "zod";
128
+ var gitSignatureSchema = z3.object({
129
+ name: z3.string(),
130
+ email: z3.string()
131
+ });
132
+ var gitMessageSchema = z3.object({
133
+ method: z3.enum(["create", "update", "delete", "upgrade"]),
134
+ reference: z3.object({
135
+ objectType: objectTypeSchema,
136
+ /**
137
+ * ID of the objectType
138
+ */
139
+ id: uuidSchema,
140
+ /**
141
+ * Only present if the objectType is of "entry"
142
+ */
143
+ collectionId: uuidSchema.optional()
144
+ })
145
+ });
146
+ var gitTagSchema = z3.object({
147
+ id: uuidSchema,
148
+ message: z3.string(),
149
+ author: gitSignatureSchema,
150
+ datetime: z3.string().datetime()
151
+ });
152
+ var gitCommitSchema = z3.object({
153
+ /**
154
+ * SHA-1 hash of the commit
155
+ */
156
+ hash: z3.string(),
157
+ message: gitMessageSchema,
158
+ author: gitSignatureSchema,
159
+ datetime: z3.string().datetime(),
160
+ tag: gitTagSchema.nullable()
161
+ });
162
+ var gitInitOptionsSchema = z3.object({
163
+ /**
164
+ * Use the specified name for the initial branch in the newly created repository. If not specified, fall back to the default name (currently master, but this is subject to change in the future; the name can be customized via the init.defaultBranch configuration variable).
165
+ */
166
+ initialBranch: z3.string()
167
+ });
168
+ var gitCloneOptionsSchema = z3.object({
148
169
  /**
149
- * The language of the file
170
+ * Create a shallow clone with a history truncated to the specified number of commits. Implies --single-branch unless --no-single-branch is given to fetch the histories near the tips of all branches. If you want to clone submodules shallowly, also pass --shallow-submodules.
171
+ */
172
+ depth: z3.number(),
173
+ /**
174
+ * Clone only the history leading to the tip of a single branch, either specified by the --branch option or the primary branch remote’s HEAD points at. Further fetches into the resulting repository will only update the remote-tracking branch for the branch this option was used for the initial cloning. If the HEAD at the remote did not point at any branch when --single-branch clone was made, no remote-tracking branch is created.
175
+ */
176
+ singleBranch: z3.boolean(),
177
+ /**
178
+ * Instead of pointing the newly created HEAD to the branch pointed to by the cloned repository’s HEAD, point to <name> branch instead. In a non-bare repository, this is the branch that will be checked out. --branch can also take tags and detaches the HEAD at that commit in the resulting repository.
179
+ */
180
+ branch: z3.string(),
181
+ /**
182
+ * Make a bare Git repository. That is, instead of creating <directory> and placing the administrative files in <directory>`/.git`, make the <directory> itself the $GIT_DIR.
183
+ * Used primarily to copy an existing local repository to a server, where you want to set up the repository as a central point to work with others.
150
184
  *
151
- * The language is part of the files name and together with it's ID the only unique identifier.
152
- * That's why the language cannot be changed after creating the file.
185
+ * The destination path for the cloned repository should end with a .git by convention.
153
186
  *
154
- * @todo Maybe remove the above restriction by implementing logic to handle changing the files language inside all services
187
+ * @see https://git-scm.com/book/en/v2/Git-on-the-Server-Getting-Git-on-a-Server
155
188
  */
156
- language: supportedLanguageSchema.readonly()
189
+ bare: z3.boolean()
157
190
  });
158
- var fileReferenceSchema = z2.object({
159
- id: uuidSchema,
160
- language: supportedLanguageSchema.optional(),
161
- extension: supportedAssetExtensionSchema.optional()
191
+ var gitMergeOptionsSchema = z3.object({
192
+ squash: z3.boolean()
193
+ });
194
+ var gitSwitchOptionsSchema = z3.object({
195
+ /**
196
+ * If true, creates a new local branch and then switches to it
197
+ *
198
+ * @see https://git-scm.com/docs/git-switch#Documentation/git-switch.txt---createltnew-branchgt
199
+ */
200
+ isNew: z3.boolean().optional()
201
+ });
202
+ var gitLogOptionsSchema = z3.object({
203
+ /**
204
+ * Limit the result to given number of commits
205
+ */
206
+ limit: z3.number().optional(),
207
+ /**
208
+ * Only list commits that are between given SHAs or tag names
209
+ *
210
+ * Note that the commits of from and to are not included in the result
211
+ */
212
+ between: z3.object({
213
+ /**
214
+ * From the oldest commit
215
+ */
216
+ from: z3.string(),
217
+ /**
218
+ * To the newest commit
219
+ *
220
+ * Defaults to the current HEAD
221
+ */
222
+ to: z3.string().optional()
223
+ }),
224
+ /**
225
+ * Only shows commits of given file
226
+ */
227
+ filePath: z3.string().optional()
228
+ });
229
+ var createGitTagSchema = gitTagSchema.pick({
230
+ message: true
231
+ }).extend({
232
+ path: z3.string(),
233
+ hash: z3.string().optional()
234
+ });
235
+ var readGitTagSchema = z3.object({
236
+ path: z3.string(),
237
+ id: uuidSchema.readonly()
238
+ });
239
+ var deleteGitTagSchema = readGitTagSchema.extend({});
240
+ var countGitTagsSchema = z3.object({
241
+ path: z3.string()
162
242
  });
163
243
 
164
244
  // src/schema/assetSchema.ts
165
245
  var assetFileSchema = baseFileSchema.extend({
166
- objectType: z3.literal(objectTypeSchema.Enum.asset).readonly(),
167
- name: z3.string(),
168
- description: z3.string(),
169
- extension: supportedAssetExtensionSchema.readonly(),
170
- mimeType: supportedAssetMimeTypeSchema.readonly(),
246
+ objectType: z4.literal(objectTypeSchema.Enum.asset).readonly(),
247
+ name: z4.string(),
248
+ description: z4.string(),
249
+ extension: z4.string().readonly(),
250
+ mimeType: z4.string().readonly(),
171
251
  /**
172
252
  * Total size in bytes
173
253
  */
174
- size: z3.number().readonly()
254
+ size: z4.number().readonly()
175
255
  });
176
256
  var assetSchema = assetFileSchema.extend({
177
257
  /**
178
258
  * Absolute path on this filesystem
179
259
  */
180
- absolutePath: z3.string().readonly()
260
+ absolutePath: z4.string().readonly(),
261
+ /**
262
+ * Commit history of this Asset
263
+ */
264
+ history: z4.array(gitCommitSchema)
181
265
  });
182
266
  var assetExportSchema = assetSchema.extend({});
183
267
  var createAssetSchema = assetFileSchema.pick({
@@ -188,12 +272,20 @@ var createAssetSchema = assetFileSchema.pick({
188
272
  /**
189
273
  * Path of the file to add as a new Asset
190
274
  */
191
- filePath: z3.string().readonly()
275
+ filePath: z4.string().readonly()
192
276
  });
193
277
  var readAssetSchema = assetFileSchema.pick({
194
278
  id: true
195
279
  }).extend({
196
- projectId: uuidSchema.readonly()
280
+ projectId: uuidSchema.readonly(),
281
+ commitHash: z4.string().optional().readonly()
282
+ });
283
+ var saveAssetSchema = assetFileSchema.pick({
284
+ id: true
285
+ }).extend({
286
+ projectId: uuidSchema.readonly(),
287
+ filePath: z4.string().readonly(),
288
+ commitHash: z4.string().optional().readonly()
197
289
  });
198
290
  var updateAssetSchema = assetFileSchema.pick({
199
291
  id: true,
@@ -204,7 +296,7 @@ var updateAssetSchema = assetFileSchema.pick({
204
296
  /**
205
297
  * Path of the new file to update the Asset with
206
298
  */
207
- newFilePath: z3.string().readonly().optional()
299
+ newFilePath: z4.string().readonly().optional()
208
300
  });
209
301
  var deleteAssetSchema = assetFileSchema.pick({
210
302
  id: true,
@@ -212,92 +304,93 @@ var deleteAssetSchema = assetFileSchema.pick({
212
304
  }).extend({
213
305
  projectId: uuidSchema.readonly()
214
306
  });
215
- var countAssetsSchema = z3.object({ projectId: uuidSchema.readonly() });
307
+ var countAssetsSchema = z4.object({ projectId: uuidSchema.readonly() });
216
308
 
217
309
  // src/schema/collectionSchema.ts
218
- import z7 from "zod";
310
+ import z8 from "zod";
219
311
 
220
312
  // src/schema/entrySchema.ts
221
- import z5 from "zod";
313
+ import z6 from "zod";
222
314
 
223
315
  // src/schema/valueSchema.ts
224
- import z4 from "zod";
225
- var ValueTypeSchema = z4.enum([
316
+ import z5 from "zod";
317
+ var ValueTypeSchema = z5.enum([
226
318
  "string",
227
319
  "number",
228
320
  "boolean",
229
321
  "reference"
230
322
  ]);
231
- var valueContentReferenceBase = z4.object({
323
+ var valueContentReferenceBase = z5.object({
232
324
  id: uuidSchema
233
325
  });
234
- var valueContentReferenceWithLanguageBase = valueContentReferenceBase.extend({
235
- language: supportedLanguageSchema
236
- });
237
326
  var valueContentReferenceToAssetSchema = valueContentReferenceBase.extend({
238
- objectType: z4.literal(objectTypeSchema.Enum.asset)
327
+ objectType: z5.literal(objectTypeSchema.Enum.asset)
239
328
  });
240
329
  var valueContentReferenceToCollectionSchema = valueContentReferenceBase.extend({
241
- objectType: z4.literal(objectTypeSchema.Enum.collection)
330
+ objectType: z5.literal(objectTypeSchema.Enum.collection)
242
331
  });
243
332
  var valueContentReferenceToEntrySchema = valueContentReferenceBase.extend({
244
- objectType: z4.literal(objectTypeSchema.Enum.entry)
333
+ objectType: z5.literal(objectTypeSchema.Enum.entry)
245
334
  });
246
- var valueContentReferenceSchema = z4.union([
335
+ var valueContentReferenceSchema = z5.union([
247
336
  valueContentReferenceToAssetSchema,
248
337
  valueContentReferenceToCollectionSchema,
249
338
  valueContentReferenceToEntrySchema
250
339
  // valueContentReferenceToSharedValueSchema,
251
340
  ]);
252
- var resolvedValueContentReferenceSchema = z4.union([
341
+ var resolvedValueContentReferenceSchema = z5.union([
253
342
  assetSchema,
254
- z4.lazy(() => entrySchema)
343
+ z5.lazy(() => entrySchema)
255
344
  // Circular dependency / recursive type @see https://github.com/colinhacks/zod?tab=readme-ov-file#recursive-types
256
345
  // resolvedValueContentReferenceToSharedValueSchema,
257
346
  ]);
258
- var directValueBaseSchema = z4.object({
259
- objectType: z4.literal(objectTypeSchema.Enum.value).readonly(),
347
+ var directValueBaseSchema = z5.object({
348
+ objectType: z5.literal(objectTypeSchema.Enum.value).readonly(),
260
349
  fieldDefinitionId: uuidSchema.readonly()
261
350
  });
262
351
  var directStringValueSchema = directValueBaseSchema.extend({
263
- valueType: z4.literal(ValueTypeSchema.Enum.string).readonly(),
352
+ valueType: z5.literal(ValueTypeSchema.Enum.string).readonly(),
264
353
  content: translatableStringSchema
265
354
  });
266
355
  var directNumberValueSchema = directValueBaseSchema.extend({
267
- valueType: z4.literal(ValueTypeSchema.Enum.number).readonly(),
356
+ valueType: z5.literal(ValueTypeSchema.Enum.number).readonly(),
268
357
  content: translatableNumberSchema
269
358
  });
270
359
  var directBooleanValueSchema = directValueBaseSchema.extend({
271
- valueType: z4.literal(ValueTypeSchema.Enum.boolean).readonly(),
360
+ valueType: z5.literal(ValueTypeSchema.Enum.boolean).readonly(),
272
361
  content: translatableBooleanSchema
273
362
  });
274
- var directValueSchema = z4.union([
363
+ var directValueSchema = z5.union([
275
364
  directStringValueSchema,
276
365
  directNumberValueSchema,
277
366
  directBooleanValueSchema
278
367
  ]);
279
- var referencedValueSchema = z4.object({
280
- objectType: z4.literal(objectTypeSchema.Enum.value).readonly(),
368
+ var referencedValueSchema = z5.object({
369
+ objectType: z5.literal(objectTypeSchema.Enum.value).readonly(),
281
370
  fieldDefinitionId: uuidSchema.readonly(),
282
- valueType: z4.literal(ValueTypeSchema.Enum.reference).readonly(),
371
+ valueType: z5.literal(ValueTypeSchema.Enum.reference).readonly(),
283
372
  content: translatableArrayOf(valueContentReferenceSchema)
284
373
  });
285
- var valueSchema = z4.union([directValueSchema, referencedValueSchema]);
374
+ var valueSchema = z5.union([directValueSchema, referencedValueSchema]);
286
375
  var resolvedReferencedValueSchema = referencedValueSchema.extend({
287
376
  content: translatableArrayOf(resolvedValueContentReferenceSchema)
288
377
  });
289
- var resolvedValueSchema = z4.union([
378
+ var resolvedValueSchema = z5.union([
290
379
  directValueSchema,
291
380
  resolvedReferencedValueSchema
292
381
  ]);
293
382
 
294
383
  // src/schema/entrySchema.ts
295
384
  var entryFileSchema = baseFileSchema.extend({
296
- objectType: z5.literal(objectTypeSchema.Enum.entry).readonly(),
297
- values: z5.array(valueSchema)
385
+ objectType: z6.literal(objectTypeSchema.Enum.entry).readonly(),
386
+ values: z6.array(valueSchema)
298
387
  });
299
388
  var entrySchema = entryFileSchema.extend({
300
- values: z5.array(z5.lazy(() => resolvedValueSchema))
389
+ values: z6.array(z6.lazy(() => resolvedValueSchema)),
390
+ /**
391
+ * Commit history of this Entry
392
+ */
393
+ history: z6.array(gitCommitSchema)
301
394
  });
302
395
  var entryExportSchema = entrySchema.extend({});
303
396
  var createEntrySchema = entryFileSchema.omit({
@@ -308,14 +401,15 @@ var createEntrySchema = entryFileSchema.omit({
308
401
  }).extend({
309
402
  projectId: uuidSchema.readonly(),
310
403
  collectionId: uuidSchema.readonly(),
311
- values: z5.array(valueSchema)
404
+ values: z6.array(valueSchema)
312
405
  });
313
- var readEntrySchema = z5.object({
406
+ var readEntrySchema = z6.object({
314
407
  id: uuidSchema.readonly(),
315
408
  projectId: uuidSchema.readonly(),
316
- collectionId: uuidSchema.readonly()
409
+ collectionId: uuidSchema.readonly(),
410
+ commitHash: z6.string().optional().readonly()
317
411
  });
318
- var updateEntrySchema = entrySchema.omit({
412
+ var updateEntrySchema = entryFileSchema.omit({
319
413
  objectType: true,
320
414
  created: true,
321
415
  updated: true
@@ -324,14 +418,14 @@ var updateEntrySchema = entrySchema.omit({
324
418
  collectionId: uuidSchema.readonly()
325
419
  });
326
420
  var deleteEntrySchema = readEntrySchema.extend({});
327
- var countEntriesSchema = z5.object({
421
+ var countEntriesSchema = z6.object({
328
422
  projectId: uuidSchema.readonly(),
329
423
  collectionId: uuidSchema.readonly()
330
424
  });
331
425
 
332
426
  // src/schema/fieldSchema.ts
333
- import { z as z6 } from "zod";
334
- var FieldTypeSchema = z6.enum([
427
+ import { z as z7 } from "zod";
428
+ var FieldTypeSchema = z7.enum([
335
429
  // String Values
336
430
  "text",
337
431
  "textarea",
@@ -353,67 +447,67 @@ var FieldTypeSchema = z6.enum([
353
447
  "entry"
354
448
  // 'sharedValue', // @todo
355
449
  ]);
356
- var FieldWidthSchema = z6.enum(["12", "6", "4", "3"]);
357
- var FieldDefinitionBaseSchema = z6.object({
450
+ var FieldWidthSchema = z7.enum(["12", "6", "4", "3"]);
451
+ var FieldDefinitionBaseSchema = z7.object({
358
452
  id: uuidSchema.readonly(),
359
453
  label: translatableStringSchema,
360
454
  description: translatableStringSchema,
361
- isRequired: z6.boolean(),
362
- isDisabled: z6.boolean(),
363
- isUnique: z6.boolean(),
455
+ isRequired: z7.boolean(),
456
+ isDisabled: z7.boolean(),
457
+ isUnique: z7.boolean(),
364
458
  inputWidth: FieldWidthSchema
365
459
  });
366
460
  var StringFieldDefinitionBaseSchema = FieldDefinitionBaseSchema.extend(
367
461
  {
368
- valueType: z6.literal(ValueTypeSchema.Enum.string),
369
- defaultValue: z6.string().nullable()
462
+ valueType: z7.literal(ValueTypeSchema.Enum.string),
463
+ defaultValue: z7.string().nullable()
370
464
  }
371
465
  );
372
466
  var textFieldDefinitionSchema = StringFieldDefinitionBaseSchema.extend(
373
467
  {
374
- fieldType: z6.literal(FieldTypeSchema.Enum.text),
375
- min: z6.number().nullable(),
376
- max: z6.number().nullable()
468
+ fieldType: z7.literal(FieldTypeSchema.Enum.text),
469
+ min: z7.number().nullable(),
470
+ max: z7.number().nullable()
377
471
  }
378
472
  );
379
473
  var textareaFieldDefinitionSchema = StringFieldDefinitionBaseSchema.extend({
380
- fieldType: z6.literal(FieldTypeSchema.Enum.textarea),
381
- min: z6.number().nullable(),
382
- max: z6.number().nullable()
474
+ fieldType: z7.literal(FieldTypeSchema.Enum.textarea),
475
+ min: z7.number().nullable(),
476
+ max: z7.number().nullable()
383
477
  });
384
478
  var emailFieldDefinitionSchema = StringFieldDefinitionBaseSchema.extend({
385
- fieldType: z6.literal(FieldTypeSchema.Enum.email),
386
- defaultValue: z6.string().email().nullable()
479
+ fieldType: z7.literal(FieldTypeSchema.Enum.email),
480
+ defaultValue: z7.string().email().nullable()
387
481
  });
388
482
  var urlFieldDefinitionSchema = StringFieldDefinitionBaseSchema.extend({
389
- fieldType: z6.literal(FieldTypeSchema.Enum.url),
390
- defaultValue: z6.string().url().nullable()
483
+ fieldType: z7.literal(FieldTypeSchema.Enum.url),
484
+ defaultValue: z7.string().url().nullable()
391
485
  });
392
486
  var ipFieldDefinitionSchema = StringFieldDefinitionBaseSchema.extend({
393
- fieldType: z6.literal(FieldTypeSchema.Enum.ip),
394
- defaultValue: z6.string().ip().nullable()
487
+ fieldType: z7.literal(FieldTypeSchema.Enum.ip),
488
+ defaultValue: z7.string().ip().nullable()
395
489
  });
396
490
  var dateFieldDefinitionSchema = StringFieldDefinitionBaseSchema.extend(
397
491
  {
398
- fieldType: z6.literal(FieldTypeSchema.Enum.date),
399
- defaultValue: z6.string().date().nullable()
492
+ fieldType: z7.literal(FieldTypeSchema.Enum.date),
493
+ defaultValue: z7.string().date().nullable()
400
494
  }
401
495
  );
402
496
  var timeFieldDefinitionSchema = StringFieldDefinitionBaseSchema.extend(
403
497
  {
404
- fieldType: z6.literal(FieldTypeSchema.Enum.time),
405
- defaultValue: z6.string().time().nullable()
498
+ fieldType: z7.literal(FieldTypeSchema.Enum.time),
499
+ defaultValue: z7.string().time().nullable()
406
500
  }
407
501
  );
408
502
  var datetimeFieldDefinitionSchema = StringFieldDefinitionBaseSchema.extend({
409
- fieldType: z6.literal(FieldTypeSchema.Enum.datetime),
410
- defaultValue: z6.string().datetime().nullable()
503
+ fieldType: z7.literal(FieldTypeSchema.Enum.datetime),
504
+ defaultValue: z7.string().datetime().nullable()
411
505
  });
412
506
  var telephoneFieldDefinitionSchema = StringFieldDefinitionBaseSchema.extend({
413
- fieldType: z6.literal(FieldTypeSchema.Enum.telephone)
507
+ fieldType: z7.literal(FieldTypeSchema.Enum.telephone)
414
508
  // defaultValue: z.string().e164(), @todo when zod v4 releases @see https://github.com/colinhacks/zod/pull/3476
415
509
  });
416
- var stringFieldDefinitionSchema = z6.union([
510
+ var stringFieldDefinitionSchema = z7.union([
417
511
  textFieldDefinitionSchema,
418
512
  textareaFieldDefinitionSchema,
419
513
  emailFieldDefinitionSchema,
@@ -426,50 +520,49 @@ var stringFieldDefinitionSchema = z6.union([
426
520
  ]);
427
521
  var NumberFieldDefinitionBaseSchema = FieldDefinitionBaseSchema.extend(
428
522
  {
429
- valueType: z6.literal(ValueTypeSchema.Enum.number),
430
- min: z6.number().nullable(),
431
- max: z6.number().nullable(),
432
- isUnique: z6.literal(false),
433
- defaultValue: z6.number().nullable()
523
+ valueType: z7.literal(ValueTypeSchema.Enum.number),
524
+ min: z7.number().nullable(),
525
+ max: z7.number().nullable(),
526
+ isUnique: z7.literal(false),
527
+ defaultValue: z7.number().nullable()
434
528
  }
435
529
  );
436
530
  var numberFieldDefinitionSchema = NumberFieldDefinitionBaseSchema.extend({
437
- fieldType: z6.literal(FieldTypeSchema.Enum.number)
531
+ fieldType: z7.literal(FieldTypeSchema.Enum.number)
438
532
  });
439
533
  var rangeFieldDefinitionSchema = NumberFieldDefinitionBaseSchema.extend({
440
- fieldType: z6.literal(FieldTypeSchema.Enum.range),
534
+ fieldType: z7.literal(FieldTypeSchema.Enum.range),
441
535
  // Overwrite from nullable to required because a range needs min, max and default to work and is required, since it always returns a number
442
- isRequired: z6.literal(true),
443
- min: z6.number(),
444
- max: z6.number(),
445
- defaultValue: z6.number()
536
+ isRequired: z7.literal(true),
537
+ min: z7.number(),
538
+ max: z7.number(),
539
+ defaultValue: z7.number()
446
540
  });
447
541
  var BooleanFieldDefinitionBaseSchema = FieldDefinitionBaseSchema.extend({
448
- valueType: z6.literal(ValueTypeSchema.Enum.boolean),
542
+ valueType: z7.literal(ValueTypeSchema.Enum.boolean),
449
543
  // Overwrite from nullable to required because a boolean needs a default to work and is required, since it always is either true or false
450
- isRequired: z6.literal(true),
451
- defaultValue: z6.boolean(),
452
- isUnique: z6.literal(false)
544
+ isRequired: z7.literal(true),
545
+ defaultValue: z7.boolean(),
546
+ isUnique: z7.literal(false)
453
547
  });
454
548
  var toggleFieldDefinitionSchema = BooleanFieldDefinitionBaseSchema.extend({
455
- fieldType: z6.literal(FieldTypeSchema.Enum.toggle)
549
+ fieldType: z7.literal(FieldTypeSchema.Enum.toggle)
456
550
  });
457
551
  var ReferenceFieldDefinitionBaseSchema = FieldDefinitionBaseSchema.extend({
458
- valueType: z6.literal(ValueTypeSchema.Enum.reference)
552
+ valueType: z7.literal(ValueTypeSchema.Enum.reference)
459
553
  });
460
554
  var assetFieldDefinitionSchema = ReferenceFieldDefinitionBaseSchema.extend({
461
- fieldType: z6.literal(FieldTypeSchema.Enum.asset),
462
- allowedMimeTypes: z6.array(supportedAssetMimeTypeSchema).min(1),
463
- min: z6.number().nullable(),
464
- max: z6.number().nullable()
555
+ fieldType: z7.literal(FieldTypeSchema.Enum.asset),
556
+ min: z7.number().nullable(),
557
+ max: z7.number().nullable()
465
558
  });
466
559
  var entryFieldDefinitionSchema = ReferenceFieldDefinitionBaseSchema.extend({
467
- fieldType: z6.literal(FieldTypeSchema.Enum.entry),
468
- ofCollections: z6.array(uuidSchema),
469
- min: z6.number().nullable(),
470
- max: z6.number().nullable()
560
+ fieldType: z7.literal(FieldTypeSchema.Enum.entry),
561
+ ofCollections: z7.array(uuidSchema),
562
+ min: z7.number().nullable(),
563
+ max: z7.number().nullable()
471
564
  });
472
- var fieldDefinitionSchema = z6.union([
565
+ var fieldDefinitionSchema = z7.union([
473
566
  stringFieldDefinitionSchema,
474
567
  numberFieldDefinitionSchema,
475
568
  rangeFieldDefinitionSchema,
@@ -496,10 +589,10 @@ function getValueContentSchemaFromFieldDefinition(fieldDefinition) {
496
589
  }
497
590
  }
498
591
  function getBooleanValueContentSchema() {
499
- return z6.boolean();
592
+ return z7.boolean();
500
593
  }
501
594
  function getNumberValueContentSchema(definition) {
502
- let schema = z6.number();
595
+ let schema = z7.number();
503
596
  if (definition.min) {
504
597
  schema = schema.min(definition.min);
505
598
  }
@@ -512,7 +605,7 @@ function getNumberValueContentSchema(definition) {
512
605
  return schema;
513
606
  }
514
607
  function getStringValueContentSchema(definition) {
515
- let schema = z6.string().trim();
608
+ let schema = z7.string().trim();
516
609
  if ("min" in definition && definition.min) {
517
610
  schema = schema.min(definition.min);
518
611
  }
@@ -551,12 +644,12 @@ function getReferenceValueContentSchema(definition) {
551
644
  switch (definition.fieldType) {
552
645
  case FieldTypeSchema.Enum.asset:
553
646
  {
554
- schema = z6.array(valueContentReferenceToAssetSchema);
647
+ schema = z7.array(valueContentReferenceToAssetSchema);
555
648
  }
556
649
  break;
557
650
  case FieldTypeSchema.Enum.entry:
558
651
  {
559
- schema = z6.array(valueContentReferenceToEntrySchema);
652
+ schema = z7.array(valueContentReferenceToEntrySchema);
560
653
  }
561
654
  break;
562
655
  }
@@ -574,24 +667,29 @@ function getReferenceValueContentSchema(definition) {
574
667
 
575
668
  // src/schema/collectionSchema.ts
576
669
  var collectionFileSchema = baseFileSchema.extend({
577
- objectType: z7.literal(objectTypeSchema.Enum.collection).readonly(),
578
- name: z7.object({
670
+ objectType: z8.literal(objectTypeSchema.Enum.collection).readonly(),
671
+ name: z8.object({
579
672
  singular: translatableStringSchema,
580
673
  plural: translatableStringSchema
581
674
  }),
582
- slug: z7.object({
583
- singular: z7.string(),
584
- plural: z7.string()
675
+ slug: z8.object({
676
+ singular: z8.string(),
677
+ plural: z8.string()
585
678
  }),
586
679
  description: translatableStringSchema,
587
680
  icon: supportedIconSchema,
588
- fieldDefinitions: z7.array(fieldDefinitionSchema)
681
+ fieldDefinitions: z8.array(fieldDefinitionSchema)
682
+ });
683
+ var collectionSchema = collectionFileSchema.extend({
684
+ /**
685
+ * Commit history of this Collection
686
+ */
687
+ history: z8.array(gitCommitSchema)
589
688
  });
590
- var collectionSchema = collectionFileSchema.extend({});
591
689
  var collectionExportSchema = collectionSchema.extend({
592
- entries: z7.array(entryExportSchema)
690
+ entries: z8.array(entryExportSchema)
593
691
  });
594
- var createCollectionSchema = collectionSchema.omit({
692
+ var createCollectionSchema = collectionFileSchema.omit({
595
693
  id: true,
596
694
  objectType: true,
597
695
  created: true,
@@ -599,9 +697,10 @@ var createCollectionSchema = collectionSchema.omit({
599
697
  }).extend({
600
698
  projectId: uuidSchema.readonly()
601
699
  });
602
- var readCollectionSchema = z7.object({
700
+ var readCollectionSchema = z8.object({
603
701
  id: uuidSchema.readonly(),
604
- projectId: uuidSchema.readonly()
702
+ projectId: uuidSchema.readonly(),
703
+ commitHash: z8.string().optional().readonly()
605
704
  });
606
705
  var updateCollectionSchema = collectionFileSchema.pick({
607
706
  id: true,
@@ -614,149 +713,45 @@ var updateCollectionSchema = collectionFileSchema.pick({
614
713
  projectId: uuidSchema.readonly()
615
714
  });
616
715
  var deleteCollectionSchema = readCollectionSchema.extend({});
617
- var countCollectionsSchema = z7.object({
716
+ var countCollectionsSchema = z8.object({
618
717
  projectId: uuidSchema.readonly()
619
718
  });
620
719
 
621
720
  // src/schema/coreSchema.ts
622
- import { z as z8 } from "zod";
623
- var elekIoCoreOptionsSchema = z8.object({
624
- /**
625
- * The environment elek.io Core is currently running in
626
- */
627
- environment: environmentSchema,
628
- /**
629
- * The current version of elek.io Core
630
- */
631
- version: versionSchema,
632
- file: z8.object({
633
- json: z8.object({
634
- /**
635
- * If set, adds indentation with spaces (number) or escape character (string)
636
- * and line break characters to saved JSON files on disk, to make them easier to read.
637
- * Defaults to 2 spaces of indentation.
638
- */
639
- indentation: z8.union([z8.number(), z8.string()])
640
- })
641
- })
642
- });
643
- var constructorElekIoCoreSchema = elekIoCoreOptionsSchema.omit({
644
- version: true
645
- }).partial({
646
- environment: true,
647
- file: true
648
- }).optional();
649
-
650
- // src/schema/gitSchema.ts
651
721
  import { z as z9 } from "zod";
652
- var gitRepositoryPathSchema = z9.string();
653
- var gitSignatureSchema = z9.object({
654
- name: z9.string(),
655
- email: z9.string()
656
- });
657
- var gitCommitSchema = z9.object({
658
- /**
659
- * SHA-1 hash of the commit
660
- */
661
- hash: z9.string(),
662
- message: z9.string(),
663
- author: gitSignatureSchema,
664
- datetime: z9.string().datetime(),
665
- tag: z9.string().nullable()
666
- });
667
- var GitCommitIconNative = /* @__PURE__ */ ((GitCommitIconNative2) => {
668
- GitCommitIconNative2["INIT"] = ":tada:";
669
- GitCommitIconNative2["CREATE"] = ":heavy_plus_sign:";
670
- GitCommitIconNative2["UPDATE"] = ":wrench:";
671
- GitCommitIconNative2["DELETE"] = ":fire:";
672
- return GitCommitIconNative2;
673
- })(GitCommitIconNative || {});
674
- var gitCommitIconSchema = z9.nativeEnum(GitCommitIconNative);
675
- var gitInitOptionsSchema = z9.object({
676
- /**
677
- * Use the specified name for the initial branch in the newly created repository. If not specified, fall back to the default name (currently master, but this is subject to change in the future; the name can be customized via the init.defaultBranch configuration variable).
678
- */
679
- initialBranch: z9.string()
680
- });
681
- var gitCloneOptionsSchema = z9.object({
682
- /**
683
- * Create a shallow clone with a history truncated to the specified number of commits. Implies --single-branch unless --no-single-branch is given to fetch the histories near the tips of all branches. If you want to clone submodules shallowly, also pass --shallow-submodules.
684
- */
685
- depth: z9.number(),
686
- /**
687
- * Clone only the history leading to the tip of a single branch, either specified by the --branch option or the primary branch remote’s HEAD points at. Further fetches into the resulting repository will only update the remote-tracking branch for the branch this option was used for the initial cloning. If the HEAD at the remote did not point at any branch when --single-branch clone was made, no remote-tracking branch is created.
688
- */
689
- singleBranch: z9.boolean(),
690
- /**
691
- * Instead of pointing the newly created HEAD to the branch pointed to by the cloned repository’s HEAD, point to <name> branch instead. In a non-bare repository, this is the branch that will be checked out. --branch can also take tags and detaches the HEAD at that commit in the resulting repository.
692
- */
693
- branch: z9.string()
694
- });
695
- var gitSwitchOptionsSchema = z9.object({
696
- /**
697
- * If true, creates a new local branch and then switches to it
698
- *
699
- * @see https://git-scm.com/docs/git-switch#Documentation/git-switch.txt---createltnew-branchgt
700
- */
701
- isNew: z9.boolean().optional()
702
- });
703
- var gitLogOptionsSchema = z9.object({
704
- /**
705
- * Limit the result to given number of commits
706
- */
707
- limit: z9.number().optional(),
708
- /**
709
- * Only list commits that are between given SHAs or tag names
710
- *
711
- * Note that the commits of from and to are not included in the result
712
- */
713
- between: z9.object({
722
+ var elekIoCoreOptionsSchema = z9.object({
723
+ log: z9.object({
714
724
  /**
715
- * From the oldest commit
725
+ * The lowest level that should be logged
726
+ *
727
+ * @default 'info'
716
728
  */
717
- from: z9.string(),
729
+ level: logLevelSchema
730
+ }),
731
+ file: z9.object({
718
732
  /**
719
- * To the newest commit
733
+ * If set to true, caches files in memory to speed up access
720
734
  *
721
- * Defaults to the current HEAD
735
+ * @default true
722
736
  */
723
- to: z9.string().optional()
737
+ cache: z9.boolean()
724
738
  })
725
739
  });
726
-
727
- // src/schema/gitTagSchema.ts
728
- import { z as z10 } from "zod";
729
- var gitTagSchema = z10.object({
730
- id: uuidSchema,
731
- message: z10.string(),
732
- author: gitSignatureSchema,
733
- datetime: z10.string().datetime()
734
- });
735
- var createGitTagSchema = gitTagSchema.pick({
736
- message: true
737
- }).extend({
738
- path: gitRepositoryPathSchema,
739
- hash: gitCommitSchema.shape.hash.optional()
740
- });
741
- var readGitTagSchema = z10.object({
742
- path: gitRepositoryPathSchema,
743
- id: uuidSchema.readonly()
744
- });
745
- var deleteGitTagSchema = readGitTagSchema.extend({});
746
- var countGitTagsSchema = z10.object({
747
- path: gitRepositoryPathSchema
748
- });
740
+ var constructorElekIoCoreSchema = elekIoCoreOptionsSchema.partial({
741
+ log: true,
742
+ file: true
743
+ }).optional();
749
744
 
750
745
  // src/schema/projectSchema.ts
751
- import { z as z11 } from "zod";
752
- var projectStatusSchema = z11.enum(["foo", "bar", "todo"]);
753
- var projectSettingsSchema = z11.object({
754
- language: z11.object({
746
+ import { z as z10 } from "zod";
747
+ var projectStatusSchema = z10.enum(["foo", "bar", "todo"]);
748
+ var projectSettingsSchema = z10.object({
749
+ language: z10.object({
755
750
  default: supportedLanguageSchema,
756
- supported: z11.array(supportedLanguageSchema)
751
+ supported: z10.array(supportedLanguageSchema)
757
752
  })
758
753
  });
759
- var projectFolderSchema = z11.enum([
754
+ var projectFolderSchema = z10.enum([
760
755
  "assets",
761
756
  "collections",
762
757
  "shared-values",
@@ -765,19 +760,36 @@ var projectFolderSchema = z11.enum([
765
760
  // 'public',
766
761
  // 'theme',
767
762
  ]);
763
+ var projectBranchSchema = z10.enum(["production", "work"]);
768
764
  var projectFileSchema = baseFileSchema.extend({
769
- objectType: z11.literal(objectTypeSchema.Enum.project).readonly(),
765
+ objectType: z10.literal(objectTypeSchema.Enum.project).readonly(),
770
766
  coreVersion: versionSchema,
771
- name: z11.string().trim().min(1, "shared.projectNameRequired"),
772
- description: z11.string().trim().min(1, "shared.projectDescriptionRequired"),
767
+ name: z10.string().trim().min(1, "shared.projectNameRequired"),
768
+ description: z10.string().trim().min(1, "shared.projectDescriptionRequired"),
773
769
  version: versionSchema,
774
770
  status: projectStatusSchema,
775
771
  settings: projectSettingsSchema
776
772
  });
777
- var projectSchema = projectFileSchema.extend({});
773
+ var projectSchema = projectFileSchema.extend({
774
+ remoteOriginUrl: z10.string().nullable(),
775
+ /**
776
+ * Commit history of this Project
777
+ */
778
+ history: z10.array(gitCommitSchema),
779
+ /**
780
+ * Full commit history of this Project
781
+ * including all Assets, Collections, Entries and other files
782
+ */
783
+ fullHistory: z10.array(gitCommitSchema)
784
+ });
785
+ var outdatedProjectSchema = projectFileSchema.pick({
786
+ id: true,
787
+ name: true,
788
+ coreVersion: true
789
+ });
778
790
  var projectExportSchema = projectSchema.extend({
779
- assets: z11.array(assetExportSchema),
780
- collections: z11.array(collectionExportSchema)
791
+ assets: z10.array(assetExportSchema),
792
+ collections: z10.array(collectionExportSchema)
781
793
  });
782
794
  var createProjectSchema = projectSchema.pick({
783
795
  name: true,
@@ -787,8 +799,9 @@ var createProjectSchema = projectSchema.pick({
787
799
  description: true,
788
800
  settings: true
789
801
  });
790
- var readProjectSchema = z11.object({
791
- id: uuidSchema.readonly()
802
+ var readProjectSchema = z10.object({
803
+ id: uuidSchema.readonly(),
804
+ commitHash: z10.string().optional().readonly()
792
805
  });
793
806
  var updateProjectSchema = projectSchema.pick({
794
807
  id: true,
@@ -800,11 +813,17 @@ var updateProjectSchema = projectSchema.pick({
800
813
  description: true,
801
814
  settings: true
802
815
  });
803
- var upgradeProjectSchema = z11.object({
804
- id: uuidSchema.readonly()
816
+ var upgradeProjectSchema = z10.object({
817
+ id: uuidSchema.readonly(),
818
+ /**
819
+ * Force the upgrade even if the Project is up-to-date
820
+ */
821
+ force: z10.boolean().optional()
822
+ });
823
+ var deleteProjectSchema = readProjectSchema.extend({
824
+ force: z10.boolean().optional()
805
825
  });
806
- var deleteProjectSchema = readProjectSchema.extend({});
807
- var projectUpgradeSchema = z11.object({
826
+ var projectUpgradeSchema = z10.object({
808
827
  /**
809
828
  * The Core version the Project will be upgraded to
810
829
  */
@@ -812,45 +831,45 @@ var projectUpgradeSchema = z11.object({
812
831
  /**
813
832
  * Function that will be executed in the process of upgrading a Project
814
833
  */
815
- run: z11.function().args(projectFileSchema).returns(z11.promise(z11.void()))
834
+ run: z10.function().args(projectFileSchema).returns(z10.promise(z10.void()))
816
835
  });
817
- var cloneProjectSchema = z11.object({
818
- url: z11.string()
836
+ var cloneProjectSchema = z10.object({
837
+ url: z10.string()
819
838
  });
820
- var listBranchesProjectSchema = z11.object({
839
+ var listBranchesProjectSchema = z10.object({
821
840
  id: uuidSchema.readonly()
822
841
  });
823
- var currentBranchProjectSchema = z11.object({
842
+ var currentBranchProjectSchema = z10.object({
824
843
  id: uuidSchema.readonly()
825
844
  });
826
- var switchBranchProjectSchema = z11.object({
845
+ var switchBranchProjectSchema = z10.object({
827
846
  id: uuidSchema.readonly(),
828
- branch: z11.string(),
847
+ branch: z10.string(),
829
848
  options: gitSwitchOptionsSchema.optional()
830
849
  });
831
- var getRemoteOriginUrlProjectSchema = z11.object({
850
+ var getRemoteOriginUrlProjectSchema = z10.object({
832
851
  id: uuidSchema.readonly()
833
852
  });
834
- var setRemoteOriginUrlProjectSchema = z11.object({
853
+ var setRemoteOriginUrlProjectSchema = z10.object({
835
854
  id: uuidSchema.readonly(),
836
- url: z11.string()
855
+ url: z10.string()
837
856
  });
838
- var getChangesProjectSchema = z11.object({
857
+ var getChangesProjectSchema = z10.object({
839
858
  id: uuidSchema.readonly()
840
859
  });
841
- var synchronizeProjectSchema = z11.object({
860
+ var synchronizeProjectSchema = z10.object({
842
861
  id: uuidSchema.readonly()
843
862
  });
844
- var searchProjectSchema = z11.object({
863
+ var searchProjectSchema = z10.object({
845
864
  id: uuidSchema.readonly(),
846
- query: z11.string(),
865
+ query: z10.string(),
847
866
  language: supportedLanguageSchema,
848
- type: z11.array(objectTypeSchema).optional()
867
+ type: z10.array(objectTypeSchema).optional()
849
868
  });
850
869
 
851
870
  // src/schema/serviceSchema.ts
852
- import { z as z12 } from "zod";
853
- var serviceTypeSchema = z12.enum([
871
+ import { z as z11 } from "zod";
872
+ var serviceTypeSchema = z11.enum([
854
873
  "Git",
855
874
  "GitTag",
856
875
  "User",
@@ -862,10 +881,10 @@ var serviceTypeSchema = z12.enum([
862
881
  "Entry",
863
882
  "Value"
864
883
  ]);
865
- var listSchema = z12.object({
884
+ var listSchema = z11.object({
866
885
  projectId: uuidSchema,
867
- limit: z12.number().optional(),
868
- offset: z12.number().optional()
886
+ limit: z11.number().optional(),
887
+ offset: z11.number().optional()
869
888
  });
870
889
  var listCollectionsSchema = listSchema;
871
890
  var listEntriesSchema = listSchema.extend({
@@ -875,33 +894,33 @@ var listAssetsSchema = listSchema;
875
894
  var listProjectsSchema = listSchema.omit({
876
895
  projectId: true
877
896
  });
878
- var listGitTagsSchema = z12.object({
879
- path: gitRepositoryPathSchema
897
+ var listGitTagsSchema = z11.object({
898
+ path: z11.string()
880
899
  });
881
900
 
882
901
  // src/schema/userSchema.ts
883
- import z13 from "zod";
884
- var UserTypeSchema = z13.enum(["local", "cloud"]);
902
+ import z12 from "zod";
903
+ var UserTypeSchema = z12.enum(["local", "cloud"]);
885
904
  var baseUserSchema = gitSignatureSchema.extend({
886
905
  userType: UserTypeSchema,
887
906
  language: supportedLanguageSchema,
888
- window: z13.object({
889
- width: z13.number(),
890
- height: z13.number(),
891
- position: z13.object({
892
- x: z13.number(),
893
- y: z13.number()
907
+ window: z12.object({
908
+ width: z12.number(),
909
+ height: z12.number(),
910
+ position: z12.object({
911
+ x: z12.number(),
912
+ y: z12.number()
894
913
  })
895
914
  }).nullable()
896
915
  });
897
916
  var localUserSchema = baseUserSchema.extend({
898
- userType: z13.literal(UserTypeSchema.Enum.local)
917
+ userType: z12.literal(UserTypeSchema.Enum.local)
899
918
  });
900
919
  var cloudUserSchema = baseUserSchema.extend({
901
- userType: z13.literal(UserTypeSchema.Enum.cloud),
920
+ userType: z12.literal(UserTypeSchema.Enum.cloud),
902
921
  id: uuidSchema
903
922
  });
904
- var userFileSchema = z13.union([localUserSchema, cloudUserSchema]);
923
+ var userFileSchema = z12.union([localUserSchema, cloudUserSchema]);
905
924
  var userSchema = userFileSchema;
906
925
  var setUserSchema = userSchema;
907
926
 
@@ -940,17 +959,14 @@ var RequiredParameterMissingError = class extends Error {
940
959
  // src/util/node.ts
941
960
  var node_exports = {};
942
961
  __export(node_exports, {
943
- assignDefaultIfMissing: () => assignDefaultIfMissing,
944
962
  files: () => files,
945
963
  folders: () => folders,
946
964
  isNoError: () => isNoError,
947
965
  notEmpty: () => notEmpty,
948
966
  pathTo: () => pathTo,
949
967
  returnResolved: () => returnResolved,
950
- spawnChildProcess: () => spawnChildProcess,
951
968
  workingDirectory: () => workingDirectory
952
969
  });
953
- import { spawn } from "child_process";
954
970
  import Fs from "fs-extra";
955
971
  import Os from "os";
956
972
  import Path from "path";
@@ -958,7 +974,7 @@ var workingDirectory = Path.join(Os.homedir(), "elek.io");
958
974
  var pathTo = {
959
975
  tmp: Path.join(workingDirectory, "tmp"),
960
976
  userFile: Path.join(workingDirectory, "user.json"),
961
- // logs: Path.join(workingDirectory, 'logs'),
977
+ logs: Path.join(workingDirectory, "logs"),
962
978
  projects: Path.join(workingDirectory, "projects"),
963
979
  project: (projectId) => {
964
980
  return Path.join(pathTo.projects, projectId);
@@ -1010,11 +1026,11 @@ var pathTo = {
1010
1026
  },
1011
1027
  asset: (projectId, id, extension) => {
1012
1028
  return Path.join(pathTo.lfs(projectId), `${id}.${extension}`);
1029
+ },
1030
+ tmpAsset: (id, extension) => {
1031
+ return Path.join(pathTo.tmp, `${id}.${extension}`);
1013
1032
  }
1014
1033
  };
1015
- function assignDefaultIfMissing(value, defaultsTo) {
1016
- return Object.assign(defaultsTo, value);
1017
- }
1018
1034
  function notEmpty(value) {
1019
1035
  if (value === null || value === void 0) {
1020
1036
  return false;
@@ -1047,27 +1063,6 @@ async function returnResolved(promises) {
1047
1063
  const checked = await Promise.all(toCheck);
1048
1064
  return checked.filter(isNoError);
1049
1065
  }
1050
- function spawnChildProcess(command, args, options) {
1051
- return new Promise((resolve, reject) => {
1052
- const childProcess = spawn(command, args, options);
1053
- let log = "";
1054
- childProcess.stdout.on("data", (data) => {
1055
- log += data;
1056
- });
1057
- childProcess.stderr.on("data", (data) => {
1058
- log += data;
1059
- });
1060
- childProcess.on("error", (error) => {
1061
- throw error;
1062
- });
1063
- childProcess.on("exit", (code) => {
1064
- if (code === 0) {
1065
- return resolve(log);
1066
- }
1067
- return reject(log);
1068
- });
1069
- });
1070
- }
1071
1066
  async function folders(path) {
1072
1067
  const dirent = await Fs.readdir(path, { withFileTypes: true });
1073
1068
  return dirent.filter((dirent2) => {
@@ -1091,21 +1086,12 @@ async function files(path, extension) {
1091
1086
  var AbstractCrudService = class {
1092
1087
  type;
1093
1088
  options;
1094
- /**
1095
- * Dynamically generated git messages for operations
1096
- */
1097
- gitMessage;
1098
1089
  /**
1099
1090
  * Do not instantiate directly as this is an abstract class
1100
1091
  */
1101
1092
  constructor(type, options) {
1102
1093
  this.type = type;
1103
1094
  this.options = options;
1104
- this.gitMessage = {
1105
- create: `${gitCommitIconSchema.enum.CREATE} Created ${this.type}`,
1106
- update: `${gitCommitIconSchema.enum.UPDATE} Updated ${this.type}`,
1107
- delete: `${gitCommitIconSchema.enum.DELETE} Deleted ${this.type}`
1108
- };
1109
1095
  }
1110
1096
  /**
1111
1097
  * Returns a list of all file references of given project and type
@@ -1165,8 +1151,7 @@ var AbstractCrudService = class {
1165
1151
  * Searches for all files inside given folder,
1166
1152
  * parses their names and returns them as FileReference
1167
1153
  *
1168
- * Ignores files not matching the [id].[language].[extension]
1169
- * or [id].[extension] format for their names
1154
+ * Ignores files if the extension is not supported.
1170
1155
  */
1171
1156
  async getFileReferences(path) {
1172
1157
  const possibleFiles = await files(path);
@@ -1174,9 +1159,8 @@ var AbstractCrudService = class {
1174
1159
  possibleFiles.map(async (possibleFile) => {
1175
1160
  const fileNameArray = possibleFile.name.split(".");
1176
1161
  const fileReference = {
1177
- id: fileNameArray[0] || "",
1178
- language: fileNameArray.length === 3 ? fileNameArray[1] : void 0,
1179
- extension: fileNameArray.length === 2 ? fileNameArray[1] : fileNameArray[2]
1162
+ id: fileNameArray[0],
1163
+ extension: fileNameArray[1]
1180
1164
  };
1181
1165
  try {
1182
1166
  return fileReferenceSchema.parse(fileReference);
@@ -1190,9 +1174,8 @@ var AbstractCrudService = class {
1190
1174
  };
1191
1175
 
1192
1176
  // src/service/AssetService.ts
1193
- import { fileTypeFromFile } from "file-type";
1194
1177
  import Fs2 from "fs-extra";
1195
- import isSvg from "is-svg";
1178
+ import mime from "mime";
1196
1179
 
1197
1180
  // src/util/shared.ts
1198
1181
  import slugify from "@sindresorhus/slugify";
@@ -1216,10 +1199,13 @@ function slug(string) {
1216
1199
 
1217
1200
  // src/service/AssetService.ts
1218
1201
  var AssetService = class extends AbstractCrudService {
1202
+ // @ts-ignore
1203
+ logService;
1219
1204
  jsonFileService;
1220
1205
  gitService;
1221
- constructor(options, jsonFileService, gitService) {
1206
+ constructor(options, logService, jsonFileService, gitService) {
1222
1207
  super(serviceTypeSchema.Enum.Asset, options);
1208
+ this.logService = logService;
1223
1209
  this.jsonFileService = jsonFileService;
1224
1210
  this.gitService = gitService;
1225
1211
  }
@@ -1230,12 +1216,13 @@ var AssetService = class extends AbstractCrudService {
1230
1216
  createAssetSchema.parse(props);
1231
1217
  const id = uuid();
1232
1218
  const projectPath = pathTo.project(props.projectId);
1233
- const fileType = await this.getSupportedFileTypeOrThrow(props.filePath);
1234
- const size = await this.getAssetSize(props.filePath);
1219
+ const fileType = this.getFileType(props.filePath);
1220
+ const size = await this.getFileSize(props.filePath);
1235
1221
  const assetPath = pathTo.asset(props.projectId, id, fileType.extension);
1236
1222
  const assetFilePath = pathTo.assetFile(props.projectId, id);
1237
1223
  const assetFile = {
1238
1224
  ...props,
1225
+ name: slug(props.name),
1239
1226
  objectType: "asset",
1240
1227
  id,
1241
1228
  created: datetime(),
@@ -1256,19 +1243,56 @@ var AssetService = class extends AbstractCrudService {
1256
1243
  throw error;
1257
1244
  }
1258
1245
  await this.gitService.add(projectPath, [assetFilePath, assetPath]);
1259
- await this.gitService.commit(projectPath, this.gitMessage.create);
1246
+ await this.gitService.commit(projectPath, {
1247
+ method: "create",
1248
+ reference: { objectType: "asset", id }
1249
+ });
1260
1250
  return this.toAsset(props.projectId, assetFile);
1261
1251
  }
1262
1252
  /**
1263
1253
  * Returns an Asset by ID
1254
+ *
1255
+ * If a commit hash is provided, the Asset is read from history
1264
1256
  */
1265
1257
  async read(props) {
1266
1258
  readAssetSchema.parse(props);
1267
- const assetFile = await this.jsonFileService.read(
1268
- pathTo.assetFile(props.projectId, props.id),
1269
- assetFileSchema
1270
- );
1271
- return this.toAsset(props.projectId, assetFile);
1259
+ if (!props.commitHash) {
1260
+ const assetFile = await this.jsonFileService.read(
1261
+ pathTo.assetFile(props.projectId, props.id),
1262
+ assetFileSchema
1263
+ );
1264
+ return this.toAsset(props.projectId, assetFile);
1265
+ } else {
1266
+ const assetFile = this.migrate(
1267
+ JSON.parse(
1268
+ await this.gitService.getFileContentAtCommit(
1269
+ pathTo.project(props.projectId),
1270
+ pathTo.assetFile(props.projectId, props.id),
1271
+ props.commitHash
1272
+ )
1273
+ )
1274
+ );
1275
+ const assetBlob = await this.gitService.getFileContentAtCommit(
1276
+ pathTo.project(props.projectId),
1277
+ pathTo.asset(props.projectId, props.id, assetFile.extension),
1278
+ props.commitHash,
1279
+ "binary"
1280
+ );
1281
+ await Fs2.writeFile(
1282
+ pathTo.tmpAsset(assetFile.id, assetFile.extension),
1283
+ assetBlob,
1284
+ "binary"
1285
+ );
1286
+ return this.toAsset(props.projectId, assetFile, true);
1287
+ }
1288
+ }
1289
+ /**
1290
+ * Copies an Asset to given file path on disk
1291
+ */
1292
+ async save(props) {
1293
+ saveAssetSchema.parse(props);
1294
+ const asset = await this.read(props);
1295
+ await Fs2.copyFile(asset.absolutePath, props.filePath);
1272
1296
  }
1273
1297
  /**
1274
1298
  * Updates given Asset
@@ -1283,13 +1307,12 @@ var AssetService = class extends AbstractCrudService {
1283
1307
  const assetFile = {
1284
1308
  ...prevAssetFile,
1285
1309
  ...props,
1310
+ name: slug(props.name),
1286
1311
  updated: datetime()
1287
1312
  };
1288
1313
  if (props.newFilePath) {
1289
- const fileType = await this.getSupportedFileTypeOrThrow(
1290
- props.newFilePath
1291
- );
1292
- const size = await this.getAssetSize(props.newFilePath);
1314
+ const fileType = this.getFileType(props.newFilePath);
1315
+ const size = await this.getFileSize(props.newFilePath);
1293
1316
  const prevAssetPath = pathTo.asset(
1294
1317
  props.projectId,
1295
1318
  props.id,
@@ -1302,6 +1325,7 @@ var AssetService = class extends AbstractCrudService {
1302
1325
  );
1303
1326
  await Fs2.remove(prevAssetPath);
1304
1327
  await Fs2.copyFile(props.newFilePath, assetPath);
1328
+ await this.gitService.add(projectPath, [prevAssetPath, assetPath]);
1305
1329
  assetFile.extension = fileType.extension;
1306
1330
  assetFile.mimeType = fileType.mimeType;
1307
1331
  assetFile.size = size;
@@ -1312,7 +1336,10 @@ var AssetService = class extends AbstractCrudService {
1312
1336
  assetFileSchema
1313
1337
  );
1314
1338
  await this.gitService.add(projectPath, [assetFilePath]);
1315
- await this.gitService.commit(projectPath, this.gitMessage.update);
1339
+ await this.gitService.commit(projectPath, {
1340
+ method: "update",
1341
+ reference: { objectType: "asset", id: assetFile.id }
1342
+ });
1316
1343
  return this.toAsset(props.projectId, assetFile);
1317
1344
  }
1318
1345
  /**
@@ -1326,7 +1353,10 @@ var AssetService = class extends AbstractCrudService {
1326
1353
  await Fs2.remove(assetPath);
1327
1354
  await Fs2.remove(assetFilePath);
1328
1355
  await this.gitService.add(projectPath, [assetFilePath, assetPath]);
1329
- await this.gitService.commit(projectPath, this.gitMessage.delete);
1356
+ await this.gitService.commit(projectPath, {
1357
+ method: "delete",
1358
+ reference: { objectType: "asset", id: props.id }
1359
+ });
1330
1360
  }
1331
1361
  async list(props) {
1332
1362
  listAssetsSchema.parse(props);
@@ -1364,11 +1394,11 @@ var AssetService = class extends AbstractCrudService {
1364
1394
  return assetSchema.safeParse(obj).success;
1365
1395
  }
1366
1396
  /**
1367
- * Returns the size of an Asset in bytes
1397
+ * Returns the size of an file in bytes
1368
1398
  *
1369
- * @param path Path of the Asset to get the size from
1399
+ * @param path Path of the file to get the size from
1370
1400
  */
1371
- async getAssetSize(path) {
1401
+ async getFileSize(path) {
1372
1402
  return (await Fs2.stat(path)).size;
1373
1403
  }
1374
1404
  /**
@@ -1377,15 +1407,15 @@ var AssetService = class extends AbstractCrudService {
1377
1407
  * @param projectId The project's ID
1378
1408
  * @param assetFile The AssetFile to convert
1379
1409
  */
1380
- async toAsset(projectId, assetFile) {
1381
- const assetPath = pathTo.asset(
1382
- projectId,
1383
- assetFile.id,
1384
- assetFile.extension
1385
- );
1410
+ async toAsset(projectId, assetFile, isFromHistory = false) {
1411
+ const assetPath = isFromHistory === false ? pathTo.asset(projectId, assetFile.id, assetFile.extension) : pathTo.tmpAsset(assetFile.id, assetFile.extension);
1412
+ const history = await this.gitService.log(pathTo.project(projectId), {
1413
+ filePath: pathTo.assetFile(projectId, assetFile.id)
1414
+ });
1386
1415
  const asset = {
1387
1416
  ...assetFile,
1388
- absolutePath: assetPath
1417
+ absolutePath: assetPath,
1418
+ history
1389
1419
  };
1390
1420
  return asset;
1391
1421
  }
@@ -1395,23 +1425,27 @@ var AssetService = class extends AbstractCrudService {
1395
1425
  *
1396
1426
  * @param filePath Path to the file to check
1397
1427
  */
1398
- async getSupportedFileTypeOrThrow(filePath) {
1399
- const fileSize = (await Fs2.stat(filePath)).size;
1400
- if (fileSize / 1e3 <= 500) {
1401
- const fileBuffer = await Fs2.readFile(filePath);
1402
- if (isSvg(fileBuffer.toString()) === true) {
1403
- return {
1404
- extension: supportedAssetExtensionSchema.Enum.svg,
1405
- mimeType: supportedAssetMimeTypeSchema.Enum["image/svg+xml"]
1406
- };
1407
- }
1428
+ getFileType(filePath) {
1429
+ const mimeType = mime.getType(filePath);
1430
+ if (mimeType === null) {
1431
+ throw new Error(`Unsupported MIME type of file "${filePath}"`);
1408
1432
  }
1409
- const fileType = await fileTypeFromFile(filePath);
1410
- const result = supportedAssetTypeSchema.parse({
1411
- extension: fileType?.ext,
1412
- mimeType: fileType?.mime
1413
- });
1414
- return result;
1433
+ const extension = mime.getExtension(mimeType);
1434
+ if (extension === null) {
1435
+ throw new Error(
1436
+ `Unsupported extension for MIME type "${mimeType}" of file "${filePath}"`
1437
+ );
1438
+ }
1439
+ return {
1440
+ extension,
1441
+ mimeType
1442
+ };
1443
+ }
1444
+ /**
1445
+ * Migrates an potentially outdated Asset file to the current schema
1446
+ */
1447
+ migrate(potentiallyOutdatedAssetFile) {
1448
+ return assetFileSchema.parse(potentiallyOutdatedAssetFile);
1415
1449
  }
1416
1450
  };
1417
1451
 
@@ -1452,19 +1486,37 @@ var CollectionService = class extends AbstractCrudService {
1452
1486
  collectionFileSchema
1453
1487
  );
1454
1488
  await this.gitService.add(projectPath, [collectionFilePath]);
1455
- await this.gitService.commit(projectPath, this.gitMessage.create);
1456
- return collectionFile;
1489
+ await this.gitService.commit(projectPath, {
1490
+ method: "create",
1491
+ reference: { objectType: "collection", id }
1492
+ });
1493
+ return this.toCollection(props.projectId, collectionFile);
1457
1494
  }
1458
1495
  /**
1459
1496
  * Returns a Collection by ID
1497
+ *
1498
+ * If a commit hash is provided, the Collection is read from history
1460
1499
  */
1461
1500
  async read(props) {
1462
1501
  readCollectionSchema.parse(props);
1463
- const collection = await this.jsonFileService.read(
1464
- pathTo.collectionFile(props.projectId, props.id),
1465
- collectionFileSchema
1466
- );
1467
- return collection;
1502
+ if (!props.commitHash) {
1503
+ const collectionFile = await this.jsonFileService.read(
1504
+ pathTo.collectionFile(props.projectId, props.id),
1505
+ collectionFileSchema
1506
+ );
1507
+ return this.toCollection(props.projectId, collectionFile);
1508
+ } else {
1509
+ const collectionFile = this.migrate(
1510
+ JSON.parse(
1511
+ await this.gitService.getFileContentAtCommit(
1512
+ pathTo.project(props.projectId),
1513
+ pathTo.collectionFile(props.projectId, props.id),
1514
+ props.commitHash
1515
+ )
1516
+ )
1517
+ );
1518
+ return this.toCollection(props.projectId, collectionFile);
1519
+ }
1468
1520
  }
1469
1521
  /**
1470
1522
  * Updates given Collection
@@ -1492,8 +1544,11 @@ var CollectionService = class extends AbstractCrudService {
1492
1544
  collectionFileSchema
1493
1545
  );
1494
1546
  await this.gitService.add(projectPath, [collectionFilePath]);
1495
- await this.gitService.commit(projectPath, this.gitMessage.update);
1496
- return collectionFile;
1547
+ await this.gitService.commit(projectPath, {
1548
+ method: "update",
1549
+ reference: { objectType: "collection", id: collectionFile.id }
1550
+ });
1551
+ return this.toCollection(props.projectId, collectionFile);
1497
1552
  }
1498
1553
  /**
1499
1554
  * Deletes given Collection (folder), including it's items
@@ -1506,7 +1561,10 @@ var CollectionService = class extends AbstractCrudService {
1506
1561
  const collectionPath = pathTo.collection(props.projectId, props.id);
1507
1562
  await Fs3.remove(collectionPath);
1508
1563
  await this.gitService.add(projectPath, [collectionPath]);
1509
- await this.gitService.commit(projectPath, this.gitMessage.delete);
1564
+ await this.gitService.commit(projectPath, {
1565
+ method: "delete",
1566
+ reference: { objectType: "collection", id: props.id }
1567
+ });
1510
1568
  }
1511
1569
  async list(props) {
1512
1570
  listCollectionsSchema.parse(props);
@@ -1549,18 +1607,42 @@ var CollectionService = class extends AbstractCrudService {
1549
1607
  isCollection(obj) {
1550
1608
  return collectionFileSchema.safeParse(obj).success;
1551
1609
  }
1610
+ /**
1611
+ * Migrates an potentially outdated Collection file to the current schema
1612
+ */
1613
+ migrate(potentiallyOutdatedCollectionFile) {
1614
+ return collectionFileSchema.parse(potentiallyOutdatedCollectionFile);
1615
+ }
1616
+ /**
1617
+ * Creates an Collection from given CollectionFile
1618
+ *
1619
+ * @param projectId The project's ID
1620
+ * @param collectionFile The CollectionFile to convert
1621
+ */
1622
+ async toCollection(projectId, collectionFile) {
1623
+ const history = await this.gitService.log(pathTo.project(projectId), {
1624
+ filePath: pathTo.collectionFile(projectId, collectionFile.id)
1625
+ });
1626
+ const collection = {
1627
+ ...collectionFile,
1628
+ history
1629
+ };
1630
+ return collection;
1631
+ }
1552
1632
  };
1553
1633
 
1554
1634
  // src/service/EntryService.ts
1555
1635
  import Fs4 from "fs-extra";
1556
1636
  var EntryService = class extends AbstractCrudService {
1637
+ logService;
1557
1638
  jsonFileService;
1558
1639
  gitService;
1559
1640
  collectionService;
1560
1641
  assetService;
1561
1642
  // private sharedValueService: SharedValueService;
1562
- constructor(options, jsonFileService, gitService, collectionService, assetService) {
1643
+ constructor(options, logService, jsonFileService, gitService, collectionService, assetService) {
1563
1644
  super(serviceTypeSchema.Enum.Entry, options);
1645
+ this.logService = logService;
1564
1646
  this.jsonFileService = jsonFileService;
1565
1647
  this.gitService = gitService;
1566
1648
  this.collectionService = collectionService;
@@ -1589,11 +1671,11 @@ var EntryService = class extends AbstractCrudService {
1589
1671
  created: datetime(),
1590
1672
  updated: null
1591
1673
  };
1592
- const entry = await this.toEntry({
1593
- projectId: props.projectId,
1594
- collectionId: props.collectionId,
1674
+ const entry = await this.toEntry(
1675
+ props.projectId,
1676
+ props.collectionId,
1595
1677
  entryFile
1596
- });
1678
+ );
1597
1679
  this.validateValues({
1598
1680
  collectionId: props.collectionId,
1599
1681
  fieldDefinitions: collection.fieldDefinitions,
@@ -1605,23 +1687,41 @@ var EntryService = class extends AbstractCrudService {
1605
1687
  entryFileSchema
1606
1688
  );
1607
1689
  await this.gitService.add(projectPath, [entryFilePath]);
1608
- await this.gitService.commit(projectPath, this.gitMessage.create);
1690
+ await this.gitService.commit(projectPath, {
1691
+ method: "create",
1692
+ reference: {
1693
+ objectType: "entry",
1694
+ id: entryFile.id,
1695
+ collectionId: props.collectionId
1696
+ }
1697
+ });
1609
1698
  return entry;
1610
1699
  }
1611
1700
  /**
1612
- * Returns an Entry from given Collection by ID and language
1701
+ * Returns an Entry from given Collection by ID
1702
+ *
1703
+ * If a commit hash is provided, the Entry is read from history
1613
1704
  */
1614
1705
  async read(props) {
1615
1706
  readEntrySchema.parse(props);
1616
- const entryFile = await this.jsonFileService.read(
1617
- pathTo.entryFile(props.projectId, props.collectionId, props.id),
1618
- entryFileSchema
1619
- );
1620
- return await this.toEntry({
1621
- projectId: props.projectId,
1622
- collectionId: props.collectionId,
1623
- entryFile
1624
- });
1707
+ if (!props.commitHash) {
1708
+ const entryFile = await this.jsonFileService.read(
1709
+ pathTo.entryFile(props.projectId, props.collectionId, props.id),
1710
+ entryFileSchema
1711
+ );
1712
+ return this.toEntry(props.projectId, props.collectionId, entryFile);
1713
+ } else {
1714
+ const entryFile = this.migrate(
1715
+ JSON.parse(
1716
+ await this.gitService.getFileContentAtCommit(
1717
+ pathTo.project(props.projectId),
1718
+ pathTo.entryFile(props.projectId, props.collectionId, props.id),
1719
+ props.commitHash
1720
+ )
1721
+ )
1722
+ );
1723
+ return this.toEntry(props.projectId, props.collectionId, entryFile);
1724
+ }
1625
1725
  }
1626
1726
  /**
1627
1727
  * Updates an Entry of given Collection with new Values and shared Values
@@ -1648,11 +1748,11 @@ var EntryService = class extends AbstractCrudService {
1648
1748
  values: props.values,
1649
1749
  updated: datetime()
1650
1750
  };
1651
- const entry = await this.toEntry({
1652
- projectId: props.projectId,
1653
- collectionId: props.collectionId,
1751
+ const entry = await this.toEntry(
1752
+ props.projectId,
1753
+ props.collectionId,
1654
1754
  entryFile
1655
- });
1755
+ );
1656
1756
  this.validateValues({
1657
1757
  collectionId: props.collectionId,
1658
1758
  fieldDefinitions: collection.fieldDefinitions,
@@ -1664,7 +1764,14 @@ var EntryService = class extends AbstractCrudService {
1664
1764
  entryFileSchema
1665
1765
  );
1666
1766
  await this.gitService.add(projectPath, [entryFilePath]);
1667
- await this.gitService.commit(projectPath, this.gitMessage.update);
1767
+ await this.gitService.commit(projectPath, {
1768
+ method: "update",
1769
+ reference: {
1770
+ objectType: "entry",
1771
+ id: entryFile.id,
1772
+ collectionId: props.collectionId
1773
+ }
1774
+ });
1668
1775
  return entry;
1669
1776
  }
1670
1777
  /**
@@ -1680,7 +1787,14 @@ var EntryService = class extends AbstractCrudService {
1680
1787
  );
1681
1788
  await Fs4.remove(entryFilePath);
1682
1789
  await this.gitService.add(projectPath, [entryFilePath]);
1683
- await this.gitService.commit(projectPath, this.gitMessage.delete);
1790
+ await this.gitService.commit(projectPath, {
1791
+ method: "delete",
1792
+ reference: {
1793
+ objectType: "entry",
1794
+ id: props.id,
1795
+ collectionId: props.collectionId
1796
+ }
1797
+ });
1684
1798
  }
1685
1799
  async list(props) {
1686
1800
  listEntriesSchema.parse(props);
@@ -1722,6 +1836,12 @@ var EntryService = class extends AbstractCrudService {
1722
1836
  isEntry(obj) {
1723
1837
  return entrySchema.safeParse(obj).success;
1724
1838
  }
1839
+ /**
1840
+ * Migrates an potentially outdated Entry file to the current schema
1841
+ */
1842
+ migrate(potentiallyOutdatedEntryFile) {
1843
+ return entryFileSchema.parse(potentiallyOutdatedEntryFile);
1844
+ }
1725
1845
  /**
1726
1846
  * Returns a Field definition by ID
1727
1847
  */
@@ -1750,14 +1870,16 @@ var EntryService = class extends AbstractCrudService {
1750
1870
  id: value.fieldDefinitionId
1751
1871
  });
1752
1872
  const contentSchema = getValueContentSchemaFromFieldDefinition(fieldDefinition);
1753
- try {
1754
- for (const [_language, content] of Object.entries(value.content)) {
1755
- contentSchema.parse(content);
1873
+ this.logService.debug(
1874
+ "Validating Value against content schema generated from Field definition",
1875
+ {
1876
+ value,
1877
+ contentSchema,
1878
+ fieldDefinition
1756
1879
  }
1757
- } catch (error) {
1758
- console.log("Definition:", fieldDefinition);
1759
- console.log("Value:", value);
1760
- throw error;
1880
+ );
1881
+ for (const [_language, content] of Object.entries(value.content)) {
1882
+ contentSchema.parse(content);
1761
1883
  }
1762
1884
  });
1763
1885
  }
@@ -1827,16 +1949,20 @@ var EntryService = class extends AbstractCrudService {
1827
1949
  /**
1828
1950
  * Creates an Entry from given EntryFile by resolving it's Values
1829
1951
  */
1830
- async toEntry(props) {
1952
+ async toEntry(projectId, collectionId, entryFile) {
1953
+ const history = await this.gitService.log(pathTo.project(projectId), {
1954
+ filePath: pathTo.entryFile(projectId, collectionId, entryFile.id)
1955
+ });
1831
1956
  return {
1832
- ...props.entryFile,
1957
+ ...entryFile,
1958
+ history,
1833
1959
  // @ts-ignore @todo fixme - I have no idea why this happens. The types seem to be compatible to me and they work
1834
1960
  values: await Promise.all(
1835
- props.entryFile.values.map(async (value) => {
1961
+ entryFile.values.map(async (value) => {
1836
1962
  if (value.valueType === ValueTypeSchema.Enum.reference) {
1837
1963
  const resolvedContentReferences = await this.resolveValueContentReferences({
1838
- projectId: props.projectId,
1839
- collectionId: props.collectionId,
1964
+ projectId,
1965
+ collectionId,
1840
1966
  valueReference: value
1841
1967
  });
1842
1968
  return {
@@ -1853,11 +1979,10 @@ var EntryService = class extends AbstractCrudService {
1853
1979
 
1854
1980
  // src/service/GitService.ts
1855
1981
  import { GitProcess } from "dugite";
1856
- import { EOL as EOL2 } from "os";
1857
1982
  import PQueue from "p-queue";
1983
+ import Path2 from "path";
1858
1984
 
1859
1985
  // src/service/GitTagService.ts
1860
- import { EOL } from "os";
1861
1986
  var GitTagService = class extends AbstractCrudService {
1862
1987
  git;
1863
1988
  constructor(options, git) {
@@ -1940,7 +2065,7 @@ var GitTagService = class extends AbstractCrudService {
1940
2065
  "--format=%(refname:short)|%(subject)|%(*authorname)|%(*authoremail)|%(*authordate:iso-strict)"
1941
2066
  ];
1942
2067
  const result = await this.git(props.path, args);
1943
- const noEmptyLinesArr = result.stdout.split(EOL).filter((line) => {
2068
+ const noEmptyLinesArr = result.stdout.split("\n").filter((line) => {
1944
2069
  return line.trim() !== "";
1945
2070
  });
1946
2071
  const lineObjArr = noEmptyLinesArr.map((line) => {
@@ -1991,16 +2116,18 @@ var GitService = class {
1991
2116
  version;
1992
2117
  gitPath;
1993
2118
  queue;
2119
+ logService;
1994
2120
  gitTagService;
1995
2121
  userService;
1996
- constructor(options, userService) {
2122
+ constructor(options, logService, userService) {
1997
2123
  this.version = null;
1998
2124
  this.gitPath = null;
1999
2125
  this.queue = new PQueue({
2000
2126
  concurrency: 1
2001
2127
  // No concurrency because git operations are sequencial
2002
2128
  });
2003
- this.gitTagService = new GitTagService(options, this.git);
2129
+ this.gitTagService = new GitTagService(options, this.git.bind(this));
2130
+ this.logService = logService;
2004
2131
  this.userService = userService;
2005
2132
  this.updateVersion();
2006
2133
  this.updateGitPath();
@@ -2026,7 +2153,6 @@ var GitService = class {
2026
2153
  }
2027
2154
  await this.git(path, args);
2028
2155
  await this.setLocalConfig(path);
2029
- await this.installLfs(path);
2030
2156
  }
2031
2157
  /**
2032
2158
  * Clone a repository into a directory
@@ -2042,6 +2168,9 @@ var GitService = class {
2042
2168
  */
2043
2169
  async clone(url, path, options) {
2044
2170
  let args = ["clone", "--progress"];
2171
+ if (options?.bare) {
2172
+ args = [...args, "--bare"];
2173
+ }
2045
2174
  if (options?.branch) {
2046
2175
  args = [...args, "--branch", options.branch];
2047
2176
  }
@@ -2063,9 +2192,25 @@ var GitService = class {
2063
2192
  * @param files Files to add
2064
2193
  */
2065
2194
  async add(path, files2) {
2066
- const args = ["add", "--", ...files2];
2195
+ const relativePathsFromRepositoryRoot = files2.map((filePath) => {
2196
+ return filePath.replace(`${path}${Path2.sep}`, "");
2197
+ });
2198
+ const args = ["add", "--", ...relativePathsFromRepositoryRoot];
2067
2199
  await this.git(path, args);
2068
2200
  }
2201
+ async status(path) {
2202
+ const args = ["status", "--porcelain=2"];
2203
+ const result = await this.git(path, args);
2204
+ const normalizedLinesArr = result.stdout.split("\n").filter((line) => {
2205
+ return line.trim() !== "";
2206
+ }).map((line) => {
2207
+ const lineArr = line.trim().split(" ");
2208
+ return {
2209
+ filePath: lineArr[8]
2210
+ };
2211
+ });
2212
+ return normalizedLinesArr;
2213
+ }
2069
2214
  branches = {
2070
2215
  /**
2071
2216
  * List branches
@@ -2077,7 +2222,7 @@ var GitService = class {
2077
2222
  list: async (path) => {
2078
2223
  const args = ["branch", "--list", "--all"];
2079
2224
  const result = await this.git(path, args);
2080
- const normalizedLinesArr = result.stdout.split(EOL2).filter((line) => {
2225
+ const normalizedLinesArr = result.stdout.split("\n").filter((line) => {
2081
2226
  return line.trim() !== "";
2082
2227
  }).map((line) => {
2083
2228
  return line.trim().replace("* ", "");
@@ -2126,6 +2271,21 @@ var GitService = class {
2126
2271
  args = [...args, branch];
2127
2272
  }
2128
2273
  await this.git(path, args);
2274
+ },
2275
+ /**
2276
+ * Delete a branch
2277
+ *
2278
+ * @see https://git-scm.com/docs/git-branch#Documentation/git-branch.txt---delete
2279
+ *
2280
+ * @param path Path to the repository
2281
+ * @param branch Name of the branch to delete
2282
+ */
2283
+ delete: async (path, branch, force) => {
2284
+ let args = ["branch", "--delete"];
2285
+ if (force === true) {
2286
+ args = [...args, "--force"];
2287
+ }
2288
+ await this.git(path, [...args, branch]);
2129
2289
  }
2130
2290
  };
2131
2291
  remotes = {
@@ -2139,7 +2299,7 @@ var GitService = class {
2139
2299
  list: async (path) => {
2140
2300
  const args = ["remote"];
2141
2301
  const result = await this.git(path, args);
2142
- const normalizedLinesArr = result.stdout.split(EOL2).filter((line) => {
2302
+ const normalizedLinesArr = result.stdout.split("\n").filter((line) => {
2143
2303
  return line.trim() !== "";
2144
2304
  });
2145
2305
  return normalizedLinesArr;
@@ -2166,7 +2326,7 @@ var GitService = class {
2166
2326
  * @param path Path to the repository
2167
2327
  */
2168
2328
  addOrigin: async (path, url) => {
2169
- const args = ["remote", "add", "origin", url];
2329
+ const args = ["remote", "add", "origin", url.trim()];
2170
2330
  await this.git(path, args);
2171
2331
  },
2172
2332
  /**
@@ -2193,10 +2353,23 @@ var GitService = class {
2193
2353
  * @param path Path to the repository
2194
2354
  */
2195
2355
  setOriginUrl: async (path, url) => {
2196
- const args = ["remote", "set-url", "origin", url];
2356
+ const args = ["remote", "set-url", "origin", url.trim()];
2197
2357
  await this.git(path, args);
2198
2358
  }
2199
2359
  };
2360
+ /**
2361
+ * Join two development histories together
2362
+ *
2363
+ * @see https://git-scm.com/docs/git-merge
2364
+ */
2365
+ async merge(path, branch, options) {
2366
+ let args = ["merge"];
2367
+ if (options?.squash === true) {
2368
+ args = [...args, "--squash"];
2369
+ }
2370
+ args = [...args, branch];
2371
+ await this.git(path, args);
2372
+ }
2200
2373
  /**
2201
2374
  * Reset current HEAD to the specified state
2202
2375
  *
@@ -2278,16 +2451,17 @@ var GitService = class {
2278
2451
  * @see https://git-scm.com/docs/git-commit
2279
2452
  *
2280
2453
  * @param path Path to the repository
2281
- * @param message A message that describes the changes
2454
+ * @param message An object describing the changes
2282
2455
  */
2283
2456
  async commit(path, message) {
2457
+ gitMessageSchema.parse(message);
2284
2458
  const user = await this.userService.get();
2285
2459
  if (!user) {
2286
2460
  throw new NoCurrentUserError();
2287
2461
  }
2288
2462
  const args = [
2289
2463
  "commit",
2290
- `--message=${message}`,
2464
+ `--message=${JSON.stringify(message)}`,
2291
2465
  `--author=${user.name} <${user.email}>`
2292
2466
  ];
2293
2467
  await this.git(path, args);
@@ -2314,28 +2488,54 @@ var GitService = class {
2314
2488
  if (options?.limit) {
2315
2489
  args = [...args, `--max-count=${options.limit}`];
2316
2490
  }
2317
- const result = await this.git(path, [
2318
- ...args,
2319
- "--format=%H|%s|%an|%ae|%aI|%D"
2320
- ]);
2321
- const noEmptyLinesArr = result.stdout.split(EOL2).filter((line) => {
2491
+ args = [...args, "--format=%H|%s|%an|%ae|%aI|%D"];
2492
+ if (options?.filePath) {
2493
+ args = [...args, "--", options.filePath];
2494
+ }
2495
+ const result = await this.git(path, args);
2496
+ const noEmptyLinesArr = result.stdout.split("\n").filter((line) => {
2322
2497
  return line.trim() !== "";
2323
2498
  });
2324
- const lineObjArr = noEmptyLinesArr.map((line) => {
2325
- const lineArray = line.split("|");
2326
- return {
2327
- hash: lineArray[0],
2328
- message: lineArray[1],
2329
- author: {
2330
- name: lineArray[2],
2331
- email: lineArray[3]
2332
- },
2333
- datetime: datetime(lineArray[4]),
2334
- tag: this.refNameToTagName(lineArray[5] || "")
2335
- };
2336
- });
2499
+ const lineObjArr = await Promise.all(
2500
+ noEmptyLinesArr.map(async (line) => {
2501
+ const lineArray = line.split("|");
2502
+ const tagId = this.refNameToTagName(lineArray[5] || "");
2503
+ const tag = tagId ? await this.tags.read({ path, id: tagId }) : null;
2504
+ return {
2505
+ hash: lineArray[0],
2506
+ message: JSON.parse(lineArray[1] || ""),
2507
+ author: {
2508
+ name: lineArray[2],
2509
+ email: lineArray[3]
2510
+ },
2511
+ datetime: datetime(lineArray[4]),
2512
+ tag
2513
+ };
2514
+ })
2515
+ );
2337
2516
  return lineObjArr.filter(this.isGitCommit.bind(this));
2338
2517
  }
2518
+ /**
2519
+ * Retrieves the content of a file at a specific commit
2520
+ *
2521
+ * @see https://git-scm.com/docs/git-show
2522
+ */
2523
+ async getFileContentAtCommit(path, filePath, commitHash, encoding = "utf8") {
2524
+ const relativePathFromRepositoryRoot = filePath.replace(
2525
+ `${path}${Path2.sep}`,
2526
+ ""
2527
+ );
2528
+ const normalizedPath = relativePathFromRepositoryRoot.split("\\").join("/");
2529
+ const args = ["show", `${commitHash}:${normalizedPath}`];
2530
+ const setEncoding = (cb) => {
2531
+ if (cb.stdout) {
2532
+ cb.stdout.setEncoding(encoding);
2533
+ }
2534
+ };
2535
+ return (await this.git(path, args, {
2536
+ processCallback: setEncoding
2537
+ })).stdout;
2538
+ }
2339
2539
  refNameToTagName(refName) {
2340
2540
  const tagName = refName.replace("tag: ", "").trim();
2341
2541
  if (tagName === "" || uuidSchema.safeParse(tagName).success === false) {
@@ -2375,16 +2575,6 @@ var GitService = class {
2375
2575
  async checkBranchOrTagName(path, name) {
2376
2576
  await this.git(path, ["check-ref-format", "--allow-onelevel", name]);
2377
2577
  }
2378
- /**
2379
- * Installs LFS support and starts tracking
2380
- * all files inside the lfs folder
2381
- *
2382
- * @param path Path to the repository
2383
- */
2384
- async installLfs(path) {
2385
- await this.git(path, ["lfs", "install"]);
2386
- await this.git(path, ["lfs", "track", "lfs/*"]);
2387
- }
2388
2578
  /**
2389
2579
  * Sets the git config of given local repository from ElekIoCoreOptions
2390
2580
  *
@@ -2422,31 +2612,37 @@ var GitService = class {
2422
2612
  * @param path Path to the repository
2423
2613
  * @param args Arguments to append after the `git` command
2424
2614
  */
2425
- async git(path, args) {
2426
- const result = await this.queue.add(
2427
- () => GitProcess.exec(args, path, {
2428
- env: {
2429
- // @todo Nasty stuff - remove after update to dugite with git > v2.45.2 once available
2430
- // @see https://github.com/git-lfs/git-lfs/issues/5749
2431
- GIT_CLONE_PROTECTION_ACTIVE: "false"
2432
- }
2433
- })
2434
- );
2615
+ async git(path, args, options) {
2616
+ const result = await this.queue.add(async () => {
2617
+ const start = Date.now();
2618
+ const gitResult = await GitProcess.exec(args, path, options);
2619
+ const durationMs = Date.now() - start;
2620
+ return {
2621
+ gitResult,
2622
+ durationMs
2623
+ };
2624
+ });
2435
2625
  if (!result) {
2436
2626
  throw new GitError(
2437
2627
  `Git ${this.version} (${this.gitPath}) command "git ${args.join(
2438
2628
  " "
2439
- )}" failed to return a result`
2629
+ )}" executed for "${path}" failed to return a result`
2440
2630
  );
2441
2631
  }
2442
- if (result.exitCode !== 0) {
2632
+ const gitLog = `Executed "git ${args.join(" ")}" in ${result.durationMs}ms`;
2633
+ if (result.durationMs >= 100) {
2634
+ this.logService.warn(gitLog);
2635
+ } else {
2636
+ this.logService.debug(gitLog);
2637
+ }
2638
+ if (result.gitResult.exitCode !== 0) {
2443
2639
  throw new GitError(
2444
2640
  `Git ${this.version} (${this.gitPath}) command "git ${args.join(
2445
2641
  " "
2446
- )}" failed with exit code "${result.exitCode}" and message "${result.stderr}"`
2642
+ )}" executed for "${path}" failed with exit code "${result.gitResult.exitCode}" and message "${result.gitResult.stderr.trim() || result.gitResult.stdout.trim()}"`
2447
2643
  );
2448
2644
  }
2449
- return result;
2645
+ return result.gitResult;
2450
2646
  }
2451
2647
  };
2452
2648
 
@@ -2454,8 +2650,10 @@ var GitService = class {
2454
2650
  import Fs5 from "fs-extra";
2455
2651
  var JsonFileService = class extends AbstractCrudService {
2456
2652
  cache = /* @__PURE__ */ new Map();
2457
- constructor(options) {
2653
+ logService;
2654
+ constructor(options, logService) {
2458
2655
  super(serviceTypeSchema.Enum.JsonFile, options);
2656
+ this.logService = logService;
2459
2657
  }
2460
2658
  /**
2461
2659
  * Creates a new file on disk. Fails if path already exists
@@ -2472,7 +2670,8 @@ var JsonFileService = class extends AbstractCrudService {
2472
2670
  flag: "wx",
2473
2671
  encoding: "utf8"
2474
2672
  });
2475
- this.cache.set(path, parsedData);
2673
+ this.options.file.cache === true && this.cache.set(path, parsedData);
2674
+ this.logService.debug(`Created file "${path}"`);
2476
2675
  return parsedData;
2477
2676
  }
2478
2677
  /**
@@ -2483,18 +2682,43 @@ var JsonFileService = class extends AbstractCrudService {
2483
2682
  * @returns Validated content of the file from disk
2484
2683
  */
2485
2684
  async read(path, schema) {
2486
- if (this.cache.has(path)) {
2487
- return this.cache.get(path);
2685
+ if (this.options.file.cache === true && this.cache.has(path)) {
2686
+ this.logService.debug(`Cache hit reading file "${path}"`);
2687
+ const json2 = this.cache.get(path);
2688
+ const parsedData2 = schema.parse(json2);
2689
+ return parsedData2;
2488
2690
  }
2691
+ this.logService.debug(`Cache miss reading file "${path}"`);
2489
2692
  const data = await Fs5.readFile(path, {
2490
2693
  flag: "r",
2491
2694
  encoding: "utf8"
2492
2695
  });
2493
2696
  const json = this.deserialize(data);
2494
2697
  const parsedData = schema.parse(json);
2495
- this.cache.set(path, parsedData);
2698
+ this.options.file.cache === true && this.cache.set(path, parsedData);
2496
2699
  return parsedData;
2497
2700
  }
2701
+ /**
2702
+ * Reads the content of a file on disk. Fails if path does not exist.
2703
+ * Does not validate the content of the file against a schema and
2704
+ * therefore is only to be used when retrieving data we do not have
2705
+ * a current schema for. E.g. reading from history or while upgrading
2706
+ * the old schema of a file to a new, current schema.
2707
+ *
2708
+ * Does not read from or write to cache.
2709
+ *
2710
+ * @param path Path to read the file from
2711
+ * @returns Unvalidated content of the file from disk
2712
+ */
2713
+ async unsafeRead(path) {
2714
+ this.logService.warn(`Unsafe reading of file "${path}"`);
2715
+ const data = await Fs5.readFile(path, {
2716
+ flag: "r",
2717
+ encoding: "utf8"
2718
+ });
2719
+ const json = this.deserialize(data);
2720
+ return json;
2721
+ }
2498
2722
  /**
2499
2723
  * Overwrites an existing file on disk
2500
2724
  *
@@ -2512,31 +2736,118 @@ var JsonFileService = class extends AbstractCrudService {
2512
2736
  flag: "w",
2513
2737
  encoding: "utf8"
2514
2738
  });
2515
- this.cache.set(path, parsedData);
2739
+ this.options.file.cache === true && this.cache.set(path, parsedData);
2740
+ this.logService.debug(`Updated file "${path}"`);
2516
2741
  return parsedData;
2517
2742
  }
2518
2743
  serialize(data) {
2519
- return JSON.stringify(data, null, this.options.file.json.indentation);
2744
+ return JSON.stringify(data, null, 2);
2520
2745
  }
2521
2746
  deserialize(data) {
2522
2747
  return JSON.parse(data);
2523
2748
  }
2524
2749
  };
2525
2750
 
2751
+ // src/service/LogService.ts
2752
+ import Path3 from "path";
2753
+ import {
2754
+ createLogger,
2755
+ format,
2756
+ transports
2757
+ } from "winston";
2758
+ import DailyRotateFile from "winston-daily-rotate-file";
2759
+ var LogService = class {
2760
+ logger;
2761
+ constructor(options) {
2762
+ const rotatingFileTransport = new DailyRotateFile({
2763
+ filename: Path3.join(pathTo.logs, "core-%DATE%.log"),
2764
+ datePattern: "YYYY-MM-DD",
2765
+ zippedArchive: true,
2766
+ maxFiles: "30d",
2767
+ handleExceptions: true,
2768
+ handleRejections: true,
2769
+ format: format.combine(format.timestamp(), format.json())
2770
+ });
2771
+ this.logger = createLogger({
2772
+ level: options.log.level,
2773
+ transports: [
2774
+ rotatingFileTransport,
2775
+ new transports.Console({
2776
+ handleExceptions: true,
2777
+ handleRejections: true,
2778
+ format: format.combine(
2779
+ format.colorize(),
2780
+ format.timestamp({ format: "YYYY-MM-DD HH:mm:ss" }),
2781
+ format.printf((info) => {
2782
+ return `${info.level} [${info["timestamp"]}]: ${info.message}`;
2783
+ })
2784
+ )
2785
+ })
2786
+ ]
2787
+ });
2788
+ rotatingFileTransport.on("rotate", (oldFilename, newFilename) => {
2789
+ this.logger.info(
2790
+ `Rotated log file from ${oldFilename} to ${newFilename}`
2791
+ );
2792
+ });
2793
+ }
2794
+ debug(message, ...meta) {
2795
+ this.logger.debug(message, ...meta);
2796
+ }
2797
+ info(message, ...meta) {
2798
+ this.logger.info(message, ...meta);
2799
+ }
2800
+ warn(message, ...meta) {
2801
+ this.logger.warn(message, ...meta);
2802
+ }
2803
+ error(message, ...meta) {
2804
+ this.logger.error(message, ...meta);
2805
+ }
2806
+ read(options) {
2807
+ return this.logger.query(options);
2808
+ }
2809
+ };
2810
+
2526
2811
  // src/service/ProjectService.ts
2527
2812
  import Fs6 from "fs-extra";
2528
2813
  import Os2 from "os";
2529
- import Path2 from "path";
2814
+ import Path4 from "path";
2530
2815
  import Semver from "semver";
2816
+
2817
+ // src/error/RemoteOriginMissingError.ts
2818
+ var RemoteOriginMissingError = class extends Error {
2819
+ constructor(projectId) {
2820
+ super(
2821
+ `Tried to delete Project "${projectId}" but it does not have a remote origin. Deleting a Project without a remote origin could lead to data loss. Use the "force" option to delete it anyway.`
2822
+ );
2823
+ this.name = "RemoteOriginMissingError";
2824
+ }
2825
+ };
2826
+
2827
+ // src/error/SynchronizeLocalChangesError.ts
2828
+ var SynchronizeLocalChangesError = class extends Error {
2829
+ constructor(projectId) {
2830
+ super(
2831
+ `Tried to delete Project "${projectId}" but it has local changes that are not yet pushed to the remote origin. Deleting a Project with local changes could lead to data loss. Use the "force" option to delete it anyway.`
2832
+ );
2833
+ this.name = "SynchronizeLocalChangesError";
2834
+ }
2835
+ };
2836
+
2837
+ // src/service/ProjectService.ts
2531
2838
  var ProjectService = class extends AbstractCrudService {
2839
+ coreVersion;
2840
+ logService;
2532
2841
  jsonFileService;
2533
2842
  userService;
2534
2843
  gitService;
2535
2844
  assetService;
2536
2845
  collectionService;
2537
2846
  entryService;
2538
- constructor(options, jsonFileService, userService, gitService, assetService, collectionService, entryService) {
2847
+ constructor(coreVersion, options, logService, jsonFileService, userService, gitService, assetService, collectionService, entryService) {
2539
2848
  super(serviceTypeSchema.Enum.Project, options);
2849
+ this.coreVersion = coreVersion;
2850
+ this.logService = logService;
2540
2851
  this.jsonFileService = jsonFileService;
2541
2852
  this.userService = userService;
2542
2853
  this.gitService = gitService;
@@ -2568,8 +2879,7 @@ var ProjectService = class extends AbstractCrudService {
2568
2879
  settings: Object.assign({}, defaultSettings, props.settings),
2569
2880
  created: datetime(),
2570
2881
  updated: null,
2571
- coreVersion: this.options.version,
2572
- // @todo should be read from package.json to avoid duplicates
2882
+ coreVersion: this.coreVersion,
2573
2883
  status: "todo",
2574
2884
  version: "0.0.1"
2575
2885
  };
@@ -2578,29 +2888,34 @@ var ProjectService = class extends AbstractCrudService {
2578
2888
  try {
2579
2889
  await this.createFolderStructure(projectPath);
2580
2890
  await this.createGitignore(projectPath);
2581
- await this.gitService.init(projectPath, { initialBranch: "main" });
2891
+ await this.gitService.init(projectPath, {
2892
+ initialBranch: projectBranchSchema.Enum.production
2893
+ });
2582
2894
  await this.jsonFileService.create(
2583
2895
  projectFile,
2584
2896
  pathTo.projectFile(id),
2585
2897
  projectFileSchema
2586
2898
  );
2587
2899
  await this.gitService.add(projectPath, ["."]);
2588
- await this.gitService.commit(
2900
+ await this.gitService.commit(projectPath, {
2901
+ method: "create",
2902
+ reference: { objectType: "project", id }
2903
+ });
2904
+ await this.gitService.branches.switch(
2589
2905
  projectPath,
2590
- `${gitCommitIconSchema.enum.INIT} Created this new elek.io project`
2906
+ projectBranchSchema.Enum.work,
2907
+ {
2908
+ isNew: true
2909
+ }
2591
2910
  );
2592
- await this.gitService.branches.switch(projectPath, "stage", {
2593
- isNew: true
2594
- });
2595
2911
  } catch (error) {
2596
2912
  await this.delete({
2597
- id
2913
+ id,
2914
+ force: true
2598
2915
  });
2599
2916
  throw error;
2600
2917
  }
2601
- return await this.toProject({
2602
- projectFile
2603
- });
2918
+ return await this.toProject(projectFile);
2604
2919
  }
2605
2920
  /**
2606
2921
  * Clones a Project by URL
@@ -2608,10 +2923,10 @@ var ProjectService = class extends AbstractCrudService {
2608
2923
  async clone(props) {
2609
2924
  cloneProjectSchema.parse(props);
2610
2925
  const tmpId = uuid();
2611
- const tmpProjectPath = Path2.join(pathTo.tmp, tmpId);
2926
+ const tmpProjectPath = Path4.join(pathTo.tmp, tmpId);
2612
2927
  await this.gitService.clone(props.url, tmpProjectPath);
2613
2928
  const projectFile = await this.jsonFileService.read(
2614
- Path2.join(tmpProjectPath, "project.json"),
2929
+ Path4.join(tmpProjectPath, "project.json"),
2615
2930
  projectFileSchema
2616
2931
  );
2617
2932
  const projectPath = pathTo.project(projectFile.id);
@@ -2623,22 +2938,33 @@ var ProjectService = class extends AbstractCrudService {
2623
2938
  }
2624
2939
  await Fs6.copy(tmpProjectPath, projectPath);
2625
2940
  await Fs6.remove(tmpProjectPath);
2626
- return await this.toProject({
2627
- projectFile
2628
- });
2941
+ return await this.toProject(projectFile);
2629
2942
  }
2630
2943
  /**
2631
2944
  * Returns a Project by ID
2945
+ *
2946
+ * If a commit hash is provided, the Project is read from history
2632
2947
  */
2633
2948
  async read(props) {
2634
2949
  readProjectSchema.parse(props);
2635
- const projectFile = await this.jsonFileService.read(
2636
- pathTo.projectFile(props.id),
2637
- projectFileSchema
2638
- );
2639
- return await this.toProject({
2640
- projectFile
2641
- });
2950
+ if (!props.commitHash) {
2951
+ const projectFile = await this.jsonFileService.read(
2952
+ pathTo.projectFile(props.id),
2953
+ projectFileSchema
2954
+ );
2955
+ return await this.toProject(projectFile);
2956
+ } else {
2957
+ const projectFile = this.migrate(
2958
+ JSON.parse(
2959
+ await this.gitService.getFileContentAtCommit(
2960
+ pathTo.project(props.id),
2961
+ pathTo.projectFile(props.id),
2962
+ props.commitHash
2963
+ )
2964
+ )
2965
+ );
2966
+ return await this.toProject(projectFile);
2967
+ }
2642
2968
  }
2643
2969
  /**
2644
2970
  * Updates given Project
@@ -2652,6 +2978,7 @@ var ProjectService = class extends AbstractCrudService {
2652
2978
  ...prevProjectFile,
2653
2979
  name: props.name || prevProjectFile.name,
2654
2980
  description: props.description || prevProjectFile.description,
2981
+ coreVersion: this.coreVersion,
2655
2982
  settings: {
2656
2983
  language: {
2657
2984
  supported: props.settings?.language.supported || prevProjectFile.settings.language.supported,
@@ -2662,83 +2989,131 @@ var ProjectService = class extends AbstractCrudService {
2662
2989
  };
2663
2990
  await this.jsonFileService.update(projectFile, filePath, projectFileSchema);
2664
2991
  await this.gitService.add(projectPath, [filePath]);
2665
- await this.gitService.commit(projectPath, this.gitMessage.update);
2666
- return await this.toProject({
2667
- projectFile
2992
+ await this.gitService.commit(projectPath, {
2993
+ method: "update",
2994
+ reference: { objectType: "project", id: projectFile.id }
2668
2995
  });
2996
+ return await this.toProject(projectFile);
2669
2997
  }
2670
2998
  /**
2671
- * Upgrades given Project to the latest version of this client
2672
- *
2673
- * Needed when a new core version is requiring changes to existing files or structure.
2999
+ * Upgrades given Project to the current version of Core
2674
3000
  *
2675
- * @todo Find out why using this.snapshotService is throwing isObjWithKeyAndValueOfString of undefined error in gitService (maybe binding issue)
3001
+ * Needed when a new Core version is requiring changes to existing files or structure.
2676
3002
  */
2677
3003
  async upgrade(props) {
2678
3004
  upgradeProjectSchema.parse(props);
2679
- const project = await this.read(props);
2680
- const projectPath = pathTo.project(project.id);
2681
- if (Semver.gt(project.coreVersion, this.options.version)) {
2682
- throw new Error(
2683
- `Failed upgrading project. The projects core version "${project.coreVersion}" is higher than the current core version "${this.options.version}" of this client. A client upgrade is needed beforehand.`
3005
+ const projectPath = pathTo.project(props.id);
3006
+ const projectFilePath = pathTo.projectFile(props.id);
3007
+ const currentBranch = await this.gitService.branches.current(projectPath);
3008
+ if (currentBranch !== projectBranchSchema.Enum.work) {
3009
+ await this.gitService.branches.switch(
3010
+ projectPath,
3011
+ projectBranchSchema.Enum.work
2684
3012
  );
2685
3013
  }
2686
- if (Semver.eq(project.coreVersion, this.options.version)) {
2687
- return;
3014
+ const currentProjectFile = outdatedProjectSchema.passthrough().parse(await this.jsonFileService.unsafeRead(projectFilePath));
3015
+ if (Semver.gt(currentProjectFile.coreVersion, this.coreVersion)) {
3016
+ throw new ProjectUpgradeError(
3017
+ `The Projects Core version "${currentProjectFile.coreVersion}" is higher than the current Core version "${this.coreVersion}".`
3018
+ );
3019
+ }
3020
+ if (Semver.eq(currentProjectFile.coreVersion, this.coreVersion) && props.force !== true) {
3021
+ throw new ProjectUpgradeError(
3022
+ `The Projects Core version "${currentProjectFile.coreVersion}" is already up to date.`
3023
+ );
2688
3024
  }
2689
- const upgradeFiles = await files(
2690
- Path2.resolve(__dirname, "../upgrade"),
2691
- "ts"
3025
+ const assetReferences = await this.listReferences("asset", props.id);
3026
+ const collectionReferences = await this.listReferences(
3027
+ "collection",
3028
+ props.id
2692
3029
  );
2693
- const upgrades = (await Promise.all(
2694
- upgradeFiles.map((file) => {
2695
- return import(Path2.join("../upgrade", file.name));
2696
- })
2697
- )).map((upgradeImport) => {
2698
- return upgradeImport.default;
2699
- });
2700
- const sortedUpgrades = upgrades.sort((a, b) => {
2701
- return Semver.compare(a.to, b.to);
2702
- }).filter((upgrade) => {
2703
- if (upgrade.to !== "0.0.0") {
2704
- return upgrade;
2705
- }
2706
- return;
3030
+ this.logService.info(
3031
+ `Attempting to upgrade Project "${props.id}" from Core version ${currentProjectFile.coreVersion} to ${this.coreVersion}`
3032
+ );
3033
+ const upgradeBranchName = `upgrade/core-${currentProjectFile.coreVersion}-to-${this.coreVersion}`;
3034
+ await this.gitService.branches.switch(projectPath, upgradeBranchName, {
3035
+ isNew: true
2707
3036
  });
2708
- for (let index = 0; index < sortedUpgrades.length; index++) {
2709
- const upgrade = sortedUpgrades[index];
2710
- if (!upgrade) {
2711
- throw new Error("Expected ProjectUpgrade but got undefined");
2712
- }
2713
- const failsafeTag = await this.gitService.tags.create({
3037
+ try {
3038
+ await Promise.all(
3039
+ assetReferences.map(async (reference) => {
3040
+ await this.upgradeObjectFile(props.id, "asset", reference);
3041
+ })
3042
+ );
3043
+ await Promise.all(
3044
+ collectionReferences.map(async (reference) => {
3045
+ await this.upgradeObjectFile(props.id, "collection", reference);
3046
+ })
3047
+ );
3048
+ await Promise.all(
3049
+ collectionReferences.map(async (collectionReference) => {
3050
+ const entryReferences = await this.listReferences(
3051
+ "entry",
3052
+ props.id,
3053
+ collectionReference.id
3054
+ );
3055
+ await Promise.all(
3056
+ entryReferences.map(async (reference) => {
3057
+ await this.upgradeObjectFile(
3058
+ props.id,
3059
+ "entry",
3060
+ reference,
3061
+ collectionReference.id
3062
+ );
3063
+ })
3064
+ );
3065
+ })
3066
+ );
3067
+ const migratedProjectFile = this.migrate(currentProjectFile);
3068
+ await this.update(migratedProjectFile);
3069
+ await this.gitService.branches.switch(
3070
+ projectPath,
3071
+ projectBranchSchema.Enum.work
3072
+ );
3073
+ await this.gitService.merge(projectPath, upgradeBranchName, {
3074
+ squash: true
3075
+ });
3076
+ await this.gitService.commit(projectPath, {
3077
+ method: "upgrade",
3078
+ reference: { objectType: "project", id: migratedProjectFile.id }
3079
+ });
3080
+ await this.gitService.tags.create({
2714
3081
  path: projectPath,
2715
- message: `Attempting to upgrade Project to Core version "${upgrade.to}"`
3082
+ message: `Upgraded Project to Core version ${migratedProjectFile.coreVersion}`
2716
3083
  });
2717
- try {
2718
- await upgrade.run(project);
2719
- project.coreVersion = upgrade.to;
2720
- await this.update(project);
2721
- await this.gitService.tags.create({
2722
- path: projectPath,
2723
- message: `Upgraded Project to Core version "${upgrade.to}"`
2724
- });
2725
- await this.gitService.tags.delete({
2726
- path: projectPath,
2727
- id: failsafeTag.id
2728
- });
2729
- } catch (error) {
2730
- await this.gitService.reset(projectPath, "hard", failsafeTag.id);
2731
- throw new ProjectUpgradeError(
2732
- `Failed to upgrade Project to Core version "${upgrade.to}"`
2733
- );
2734
- }
3084
+ await this.gitService.branches.delete(
3085
+ projectPath,
3086
+ upgradeBranchName,
3087
+ true
3088
+ );
3089
+ this.logService.info(
3090
+ `Upgraded Project "${projectFilePath}" to Core version "${this.coreVersion}"`,
3091
+ {
3092
+ previous: currentProjectFile,
3093
+ migrated: migratedProjectFile
3094
+ }
3095
+ );
3096
+ } catch (error) {
3097
+ await this.gitService.branches.switch(
3098
+ projectPath,
3099
+ projectBranchSchema.Enum.work
3100
+ );
3101
+ await this.gitService.branches.delete(
3102
+ projectPath,
3103
+ upgradeBranchName,
3104
+ true
3105
+ );
3106
+ throw error;
2735
3107
  }
2736
3108
  }
2737
3109
  branches = {
2738
3110
  list: async (props) => {
2739
3111
  listBranchesProjectSchema.parse(props);
2740
3112
  const projectPath = pathTo.project(props.id);
2741
- await this.gitService.fetch(projectPath);
3113
+ const hasOrigin = await this.gitService.remotes.hasOrigin(projectPath);
3114
+ if (hasOrigin) {
3115
+ await this.gitService.fetch(projectPath);
3116
+ }
2742
3117
  return await this.gitService.branches.list(projectPath);
2743
3118
  },
2744
3119
  current: async (props) => {
@@ -2756,33 +3131,37 @@ var ProjectService = class extends AbstractCrudService {
2756
3131
  );
2757
3132
  }
2758
3133
  };
2759
- remotes = {
2760
- getOriginUrl: async (props) => {
2761
- getRemoteOriginUrlProjectSchema.parse(props);
2762
- const projectPath = pathTo.project(props.id);
2763
- return await this.gitService.remotes.getOriginUrl(projectPath);
2764
- },
2765
- setOriginUrl: async (props) => {
2766
- setRemoteOriginUrlProjectSchema.parse(props);
2767
- const projectPath = pathTo.project(props.id);
2768
- const hasOrigin = await this.gitService.remotes.hasOrigin(projectPath);
2769
- if (!hasOrigin) {
2770
- await this.gitService.remotes.addOrigin(projectPath, props.url);
2771
- } else {
2772
- await this.gitService.remotes.setOriginUrl(projectPath, props.url);
2773
- }
3134
+ /**
3135
+ * Updates the remote origin URL of given Project
3136
+ */
3137
+ async setRemoteOriginUrl(props) {
3138
+ setRemoteOriginUrlProjectSchema.parse(props);
3139
+ const projectPath = pathTo.project(props.id);
3140
+ const hasOrigin = await this.gitService.remotes.hasOrigin(projectPath);
3141
+ if (!hasOrigin) {
3142
+ await this.gitService.remotes.addOrigin(projectPath, props.url);
3143
+ } else {
3144
+ await this.gitService.remotes.setOriginUrl(projectPath, props.url);
2774
3145
  }
2775
- };
3146
+ }
2776
3147
  /**
2777
3148
  * Returns the differences of the given Projects current branch
2778
3149
  * between the local and remote `origin` (commits ahead & behind)
2779
3150
  *
3151
+ * Throws an error if the Project does not have a remote origin.
3152
+ *
2780
3153
  * - `behind` contains a list of commits on the current branch that are available on the remote `origin` but not yet locally
2781
3154
  * - `ahead` contains a list of commits on the current branch that are available locally but not yet on the remote `origin`
2782
3155
  */
2783
3156
  async getChanges(props) {
2784
3157
  getChangesProjectSchema.parse(props);
2785
3158
  const projectPath = pathTo.project(props.id);
3159
+ const hasRemoteOrigin = await this.gitService.remotes.hasOrigin(
3160
+ projectPath
3161
+ );
3162
+ if (hasRemoteOrigin === false) {
3163
+ throw new Error(`Project "${props.id}" does not have a remote origin`);
3164
+ }
2786
3165
  const currentBranch = await this.gitService.branches.current(projectPath);
2787
3166
  await this.gitService.fetch(projectPath);
2788
3167
  const behind = await this.gitService.log(projectPath, {
@@ -2810,13 +3189,46 @@ var ProjectService = class extends AbstractCrudService {
2810
3189
  * Deletes given Project
2811
3190
  *
2812
3191
  * Deletes the whole Project folder including the history, not only the config file.
2813
- * Use with caution, since a Project that is only available locally could be lost forever.
2814
- * Or changes that are not pushed to a remote yet, will be lost too.
3192
+ * Throws in case a Project is only available locally and could be lost forever,
3193
+ * or changes are not pushed to a remote yet.
2815
3194
  */
2816
3195
  async delete(props) {
2817
3196
  deleteProjectSchema.parse(props);
3197
+ const hasRemoteOrigin = await this.gitService.remotes.hasOrigin(
3198
+ pathTo.project(props.id)
3199
+ );
3200
+ if (hasRemoteOrigin === false && props.force !== true) {
3201
+ throw new RemoteOriginMissingError(props.id);
3202
+ }
3203
+ if (hasRemoteOrigin === true && props.force !== true) {
3204
+ const changes = await this.getChanges({ id: props.id });
3205
+ if (changes.ahead.length > 0) {
3206
+ throw new SynchronizeLocalChangesError(props.id);
3207
+ }
3208
+ }
2818
3209
  await Fs6.remove(pathTo.project(props.id));
2819
3210
  }
3211
+ /**
3212
+ * Lists outdated Projects that need to be upgraded
3213
+ */
3214
+ async listOutdated() {
3215
+ const projectReferences = await this.listReferences(
3216
+ objectTypeSchema.Enum.project
3217
+ );
3218
+ const result = await Promise.all(
3219
+ projectReferences.map(async (reference) => {
3220
+ const json = await this.jsonFileService.unsafeRead(
3221
+ pathTo.projectFile(reference.id)
3222
+ );
3223
+ const projectFile = outdatedProjectSchema.parse(json);
3224
+ if (projectFile.coreVersion !== this.coreVersion) {
3225
+ return projectFile;
3226
+ }
3227
+ return null;
3228
+ })
3229
+ );
3230
+ return result.filter(notEmpty);
3231
+ }
2820
3232
  async list(props) {
2821
3233
  if (props) {
2822
3234
  listProjectsSchema.parse(props);
@@ -2879,11 +3291,32 @@ var ProjectService = class extends AbstractCrudService {
2879
3291
  };
2880
3292
  }
2881
3293
  /**
2882
- * Creates a Project from given ProjectFile by adding git information
3294
+ * Migrates an potentially outdated Project file to the current schema
3295
+ */
3296
+ migrate(potentiallyOutdatedProjectFile) {
3297
+ return projectFileSchema.parse(potentiallyOutdatedProjectFile);
3298
+ }
3299
+ /**
3300
+ * Creates a Project from given ProjectFile
2883
3301
  */
2884
- async toProject(props) {
3302
+ async toProject(projectFile) {
3303
+ const projectPath = pathTo.project(projectFile.id);
3304
+ let remoteOriginUrl = null;
3305
+ const hasOrigin = await this.gitService.remotes.hasOrigin(projectPath);
3306
+ if (hasOrigin) {
3307
+ remoteOriginUrl = await this.gitService.remotes.getOriginUrl(projectPath);
3308
+ }
3309
+ const fullHistory = await this.gitService.log(
3310
+ pathTo.project(projectFile.id)
3311
+ );
3312
+ const history = await this.gitService.log(pathTo.project(projectFile.id), {
3313
+ filePath: pathTo.projectFile(projectFile.id)
3314
+ });
2885
3315
  return {
2886
- ...props.projectFile
3316
+ ...projectFile,
3317
+ remoteOriginUrl,
3318
+ history,
3319
+ fullHistory
2887
3320
  };
2888
3321
  }
2889
3322
  /**
@@ -2895,8 +3328,8 @@ var ProjectService = class extends AbstractCrudService {
2895
3328
  const folders2 = Object.values(projectFolderSchema.Values);
2896
3329
  await Promise.all(
2897
3330
  folders2.map(async (folder) => {
2898
- await Fs6.mkdirp(Path2.join(path, folder));
2899
- await Fs6.writeFile(Path2.join(path, folder, ".gitkeep"), "");
3331
+ await Fs6.mkdirp(Path4.join(path, folder));
3332
+ await Fs6.writeFile(Path4.join(path, folder, ".gitkeep"), "");
2900
3333
  })
2901
3334
  );
2902
3335
  }
@@ -2920,14 +3353,80 @@ var ProjectService = class extends AbstractCrudService {
2920
3353
  // projectFolderSchema.Enum.public + '/',
2921
3354
  // projectFolderSchema.Enum.logs + '/',
2922
3355
  ];
2923
- await Fs6.writeFile(Path2.join(path, ".gitignore"), lines.join(Os2.EOL));
3356
+ await Fs6.writeFile(Path4.join(path, ".gitignore"), lines.join(Os2.EOL));
3357
+ }
3358
+ async upgradeObjectFile(projectId, objectType, reference, collectionId) {
3359
+ switch (objectType) {
3360
+ case "asset": {
3361
+ const assetFilePath = pathTo.assetFile(projectId, reference.id);
3362
+ const prevAssetFile = await this.jsonFileService.unsafeRead(
3363
+ assetFilePath
3364
+ );
3365
+ const migratedAssetFile = this.assetService.migrate(prevAssetFile);
3366
+ await this.assetService.update({ projectId, ...migratedAssetFile });
3367
+ this.logService.info(`Upgraded ${objectType} "${assetFilePath}"`, {
3368
+ previous: prevAssetFile,
3369
+ migrated: migratedAssetFile
3370
+ });
3371
+ return;
3372
+ }
3373
+ case "collection": {
3374
+ const collectionFilePath = pathTo.collectionFile(
3375
+ projectId,
3376
+ reference.id
3377
+ );
3378
+ const prevCollectionFile = await this.jsonFileService.unsafeRead(
3379
+ collectionFilePath
3380
+ );
3381
+ const migratedCollectionFile = this.collectionService.migrate(prevCollectionFile);
3382
+ await this.collectionService.update({
3383
+ projectId,
3384
+ ...migratedCollectionFile
3385
+ });
3386
+ this.logService.info(`Upgraded ${objectType} "${collectionFilePath}"`, {
3387
+ previous: prevCollectionFile,
3388
+ migrated: migratedCollectionFile
3389
+ });
3390
+ return;
3391
+ }
3392
+ case "entry": {
3393
+ if (!collectionId) {
3394
+ throw new RequiredParameterMissingError("collectionId");
3395
+ }
3396
+ const entryFilePath = pathTo.entryFile(
3397
+ projectId,
3398
+ collectionId,
3399
+ reference.id
3400
+ );
3401
+ const prevEntryFile = await this.jsonFileService.unsafeRead(
3402
+ entryFilePath
3403
+ );
3404
+ const migratedEntryFile = this.entryService.migrate(prevEntryFile);
3405
+ await this.entryService.update({
3406
+ projectId,
3407
+ collectionId,
3408
+ ...migratedEntryFile
3409
+ });
3410
+ this.logService.info(`Upgraded ${objectType} "${entryFilePath}"`, {
3411
+ previous: prevEntryFile,
3412
+ migrated: migratedEntryFile
3413
+ });
3414
+ return;
3415
+ }
3416
+ default:
3417
+ throw new Error(
3418
+ `Trying to upgrade unsupported object file of type "${objectType}"`
3419
+ );
3420
+ }
2924
3421
  }
2925
3422
  };
2926
3423
 
2927
3424
  // src/service/UserService.ts
2928
3425
  var UserService = class {
3426
+ logService;
2929
3427
  jsonFileService;
2930
- constructor(jsonFileService) {
3428
+ constructor(logService, jsonFileService) {
3429
+ this.logService = logService;
2931
3430
  this.jsonFileService = jsonFileService;
2932
3431
  }
2933
3432
  /**
@@ -2937,6 +3436,7 @@ var UserService = class {
2937
3436
  try {
2938
3437
  return await this.jsonFileService.read(pathTo.userFile, userFileSchema);
2939
3438
  } catch (error) {
3439
+ this.logService.info("No User found");
2940
3440
  return void 0;
2941
3441
  }
2942
3442
  }
@@ -2954,13 +3454,16 @@ var UserService = class {
2954
3454
  if (userFile.userType === UserTypeSchema.Enum.cloud) {
2955
3455
  }
2956
3456
  await this.jsonFileService.update(userFile, userFilePath, userFileSchema);
3457
+ this.logService.debug("Updated User");
2957
3458
  return userFile;
2958
3459
  }
2959
3460
  };
2960
3461
 
2961
3462
  // src/index.node.ts
2962
3463
  var ElekIoCore = class {
3464
+ coreVersion;
2963
3465
  options;
3466
+ logService;
2964
3467
  userService;
2965
3468
  gitService;
2966
3469
  jsonFileService;
@@ -2968,24 +3471,29 @@ var ElekIoCore = class {
2968
3471
  projectService;
2969
3472
  collectionService;
2970
3473
  entryService;
2971
- // private readonly sharedValueService: SharedValueService;
2972
3474
  constructor(props) {
3475
+ this.coreVersion = version;
2973
3476
  const parsedProps = constructorElekIoCoreSchema.parse(props);
2974
3477
  const defaults = {
2975
- environment: "production",
2976
- version: "0.0.0",
3478
+ log: {
3479
+ level: "info"
3480
+ },
2977
3481
  file: {
2978
- json: {
2979
- indentation: 2
2980
- }
3482
+ cache: true
2981
3483
  }
2982
3484
  };
2983
3485
  this.options = Object.assign({}, defaults, parsedProps);
2984
- this.jsonFileService = new JsonFileService(this.options);
2985
- this.userService = new UserService(this.jsonFileService);
2986
- this.gitService = new GitService(this.options, this.userService);
3486
+ this.logService = new LogService(this.options);
3487
+ this.jsonFileService = new JsonFileService(this.options, this.logService);
3488
+ this.userService = new UserService(this.logService, this.jsonFileService);
3489
+ this.gitService = new GitService(
3490
+ this.options,
3491
+ this.logService,
3492
+ this.userService
3493
+ );
2987
3494
  this.assetService = new AssetService(
2988
3495
  this.options,
3496
+ this.logService,
2989
3497
  this.jsonFileService,
2990
3498
  this.gitService
2991
3499
  );
@@ -2996,14 +3504,16 @@ var ElekIoCore = class {
2996
3504
  );
2997
3505
  this.entryService = new EntryService(
2998
3506
  this.options,
3507
+ this.logService,
2999
3508
  this.jsonFileService,
3000
3509
  this.gitService,
3001
3510
  this.collectionService,
3002
3511
  this.assetService
3003
- // this.sharedValueService
3004
3512
  );
3005
3513
  this.projectService = new ProjectService(
3514
+ this.coreVersion,
3006
3515
  this.options,
3516
+ this.logService,
3007
3517
  this.jsonFileService,
3008
3518
  this.userService,
3009
3519
  this.gitService,
@@ -3011,18 +3521,19 @@ var ElekIoCore = class {
3011
3521
  this.collectionService,
3012
3522
  this.entryService
3013
3523
  );
3014
- if (this.options.environment !== "production") {
3015
- console.info(
3016
- `Initializing inside an "${this.options.environment}" environment`,
3017
- {
3018
- ...this.options
3019
- }
3020
- );
3021
- }
3524
+ this.logService.info(`Initializing elek.io Core ${this.coreVersion}`, {
3525
+ options: this.options
3526
+ });
3022
3527
  Fs7.mkdirpSync(pathTo.projects);
3023
3528
  Fs7.mkdirpSync(pathTo.tmp);
3024
3529
  Fs7.emptyDirSync(pathTo.tmp);
3025
3530
  }
3531
+ /**
3532
+ * Exposes the logger
3533
+ */
3534
+ get logger() {
3535
+ return this.logService;
3536
+ }
3026
3537
  /**
3027
3538
  * Utility / helper functions
3028
3539
  */
@@ -3065,12 +3576,6 @@ var ElekIoCore = class {
3065
3576
  get entries() {
3066
3577
  return this.entryService;
3067
3578
  }
3068
- /**
3069
- * CRUD methods to work with Values
3070
- */
3071
- // public get sharedValues(): SharedValueService {
3072
- // return this.sharedValueService;
3073
- // }
3074
3579
  };
3075
3580
  export {
3076
3581
  BooleanFieldDefinitionBaseSchema,
@@ -3087,7 +3592,6 @@ export {
3087
3592
  assetFileSchema,
3088
3593
  assetSchema,
3089
3594
  baseFileSchema,
3090
- baseFileWithLanguageSchema,
3091
3595
  baseUserSchema,
3092
3596
  cloneProjectSchema,
3093
3597
  cloudUserSchema,
@@ -3125,18 +3629,17 @@ export {
3125
3629
  entryFieldDefinitionSchema,
3126
3630
  entryFileSchema,
3127
3631
  entrySchema,
3128
- environmentSchema,
3129
3632
  fieldDefinitionSchema,
3130
3633
  fileReferenceSchema,
3131
3634
  getChangesProjectSchema,
3132
3635
  getRemoteOriginUrlProjectSchema,
3133
3636
  getValueContentSchemaFromFieldDefinition,
3134
3637
  gitCloneOptionsSchema,
3135
- gitCommitIconSchema,
3136
3638
  gitCommitSchema,
3137
3639
  gitInitOptionsSchema,
3138
3640
  gitLogOptionsSchema,
3139
- gitRepositoryPathSchema,
3641
+ gitMergeOptionsSchema,
3642
+ gitMessageSchema,
3140
3643
  gitSignatureSchema,
3141
3644
  gitSwitchOptionsSchema,
3142
3645
  gitTagSchema,
@@ -3148,8 +3651,11 @@ export {
3148
3651
  listGitTagsSchema,
3149
3652
  listProjectsSchema,
3150
3653
  localUserSchema,
3654
+ logLevelSchema,
3151
3655
  numberFieldDefinitionSchema,
3152
3656
  objectTypeSchema,
3657
+ outdatedProjectSchema,
3658
+ projectBranchSchema,
3153
3659
  projectExportSchema,
3154
3660
  projectFileSchema,
3155
3661
  projectFolderSchema,
@@ -3167,15 +3673,13 @@ export {
3167
3673
  resolvedReferencedValueSchema,
3168
3674
  resolvedValueContentReferenceSchema,
3169
3675
  resolvedValueSchema,
3676
+ saveAssetSchema,
3170
3677
  searchProjectSchema,
3171
3678
  serviceTypeSchema,
3172
3679
  setRemoteOriginUrlProjectSchema,
3173
3680
  setUserSchema,
3174
3681
  slug,
3175
3682
  stringFieldDefinitionSchema,
3176
- supportedAssetExtensionSchema,
3177
- supportedAssetMimeTypeSchema,
3178
- supportedAssetTypeSchema,
3179
3683
  supportedIconSchema,
3180
3684
  supportedLanguageSchema,
3181
3685
  switchBranchProjectSchema,
@@ -3204,7 +3708,6 @@ export {
3204
3708
  valueContentReferenceToAssetSchema,
3205
3709
  valueContentReferenceToCollectionSchema,
3206
3710
  valueContentReferenceToEntrySchema,
3207
- valueContentReferenceWithLanguageBase,
3208
3711
  valueSchema,
3209
3712
  versionSchema
3210
3713
  };