bloko 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/cascade/manager.d.ts +21 -0
  2. package/dist/cascade/manager.d.ts.map +1 -0
  3. package/dist/cascade/manager.js +282 -0
  4. package/dist/cascade/manager.js.map +1 -0
  5. package/dist/cli/index.d.ts +3 -0
  6. package/dist/cli/index.d.ts.map +1 -0
  7. package/dist/cli/index.js +145 -0
  8. package/dist/cli/index.js.map +1 -0
  9. package/dist/client.d.ts +55 -0
  10. package/dist/client.d.ts.map +1 -0
  11. package/dist/client.js +146 -0
  12. package/dist/client.js.map +1 -0
  13. package/dist/config.d.ts +29 -0
  14. package/dist/config.d.ts.map +1 -0
  15. package/dist/config.js +17 -0
  16. package/dist/config.js.map +1 -0
  17. package/dist/db/mongo.d.ts +15 -0
  18. package/dist/db/mongo.d.ts.map +1 -0
  19. package/dist/db/mongo.js +99 -0
  20. package/dist/db/mongo.js.map +1 -0
  21. package/dist/entities/base.d.ts +25 -0
  22. package/dist/entities/base.d.ts.map +1 -0
  23. package/dist/entities/base.js +71 -0
  24. package/dist/entities/base.js.map +1 -0
  25. package/dist/entities/blocks.d.ts +80 -0
  26. package/dist/entities/blocks.d.ts.map +1 -0
  27. package/dist/entities/blocks.js +152 -0
  28. package/dist/entities/blocks.js.map +1 -0
  29. package/dist/entities/collections.d.ts +40 -0
  30. package/dist/entities/collections.d.ts.map +1 -0
  31. package/dist/entities/collections.js +55 -0
  32. package/dist/entities/collections.js.map +1 -0
  33. package/dist/entities/contents.d.ts +60 -0
  34. package/dist/entities/contents.d.ts.map +1 -0
  35. package/dist/entities/contents.js +169 -0
  36. package/dist/entities/contents.js.map +1 -0
  37. package/dist/entities/image-variants.d.ts +95 -0
  38. package/dist/entities/image-variants.d.ts.map +1 -0
  39. package/dist/entities/image-variants.js +146 -0
  40. package/dist/entities/image-variants.js.map +1 -0
  41. package/dist/entities/images.d.ts +99 -0
  42. package/dist/entities/images.d.ts.map +1 -0
  43. package/dist/entities/images.js +128 -0
  44. package/dist/entities/images.js.map +1 -0
  45. package/dist/entities/languages.d.ts +25 -0
  46. package/dist/entities/languages.d.ts.map +1 -0
  47. package/dist/entities/languages.js +123 -0
  48. package/dist/entities/languages.js.map +1 -0
  49. package/dist/entities/node-relation-types.d.ts +60 -0
  50. package/dist/entities/node-relation-types.d.ts.map +1 -0
  51. package/dist/entities/node-relation-types.js +85 -0
  52. package/dist/entities/node-relation-types.js.map +1 -0
  53. package/dist/entities/node-relations.d.ts +61 -0
  54. package/dist/entities/node-relations.d.ts.map +1 -0
  55. package/dist/entities/node-relations.js +95 -0
  56. package/dist/entities/node-relations.js.map +1 -0
  57. package/dist/entities/node-types.d.ts +52 -0
  58. package/dist/entities/node-types.d.ts.map +1 -0
  59. package/dist/entities/node-types.js +67 -0
  60. package/dist/entities/node-types.js.map +1 -0
  61. package/dist/entities/nodes.d.ts +159 -0
  62. package/dist/entities/nodes.d.ts.map +1 -0
  63. package/dist/entities/nodes.js +265 -0
  64. package/dist/entities/nodes.js.map +1 -0
  65. package/dist/entities/templates.d.ts +60 -0
  66. package/dist/entities/templates.d.ts.map +1 -0
  67. package/dist/entities/templates.js +84 -0
  68. package/dist/entities/templates.js.map +1 -0
  69. package/dist/index.d.ts +16 -0
  70. package/dist/index.d.ts.map +1 -0
  71. package/dist/index.js +76 -0
  72. package/dist/index.js.map +1 -0
  73. package/dist/storage/s3.d.ts +23 -0
  74. package/dist/storage/s3.d.ts.map +1 -0
  75. package/dist/storage/s3.js +98 -0
  76. package/dist/storage/s3.js.map +1 -0
  77. package/dist/types.d.ts +113 -0
  78. package/dist/types.d.ts.map +1 -0
  79. package/dist/types.js +51 -0
  80. package/dist/types.js.map +1 -0
  81. package/dist/utils/image.d.ts +46 -0
  82. package/dist/utils/image.d.ts.map +1 -0
  83. package/dist/utils/image.js +117 -0
  84. package/dist/utils/image.js.map +1 -0
  85. package/dist/utils/multilang.d.ts +50 -0
  86. package/dist/utils/multilang.d.ts.map +1 -0
  87. package/dist/utils/multilang.js +124 -0
  88. package/dist/utils/multilang.js.map +1 -0
  89. package/dist/utils/slug.d.ts +25 -0
  90. package/dist/utils/slug.d.ts.map +1 -0
  91. package/dist/utils/slug.js +80 -0
  92. package/dist/utils/slug.js.map +1 -0
  93. package/dist/validation/schemas.d.ts +728 -0
  94. package/dist/validation/schemas.d.ts.map +1 -0
  95. package/dist/validation/schemas.js +164 -0
  96. package/dist/validation/schemas.js.map +1 -0
  97. package/package.json +48 -0
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ImageVariants = void 0;
4
+ const mongodb_1 = require("mongodb");
5
+ const base_js_1 = require("./base.js");
6
+ const types_js_1 = require("../types.js");
7
+ const schemas_js_1 = require("../validation/schemas.js");
8
+ const config_js_1 = require("../config.js");
9
+ const image_js_1 = require("../utils/image.js");
10
+ class ImageVariants extends base_js_1.BaseEntity {
11
+ s3;
12
+ imageExists;
13
+ collectionName = config_js_1.COLLECTION_NAMES.imageVariants;
14
+ createSchema = schemas_js_1.imageVariantCreateSchema;
15
+ updateSchema = schemas_js_1.imageVariantCreateSchema; // Variants are not updated, only created/deleted
16
+ constructor(ctx, s3, imageExists) {
17
+ super(ctx);
18
+ this.s3 = s3;
19
+ this.imageExists = imageExists;
20
+ }
21
+ async create(data) {
22
+ const validated = this.validateCreate(data);
23
+ const imageId = new mongodb_1.ObjectId(validated._image);
24
+ // Verify image exists
25
+ if (!(await this.imageExists(imageId))) {
26
+ throw new types_js_1.ReferenceError('Image not found', { _image: validated._image });
27
+ }
28
+ // Check for duplicate variant (same image/width/height/format)
29
+ const existing = await this.collection.findOne({
30
+ _image: imageId,
31
+ width: validated.width,
32
+ height: validated.height,
33
+ format: validated.format,
34
+ });
35
+ if (existing) {
36
+ throw new types_js_1.DuplicateError('ImageVariant', '_image/width/height/format', `${imageId}/${validated.width}/${validated.height}/${validated.format}`);
37
+ }
38
+ // Check for duplicate s3_key
39
+ const existingKey = await this.collection.findOne({ s3_key: validated.s3_key });
40
+ if (existingKey) {
41
+ throw new types_js_1.DuplicateError('ImageVariant', 's3_key', validated.s3_key);
42
+ }
43
+ const doc = {
44
+ _image: imageId,
45
+ width: validated.width,
46
+ height: validated.height,
47
+ s3_key: validated.s3_key,
48
+ format: validated.format,
49
+ file_size: validated.file_size,
50
+ };
51
+ const result = await this.collection.insertOne(doc);
52
+ return { ...doc, _id: result.insertedId };
53
+ }
54
+ async delete(id) {
55
+ const variant = await this.findById(id);
56
+ if (!variant) {
57
+ return false;
58
+ }
59
+ // Delete from S3
60
+ await this.s3.delete(variant.s3_key);
61
+ return this.deleteOne(id);
62
+ }
63
+ async deleteByImage(imageId) {
64
+ // Get all variants to delete their S3 files
65
+ const variants = await this.findByImage(imageId);
66
+ // Delete S3 files
67
+ if (variants.length > 0) {
68
+ await this.s3.deleteMany(variants.map((v) => v.s3_key));
69
+ }
70
+ return this.deleteMany({ _image: imageId });
71
+ }
72
+ async findByImage(imageId) {
73
+ return this.collection.find({ _image: imageId }).toArray();
74
+ }
75
+ async findVariant(imageId, width, height, format) {
76
+ return this.collection.findOne({
77
+ _image: imageId,
78
+ width,
79
+ height,
80
+ format,
81
+ });
82
+ }
83
+ /**
84
+ * Create a variant by uploading a resized image
85
+ */
86
+ async createVariant(imageId, variant) {
87
+ // Verify image exists
88
+ if (!(await this.imageExists(imageId))) {
89
+ throw new types_js_1.ReferenceError('Image not found', { _image: imageId.toString() });
90
+ }
91
+ // Generate S3 key for variant
92
+ const timestamp = Date.now();
93
+ const randomStr = Math.random().toString(36).substring(2, 8);
94
+ const s3Key = `variants/${imageId}/${variant.width}x${variant.height}-${timestamp}-${randomStr}.${variant.format}`;
95
+ // Upload to S3
96
+ await this.s3.upload({
97
+ key: s3Key,
98
+ body: variant.buffer,
99
+ contentType: variant.mimeType,
100
+ });
101
+ // Create database record
102
+ return this.create({
103
+ _image: imageId.toString(),
104
+ width: variant.width,
105
+ height: variant.height,
106
+ s3_key: s3Key,
107
+ format: variant.format,
108
+ file_size: variant.buffer.length,
109
+ });
110
+ }
111
+ /**
112
+ * Generate and upload a resized variant from an original image buffer
113
+ */
114
+ async generateVariant(imageId, originalBuffer, options) {
115
+ // Resize the image
116
+ const resized = await (0, image_js_1.resizeImage)(originalBuffer, options);
117
+ // Create the variant
118
+ return this.createVariant(imageId, {
119
+ buffer: resized.buffer,
120
+ width: resized.width,
121
+ height: resized.height,
122
+ format: resized.format,
123
+ mimeType: resized.mimeType,
124
+ });
125
+ }
126
+ /**
127
+ * Generate multiple variants from an original image buffer
128
+ */
129
+ async generateVariants(imageId, originalBuffer, sizes, formats = ['webp']) {
130
+ const results = [];
131
+ for (const size of sizes) {
132
+ for (const format of formats) {
133
+ const variant = await this.generateVariant(imageId, originalBuffer, {
134
+ width: size.width,
135
+ height: size.height,
136
+ format,
137
+ fit: 'inside',
138
+ });
139
+ results.push(variant);
140
+ }
141
+ }
142
+ return results;
143
+ }
144
+ }
145
+ exports.ImageVariants = ImageVariants;
146
+ //# sourceMappingURL=image-variants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-variants.js","sourceRoot":"","sources":["../../src/entities/image-variants.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ import { ObjectId } from 'mongodb';
2
+ import { BaseEntity, type EntityContext } from './base.js';
3
+ import type { ImageDoc } from '../types.js';
4
+ import { type ImageInput } from '../validation/schemas.js';
5
+ import type { S3Storage } from '../storage/s3.js';
6
+ export declare class Images extends BaseEntity<ImageDoc, ImageInput, Partial<ImageInput>> {
7
+ private s3;
8
+ private cascadeDelete;
9
+ private collectionExists;
10
+ protected collectionName: "images";
11
+ protected createSchema: import("zod").ZodObject<{
12
+ _collection: import("zod").ZodEffects<import("zod").ZodString, string, string>;
13
+ s3_key: import("zod").ZodString;
14
+ file_name: import("zod").ZodString;
15
+ mime_type: import("zod").ZodString;
16
+ format: import("zod").ZodEnum<["jpg", "jpeg", "png", "gif", "webp", "svg"]>;
17
+ file_size: import("zod").ZodNumber;
18
+ width: import("zod").ZodNumber;
19
+ height: import("zod").ZodNumber;
20
+ caption: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodNullable<import("zod").ZodString>>>>;
21
+ credit: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodNullable<import("zod").ZodString>>>>;
22
+ }, "strip", import("zod").ZodTypeAny, {
23
+ _collection: string;
24
+ s3_key: string;
25
+ width: number;
26
+ height: number;
27
+ format: "jpg" | "jpeg" | "png" | "gif" | "webp" | "svg";
28
+ file_name: string;
29
+ mime_type: string;
30
+ file_size: number;
31
+ caption?: Record<string, string | null> | null | undefined;
32
+ credit?: Record<string, string | null> | null | undefined;
33
+ }, {
34
+ _collection: string;
35
+ s3_key: string;
36
+ width: number;
37
+ height: number;
38
+ format: "jpg" | "jpeg" | "png" | "gif" | "webp" | "svg";
39
+ file_name: string;
40
+ mime_type: string;
41
+ file_size: number;
42
+ caption?: Record<string, string | null> | null | undefined;
43
+ credit?: Record<string, string | null> | null | undefined;
44
+ }>;
45
+ protected updateSchema: import("zod").ZodObject<Omit<{
46
+ _collection: import("zod").ZodOptional<import("zod").ZodEffects<import("zod").ZodString, string, string>>;
47
+ s3_key: import("zod").ZodOptional<import("zod").ZodString>;
48
+ file_name: import("zod").ZodOptional<import("zod").ZodString>;
49
+ mime_type: import("zod").ZodOptional<import("zod").ZodString>;
50
+ format: import("zod").ZodOptional<import("zod").ZodEnum<["jpg", "jpeg", "png", "gif", "webp", "svg"]>>;
51
+ file_size: import("zod").ZodOptional<import("zod").ZodNumber>;
52
+ width: import("zod").ZodOptional<import("zod").ZodNumber>;
53
+ height: import("zod").ZodOptional<import("zod").ZodNumber>;
54
+ caption: import("zod").ZodOptional<import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodNullable<import("zod").ZodString>>>>>;
55
+ credit: import("zod").ZodOptional<import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodNullable<import("zod").ZodString>>>>>;
56
+ }, "_collection" | "s3_key" | "width" | "height" | "file_size">, "strip", import("zod").ZodTypeAny, {
57
+ format?: "jpg" | "jpeg" | "png" | "gif" | "webp" | "svg" | undefined;
58
+ file_name?: string | undefined;
59
+ mime_type?: string | undefined;
60
+ caption?: Record<string, string | null> | null | undefined;
61
+ credit?: Record<string, string | null> | null | undefined;
62
+ }, {
63
+ format?: "jpg" | "jpeg" | "png" | "gif" | "webp" | "svg" | undefined;
64
+ file_name?: string | undefined;
65
+ mime_type?: string | undefined;
66
+ caption?: Record<string, string | null> | null | undefined;
67
+ credit?: Record<string, string | null> | null | undefined;
68
+ }>;
69
+ constructor(ctx: EntityContext, s3: S3Storage, cascadeDelete: (imageId: ObjectId) => Promise<void>, collectionExists: (id: ObjectId) => Promise<boolean>);
70
+ create(data: ImageInput): Promise<ImageDoc & {
71
+ _id: ObjectId;
72
+ }>;
73
+ update(id: ObjectId, data: Partial<ImageInput>): Promise<ImageDoc & {
74
+ _id: ObjectId;
75
+ }>;
76
+ delete(id: ObjectId): Promise<boolean>;
77
+ findByCollection(collectionId: ObjectId): Promise<(ImageDoc & {
78
+ _id: ObjectId;
79
+ })[]>;
80
+ findByS3Key(s3Key: string): Promise<(ImageDoc & {
81
+ _id: ObjectId;
82
+ }) | null>;
83
+ /**
84
+ * Upload an image file and create the database record
85
+ */
86
+ upload(collectionId: ObjectId, file: {
87
+ buffer: Buffer;
88
+ originalName: string;
89
+ mimeType: string;
90
+ width: number;
91
+ height: number;
92
+ }, metadata?: {
93
+ caption?: Record<string, string | null>;
94
+ credit?: Record<string, string | null>;
95
+ }): Promise<ImageDoc & {
96
+ _id: ObjectId;
97
+ }>;
98
+ }
99
+ //# sourceMappingURL=images.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"images.d.ts","sourceRoot":"","sources":["../../src/entities/images.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,qBAAa,MAAO,SAAQ,UAAU,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAO7E,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,gBAAgB;IAR1B,SAAS,CAAC,cAAc,WAA2B;IACnD,SAAS,CAAC,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAAqB;IAC3C,SAAS,CAAC,YAAY;;;;;;;;;;;;;;;;;;;;;;;OAAqB;gBAGzC,GAAG,EAAE,aAAa,EACV,EAAE,EAAE,SAAS,EACb,aAAa,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,EACnD,gBAAgB,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,OAAO,CAAC,OAAO,CAAC;IAKxD,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,GAAG;QAAE,GAAG,EAAE,QAAQ,CAAA;KAAE,CAAC;IAgC/D,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,QAAQ,GAAG;QAAE,GAAG,EAAE,QAAQ,CAAA;KAAE,CAAC;IAatF,MAAM,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAetC,gBAAgB,CAAC,YAAY,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC,QAAQ,GAAG;QAAE,GAAG,EAAE,QAAQ,CAAA;KAAE,CAAC,EAAE,CAAC;IAInF,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,QAAQ,GAAG;QAAE,GAAG,EAAE,QAAQ,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC;IAIhF;;OAEG;IACG,MAAM,CACV,YAAY,EAAE,QAAQ,EACtB,IAAI,EAAE;QACJ,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,EACD,QAAQ,CAAC,EAAE;QACT,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;QACxC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;KACxC,GACA,OAAO,CAAC,QAAQ,GAAG;QAAE,GAAG,EAAE,QAAQ,CAAA;KAAE,CAAC;CA6CzC"}
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Images = void 0;
4
+ const mongodb_1 = require("mongodb");
5
+ const base_js_1 = require("./base.js");
6
+ const types_js_1 = require("../types.js");
7
+ const schemas_js_1 = require("../validation/schemas.js");
8
+ const config_js_1 = require("../config.js");
9
+ const multilang_js_1 = require("../utils/multilang.js");
10
+ class Images extends base_js_1.BaseEntity {
11
+ s3;
12
+ cascadeDelete;
13
+ collectionExists;
14
+ collectionName = config_js_1.COLLECTION_NAMES.images;
15
+ createSchema = schemas_js_1.imageCreateSchema;
16
+ updateSchema = schemas_js_1.imageUpdateSchema;
17
+ constructor(ctx, s3, cascadeDelete, collectionExists) {
18
+ super(ctx);
19
+ this.s3 = s3;
20
+ this.cascadeDelete = cascadeDelete;
21
+ this.collectionExists = collectionExists;
22
+ }
23
+ async create(data) {
24
+ const validated = this.validateCreate(data);
25
+ const collectionId = new mongodb_1.ObjectId(validated._collection);
26
+ // Verify collection exists
27
+ if (!(await this.collectionExists(collectionId))) {
28
+ throw new types_js_1.ReferenceError('Collection not found', { _collection: validated._collection });
29
+ }
30
+ // Check for duplicate s3_key
31
+ const existing = await this.collection.findOne({ s3_key: validated.s3_key });
32
+ if (existing) {
33
+ throw new types_js_1.DuplicateError('Image', 's3_key', validated.s3_key);
34
+ }
35
+ const doc = {
36
+ _collection: collectionId,
37
+ s3_key: validated.s3_key,
38
+ file_name: validated.file_name,
39
+ mime_type: validated.mime_type,
40
+ format: validated.format,
41
+ file_size: validated.file_size,
42
+ width: validated.width,
43
+ height: validated.height,
44
+ caption: (0, multilang_js_1.cleanMultiLangString)(validated.caption),
45
+ credit: (0, multilang_js_1.cleanMultiLangString)(validated.credit),
46
+ };
47
+ const result = await this.collection.insertOne(doc);
48
+ return { ...doc, _id: result.insertedId };
49
+ }
50
+ async update(id, data) {
51
+ const validated = this.validateUpdate(data);
52
+ const updateData = {};
53
+ if (validated.file_name !== undefined)
54
+ updateData.file_name = validated.file_name;
55
+ if (validated.mime_type !== undefined)
56
+ updateData.mime_type = validated.mime_type;
57
+ if (validated.format !== undefined)
58
+ updateData.format = validated.format;
59
+ if (validated.caption !== undefined)
60
+ updateData.caption = (0, multilang_js_1.cleanMultiLangString)(validated.caption);
61
+ if (validated.credit !== undefined)
62
+ updateData.credit = (0, multilang_js_1.cleanMultiLangString)(validated.credit);
63
+ return this.updateOne(id, { $set: updateData });
64
+ }
65
+ async delete(id) {
66
+ const image = await this.findById(id);
67
+ if (!image) {
68
+ return false;
69
+ }
70
+ // Cascade delete variants and remove from node references
71
+ await this.cascadeDelete(id);
72
+ // Delete from S3
73
+ await this.s3.delete(image.s3_key);
74
+ return this.deleteOne(id);
75
+ }
76
+ async findByCollection(collectionId) {
77
+ return this.collection.find({ _collection: collectionId }).toArray();
78
+ }
79
+ async findByS3Key(s3Key) {
80
+ return this.collection.findOne({ s3_key: s3Key });
81
+ }
82
+ /**
83
+ * Upload an image file and create the database record
84
+ */
85
+ async upload(collectionId, file, metadata) {
86
+ // Verify collection exists
87
+ if (!(await this.collectionExists(collectionId))) {
88
+ throw new types_js_1.ReferenceError('Collection not found', { _collection: collectionId.toString() });
89
+ }
90
+ // Determine format from mime type
91
+ const formatMap = {
92
+ 'image/jpeg': 'jpg',
93
+ 'image/png': 'png',
94
+ 'image/gif': 'gif',
95
+ 'image/webp': 'webp',
96
+ 'image/svg+xml': 'svg',
97
+ };
98
+ const format = formatMap[file.mimeType];
99
+ if (!format) {
100
+ throw new types_js_1.ReferenceError('Unsupported image format', { mimeType: file.mimeType });
101
+ }
102
+ // Generate S3 key
103
+ const timestamp = Date.now();
104
+ const randomStr = Math.random().toString(36).substring(2, 8);
105
+ const s3Key = `images/${collectionId}/${timestamp}-${randomStr}.${format}`;
106
+ // Upload to S3
107
+ await this.s3.upload({
108
+ key: s3Key,
109
+ body: file.buffer,
110
+ contentType: file.mimeType,
111
+ });
112
+ // Create database record
113
+ return this.create({
114
+ _collection: collectionId.toString(),
115
+ s3_key: s3Key,
116
+ file_name: file.originalName,
117
+ mime_type: file.mimeType,
118
+ format: format,
119
+ file_size: file.buffer.length,
120
+ width: file.width,
121
+ height: file.height,
122
+ caption: metadata?.caption,
123
+ credit: metadata?.credit,
124
+ });
125
+ }
126
+ }
127
+ exports.Images = Images;
128
+ //# sourceMappingURL=images.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"images.js","sourceRoot":"","sources":["../../src/entities/images.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { Filter } from 'mongodb';
2
+ import type { EntityContext } from './base.js';
3
+ import type { LanguageDoc } from '../types.js';
4
+ import { type LanguageInput } from '../validation/schemas.js';
5
+ export declare class Languages {
6
+ private ctx;
7
+ private cascadeLanguageDelete;
8
+ private cascadeLanguageRename;
9
+ private collectionName;
10
+ private createSchema;
11
+ private updateSchema;
12
+ constructor(ctx: EntityContext, cascadeLanguageDelete: (langId: string) => Promise<void>, cascadeLanguageRename: (oldLangId: string, newLangId: string) => Promise<void>);
13
+ private get collection();
14
+ private validateCreate;
15
+ private validateUpdate;
16
+ create(data: LanguageInput): Promise<LanguageDoc>;
17
+ update(id: string, data: Partial<LanguageInput>): Promise<LanguageDoc>;
18
+ delete(id: string): Promise<boolean>;
19
+ findById(id: string): Promise<LanguageDoc | null>;
20
+ findByIdOrThrow(id: string): Promise<LanguageDoc>;
21
+ findMany(filter?: Filter<LanguageDoc>): Promise<LanguageDoc[]>;
22
+ findAll(): Promise<LanguageDoc[]>;
23
+ getAllIds(): Promise<string[]>;
24
+ }
25
+ //# sourceMappingURL=languages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"languages.d.ts","sourceRoot":"","sources":["../../src/entities/languages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,MAAM,EAAE,MAAM,SAAS,CAAC;AAElD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,0BAA0B,CAAC;AAGlC,qBAAa,SAAS;IAMlB,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,qBAAqB;IAC7B,OAAO,CAAC,qBAAqB;IAP/B,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,YAAY,CAAkD;IACtE,OAAO,CAAC,YAAY,CAA2D;gBAGrE,GAAG,EAAE,aAAa,EAClB,qBAAqB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,EACxD,qBAAqB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;IAGxF,OAAO,KAAK,UAAU,GAErB;IAED,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,cAAc;IAUhB,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC;IAmBjD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IA4CtE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAapC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAIjD,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAQjD,QAAQ,CAAC,MAAM,GAAE,MAAM,CAAC,WAAW,CAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAIlE,OAAO,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAIjC,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAIrC"}
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Languages = void 0;
4
+ const types_js_1 = require("../types.js");
5
+ const schemas_js_1 = require("../validation/schemas.js");
6
+ const config_js_1 = require("../config.js");
7
+ class Languages {
8
+ ctx;
9
+ cascadeLanguageDelete;
10
+ cascadeLanguageRename;
11
+ collectionName = config_js_1.COLLECTION_NAMES.languages;
12
+ createSchema = schemas_js_1.languageCreateSchema;
13
+ updateSchema = schemas_js_1.languageUpdateSchema;
14
+ constructor(ctx, cascadeLanguageDelete, cascadeLanguageRename) {
15
+ this.ctx = ctx;
16
+ this.cascadeLanguageDelete = cascadeLanguageDelete;
17
+ this.cascadeLanguageRename = cascadeLanguageRename;
18
+ }
19
+ get collection() {
20
+ return this.ctx.getCollection(this.collectionName);
21
+ }
22
+ validateCreate(data) {
23
+ const result = this.createSchema.safeParse(data);
24
+ if (!result.success) {
25
+ throw new types_js_1.ValidationError('Validation failed', {
26
+ errors: result.error.errors,
27
+ });
28
+ }
29
+ return result.data;
30
+ }
31
+ validateUpdate(data) {
32
+ const result = this.updateSchema.safeParse(data);
33
+ if (!result.success) {
34
+ throw new types_js_1.ValidationError('Validation failed', {
35
+ errors: result.error.errors,
36
+ });
37
+ }
38
+ return result.data;
39
+ }
40
+ async create(data) {
41
+ const validated = this.validateCreate(data);
42
+ // Check for duplicate id
43
+ const existing = await this.collection.findOne({ _id: validated.id });
44
+ if (existing) {
45
+ throw new types_js_1.DuplicateError('Language', 'id', validated.id);
46
+ }
47
+ const doc = {
48
+ _id: validated.id,
49
+ title: validated.title,
50
+ sort: validated.sort ?? null,
51
+ };
52
+ await this.collection.insertOne(doc);
53
+ return doc;
54
+ }
55
+ async update(id, data) {
56
+ const validated = this.validateUpdate(data);
57
+ const existing = await this.findById(id);
58
+ if (!existing) {
59
+ throw new types_js_1.NotFoundError('Language', id);
60
+ }
61
+ // Handle ID change (rename)
62
+ if (validated.id && validated.id !== id) {
63
+ // Check if new ID already exists
64
+ const duplicate = await this.collection.findOne({ _id: validated.id });
65
+ if (duplicate) {
66
+ throw new types_js_1.DuplicateError('Language', 'id', validated.id);
67
+ }
68
+ // Cascade rename in all multi-language fields
69
+ await this.cascadeLanguageRename(id, validated.id);
70
+ // Create new document with new ID
71
+ const newDoc = {
72
+ _id: validated.id,
73
+ title: validated.title ?? existing.title,
74
+ sort: validated.sort !== undefined ? validated.sort : existing.sort,
75
+ };
76
+ await this.collection.insertOne(newDoc);
77
+ await this.collection.deleteOne({ _id: id });
78
+ return newDoc;
79
+ }
80
+ // Regular update
81
+ const updateData = {};
82
+ if (validated.title !== undefined)
83
+ updateData.title = validated.title;
84
+ if (validated.sort !== undefined)
85
+ updateData.sort = validated.sort;
86
+ if (Object.keys(updateData).length > 0) {
87
+ await this.collection.updateOne({ _id: id }, { $set: updateData });
88
+ }
89
+ return (await this.findById(id));
90
+ }
91
+ async delete(id) {
92
+ const existing = await this.findById(id);
93
+ if (!existing) {
94
+ return false;
95
+ }
96
+ // Cascade delete language key from all multi-language fields
97
+ await this.cascadeLanguageDelete(id);
98
+ const result = await this.collection.deleteOne({ _id: id });
99
+ return result.deletedCount > 0;
100
+ }
101
+ async findById(id) {
102
+ return this.collection.findOne({ _id: id });
103
+ }
104
+ async findByIdOrThrow(id) {
105
+ const doc = await this.findById(id);
106
+ if (!doc) {
107
+ throw new types_js_1.NotFoundError('Language', id);
108
+ }
109
+ return doc;
110
+ }
111
+ async findMany(filter = {}) {
112
+ return this.collection.find(filter).sort({ sort: 1, _id: 1 }).toArray();
113
+ }
114
+ async findAll() {
115
+ return this.findMany();
116
+ }
117
+ async getAllIds() {
118
+ const langs = await this.findAll();
119
+ return langs.map((l) => l._id);
120
+ }
121
+ }
122
+ exports.Languages = Languages;
123
+ //# sourceMappingURL=languages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"languages.js","sourceRoot":"","sources":["../../src/entities/languages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import { ObjectId } from 'mongodb';
2
+ import { BaseEntity, type EntityContext } from './base.js';
3
+ import type { NodeRelationTypeDoc } from '../types.js';
4
+ import { type NodeRelationTypeInput } from '../validation/schemas.js';
5
+ export declare class NodeRelationTypes extends BaseEntity<NodeRelationTypeDoc, NodeRelationTypeInput, Partial<Omit<NodeRelationTypeInput, '_collection'>>> {
6
+ private cascadeDelete;
7
+ private collectionExists;
8
+ protected collectionName: "node_relation_types";
9
+ protected createSchema: import("zod").ZodObject<{
10
+ code: import("zod").ZodString;
11
+ _collection: import("zod").ZodEffects<import("zod").ZodString, string, string>;
12
+ title: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodNullable<import("zod").ZodString>>>>;
13
+ reverse_title: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodNullable<import("zod").ZodString>>>>;
14
+ notes: import("zod").ZodNullable<import("zod").ZodOptional<import("zod").ZodString>>;
15
+ }, "strip", import("zod").ZodTypeAny, {
16
+ code: string;
17
+ _collection: string;
18
+ title?: Record<string, string | null> | null | undefined;
19
+ notes?: string | null | undefined;
20
+ reverse_title?: Record<string, string | null> | null | undefined;
21
+ }, {
22
+ code: string;
23
+ _collection: string;
24
+ title?: Record<string, string | null> | null | undefined;
25
+ notes?: string | null | undefined;
26
+ reverse_title?: Record<string, string | null> | null | undefined;
27
+ }>;
28
+ protected updateSchema: import("zod").ZodObject<Omit<{
29
+ code: import("zod").ZodOptional<import("zod").ZodString>;
30
+ _collection: import("zod").ZodOptional<import("zod").ZodEffects<import("zod").ZodString, string, string>>;
31
+ title: import("zod").ZodOptional<import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodNullable<import("zod").ZodString>>>>>;
32
+ reverse_title: import("zod").ZodOptional<import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodNullable<import("zod").ZodString>>>>>;
33
+ notes: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodOptional<import("zod").ZodString>>>;
34
+ }, "_collection">, "strip", import("zod").ZodTypeAny, {
35
+ code?: string | undefined;
36
+ title?: Record<string, string | null> | null | undefined;
37
+ notes?: string | null | undefined;
38
+ reverse_title?: Record<string, string | null> | null | undefined;
39
+ }, {
40
+ code?: string | undefined;
41
+ title?: Record<string, string | null> | null | undefined;
42
+ notes?: string | null | undefined;
43
+ reverse_title?: Record<string, string | null> | null | undefined;
44
+ }>;
45
+ constructor(ctx: EntityContext, cascadeDelete: (nodeRelationTypeId: ObjectId) => Promise<void>, collectionExists: (id: ObjectId) => Promise<boolean>);
46
+ create(data: NodeRelationTypeInput): Promise<NodeRelationTypeDoc & {
47
+ _id: ObjectId;
48
+ }>;
49
+ update(id: ObjectId, data: Partial<Omit<NodeRelationTypeInput, '_collection'>>): Promise<NodeRelationTypeDoc & {
50
+ _id: ObjectId;
51
+ }>;
52
+ delete(id: ObjectId): Promise<boolean>;
53
+ findByCode(collectionId: ObjectId, code: string): Promise<(NodeRelationTypeDoc & {
54
+ _id: ObjectId;
55
+ }) | null>;
56
+ findByCollection(collectionId: ObjectId): Promise<(NodeRelationTypeDoc & {
57
+ _id: ObjectId;
58
+ })[]>;
59
+ }
60
+ //# sourceMappingURL=node-relation-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-relation-types.d.ts","sourceRoot":"","sources":["../../src/entities/node-relation-types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,0BAA0B,CAAC;AAIlC,qBAAa,iBAAkB,SAAQ,UAAU,CAC/C,mBAAmB,EACnB,qBAAqB,EACrB,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE,aAAa,CAAC,CAAC,CACpD;IAOG,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,gBAAgB;IAP1B,SAAS,CAAC,cAAc,wBAAsC;IAC9D,SAAS,CAAC,YAAY;;;;;;;;;;;;;;;;;;OAAgC;IACtD,SAAS,CAAC,YAAY;;;;;;;;;;;;;;;;OAAgC;gBAGpD,GAAG,EAAE,aAAa,EACV,aAAa,EAAE,CAAC,kBAAkB,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,EAC9D,gBAAgB,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,OAAO,CAAC,OAAO,CAAC;IAKxD,MAAM,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,mBAAmB,GAAG;QAAE,GAAG,EAAE,QAAQ,CAAA;KAAE,CAAC;IA8BrF,MAAM,CACV,EAAE,EAAE,QAAQ,EACZ,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE,aAAa,CAAC,CAAC,GACxD,OAAO,CAAC,mBAAmB,GAAG;QAAE,GAAG,EAAE,QAAQ,CAAA;KAAE,CAAC;IA2B7C,MAAM,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAOtC,UAAU,CACd,YAAY,EAAE,QAAQ,EACtB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,CAAC,mBAAmB,GAAG;QAAE,GAAG,EAAE,QAAQ,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC;IAItD,gBAAgB,CAAC,YAAY,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC,mBAAmB,GAAG;QAAE,GAAG,EAAE,QAAQ,CAAA;KAAE,CAAC,EAAE,CAAC;CAGrG"}