es-mapping-ts
Advanced tools
Comparing version
@@ -8,3 +8,5 @@ /** | ||
/** Type of the index */ | ||
type: string; | ||
type?: string; | ||
/** create mapping or not **/ | ||
readonly?: boolean; | ||
} | ||
@@ -15,2 +17,2 @@ /** | ||
*/ | ||
export declare function EsEntity(args: EsEntityArgs): ClassDecorator; | ||
export declare function EsEntity(args?: EsEntityArgs): ClassDecorator; |
@@ -0,1 +1,2 @@ | ||
import 'reflect-metadata'; | ||
/** | ||
@@ -11,2 +12,18 @@ * Argument for a simple elasticsearch field | ||
analyzer?: string; | ||
/** Additionnal ES fields **/ | ||
fields?: any; | ||
/** Format */ | ||
format?: any; | ||
/** Enabled */ | ||
enabled?: boolean; | ||
/** Define the null value */ | ||
null_value?: any; | ||
/** copy into a group field */ | ||
copy_to?: string; | ||
/** Relations for join datatype */ | ||
relations?: any; | ||
/** Nested type for nested datatype */ | ||
nestedType?: any; | ||
/** Additional properties */ | ||
[x: string]: any; | ||
} | ||
@@ -13,0 +30,0 @@ /** |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var es_mapping_service_1 = require("./es-mapping.service"); | ||
require("reflect-metadata"); | ||
/** | ||
@@ -19,5 +20,17 @@ * Argument for a simple elasticsearch field | ||
return function (target, propertyKey) { | ||
es_mapping_service_1.EsMappingService.getInstance().addField(args, target, propertyKey); | ||
var propertyType = Reflect.getMetadata("design:type", target, propertyKey); | ||
if (args.type === 'join' && !args.relations) { | ||
throw new Error("es-mapping-error no relations defined for join datatype : " + target.constructor.name + ":" + propertyKey); | ||
} | ||
if (args.type === 'nested') { | ||
if (!args.nestedType) { | ||
throw new Error("es-mapping-error no nestedType defined for nested datatype : " + target.constructor.name + ":" + propertyKey); | ||
} | ||
if (propertyType.name !== 'Array') { | ||
throw new Error("es-mapping-error type of a nested field my be an array : " + target.constructor.name + ":" + propertyKey); | ||
} | ||
} | ||
es_mapping_service_1.EsMappingService.getInstance().addField(args, target, propertyKey, propertyType); | ||
}; | ||
} | ||
exports.EsField = EsField; |
@@ -13,2 +13,15 @@ /** | ||
/** | ||
* Internal mapping to handle specific parameter | ||
*/ | ||
export declare class InternalEsMapping { | ||
index: string; | ||
type: string; | ||
readonly: boolean; | ||
esmapping: EsMapping; | ||
properties: Map<string | symbol, InternalEsMappingProperty>; | ||
constructor(); | ||
mergeEsMapping(): void; | ||
addProperty(name: string | symbol, mapping: InternalEsMappingProperty): void; | ||
} | ||
/** | ||
* Base format of an elasticsearch property | ||
@@ -20,2 +33,17 @@ */ | ||
properties?: any; | ||
fields?: any; | ||
} | ||
/** | ||
* Base format of an elasticsearch property | ||
*/ | ||
export interface InternalEsMappingProperty extends EsMappingProperty { | ||
propertyMapping: EsMappingProperty; | ||
transformers?: EsMappingPropertyTranformer[]; | ||
} | ||
export interface EsMappingPropertyTranformer { | ||
fieldName: string; | ||
transformer: EsPropertyTranformer; | ||
} | ||
export interface EsPropertyTranformer { | ||
transform(input: any): any; | ||
} |
@@ -8,3 +8,2 @@ "use strict"; | ||
function EsMapping() { | ||
this.body = { properties: {} }; | ||
} | ||
@@ -14,1 +13,23 @@ return EsMapping; | ||
exports.EsMapping = EsMapping; | ||
/** | ||
* Internal mapping to handle specific parameter | ||
*/ | ||
var InternalEsMapping = /** @class */ (function () { | ||
function InternalEsMapping() { | ||
this.properties = new Map(); | ||
this.esmapping = new EsMapping(); | ||
} | ||
InternalEsMapping.prototype.mergeEsMapping = function () { | ||
if (!this.esmapping) { | ||
this.esmapping = new EsMapping(); | ||
} | ||
this.esmapping.index = this.esmapping.index; | ||
this.esmapping.type = this.esmapping.type; | ||
}; | ||
InternalEsMapping.prototype.addProperty = function (name, mapping) { | ||
this.properties.set(name, mapping); | ||
this.esmapping.body.properties[name] = mapping.propertyMapping; | ||
}; | ||
return InternalEsMapping; | ||
}()); | ||
exports.InternalEsMapping = InternalEsMapping; |
@@ -1,5 +0,5 @@ | ||
import { EsMapping } from "./es-mapping"; | ||
import { EsMapping, InternalEsMapping } from "./es-mapping"; | ||
import { EsFieldArgs } from "./es-field.decorator"; | ||
import { EsEntityArgs } from "./es-entity.decorator"; | ||
import { EsNestedFieldArgs } from "./es-nested-field.decorator"; | ||
import { Client } from 'elasticsearch'; | ||
/** | ||
@@ -10,3 +10,3 @@ * Service used to manage mapping loading and share it | ||
static instance: EsMappingService; | ||
esMappings: Map<String, EsMapping>; | ||
esMappings: Map<String, InternalEsMapping>; | ||
constructor(); | ||
@@ -24,9 +24,2 @@ /** | ||
/** | ||
* Add the nested field in the mapping | ||
* @param _args decorator args | ||
* @param target class | ||
* @param propertyKey the property | ||
*/ | ||
addNestedField(_args: EsNestedFieldArgs, target: any, propertyKey: any, typeName: string): void; | ||
/** | ||
* Add the field in the mapping | ||
@@ -37,11 +30,15 @@ * @param args decorator args | ||
*/ | ||
addField(args: EsFieldArgs, target: any, propertyKey: string | symbol, nestedProperties?: any): void; | ||
addField(args: EsFieldArgs, target: any, propertyKey: string | symbol, propertyType?: any): void; | ||
/** | ||
* Alllow you to get the generated mapping list ready to be inserted inside elasticsearch | ||
*/ | ||
getMappings(): Array<EsMapping>; | ||
getMappings(): Array<InternalEsMapping>; | ||
/** | ||
* Allow you to get all index | ||
*/ | ||
getEsMappings(): Array<EsMapping>; | ||
/** | ||
* Allow you to get the generate mapping map | ||
*/ | ||
getMappingsMap(): Map<String, EsMapping>; | ||
getMappingsMap(): Map<String, InternalEsMapping>; | ||
/** | ||
@@ -66,2 +63,6 @@ * Alllow you to get the generated mapping ready to be inserted inside elasticsearch | ||
getAllIndex(): Array<String>; | ||
/** | ||
* Allow to insert/update mapping into elasticsearch | ||
*/ | ||
uploadMappings(esclient: Client): Promise<void>; | ||
} |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [0, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var es_mapping_1 = require("./es-mapping"); | ||
var lodash = require("lodash"); | ||
var bluebird = require("bluebird"); | ||
/** | ||
@@ -31,18 +67,13 @@ * Service used to manage mapping loading and share it | ||
if (!mapping) { | ||
mapping = new es_mapping_1.EsMapping(); | ||
mapping = new es_mapping_1.InternalEsMapping(); | ||
this.esMappings.set(className, mapping); | ||
} | ||
mapping.index = args.index; | ||
mapping.type = args.type; | ||
if (args) { | ||
mapping.esmapping.index = args.index; | ||
mapping.esmapping.type = args.type; | ||
mapping.readonly = (args.readonly === true); | ||
} | ||
mapping.mergeEsMapping(); | ||
}; | ||
/** | ||
* Add the nested field in the mapping | ||
* @param _args decorator args | ||
* @param target class | ||
* @param propertyKey the property | ||
*/ | ||
EsMappingService.prototype.addNestedField = function (_args, target, propertyKey, typeName) { | ||
this.addField({ type: "nested" }, target, propertyKey, this.esMappings.get(typeName).body.properties); | ||
}; | ||
/** | ||
* Add the field in the mapping | ||
@@ -53,22 +84,33 @@ * @param args decorator args | ||
*/ | ||
EsMappingService.prototype.addField = function (args, target, propertyKey, nestedProperties) { | ||
EsMappingService.prototype.addField = function (args, target, propertyKey, propertyType) { | ||
var className = target.constructor.name; | ||
var mapping = this.esMappings.get(className); | ||
if (!mapping) { | ||
mapping = new es_mapping_1.EsMapping(); | ||
mapping = new es_mapping_1.InternalEsMapping(); | ||
this.esMappings.set(className, mapping); | ||
mapping.mergeEsMapping(); | ||
} | ||
var property = {}; | ||
var properties = {}; | ||
if (args) { | ||
property = { | ||
type: args.type, | ||
analyzer: args.analyzer | ||
if (args.type === 'nested') { | ||
properties.type = 'nested'; | ||
properties.properties = this.esMappings.get(args.nestedType.name).esmapping.body.properties; | ||
} | ||
else if (args.type === 'object') { | ||
properties.properties = this.esMappings.get(propertyType.name).esmapping.body.properties; | ||
} | ||
else { | ||
properties = args; | ||
} | ||
var internalProperty = { | ||
propertyMapping: properties | ||
}; | ||
if (nestedProperties) { | ||
property.properties = nestedProperties; | ||
} | ||
mapping.body.properties[args.name || propertyKey] = property; | ||
var propertyName = args.name || propertyKey; | ||
mapping.addProperty(propertyName, internalProperty); | ||
} | ||
else { | ||
mapping.body.properties[propertyKey] = {}; | ||
var internalProperty = { | ||
propertyMapping: {} | ||
}; | ||
mapping.addProperty(propertyKey, internalProperty); | ||
} | ||
@@ -83,2 +125,10 @@ }; | ||
/** | ||
* Allow you to get all index | ||
*/ | ||
EsMappingService.prototype.getEsMappings = function () { | ||
return lodash.map(Array.from(this.esMappings.values()), function (mapping) { | ||
return mapping.esmapping; | ||
}); | ||
}; | ||
/** | ||
* Allow you to get the generate mapping map | ||
@@ -94,3 +144,3 @@ */ | ||
EsMappingService.prototype.getMappingForClass = function (className) { | ||
return this.esMappings.get(className); | ||
return this.esMappings.get(className).esmapping; | ||
}; | ||
@@ -102,5 +152,5 @@ /** | ||
EsMappingService.prototype.getMappingForIndex = function (indexName) { | ||
return lodash.find(this.esMappings.values, function (esMapping) { | ||
return esMapping.index === indexName; | ||
}); | ||
return lodash.find(Array.from(this.esMappings.values()), function (internalEsMapping) { | ||
return internalEsMapping.esmapping.index === indexName; | ||
}).esmapping; | ||
}; | ||
@@ -112,5 +162,5 @@ /** | ||
EsMappingService.prototype.getMappingForType = function (type) { | ||
return lodash.find(this.esMappings.values, function (esMapping) { | ||
return esMapping.type === type; | ||
}); | ||
return lodash.find(Array.from(this.esMappings.values()), function (internalEsMapping) { | ||
return internalEsMapping.esmapping.type === type; | ||
}).esmapping; | ||
}; | ||
@@ -122,7 +172,61 @@ /** | ||
return lodash.map(Array.from(this.esMappings.values()), function (mapping) { | ||
return mapping.index; | ||
return mapping.esmapping.index; | ||
}); | ||
}; | ||
/** | ||
* Allow to insert/update mapping into elasticsearch | ||
*/ | ||
EsMappingService.prototype.uploadMappings = function (esclient) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var _this = this; | ||
var mappings; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
mappings = EsMappingService.getInstance().getMappings(); | ||
return [4 /*yield*/, bluebird.each(mappings, function (internalMapping) { return __awaiter(_this, void 0, void 0, function () { | ||
var esMapping, index, indexExist; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
if (!!internalMapping.readonly) return [3 /*break*/, 6]; | ||
esMapping = internalMapping.esmapping; | ||
index = internalMapping.esmapping.index; | ||
// Delete readonly for ES compatibility | ||
delete internalMapping.readonly; | ||
return [4 /*yield*/, esclient.indices.exists({ index: index })]; | ||
case 1: | ||
indexExist = _a.sent(); | ||
if (!!indexExist) return [3 /*break*/, 4]; | ||
//create index | ||
return [4 /*yield*/, esclient.indices.create({ index: esMapping.index })]; | ||
case 2: | ||
//create index | ||
_a.sent(); | ||
//create mapping | ||
return [4 /*yield*/, esclient.indices.putMapping(esMapping)]; | ||
case 3: | ||
//create mapping | ||
_a.sent(); | ||
return [3 /*break*/, 6]; | ||
case 4: | ||
//update mapping | ||
return [4 /*yield*/, esclient.indices.putMapping(esMapping)]; | ||
case 5: | ||
//update mapping | ||
_a.sent(); | ||
_a.label = 6; | ||
case 6: return [2 /*return*/]; | ||
} | ||
}); | ||
}); })]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
}; | ||
return EsMappingService; | ||
}()); | ||
exports.EsMappingService = EsMappingService; |
export * from './es-entity.decorator'; | ||
export * from './es-field.decorator'; | ||
export * from './es-nested-field.decorator'; | ||
export * from './es-mapping.service'; | ||
export * from './es-mapping'; |
@@ -8,4 +8,3 @@ "use strict"; | ||
__export(require("./es-field.decorator")); | ||
__export(require("./es-nested-field.decorator")); | ||
__export(require("./es-mapping.service")); | ||
__export(require("./es-mapping")); |
{ | ||
"name": "es-mapping-ts", | ||
"version": "0.0.8", | ||
"version": "0.0.9", | ||
"description": "ES Mapping TypeScript", | ||
@@ -14,16 +14,21 @@ "main": "./dist/index.js", | ||
"dependencies": { | ||
"lodash": "^4.17.5", | ||
"reflect-metadata": "^0.1.12" | ||
}, | ||
"peerDependencies": { | ||
"bluebird": "^3.5.1", | ||
"elasticsearch": "^14.2.2", | ||
"lodash": "^4.17.5" | ||
}, | ||
"devDependencies": { | ||
"@types/bluebird": "^3.5.20", | ||
"@types/lodash": "^4.14.105", | ||
"cross-env": "^5.1.3", | ||
"gulp": "^3.9.1", | ||
"gulp-clean": "^0.3.2", | ||
"gulp-sourcemaps": "^2.6.1", | ||
"gulp-typescript": "^3.2.3", | ||
"mocha": "^5.0.1", | ||
"nyc": "^11.4.1", | ||
"ts-node": "^3.3.0", | ||
"typescript": "^2.6.2", | ||
"gulp-clean": "^0.3.2", | ||
"gulp": "^3.9.1", | ||
"gulp-sourcemaps": "^2.6.1", | ||
"gulp-typescript": "^3.2.3" | ||
"typescript": "^2.6.2" | ||
}, | ||
@@ -48,2 +53,2 @@ "keywords": [ | ||
"license": "MIT" | ||
} | ||
} |
@@ -15,4 +15,5 @@ # Es Mapping Ts | ||
```typescript | ||
import { EsEntity, EsField, EsNestedField } from "es-mapping-ts"; | ||
import { DogEntity } from "./dog.entity"; | ||
import { EsEntity, EsField } from "../lib/es-mapping-ts"; | ||
import { Budget } from "./budget.entity"; | ||
import { MasterEntity } from "./master.entity"; | ||
@@ -36,4 +37,18 @@ @EsEntity({ | ||
@EsNestedField() | ||
dog: DogEntity; | ||
@EsField({ | ||
type: 'join', | ||
relations: { "parent" : "child"} | ||
}) | ||
children: Array<UserEntity>; | ||
@EsField({ | ||
type: 'object' | ||
}) | ||
dog: Budget; | ||
@EsField({ | ||
type: 'nested', | ||
nestedType : MasterEntity | ||
}) | ||
master: Array<MasterEntity>; | ||
} | ||
@@ -44,5 +59,21 @@ ``` | ||
#### Simply call the "uploadMappings" function | ||
```typescript | ||
import { EsMappingService } from 'es-mapping-ts'; | ||
import { Client } from 'elasticsearch'; | ||
const esClient = new Client(); | ||
// Upload the mapping | ||
const mappings = EsMappingService.getInstance(esClient).uploadMappings(); | ||
``` | ||
only none readonly entity will be uploaded | ||
#### or do it yourself | ||
```typescript | ||
import { EsMappingService } from 'es-mapping-ts'; | ||
//List of ready to use generated mapping | ||
@@ -67,2 +98,3 @@ const mappings = EsMappingService.getInstance().getMappings(); | ||
| type | string | Allow you to define the index type | | ||
| readonly | boolean | Define if the mapping must be uploaded when using uploadMappings function | | ||
@@ -75,13 +107,12 @@ #### @EsField | ||
| analyzer | string | Allow you to define the elasticsearch analyzer | | ||
| fields | string | Allow you to define the elasticsearch fields | | ||
| format | string | Allow you to define the format (ie for date field) | | ||
| enabled | string | Allow you to enable ou disable the field | | ||
| null_value | string | Allow you to define the null value of the field | | ||
| copy_to | string | Allow you to copy the field value into a group field for _search | | ||
| relations | string | Define the releation for a join type | | ||
| nestedType | string | Class used to get the properties of the nested type | | ||
#### @EsNested | ||
Additional properties are allowed, allowing you to manage other elasticsearch properties | ||
Define a basic field of type nested | ||
| Param | Type | Description | | ||
| ------ | ------ | ------ | | ||
| name | string | Allow you to define the name of the property if different from the property name | | ||
/!\ The nested class must be an @EsEntity | ||
# License | ||
@@ -88,0 +119,0 @@ ---- |
24030
59.34%488
43.95%117
36.05%4
100%11
10%13
-13.33%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed