@elek-io/core 0.15.3 → 0.16.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.
@@ -1,10 +1,10 @@
1
1
  #! /usr/bin/env node
2
2
  import { Command } from "@commander-js/extra-typings";
3
- import Path from "path";
3
+ import Path from "node:path";
4
4
  import Fs from "fs-extra";
5
5
  import { build } from "tsdown";
6
6
  import CodeBlockWriter from "code-block-writer";
7
- import assert from "assert";
7
+ import assert from "node:assert";
8
8
  import chokidar from "chokidar";
9
9
  import { serve } from "@hono/node-server";
10
10
  import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
@@ -14,25 +14,30 @@ import { cors } from "hono/cors";
14
14
  import { trimTrailingSlash } from "hono/trailing-slash";
15
15
  import { z as z$1 } from "zod";
16
16
  import { Scalar } from "@scalar/hono-api-reference";
17
- import Os from "os";
18
- import { execFile } from "child_process";
17
+ import Os from "node:os";
18
+ import { execFile } from "node:child_process";
19
19
  import mime from "mime";
20
20
  import slugify from "@sindresorhus/slugify";
21
21
  import { v4 } from "uuid";
22
- import { GitProcess } from "dugite";
22
+ import { exec } from "dugite";
23
23
  import PQueue from "p-queue";
24
24
  import { createLogger, format, transports } from "winston";
25
25
  import DailyRotateFile from "winston-daily-rotate-file";
26
26
  import Semver from "semver";
27
27
 
28
- //#region rolldown:runtime
28
+ //#region \0rolldown/runtime.js
29
29
  var __defProp = Object.defineProperty;
