@cheetah.js/orm 0.1.89 → 0.1.91

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -123,7 +123,7 @@ export class User {
123
123
  }
124
124
  ```
125
125
 
126
- For define a index for a multiple properties, add the @Index decorator:
126
+ For define a index for a multiple properties, add the @Index decorator. You can use it on a property or on the class. It accepts either an array of property names (legacy) or an object with a properties field (recommended):
127
127
 
128
128
  ```javascript
129
129
  @Entity()
@@ -134,10 +134,29 @@ export class User {
134
134
  @Property()
135
135
  name: string;
136
136
 
137
- @Index(['name', 'email'])
138
- @Property()
139
- email: string;
140
- }
137
+ // Property-level (compound index)
138
+ @Index({ properties: ['name', 'email'] })
139
+ @Property()
140
+ email: string;
141
+ }
142
+
143
+ // Or, at the class level
144
+
145
+ @Entity()
146
+ @Index<{ User }>({ properties: ['name', 'email'] })
147
+ export class User {
148
+ @PrimaryKey()
149
+ id: number;
150
+
151
+ @Property()
152
+ name: string;
153
+
154
+ @Property()
155
+ email: string;
156
+ }
157
+
158
+ // Backward compatible usage (array):
159
+ // @Index(['name', 'email'])
141
160
  ```
142
161
 
143
162
  #### Property options
@@ -1,3 +1,5 @@
1
- export declare function Index<T>(options?: {
1
+ type IndexOptions<T> = {
2
2
  properties: (keyof T)[];
3
- }): PropertyDecorator;
3
+ } | (keyof T)[] | undefined;
4
+ export declare function Index<T>(options?: IndexOptions<T>): ClassDecorator & PropertyDecorator;
5
+ export {};
@@ -2,18 +2,34 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Index = Index;
4
4
  const core_1 = require("@cheetah.js/core");
5
+ function getCtor(target) {
6
+ return typeof target === "function" ? target : target.constructor;
7
+ }
8
+ function buildFromOptions(options) {
9
+ const props = Array.isArray(options) ? options : options?.properties;
10
+ if (!props || props.length === 0)
11
+ return null;
12
+ const keys = props;
13
+ return { name: `${keys.join('_')}_index`, properties: keys };
14
+ }
15
+ function buildFromProperty(propertyKey) {
16
+ const name = String(propertyKey);
17
+ return { name: `${name}_index`, properties: [name] };
18
+ }
19
+ function resolveIndex(options, propertyKey) {
20
+ const fromOptions = buildFromOptions(options);
21
+ if (fromOptions)
22
+ return fromOptions;
23
+ if (!propertyKey)
24
+ throw new Error("@Index on class requires properties option");
25
+ return buildFromProperty(propertyKey);
26
+ }
5
27
  function Index(options) {
6
28
  return (target, propertyKey) => {
7
- const indexes = core_1.Metadata.get('indexes', target.constructor) || [];
8
- let index;
9
- if (options && options.properties) {
10
- const properties = options.properties;
11
- index = { name: `${properties.join('_')}_index`, properties: options.properties };
12
- }
13
- else {
14
- index = { name: `${propertyKey}_index`, properties: [propertyKey] };
15
- }
29
+ const ctor = getCtor(target);
30
+ const indexes = core_1.Metadata.get("indexes", ctor) || [];
31
+ const index = resolveIndex(options, propertyKey);
16
32
  indexes.push(index);
17
- core_1.Metadata.set('indexes', indexes, target.constructor);
33
+ core_1.Metadata.set("indexes", indexes, ctor);
18
34
  };
19
35
  }
@@ -28,10 +28,33 @@ let EntityStorage = EntityStorage_1 = class EntityStorage {
28
28
  .map(([key]) => key),
29
29
  relations,
30
30
  indexes: indexes.map((index) => {
31
+ // Convert property names to database column names
32
+ const columnNames = index.properties.map(propName => {
33
+ // Check if it's a regular property
34
+ if (properties[propName]) {
35
+ return properties[propName].options.columnName;
36
+ }
37
+ // Check if it's a relation
38
+ const relation = relations.find(rel => String(rel.propertyKey) === propName);
39
+ if (relation) {
40
+ return relation.columnName;
41
+ }
42
+ // Fallback to snake_case conversion if not found
43
+ return (0, utils_1.toSnakeCase)(propName);
44
+ });
45
+ // Preserve the original index name if it's a primary key index (contains _pkey or [TABLE])
46
+ // Otherwise, generate index name using column names
47
+ let indexName;
48
+ if (index.name.includes('_pkey') || index.name.includes('[TABLE]')) {
49
+ indexName = index.name.replace("[TABLE]", entityName);
50
+ }
51
+ else {
52
+ indexName = `${columnNames.join("_")}_index`;
53
+ }
31
54
  return {
32
55
  table: entityName,
33
- indexName: index.name.replace("[TABLE]", entityName),
34
- columnName: index.properties.join(","),
56
+ indexName,
57
+ columnName: columnNames.join(","),
35
58
  };
36
59
  }),
37
60
  hooks,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cheetah.js/orm",
3
- "version": "0.1.89",
3
+ "version": "0.1.91",
4
4
  "description": "A simple ORM for Cheetah.js",
5
5
  "type": "commonjs",
6
6
  "main": "dist/index.js",
@@ -37,7 +37,7 @@
37
37
  "uuid": "^9.0.1"
38
38
  },
39
39
  "peerDependencies": {
40
- "@cheetah.js/core": "^0.1.35"
40
+ "@cheetah.js/core": "^0.1.90"
41
41
  },
42
42
  "author": "",
43
43
  "license": "MIT",
@@ -55,5 +55,5 @@
55
55
  "bun",
56
56
  "value-object"
57
57
  ],
58
- "gitHead": "466942b8f3150372473238d0860408d0651ddd39"
58
+ "gitHead": "f173c0f552aac5f22debe446c8192abd5a80d9a3"
59
59
  }