-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
27 changed files
with
2,841 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"env": { | ||
"node": true | ||
}, | ||
"extends": [ | ||
"@croquiscom/eslint-config/requiring-type-checking" | ||
], | ||
"parserOptions": { | ||
"project": [ | ||
"./tsconfig.json" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
src |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import Query from './Query'; | ||
export declare class BaseModel { | ||
static dynogelsModel: any; | ||
static setSchema(name: any, schema: any): void; | ||
private static checkHasModelInstance; | ||
static query(hashKey: any): Query; | ||
static scan(indexName?: string): Query; | ||
static getAsync(hashKey: string | number, options?: object): Promise<any>; | ||
static getAsync(hashKey: string | number, rangeKey: string | number, options?: object): Promise<any>; | ||
static createAsync(data: any, options?: object): Promise<any>; | ||
static updateAsync(data: any, options?: object): Promise<any>; | ||
static destroyAsync(hashKey: string | number, options?: object): Promise<any>; | ||
static destroyAsync(hashKey: string | number, rangeKey: string | number, options?: object): Promise<any>; | ||
static create<M extends BaseModel>(this: (new () => M) & typeof BaseModel, data: any, options?: object): Promise<M>; | ||
static createBulk<M extends BaseModel>(this: (new () => M) & typeof BaseModel, data: any[], options?: object): Promise<M[]>; | ||
static get(hashKey: string | number, options?: object): Promise<any>; | ||
static get(hashKey: string | number, rangeKey: string | number, options?: object): Promise<any>; | ||
static update<M extends BaseModel>(this: (new () => M) & typeof BaseModel, data: any, options?: object): Promise<M>; | ||
static destroy(hashKey: string | number, options?: object): Promise<any>; | ||
static destroy(hashKey: string | number, rangeKey: string | number, options?: object): Promise<any>; | ||
static updateTable(params?: any): Promise<any>; | ||
static describeTable(): Promise<any>; | ||
static list(cursor?: string): Promise<import("./Types").QueryResult<unknown>>; | ||
static getItems(keys: any[], options?: any): Promise<any[]>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
"use strict"; | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; | ||
result["default"] = mod; | ||
return result; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const _ = __importStar(require("lodash")); | ||
const Dynogels = __importStar(require("./Dynogels")); | ||
const ResultMapper_1 = require("./ResultMapper"); | ||
class BaseModel { | ||
static setSchema(name, schema) { | ||
this.dynogelsModel = Dynogels.define(name, schema); | ||
} | ||
static checkHasModelInstance() { | ||
if (!this.dynogelsModel) { | ||
throw new Error('setSchema should be called'); | ||
} | ||
} | ||
static query(hashKey) { | ||
this.checkHasModelInstance(); | ||
return this.dynogelsModel.query(hashKey); | ||
} | ||
static scan(indexName) { | ||
this.checkHasModelInstance(); | ||
const scan = this.dynogelsModel.scan(); | ||
if (indexName) { | ||
_.assign(scan.request, { IndexName: indexName }); | ||
} | ||
return scan; | ||
} | ||
static getAsync(hashKey, rangeKeyOrOptions, options) { | ||
this.checkHasModelInstance(); | ||
if (options) { | ||
return this.dynogelsModel.getAsync(hashKey, rangeKeyOrOptions, options); | ||
} | ||
else { | ||
return this.dynogelsModel.getAsync(hashKey, rangeKeyOrOptions); | ||
} | ||
} | ||
static createAsync(data, options) { | ||
this.checkHasModelInstance(); | ||
return this.dynogelsModel.createAsync(data, options); | ||
} | ||
static updateAsync(data, options) { | ||
this.checkHasModelInstance(); | ||
return this.dynogelsModel.updateAsync(data, options); | ||
} | ||
static destroyAsync(hashKey, rangeKeyOrOptions, options) { | ||
this.checkHasModelInstance(); | ||
if (options) { | ||
return this.dynogelsModel.destroyAsync(hashKey, rangeKeyOrOptions, options); | ||
} | ||
else { | ||
return this.dynogelsModel.destroyAsync(hashKey, rangeKeyOrOptions); | ||
} | ||
} | ||
// V2, with mapItem | ||
static async create(data, options) { | ||
this.checkHasModelInstance(); | ||
const createResult = await this.dynogelsModel.createAsync(data, options); | ||
return ResultMapper_1.ResultMapper.mapItem(createResult); | ||
} | ||
static async createBulk(data, options) { | ||
this.checkHasModelInstance(); | ||
if (data.length === 0) { | ||
return []; | ||
} | ||
const results = await this.dynogelsModel.createAsync(data, options); | ||
return results.map((result) => ResultMapper_1.ResultMapper.mapItem(result)); | ||
} | ||
static async get(hashKey, rangeKeyOrOptions, options) { | ||
this.checkHasModelInstance(); | ||
let getResult; | ||
if (options) { | ||
getResult = await this.dynogelsModel.getAsync(hashKey, rangeKeyOrOptions, options); | ||
} | ||
else { | ||
getResult = await this.dynogelsModel.getAsync(hashKey, rangeKeyOrOptions); | ||
} | ||
return ResultMapper_1.ResultMapper.mapItem(getResult); | ||
} | ||
static async update(data, options) { | ||
/** | ||
* Dynogel이 undefined 처리를 못하므로 직접 null로 변경 | ||
*/ | ||
Object.keys(data).forEach((key) => { | ||
if (data[key] === undefined) { | ||
data[key] = null; | ||
} | ||
}); | ||
this.checkHasModelInstance(); | ||
const updateResult = await this.dynogelsModel.updateAsync(data, options); | ||
return ResultMapper_1.ResultMapper.mapItem(updateResult); | ||
} | ||
static async destroy(hashKey, rangeKeyOrOptions, options) { | ||
this.checkHasModelInstance(); | ||
let destroyResult; | ||
if (options) { | ||
destroyResult = await this.dynogelsModel.destroyAsync(hashKey, rangeKeyOrOptions, options); | ||
} | ||
else { | ||
destroyResult = await this.dynogelsModel.destroyAsync(hashKey, rangeKeyOrOptions); | ||
} | ||
return ResultMapper_1.ResultMapper.mapItem(destroyResult); | ||
} | ||
static updateTable(params) { | ||
return this.dynogelsModel.updateTableAsync(params); | ||
} | ||
static describeTable() { | ||
return this.dynogelsModel.describeTableAsync(); | ||
} | ||
static async list(cursor) { | ||
const scan = this.scan(); | ||
if (cursor) { | ||
scan.startKey(cursor); | ||
} | ||
return ResultMapper_1.ResultMapper.mapQueryResult(await scan.execAsync()); | ||
} | ||
static async getItems(keys, options) { | ||
const getResult = await this.dynogelsModel.getItemsAsync(keys, options); | ||
return _.map(getResult, (item) => ResultMapper_1.ResultMapper.mapItem(item)); | ||
} | ||
} | ||
exports.BaseModel = BaseModel; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
declare function Model(target: any): void; | ||
export declare function SubModel(target: any): void; | ||
declare function HashKey(target: any, property: string | symbol): void; | ||
declare function RangeKey(target: any, property: string | symbol): void; | ||
declare function Field(type: any): (target: any, property: string | symbol) => void; | ||
export declare function ArrayField(type: any): (target: any, property: string | symbol) => void; | ||
declare function GlobalIndex(hashKey: string, rangeKey?: string, projection?: object): (target: any, property: string | symbol) => void; | ||
declare function LocalIndex(rangeKey: string): (target: any, property: string | symbol) => void; | ||
export { Model, HashKey, RangeKey, Field, GlobalIndex, LocalIndex }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
"use strict"; | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; | ||
result["default"] = mod; | ||
return result; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const _ = __importStar(require("lodash")); | ||
const Dynogels_1 = require("./Dynogels"); | ||
const ModelDefs = {}; | ||
function getModelDefinition(name) { | ||
if (!ModelDefs[name]) { | ||
ModelDefs[name] = { schema: {}, indexes: [] }; | ||
} | ||
return ModelDefs[name]; | ||
} | ||
function Model(target) { | ||
const modelName = target.prototype.constructor.name; | ||
const def = getModelDefinition(modelName); | ||
target.setSchema(modelName, def); | ||
} | ||
exports.Model = Model; | ||
function SubModel(target) { | ||
const modelName = target.prototype.constructor.name; | ||
const def = getModelDefinition(modelName); | ||
ModelDefs[modelName] = Dynogels_1.types.object().keys(def.schema); | ||
} | ||
exports.SubModel = SubModel; | ||
function HashKey(target, property) { | ||
const modelName = target.constructor.name; | ||
const def = getModelDefinition(modelName); | ||
def.hashKey = property; | ||
} | ||
exports.HashKey = HashKey; | ||
function RangeKey(target, property) { | ||
const modelName = target.constructor.name; | ||
const def = getModelDefinition(modelName); | ||
def.rangeKey = property; | ||
} | ||
exports.RangeKey = RangeKey; | ||
function getModelDefinitionByVariantType(type) { | ||
if (typeof type === 'string') { | ||
return getModelDefinition(type); | ||
} | ||
else if (typeof type === 'function') { | ||
return getModelDefinition(type.prototype.constructor.name); | ||
} | ||
else { | ||
return type; | ||
} | ||
} | ||
function Field(type) { | ||
// tslint:disable-next-line: only-arrow-functions | ||
return function (target, property) { | ||
const modelName = target.constructor.name; | ||
const def = getModelDefinition(modelName); | ||
def.schema[property] = getModelDefinitionByVariantType(type); | ||
}; | ||
} | ||
exports.Field = Field; | ||
function ArrayField(type) { | ||
// tslint:disable-next-line: only-arrow-functions | ||
return function (target, property) { | ||
const modelName = target.constructor.name; // AdDisplaySlot | ||
const def = getModelDefinition(modelName); | ||
const arrayModel = getModelDefinitionByVariantType(type); | ||
def.schema[property] = Dynogels_1.types.array().items(arrayModel); | ||
}; | ||
} | ||
exports.ArrayField = ArrayField; | ||
function GlobalIndex(hashKey, rangeKey, projection) { | ||
// tslint:disable-next-line: only-arrow-functions | ||
return function (target, property) { | ||
const modelName = target.prototype.constructor.name; | ||
const def = getModelDefinition(modelName); | ||
const globalIndex = { name: property, hashKey, type: 'global', projection }; | ||
if (rangeKey) { | ||
_.assign(globalIndex, { rangeKey }); | ||
} | ||
def.indexes.push(globalIndex); | ||
target[property] = `${property.toString()}`; | ||
}; | ||
} | ||
exports.GlobalIndex = GlobalIndex; | ||
function LocalIndex(rangeKey) { | ||
// tslint:disable-next-line: only-arrow-functions | ||
return function (target, property) { | ||
const modelName = target.prototype.constructor.name; | ||
const def = getModelDefinition(modelName); | ||
const localIndex = { name: property, hashKey: def.hashKey, rangeKey, type: 'local' }; | ||
def.indexes.push(localIndex); | ||
target[property] = `${property.toString()}`; | ||
}; | ||
} | ||
exports.LocalIndex = LocalIndex; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
declare function getEndPoint(): string; | ||
declare function define(name: any, schema: any): any; | ||
declare const types: any; | ||
export { types, define, getEndPoint }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
"use strict"; | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; | ||
result["default"] = mod; | ||
return result; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const AWS = __importStar(require("aws-sdk")); | ||
const dynogels = __importStar(require("dynogels-promisified")); | ||
const Joi = __importStar(require("joi")); | ||
const _ = __importStar(require("lodash")); | ||
/** | ||
* enabled WARN log level on all tables | ||
*/ | ||
// import * as logger from 'winston'; | ||
// dynogels.log = logger; | ||
const { NODE_ENV } = process.env; | ||
const useRealDatabase = Boolean(NODE_ENV && ['real-prod', 'production', 'real-alpha', 'alpha'].indexOf(NODE_ENV) > -1); | ||
function getEndPoint() { | ||
return 'http://localhost:11505'; | ||
} | ||
exports.getEndPoint = getEndPoint; | ||
if (!useRealDatabase) { | ||
if (NODE_ENV === 'test') { | ||
const dynamodb = new AWS.DynamoDB({ | ||
endpoint: getEndPoint(), | ||
accessKeyId: 'mock', | ||
secretAccessKey: 'mock', | ||
region: 'us-east-1', | ||
}); | ||
dynogels.dynamoDriver(dynamodb); | ||
} | ||
else { | ||
const dynamodb = new AWS.DynamoDB({ | ||
endpoint: getEndPoint(), | ||
region: 'localhost', | ||
}); | ||
dynogels.dynamoDriver(dynamodb); | ||
} | ||
} | ||
else if (NODE_ENV === 'real-prod' || NODE_ENV === 'real-alpha') { | ||
const dynamodb = new AWS.DynamoDB({ | ||
region: 'ap-northeast-2', | ||
}); | ||
dynogels.dynamoDriver(dynamodb); | ||
} | ||
function define(name, schema) { | ||
if (process.env.NODE_ENV === 'test') { | ||
schema.tableName = 'test-' + name; | ||
} | ||
else { | ||
schema.tableName = name; | ||
} | ||
const output = dynogels.define(name, schema); | ||
return output; | ||
} | ||
exports.define = define; | ||
const types = _.assign({}, dynogels.types, Joi); | ||
exports.types = types; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { IndexType, ValueTypes } from './Types'; | ||
interface RawQueryResult { | ||
LastEvaluatedKey?: ValueTypes; | ||
Count: number; | ||
Items?: any[]; | ||
} | ||
interface Query { | ||
usingIndex(index: IndexType): Query; | ||
descending(): Query; | ||
ascending(): Query; | ||
limit(count: number): Query; | ||
where(field: string): Query; | ||
equals(value: ValueTypes): Query; | ||
eq(value: ValueTypes): Query; | ||
filter(field: string): Query; | ||
gt(value: ValueTypes): Query; | ||
gte(value: ValueTypes): Query; | ||
lt(value: ValueTypes): Query; | ||
lte(value: ValueTypes): Query; | ||
beginsWith(value: ValueTypes): Query; | ||
between(fromValue: ValueTypes, toValue: ValueTypes): Query; | ||
ne(value: ValueTypes): Query; | ||
null(): Query; | ||
notNull(): Query; | ||
exists(): Query; | ||
contains(value: ValueTypes): Query; | ||
notContains(value: ValueTypes): Query; | ||
in(values: ValueTypes[]): Query; | ||
select(field: string): Query; | ||
attributes(fields: string[]): Query; | ||
startKey(key: string): Query; | ||
loadAll(): Query; | ||
consistentRead(): Query; | ||
returnConsumedCapacity(): Query; | ||
filterExpression(expr: string): Query; | ||
expressionAttributeValues(params: any): Query; | ||
expressionAttributeNames(params: any): Query; | ||
execAsync(): Promise<RawQueryResult>; | ||
} | ||
export default Query; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); |
Oops, something went wrong.