30
- var __export = (all) => {
30
+ var __exportAll = (all, no_symbols) => {
31
31
  let target = {};
32
- for (var name$1 in all) __defProp(target, name$1, {
33
- get: all[name$1],
34
- enumerable: true
35
- });
32
+ for (var name in all) {
33
+ __defProp(target, name, {
34
+ get: all[name],
35
+ enumerable: true
36
+ });
37
+ }
38
+ if (!no_symbols) {
39
+ __defProp(target, Symbol.toStringTag, { value: "Module" });
40
+ }
36
41
  return target;
37
42
  };
38
43
 
@@ -40,24 +45,34 @@ var __export = (all) => {
40
45
  //#region package.json
41
46
  var package_default = {
42
47
  name: "@elek-io/core",
43
- version: "0.15.3",
48
+ version: "0.16.0",
44
49
  description: "Handles core functionality of elek.io Projects like file IO and version control.",
45
50
  homepage: "https://elek.io",
46
51
  repository: "https://github.com/elek-io/core",
47
52
  bugs: { "url": "https://github.com/elek-io/core/issues" },
48
53
  type: "module",
49
- bin: { "elek": "./dist/cli/index.cli.js" },
50
- files: ["dist/node", "dist/browser"],
51
- exports: { ".": {
52
- "node": { "import": {
53
- "types": "./dist/node/index.node.d.ts",
54
- "default": "./dist/node/index.node.js"
55
- } },
56
- "import": {
57
- "types": "./dist/browser/index.browser.d.ts",
58
- "default": "./dist/browser/index.browser.js"
59
- }
60
- } },
54
+ bin: { "elek": "./dist/cli/index.cli.mjs" },
55
+ files: [
56
+ "dist/node",
57
+ "dist/browser",
58
+ "dist/astro"
59
+ ],
60
+ exports: {
61
+ ".": {
62
+ "node": { "import": {
63
+ "types": "./dist/node/index.node.d.mts",
64
+ "default": "./dist/node/index.node.mjs"
65
+ } },
66
+ "import": {
67
+ "types": "./dist/browser/index.browser.d.ts",
68
+ "default": "./dist/browser/index.browser.js"
69
+ }
70
+ },
71
+ "./astro": { "import": {
72
+ "types": "./dist/astro/index.astro.d.mts",
73
+ "default": "./dist/astro/index.astro.mjs"
74
+ } }
75
+ },
61
76
  pnpm: { "overrides": {} },
62
77
  scripts: {
63
78
  "lint": "eslint",
@@ -72,105 +87,222 @@ var package_default = {
72
87
  },
73
88
  dependencies: {
74
89
  "@commander-js/extra-typings": "14.0.0",
75
- "@hono/node-server": "1.19.5",
76
- "@hono/zod-openapi": "1.1.4",
77
- "@scalar/hono-api-reference": "0.9.22",
90
+ "@hono/node-server": "1.19.11",
91
+ "@hono/zod-openapi": "1.2.2",
92
+ "@scalar/hono-api-reference": "0.10.0",
78
93
  "@sindresorhus/slugify": "3.0.0",
79
- "chokidar": "4.0.3",
94
+ "chokidar": "5.0.0",
80
95
  "code-block-writer": "13.0.3",
81
- "commander": "14.0.2",
82
- "fs-extra": "11.3.2",
83
- "hono": "4.10.4",
96
+ "commander": "14.0.3",
97
+ "fs-extra": "11.3.4",
98
+ "hono": "4.12.5",
84
99
  "mime": "4.1.0",
85
- "p-queue": "9.0.0",
86
- "semver": "7.7.3",
87
- "tsdown": "0.15.12",
100
+ "p-queue": "9.1.0",
101
+ "semver": "7.7.4",
102
+ "tsdown": "0.21.0",
88
103
  "uuid": "13.0.0",
89
- "winston": "3.18.3",
104
+ "winston": "3.19.0",
90
105
  "winston-daily-rotate-file": "5.0.0",
91
- "zod": "4.1.12"
106
+ "zod": "4.3.6"
92
107
  },
93
108
  devDependencies: {
94
- "@changesets/cli": "2.29.7",
95
- "@eslint/js": "9.38.0",
96
- "@faker-js/faker": "10.1.0",
97
- "@tsconfig/node22": "22.0.2",
98
- "@tsconfig/strictest": "2.0.7",
109
+ "@changesets/cli": "2.30.0",
110
+ "@eslint/js": "10.0.1",
111
+ "@faker-js/faker": "10.3.0",
112
+ "@tsconfig/node24": "24.0.4",
113
+ "@tsconfig/strictest": "2.0.8",
99
114
  "@types/fs-extra": "11.0.4",
100
- "@types/node": "22.18.13",
115
+ "@types/node": "24.12.0",
101
116
  "@types/semver": "7.7.1",
102
- "@vitest/coverage-v8": "4.0.5",
103
- "eslint": "9.38.0",
117
+ "@vitest/coverage-v8": "4.0.18",
118
+ "astro": "5.18.0",
119
+ "eslint": "10.0.3",
104
120
  "eslint-config-prettier": "10.1.8",
105
- "globals": "16.4.0",
121
+ "globals": "17.4.0",
106
122
  "jiti": "2.6.1",
107
- "prettier": "3.6.2",
123
+ "prettier": "3.8.1",
108
124
  "typescript": "5.9.3",
109
- "typescript-eslint": "8.46.2",
110
- "vitest": "4.0.5"
125
+ "typescript-eslint": "8.56.1",
126
+ "vitest": "4.0.18"
111
127
  },
112
- peerDependencies: { "dugite": "2.7.1" }
128
+ peerDependencies: {
129
+ "astro": ">=5.0.0",
130
+ "dugite": "3.2.0"
131
+ },
132
+ peerDependenciesMeta: { "astro": { "optional": true } }
113
133
  };
114
134
 
115
135
  //#endregion
116
136
  //#region src/cli/exportAction.ts
117
- async function exportProjects({ outDir, projects, options }) {
118
- const projectsToExport = [];
119
- const resolvedOutDir = Path.resolve(outDir);
120
- await Fs.ensureDir(resolvedOutDir);
121
- let content = {};
122
- if (projects === "all") projectsToExport.push(...(await core.projects.list({ limit: 0 })).list);
123
- else for (const projectId of projects) projectsToExport.push(await core.projects.read({ id: projectId }));
137
+ async function exportFile({ resolvedOutDir, name, content }) {
138
+ await Fs.writeFile(Path.join(resolvedOutDir, `${name}.json`), JSON.stringify(content, null, 2));
139
+ }
140
+ async function exportProjectNested({ projectToExport }) {
141
+ const assets = (await core.assets.list({
142
+ projectId: projectToExport.id,
143
+ limit: 0
144
+ })).list;
145
+ let assetContent = {};
146
+ for (const asset of assets) assetContent = {
147
+ ...assetContent,
148
+ [asset.id]: { ...asset }
149
+ };
150
+ let collectionContent = {};
151
+ const collections = (await core.collections.list({
152
+ projectId: projectToExport.id,
153
+ limit: 0
154
+ })).list;
155
+ for (const collection of collections) {
156
+ let entryContent = {};
157
+ const entries = (await core.entries.list({
158
+ projectId: projectToExport.id,
159
+ collectionId: collection.id,
160
+ limit: 0
161
+ })).list;
162
+ for (const entry of entries) entryContent = {
163
+ ...entryContent,
164
+ [entry.id]: { ...entry }
165
+ };
166
+ collectionContent = {
167
+ ...collectionContent,
168
+ [collection.id]: {
169
+ ...collection,
170
+ entries: entryContent
171
+ }
172
+ };
173
+ }
174
+ return {
175
+ ...projectToExport,
176
+ assets: assetContent,
177
+ collections: collectionContent
178
+ };
179
+ }
180
+ async function exportProjectsNested({ resolvedOutDir, projectsToExport, options }) {
181
+ if (projectsToExport.length === 1) {
182
+ const projectToExport = projectsToExport[0];
183
+ const project = await exportProjectNested({
184
+ resolvedOutDir,
185
+ projectToExport,
186
+ options
187
+ });
188
+ await exportFile({
189
+ resolvedOutDir,
190
+ options,
191
+ name: `project-${projectToExport.id}`,
192
+ content: project
193
+ });
194
+ } else {
195
+ let projects = {};
196
+ for (const project of projectsToExport) projects = {
197
+ ...projects,
198
+ [project.id]: await exportProjectNested({
199
+ resolvedOutDir,
200
+ projectToExport: project,
201
+ options
202
+ })
203
+ };
204
+ await exportFile({
205
+ resolvedOutDir,
206
+ options,
207
+ name: "projects",
208
+ content: projects
209
+ });
210
+ }
211
+ }
212
+ async function exportProjectsSeparate({ resolvedOutDir, projectsToExport, options }) {
124
213
  for (const project of projectsToExport) {
125
- const assets = (await core.assets.list({
214
+ const projectOutDir = Path.join(resolvedOutDir, `project-${project.id}`);
215
+ await Fs.ensureDir(projectOutDir);
216
+ await exportFile({
217
+ resolvedOutDir: projectOutDir,
218
+ options,
219
+ name: `project`,
220
+ content: project
221
+ });
222
+ const tmpAssets = (await core.assets.list({
126
223
  projectId: project.id,
127
224
  limit: 0
128
225
  })).list;
129
- let assetContent = {};
130
- for (const asset of assets) assetContent = {
131
- ...assetContent,
132
- [asset.id]: { ...asset }
133
- };
134
- let collectionContent = {};
226
+ const assets = [];
227
+ const assetOutDir = Path.join(projectOutDir, "assets");
228
+ await Fs.ensureDir(assetOutDir);
229
+ for (const asset of tmpAssets) {
230
+ const assetDestination = Path.join(assetOutDir, `${asset.id}.${asset.extension}`);
231
+ await Fs.copyFile(asset.absolutePath, assetDestination);
232
+ assets.push({
233
+ ...asset,
234
+ absolutePath: assetDestination
235
+ });
236
+ }
237
+ await exportFile({
238
+ resolvedOutDir: assetOutDir,
239
+ options,
240
+ name: `assets`,
241
+ content: assets
242
+ });
135
243
  const collections = (await core.collections.list({
136
244
  projectId: project.id,
137
245
  limit: 0
138
246
  })).list;
247
+ const collectionsOutDir = Path.join(projectOutDir, "collections");
248
+ await Fs.ensureDir(collectionsOutDir);
139
249
  for (const collection of collections) {
140
- let entryContent = {};
250
+ const collectionOutDir = Path.join(collectionsOutDir, collection.slug.plural);
251
+ await Fs.ensureDir(collectionOutDir);
252
+ await exportFile({
253
+ resolvedOutDir: collectionOutDir,
254
+ options,
255
+ name: `collection`,
256
+ content: collection
257
+ });
141
258
  const entries = (await core.entries.list({
142
259
  projectId: project.id,
143
260
  collectionId: collection.id,
144
261
  limit: 0
145
262
  })).list;
146
- for (const entry of entries) entryContent = {
147
- ...entryContent,
148
- [entry.id]: { ...entry }
149
- };
150
- collectionContent = {
151
- ...collectionContent,
152
- [collection.id]: {
153
- ...collection,
154
- entries: entryContent
155
- }
156
- };
263
+ await exportFile({
264
+ resolvedOutDir: collectionOutDir,
265
+ options,
266
+ name: `entries`,
267
+ content: entries
268
+ });
157
269
  }
158
- content = {
159
- ...content,
160
- [project.id]: {
161
- ...project,
162
- assets: assetContent,
163
- collections: collectionContent
164
- }
165
- };
270
+ await exportFile({
271
+ resolvedOutDir: collectionsOutDir,
272
+ options,
273
+ name: `collections`,
274
+ content: collections
275
+ });
276
+ }
277
+ }
278
+ async function exportProjects({ outDir, projects, template, options }) {
279
+ const projectsToExport = [];
280
+ const resolvedOutDir = Path.resolve(outDir);
281
+ await Fs.ensureDir(resolvedOutDir);
282
+ if (projects === "all") projectsToExport.push(...(await core.projects.list({ limit: 0 })).list);
283
+ else for (const projectId of projects) projectsToExport.push(await core.projects.read({ id: projectId }));
284
+ switch (template) {
285
+ case "nested":
286
+ await exportProjectsNested({
287
+ resolvedOutDir,
288
+ projectsToExport,
289
+ options
290
+ });
291
+ break;
292
+ case "separate":
293
+ await exportProjectsSeparate({
294
+ resolvedOutDir,
295
+ projectsToExport,
296
+ options
297
+ });
298
+ break;
166
299
  }
167
- if (options.separate === true) for (const project of projectsToExport) await Fs.writeFile(Path.join(resolvedOutDir, `project-${project.id}.json`), JSON.stringify(content[project.id], null, 2));
168
- else await Fs.writeFile(Path.join(resolvedOutDir, "projects.json"), JSON.stringify(content, null, 2));
169
300
  }
170
- const exportAction = async ({ outDir, projects, options }) => {
301
+ const exportAction = async ({ outDir, projects, template, options }) => {
171
302
  await exportProjects({
172
303
  outDir,
173
304
  projects,
305
+ template,
174
306
  options
175
307
  });
176
308
  if (options.watch === true) {
@@ -186,6 +318,7 @@ const exportAction = async ({ outDir, projects, options }) => {
186
318
  exportProjects({
187
319
  outDir,
188
320
  projects,
321
+ template,
189
322
  options
190
323
  });
191
324
  });
@@ -326,7 +459,7 @@ function writeFetch(writer, to, method = "GET") {
326
459
  }).write(`);`).newLine();
327
460
  writer.writeLine(`const entries = await response.json();`);
328
461
  }
329
- async function generateApiClientAs({ outDir, language, format: format$1, target }) {
462
+ async function generateApiClientAs({ outDir, language, format, target }) {
330
463
  const resolvedOutDir = Path.resolve(outDir);
331
464
  await Fs.ensureDir(resolvedOutDir);
332
465
  const outFileTs = Path.join(resolvedOutDir, "client.ts");
@@ -337,8 +470,9 @@ async function generateApiClientAs({ outDir, language, format: format$1, target
337
470
  external: ["@elek-io/core", "zod"],
338
471
  entry: outFileTs.split(Path.sep).join(Path.posix.sep),
339
472
  outDir: resolvedOutDir,
340
- format: format$1,
473
+ format,
341
474
  target,
475
+ platform: "neutral",
342
476
  sourcemap: true,
343
477
  clean: false,
344
478
  dts: true,
@@ -347,11 +481,11 @@ async function generateApiClientAs({ outDir, language, format: format$1, target
347
481
  await Fs.remove(outFileTs);
348
482
  }
349
483
  }
350
- const generateApiClientAction = async ({ outDir, language, format: format$1, target, options }) => {
484
+ const generateApiClientAction = async ({ outDir, language, format, target, options }) => {
351
485
  await generateApiClientAs({
352
486
  outDir,
353
487
  language,
354
- format: format$1,
488
+ format,
355
489
  target,
356
490
  options
357
491
  });
@@ -368,7 +502,7 @@ const generateApiClientAction = async ({ outDir, language, format: format$1, tar
368
502
  generateApiClientAs({
369
503
  outDir,
370
504
  language,
371
- format: format$1,
505
+ format,
372
506
  target,
373
507
  options
374
508
  });
@@ -383,10 +517,10 @@ const generateApiClientAction = async ({ outDir, language, format: format$1, tar
383
517
  */
384
518
  const requestResponseLogger = createMiddleware(async (c, next) => {
385
519
  const { method, url } = c.req;
386
- const requestId$1 = c.get("requestId");
520
+ const requestId = c.get("requestId");
387
521
  c.var.logService.info({
388
522
  source: "core",
389
- message: `Recieved API request "${method} ${url}" with requestId ${requestId$1}`
523
+ message: `Recieved API request "${method} ${url}" with requestId ${requestId}`
390
524
  });
391
525
  const start = Date.now();
392
526
  await next();
@@ -394,7 +528,7 @@ const requestResponseLogger = createMiddleware(async (c, next) => {
394
528
  const statusCode = c.res.status.toString();
395
529
  const resultLog = {
396
530
  source: "core",
397
- message: `Response for API request "${method} ${url}" with requestId ${requestId$1} and status code ${statusCode} in ${durationMs}ms`
531
+ message: `Response for API request "${method} ${url}" with requestId ${requestId} and status code ${statusCode} in ${durationMs}ms`
398
532
  };
399
533
  if (statusCode.startsWith("2")) c.var.logService.info(resultLog);
400
534
  else if (statusCode.startsWith("3")) c.var.logService.warn(resultLog);
@@ -504,19 +638,19 @@ const logLevelSchema = z.enum([
504
638
  "debug"
505
639
  ]);
506
640
  const versionSchema = z.string();
507
- const uuidSchema = z.uuid("shared.invalidUuid");
641
+ const uuidSchema = z.uuid();
508
642
  /**
509
643
  * A record that can be used to translate a string value into all supported languages
510
644
  */
511
- const translatableStringSchema = z.partialRecord(supportedLanguageSchema, z.string().trim().min(1, "shared.translatableStringRequired"));
645
+ const translatableStringSchema = z.partialRecord(supportedLanguageSchema, z.string().trim().min(1));
512
646
  /**
513
647
  * A record that can be used to translate a number value into all supported languages
514
648
  */
515
- const translatableNumberSchema = z.partialRecord(supportedLanguageSchema, z.number({ error: (error) => error.input === void 0 ? "shared.translatableNumberRequired" : "shared.translatableNumberNotANumber" }));
649
+ const translatableNumberSchema = z.partialRecord(supportedLanguageSchema, z.number());
516
650
  /**
517
651
  * A record that can be used to translate a boolean value into all supported languages
518
652
  */
519
- const translatableBooleanSchema = z.partialRecord(supportedLanguageSchema, z.boolean({ error: (error) => error.input === void 0 ? "shared.translatableBooleanRequired" : "shared.translatableBooleanNotABoolean" }));
653
+ const translatableBooleanSchema = z.partialRecord(supportedLanguageSchema, z.boolean());
520
654
  function translatableArrayOf(schema) {
521
655
  return z.partialRecord(supportedLanguageSchema, z.array(schema));
522
656
  }
@@ -951,8 +1085,8 @@ const projectBranchSchema = z.enum(["production", "work"]);
951
1085
  const projectFileSchema = baseFileSchema.extend({
952
1086
  objectType: z.literal(objectTypeSchema.enum.project).readonly(),
953
1087
  coreVersion: versionSchema,
954
- name: z.string().trim().min(1, "shared.projectNameRequired"),
955
- description: z.string().trim().min(1, "shared.projectDescriptionRequired"),
1088
+ name: z.string().trim().min(1),
1089
+ description: z.string().trim().min(1),
956
1090
  version: versionSchema,
957
1091
  status: projectStatusSchema,
958
1092
  settings: projectSettingsSchema
@@ -1022,6 +1156,12 @@ const searchProjectSchema = z.object({
1022
1156
  //#endregion
1023
1157
  //#region src/schema/schemaFromFieldDefinition.ts
1024
1158
  /**
1159
+ * Dynamic zod schema generation
1160
+ *
1161
+ * Altough everything is already strictly typed, a type of string might not be an email or text of a certain length.
1162
+ * To validate this, we need to generate zod schemas based on Field definitions the user created.
1163
+ */
1164
+ /**
1025
1165
  * Boolean Values are always either true or false, so we don't need the Field definition here
1026
1166
  */
1027
1167
  function getBooleanValueContentSchemaFromFieldDefinition() {
@@ -1073,7 +1213,7 @@ function getStringValueContentSchemaFromFieldDefinition(fieldDefinition) {
1073
1213
  if ("min" in fieldDefinition && fieldDefinition.min) schema = schema.min(fieldDefinition.min);
1074
1214
  if ("max" in fieldDefinition && fieldDefinition.max) schema = schema.max(fieldDefinition.max);
1075
1215
  if (fieldDefinition.isRequired === false) return schema.nullable();
1076
- return schema.min(1, "shared.stringValueRequired");
1216
+ return schema.min(1);
1077
1217
  }
1078
1218
  /**
1079
1219
  * Reference Values can reference either Assets or Entries (or Shared Values in the future)
@@ -1089,7 +1229,7 @@ function getReferenceValueContentSchemaFromFieldDefinition(fieldDefinition) {
1089
1229
  schema = z.array(valueContentReferenceToEntrySchema);
1090
1230
  break;
1091
1231
  }
1092
- if (fieldDefinition.isRequired) schema = schema.min(1, "shared.referenceRequired");
1232
+ if (fieldDefinition.isRequired) schema = schema.min(1);
1093
1233
  if (fieldDefinition.min) schema = schema.min(fieldDefinition.min);
1094
1234
  if (fieldDefinition.max) schema = schema.max(fieldDefinition.max);
1095
1235
  return schema;
@@ -1222,7 +1362,7 @@ const projectsSchema = z$1.string().default("all").transform((value) => {
1222
1362
  return value.split(",").map((v) => uuidSchema.parse(v.trim()));
1223
1363
  });
1224
1364
  const generateApiClientOptionsSchema = z$1.object({ watch: z$1.boolean().default(false) });
1225
- const exportProjectsOptionsSchema = generateApiClientOptionsSchema.extend({ separate: z$1.boolean().default(false) });
1365
+ const exportProjectsOptionsSchema = generateApiClientOptionsSchema.extend({ watch: z$1.boolean().default(false) });
1226
1366
  const generateApiClientSchema = z$1.object({
1227
1367
  outDir: outDirSchema,
1228
1368
  language: languageSchema,
@@ -1246,6 +1386,7 @@ const apiStartSchema = z$1.object({ port: portSchema });
1246
1386
  const exportSchema = z$1.object({
1247
1387
  outDir: outDirSchema,
1248
1388
  projects: projectsSchema,
1389
+ template: z$1.enum(["nested", "separate"]).default("nested"),
1249
1390
  options: exportProjectsOptionsSchema
1250
1391
  });
1251
1392
 
@@ -1324,7 +1465,6 @@ const router$6 = createRouter().openapi(createRoute({
1324
1465
  const project = await c.var.projectService.read({ id: projectId });
1325
1466
  return c.json(project, 200);
1326
1467
  });
1327
- var projects_default = router$6;
1328
1468
 
1329
1469
  //#endregion
1330
1470
  //#region src/api/routes/content/v1/collections.ts
@@ -1410,7 +1550,6 @@ const router$5 = createRouter().openapi(createRoute({
1410
1550
  });
1411
1551
  return c.json(collection, 200);
1412
1552
  });
1413
- var collections_default = router$5;
1414
1553
 
1415
1554
  //#endregion
1416
1555
  //#region src/api/routes/content/v1/entries.ts
@@ -1517,7 +1656,6 @@ const router$4 = createRouter().openapi(createRoute({
1517
1656
  });
1518
1657
  return c.json(entry, 200);
1519
1658
  });
1520
- var entries_default = router$4;
1521
1659
 
1522
1660
  //#endregion
1523
1661
  //#region src/api/routes/content/v1/assets.ts
@@ -1603,22 +1741,18 @@ const router$3 = createRouter().openapi(createRoute({
1603
1741
  });
1604
1742
  return c.json(asset, 200);
1605
1743
  });
1606
- var assets_default = router$3;
1607
1744
 
1608
1745
  //#endregion
1609
1746
  //#region src/api/routes/content/v1/index.ts
1610
- const router$2 = createRouter().route("/projects", projects_default).route("/projects", collections_default).route("/projects", entries_default).route("/projects", assets_default);
1611
- var v1_default = router$2;
1747
+ const router$2 = createRouter().route("/projects", router$6).route("/projects", router$5).route("/projects", router$4).route("/projects", router$3);
1612
1748
 
1613
1749
  //#endregion
1614
1750
  //#region src/api/routes/content/index.ts
1615
- const router$1 = createRouter().route("/v1", v1_default);
1616
- var content_default = router$1;
1751
+ const router$1 = createRouter().route("/v1", router$2);
1617
1752
 
1618
1753
  //#endregion
1619
1754
  //#region src/api/routes/index.ts
1620
- const router = createRouter().route("/content", content_default);
1621
- var routes_default = router;
1755
+ const router = createRouter().route("/content", router$1);
1622
1756
 
1623
1757
  //#endregion
1624
1758
  //#region src/api/index.ts
@@ -1636,7 +1770,7 @@ var LocalApi = class {
1636
1770
  this.collectionService = collectionService;
1637
1771
  this.entryService = entryService;
1638
1772
  this.assetService = assetService;
1639
- this.api = createApi(this.logService, this.projectService, this.collectionService, this.entryService, this.assetService).route("/", routes_default).doc("/openapi.json", {
1773
+ this.api = createApi(this.logService, this.projectService, this.collectionService, this.entryService, this.assetService).route("/", router).doc("/openapi.json", {
1640
1774
  openapi: "3.0.0",
1641
1775
  externalDocs: { url: "https://elek.io/docs" },
1642
1776
  info: {
@@ -1740,7 +1874,7 @@ var RequiredParameterMissingError = class extends Error {
1740
1874
 
1741
1875
  //#endregion
1742
1876
  //#region src/util/node.ts
1743
- var node_exports = /* @__PURE__ */ __export({
1877
+ var node_exports = /* @__PURE__ */ __exportAll({
1744
1878
  execCommand: () => execCommand,
1745
1879
  files: () => files,
1746
1880
  folders: () => folders,
@@ -1907,8 +2041,8 @@ var AbstractCrudService = class {
1907
2041
  /**
1908
2042
  * Do not instantiate directly as this is an abstract class
1909
2043
  */
1910
- constructor(type$1, options, logService) {
1911
- this.type = type$1;
2044
+ constructor(type, options, logService) {
2045
+ this.type = type;
1912
2046
  this.options = options;
1913
2047
  this.logService = logService;
1914
2048
  }
@@ -1944,8 +2078,8 @@ var AbstractCrudService = class {
1944
2078
  * @param projectId Project to get all asset references from
1945
2079
  * @param collectionId Only needed when requesting files of type "Entry"
1946
2080
  */
1947
- async listReferences(type$1, projectId, collectionId) {
1948
- switch (type$1) {
2081
+ async listReferences(type, projectId, collectionId) {
2082
+ switch (type) {
1949
2083
  case objectTypeSchema.enum.asset:
1950
2084
  if (!projectId) throw new RequiredParameterMissingError("projectId");
1951
2085
  return this.getFileReferences(pathTo.lfs(projectId));
@@ -1960,7 +2094,7 @@ var AbstractCrudService = class {
1960
2094
  case objectTypeSchema.enum.sharedValue:
1961
2095
  if (!projectId) throw new RequiredParameterMissingError("projectId");
1962
2096
  return this.getFileReferences(pathTo.sharedValues(projectId));
1963
- default: throw new Error(`Trying to list files of unsupported type "${type$1}"`);
2097
+ default: throw new Error(`Trying to list files of unsupported type "${type}"`);
1964
2098
  }
1965
2099
  }
1966
2100
  async getFolderReferences(path) {
@@ -2180,9 +2314,9 @@ var AssetService = class extends AbstractCrudService {
2180
2314
  async list(props) {
2181
2315
  listAssetsSchema.parse(props);
2182
2316
  const offset = props.offset || 0;
2183
- const limit = props.limit || 15;
2317
+ const limit = props.limit ?? 15;
2184
2318
  const assetReferences = await this.listReferences(objectTypeSchema.enum.asset, props.projectId);
2185
- const partialAssetReferences = assetReferences.slice(offset, limit);
2319
+ const partialAssetReferences = limit === 0 ? assetReferences.slice(offset) : assetReferences.slice(offset, offset + limit);
2186
2320
  const assets = await this.returnResolved(partialAssetReferences.map((assetReference) => {
2187
2321
  return this.read({
2188
2322
  projectId: props.projectId,
@@ -2365,9 +2499,9 @@ var CollectionService = class extends AbstractCrudService {
2365
2499
  async list(props) {
2366
2500
  listCollectionsSchema.parse(props);
2367
2501
  const offset = props.offset || 0;
2368
- const limit = props.limit || 15;
2502
+ const limit = props.limit ?? 15;
2369
2503
  const collectionReferences = await this.listReferences(objectTypeSchema.enum.collection, props.projectId);
2370
- const partialCollectionReferences = collectionReferences.slice(offset, limit);
2504
+ const partialCollectionReferences = limit === 0 ? collectionReferences.slice(offset) : collectionReferences.slice(offset, offset + limit);
2371
2505
  const collections = await this.returnResolved(partialCollectionReferences.map((reference) => {
2372
2506
  return this.read({
2373
2507
  projectId: props.projectId,
@@ -2530,9 +2664,9 @@ var EntryService = class extends AbstractCrudService {
2530
2664
  async list(props) {
2531
2665
  listEntriesSchema.parse(props);
2532
2666
  const offset = props.offset || 0;
2533
- const limit = props.limit || 15;
2667
+ const limit = props.limit ?? 15;
2534
2668
  const entryReferences = await this.listReferences(objectTypeSchema.enum.entry, props.projectId, props.collectionId);
2535
- const partialEntryReferences = entryReferences.slice(offset, limit);
2669
+ const partialEntryReferences = limit === 0 ? entryReferences.slice(offset) : entryReferences.slice(offset, offset + limit);
2536
2670
  const entries = await this.returnResolved(partialEntryReferences.map((reference) => {
2537
2671
  return this.read({
2538
2672
  projectId: props.projectId,
@@ -2618,8 +2752,8 @@ var GitTagService = class extends AbstractCrudService {
2618
2752
  */
2619
2753
  async read(props) {
2620
2754
  readGitTagSchema.parse(props);
2621
- const tag = (await this.list({ path: props.path })).list.find((tag$1) => {
2622
- return tag$1.id === props.id;
2755
+ const tag = (await this.list({ path: props.path })).list.find((tag) => {
2756
+ return tag.id === props.id;
2623
2757
  });
2624
2758
  if (!tag) throw new GitError(`Provided tag with UUID "${props.id}" did not match any known tags`);
2625
2759
  return tag;
@@ -2810,11 +2944,11 @@ var GitService = class {
2810
2944
  * @param path Path to the repository
2811
2945
  * @param files Files to add
2812
2946
  */
2813
- async add(path, files$2) {
2947
+ async add(path, files) {
2814
2948
  const args = [
2815
2949
  "add",
2816
2950
  "--",
2817
- ...files$2.map((filePath) => {
2951
+ ...files.map((filePath) => {
2818
2952
  return filePath.replace(`${path}${Path.sep}`, "");
2819
2953
  })
2820
2954
  ];
@@ -3088,11 +3222,11 @@ var GitService = class {
3088
3222
  * @param path Path to the repository
3089
3223
  * @param name Name to check
3090
3224
  */
3091
- async checkBranchOrTagName(path, name$1) {
3225
+ async checkBranchOrTagName(path, name) {
3092
3226
  await this.git(path, [
3093
3227
  "check-ref-format",
3094
3228
  "--allow-onelevel",
3095
- name$1
3229
+ name
3096
3230
  ]);
3097
3231
  }
3098
3232
  /**
@@ -3151,7 +3285,7 @@ var GitService = class {
3151
3285
  const result = await this.queue.add(async () => {
3152
3286
  const start = Date.now();
3153
3287
  return {
3154
- gitResult: await GitProcess.exec(args, path, options),
3288
+ gitResult: await exec(args, path, options),
3155
3289
  durationMs: Date.now() - start
3156
3290
  };
3157
3291
  });
@@ -3163,8 +3297,12 @@ var GitService = class {
3163
3297
  };
3164
3298
  if (result.durationMs >= 100) this.logService.warn(gitLog);
3165
3299
  else this.logService.debug(gitLog);
3166
- if (result.gitResult.exitCode !== 0) throw new GitError(`Git ${this.version} (${this.gitPath}) command "git ${args.join(" ")}" executed for "${path}" failed with exit code "${result.gitResult.exitCode}" and message "${result.gitResult.stderr.trim() || result.gitResult.stdout.trim()}"`);
3167
- return result.gitResult;
3300
+ if (result.gitResult.exitCode !== 0) throw new GitError(`Git ${this.version} (${this.gitPath}) command "git ${args.join(" ")}" executed for "${path}" failed with exit code "${result.gitResult.exitCode}" and message "${result.gitResult.stderr.toString().trim() || result.gitResult.stdout.toString().trim()}"`);
3301
+ return {
3302
+ ...result.gitResult,
3303
+ stdout: result.gitResult.stdout.toString(),
3304
+ stderr: result.gitResult.stderr.toString()
3305
+ };
3168
3306
  }
3169
3307
  };
3170
3308
 
@@ -3213,8 +3351,8 @@ var JsonFileService = class extends AbstractCrudService {
3213
3351
  source: "core",
3214
3352
  message: `Cache hit reading file "${path}"`
3215
3353
  });
3216
- const json$1 = this.cache.get(path);
3217
- return schema.parse(json$1);
3354
+ const json = this.cache.get(path);
3355
+ return schema.parse(json);
3218
3356
  }
3219
3357
  this.logService.debug({
3220
3358
  source: "core",
@@ -3319,13 +3457,18 @@ var LogService = class {
3319
3457
  handleExceptions: true,
3320
3458
  handleRejections: true,
3321
3459
  format: format.combine(format.colorize(), format.timestamp({ format: "HH:mm:ss" }), format.printf((props) => {
3322
- const { timestamp, level, source, message } = logConsoleTransportSchema.parse({
3323
- ...props[Symbol.for("splat")][0],
3460
+ const splatArgs = props[Symbol.for("splat")];
3461
+ const result = logConsoleTransportSchema.safeParse({
3462
+ ...splatArgs?.[0] ?? {},
3324
3463
  timestamp: props["timestamp"],
3325
3464
  level: props.level,
3326
3465
  message: props.message
3327
3466
  });
3328
- return `${timestamp} [${source}] ${level}: ${message}`;
3467
+ if (result.success) {
3468
+ const { timestamp, level, source, message } = result.data;
3469
+ return `${timestamp} [${source}] ${level}: ${message}`;
3470
+ }
3471
+ return `${String(props["timestamp"])} ${props.level}: ${String(props.message)}`;
3329
3472
  }))
3330
3473
  });
3331
3474
  this.logger = createLogger({
@@ -3656,9 +3799,9 @@ var ProjectService = class extends AbstractCrudService {
3656
3799
  async list(props) {
3657
3800
  if (props) listProjectsSchema.parse(props);
3658
3801
  const offset = props?.offset || 0;
3659
- const limit = props?.limit || 15;
3802
+ const limit = props?.limit ?? 15;
3660
3803
  const projectReferences = await this.listReferences(objectTypeSchema.enum.project);
3661
- const partialProjectReferences = projectReferences.slice(offset, limit);
3804
+ const partialProjectReferences = limit === 0 ? projectReferences.slice(offset) : projectReferences.slice(offset, offset + limit);
3662
3805
  const projects = await this.returnResolved(partialProjectReferences.map((reference) => {
3663
3806
  return this.read({ id: reference.id });
3664
3807
  }));
@@ -3707,8 +3850,8 @@ var ProjectService = class extends AbstractCrudService {
3707
3850
  * committed
3708
3851
  */
3709
3852
  async createFolderStructure(path) {
3710
- const folders$1 = Object.values(projectFolderSchema.enum);
3711
- await Promise.all(folders$1.map(async (folder) => {
3853
+ const folders = Object.values(projectFolderSchema.enum);
3854
+ await Promise.all(folders.map(async (folder) => {
3712
3855
  await Fs.mkdirp(Path.join(path, folder));
3713
3856
  await Fs.writeFile(Path.join(path, folder, ".gitkeep"), "");
3714
3857
  }));
@@ -3954,11 +4097,11 @@ function watchProjects() {
3954
4097
  //#region src/index.cli.ts
3955
4098
  const program = new Command();
3956
4099
  program.name("elek").description("CLI for elek.io").version(package_default.version);
3957
- program.command("generate:client").description("Generates a JS/TS API Client").argument("[outDir]", "The directory to generate the API Client in", "./.elek.io").argument("[language]", "The programming language of the generated API Client. Choose \"ts\" if you bundle it yourself in your TypeScript project, or \"js\" if you want a ready-to-use JavaScript API Client.", "ts").argument("[format]", "The output format of the generated API Client. Choose \"esm\" for ES Modules, or \"cjs\" for CommonJS. This option is only relevant if you choose \"js\" as the language.", "esm").argument("[target]", "The target environment of the generated API Client. Choose this depending on the JavaScript runtime you want to support. This option is only relevant if you choose \"js\" as the language.", "es2020").option("-w, --watch", "Watches for changes in your Projects and regenerates the API Client automatically.").action(async (outDir, language, format$1, target, options) => {
4100
+ program.command("generate:client").description("Generates a JS/TS API Client").argument("[outDir]", "The directory to generate the API Client in", "./.elek.io").argument("[language]", "The programming language of the generated API Client. Choose \"ts\" if you bundle it yourself in your TypeScript project, or \"js\" if you want a ready-to-use JavaScript API Client.", "ts").argument("[format]", "The output format of the generated API Client. Choose \"esm\" for ES Modules, or \"cjs\" for CommonJS. This option is only relevant if you choose \"js\" as the language.", "esm").argument("[target]", "The target environment of the generated API Client. Choose this depending on the JavaScript runtime you want to support. This option is only relevant if you choose \"js\" as the language.", "es2020").option("-w, --watch", "Watches for changes in your Projects and regenerates the API Client automatically.").action(async (outDir, language, format, target, options) => {
3958
4101
  await generateApiClientAction(generateApiClientSchema.parse({
3959
4102
  outDir,
3960
4103
  language,
3961
- format: format$1,
4104
+ format,
3962
4105
  target,
3963
4106
  options
3964
4107
  }));
@@ -3966,10 +4109,11 @@ program.command("generate:client").description("Generates a JS/TS API Client").a
3966
4109
  program.command("api:start").description("Starts the local API").argument("[port]", "The port to run the local API on", "31310").action((port) => {
3967
4110
  startApiAction(apiStartSchema.parse({ port }));
3968
4111
  });
3969
- program.command("export").description("Exports all locally available Projects into a JSON file").argument("[outDir]", "The directory to write the JSON file to", "./.elek.io").argument("[projects]", "One or more Project IDs, separated by commas to export. If not provided, all Projects will be exported.", "all").option("-s, --separate", "Separates the exported Projects into individual files.").option("-w, --watch", "Watches for changes in your Projects and updates the JSON file automatically.").action(async (outDir, projects, options) => {
4112
+ program.command("export").description("Exports locally available Projects to JSON").argument("[outDir]", "The directory to write the JSON to", "./.elek.io").argument("[projects]", "One or more Project IDs, separated by commas to export. If not provided, all Projects will be exported.", "all").argument("[template]", "The template to use for exporting Projects. Choose \"nested\" to export all Projects in a single, nested file or \"separate\" to export each Project in a separate folder with individual files.", "nested").option("-w, --watch", "Watches for changes in your Projects and updates the JSON file automatically.").action(async (outDir, projects, template, options) => {
3970
4113
  await exportAction(exportSchema.parse({
3971
4114
  outDir,
3972
4115
  projects,
4116
+ template,
3973
4117
  options
3974
4118
  }));
3975
4119
  });
@@ -3977,4 +4121,4 @@ await program.parseAsync();
3977
4121
 
3978
4122
  //#endregion
3979
4123
  export { };
3980
- //# sourceMappingURL=index.cli.js.map
4124
+ //# sourceMappingURL=index.cli.mjs.map