sonamu 0.5.1 → 0.5.3
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/dist/database/db.d.ts +1 -0
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +1 -1
- package/dist/database/db.js.map +1 -1
- package/package.json +7 -3
- package/src/api/code-converters.ts +1 -1
- package/src/api/decorators.ts +23 -9
- package/src/bin/cli-wrapper.ts +1 -1
- package/src/database/db.ts +3 -2
- package/src/database/puri-wrapper.ts +24 -4
- package/src/database/puri.ts +128 -25
- package/src/database/puri.types.ts +46 -41
- package/src/index.ts +2 -1
- package/src/migration/code-generation.ts +3 -3
- package/src/migration/types.ts +2 -1
- package/src/templates/generated_http.template.ts +42 -11
- package/src/templates/generated_sso.template.ts +3 -1
- package/src/templates/service.template.ts +20 -7
- package/src/testing/fixture-manager.ts +2 -0
- package/.swcrc +0 -15
- package/import-to-require.js +0 -27
- package/nodemon.json +0 -6
- package/tsconfig.json +0 -56
- package/tsup.config.js +0 -47
package/dist/database/db.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/database/db.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,GAAG,GAAG,GAAG,CAAC;AACjC,OAAa,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAKlC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,KAAK,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG;IACnD,UAAU,CAAC,EAAE,IAAI,CAAC,sBAAsB,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAE/B,QAAQ,EAAE,MAAM,CAAC;IAGjB,cAAc,CAAC,EAAE,WAAW,CAAC;IAG7B,YAAY,CAAC,EAAE;QACb,WAAW,CAAC,EAAE,WAAW,CAAC;QAC1B,iBAAiB,CAAC,EAAE,WAAW,CAAC;QAChC,UAAU,CAAC,EAAE,WAAW,CAAC;QACzB,gBAAgB,CAAC,EAAE,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/database/db.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,GAAG,GAAG,GAAG,CAAC;AACjC,OAAa,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAKlC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,KAAK,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG;IACnD,UAAU,CAAC,EAAE,IAAI,CAAC,sBAAsB,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAE/B,QAAQ,EAAE,MAAM,CAAC;IAGjB,cAAc,CAAC,EAAE,WAAW,CAAC;IAG7B,YAAY,CAAC,EAAE;QACb,WAAW,CAAC,EAAE,WAAW,CAAC;QAC1B,iBAAiB,CAAC,EAAE,WAAW,CAAC;QAChC,UAAU,CAAC,EAAE,WAAW,CAAC;QACzB,gBAAgB,CAAC,EAAE,WAAW,CAAC;QAC/B,cAAc,CAAC,EAAE,WAAW,CAAC;KAC9B,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,kBAAkB,EAAE,IAAI,CAAC,MAAM,CAAC;IAChC,iBAAiB,EAAE,IAAI,CAAC,MAAM,CAAC;IAC/B,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;IAClB,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC;IAC3B,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC;IAC5B,iBAAiB,EAAE,IAAI,CAAC,MAAM,CAAC;IAC/B,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC;CAC/B,CAAC;AAEF,cAAM,OAAO;IACX,OAAO,CAAC,GAAG,CAAC,CAAO;IACnB,OAAO,CAAC,GAAG,CAAC,CAAO;IAEZ,kBAAkB,wCAA+C;IAEjE,kBAAkB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAI7D,qBAAqB,IAAI,kBAAkB;IAI5C,YAAY,IAAI,OAAO,CAAC,cAAc,CAAC;IAmB7C,KAAK,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAmCtB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAW9B,OAAO,CAAC,gBAAgB;CAyEzB;AACD,eAAO,MAAM,EAAE,SAAgB,CAAC"}
|
package/dist/database/db.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"DB",{enumerable:true,get:function(){return DB}});var _knex=/*#__PURE__*/_interop_require_default(require("knex"));var _path=/*#__PURE__*/_interop_require_default(require("path"));var _lodash=/*#__PURE__*/_interop_require_default(require("lodash"));var _api=require("../api");var _soexceptions=require("../exceptions/so-exceptions");var _async_hooks=require("async_hooks");var _transactioncontext=require("./transaction-context");function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{Promise.resolve(value).then(_next,_throw)}}function _async_to_generator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value)}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err)}_next(undefined)})}}function _class_call_check(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}function _create_class(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor}function _define_property(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true})}else{obj[key]=value}return obj}function _interop_require_default(obj){return obj&&obj.__esModule?obj:{default:obj}}function _getRequireWildcardCache(nodeInterop){if(typeof WeakMap!=="function")return null;var cacheBabelInterop=new WeakMap;var cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interop_require_wildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule){return obj}if(obj===null||typeof obj!=="object"&&typeof obj!=="function"){return{default:obj}}var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj)){return cache.get(obj)}var newObj={__proto__:null};var hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj){if(key!=="default"&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;if(desc&&(desc.get||desc.set)){Object.defineProperty(newObj,key,desc)}else{newObj[key]=obj[key]}}}newObj.default=obj;if(cache){cache.set(obj,newObj)}return newObj}function _object_spread(target){for(var i=1;i<arguments.length;i++){var source=arguments[i]!=null?arguments[i]:{};var ownKeys=Object.keys(source);if(typeof Object.getOwnPropertySymbols==="function"){ownKeys=ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym){return Object.getOwnPropertyDescriptor(source,sym).enumerable}))}ownKeys.forEach(function(key){_define_property(target,key,source[key])})}return target}function _ts_generator(thisArg,body){var f,y,t,_={label:0,sent:function(){if(t[0]&1)throw t[1];return t[1]},trys:[],ops:[]},g=Object.create((typeof Iterator==="function"?Iterator:Object).prototype);return g.next=verb(0),g["throw"]=verb(1),g["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(g&&(g=0,op[0]&&(_=0)),_)try{if(f=1,y&&(t=op[0]&2?y["return"]:op[0]?y["throw"]||((t=y["return"])&&t.call(y),0):y.next)&&!(t=t.call(y,op[1])).done)return t;if(y=0,t)op=[op[0]&2,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}}}var DBClass=/*#__PURE__*/function(){"use strict";function DBClass(){_class_call_check(this,DBClass);_define_property(this,"wdb",void 0);_define_property(this,"rdb",void 0);_define_property(this,"transactionStorage",new _async_hooks.AsyncLocalStorage)}_create_class(DBClass,[{key:"runWithTransaction",value:function runWithTransaction(callback){return this.transactionStorage.run(new _transactioncontext.TransactionContext,callback)}},{key:"getTransactionContext",value:function getTransactionContext(){var _this_transactionStorage_getStore;return(_this_transactionStorage_getStore=this.transactionStorage.getStore())!==null&&_this_transactionStorage_getStore!==void 0?_this_transactionStorage_getStore:new _transactioncontext.TransactionContext}},{key:"readKnexfile",value:function readKnexfile(){return _async_to_generator(function(){var dbConfigPath,_knexfileModule_default,knexfileModule,_knexfileModule_default_default,_ref,config,e;return _ts_generator(this,function(_state){switch(_state.label){case 0:dbConfigPath=_path.default.join(_api.Sonamu.apiRootPath,"/dist/configs/db.js");_state.label=1;case 1:_state.trys.push([1,3,,4]);return[4,Promise.resolve(dbConfigPath).then(function(p){return /*#__PURE__*/_interop_require_wildcard(require(p))})];case 2:knexfileModule=_state.sent();config=(_ref=(_knexfileModule_default_default=(_knexfileModule_default=knexfileModule.default)===null||_knexfileModule_default===void 0?void 0:_knexfileModule_default.default)!==null&&_knexfileModule_default_default!==void 0?_knexfileModule_default_default:knexfileModule.default)!==null&&_ref!==void 0?_ref:knexfileModule;return[2,this.generateDBConfig(config)];case 3:e=_state.sent();return[3,4];case 4:throw new _soexceptions.ServiceUnavailableException("다음 경로에서 DB설정 파일을 찾을 수 없습니다: ".concat(dbConfigPath,". 먼저 빌드(yarn build)를 수행해주세요."))}})}).call(this)}},{key:"getDB",value:function getDB(which){var dbConfig=_api.Sonamu.dbConfig;var instanceName=which==="w"?"wdb":"rdb";if(!this[instanceName]){var config;var _process_env_NODE_ENV;switch((_process_env_NODE_ENV=process.env.NODE_ENV)!==null&&_process_env_NODE_ENV!==void 0?_process_env_NODE_ENV:"development"){case"development":case"staging":var _dbConfig_development_slave;config=which==="w"?dbConfig["development_master"]:(_dbConfig_development_slave=dbConfig["development_slave"])!==null&&_dbConfig_development_slave!==void 0?_dbConfig_development_slave:dbConfig["development_master"];break;case"production":var _dbConfig_production_slave;config=which==="w"?dbConfig["production_master"]:(_dbConfig_production_slave=dbConfig["production_slave"])!==null&&_dbConfig_production_slave!==void 0?_dbConfig_production_slave:dbConfig["production_master"];break;case"test":config=dbConfig["test"];break;default:throw new Error("현재 ENV ".concat(process.env.NODE_ENV,"에는 설정 가능한 DB설정이 없습니다."))}this[instanceName]=(0,_knex.default)(config)}return this[instanceName]}},{key:"destroy",value:function destroy(){return _async_to_generator(function(){return _ts_generator(this,function(_state){switch(_state.label){case 0:if(!(this.wdb!==undefined))return[3,2];return[4,this.wdb.destroy()];case 1:_state.sent();this.wdb=undefined;_state.label=2;case 2:if(!(this.rdb!==undefined))return[3,4];return[4,this.rdb.destroy()];case 3:_state.sent();this.rdb=undefined;_state.label=4;case 4:return[2]}})}).call(this)}},{key:"generateDBConfig",value:function generateDBConfig(config){var _config_defaultOptions,_config_defaultOptions1,_config_defaultOptions2,_config_environments,_config_environments1,_config_environments2,_config_environments3;var defaultKnexConfig=_lodash.default.merge({client:"mysql2",pool:{min:1,max:5},migrations:{extension:"js",directory:"./dist/migrations"},connection:_object_spread({database:config.database},(_config_defaultOptions=config.defaultOptions)===null||_config_defaultOptions===void 0?void 0:_config_defaultOptions.connection)},config.defaultOptions);var test=_lodash.default.merge({},defaultKnexConfig,{connection:_object_spread({database:"".concat(config.database,"_test")},(_config_defaultOptions1=config.defaultOptions)===null||_config_defaultOptions1===void 0?void 0:_config_defaultOptions1.connection)});var fixture_local=_lodash.default.merge({},defaultKnexConfig,{connection:_object_spread({database:"".concat(config.database,"_fixture_local")},(_config_defaultOptions2=config.defaultOptions)===null||_config_defaultOptions2===void 0?void 0:_config_defaultOptions2.connection)});var devMasterOptions=(_config_environments=config.environments)===null||_config_environments===void 0?void 0:_config_environments.development;var devSlaveOptions=(_config_environments1=config.environments)===null||_config_environments1===void 0?void 0:_config_environments1.development_slave;var development_master=_lodash.default.merge({},defaultKnexConfig,devMasterOptions);var development_slave=_lodash.default.merge({},defaultKnexConfig,devMasterOptions,devSlaveOptions);var fixture_remote=_lodash.default.merge({},defaultKnexConfig,devMasterOptions,{connection:{database:"".concat(config.database,"_fixture_remote")}});var _config_environments_production;var prodMasterOptions=(_config_environments_production=(_config_environments2=config.environments)===null||_config_environments2===void 0?void 0:_config_environments2.production)!==null&&_config_environments_production!==void 0?_config_environments_production:{};var _config_environments_production_slave;var prodSlaveOptions=(_config_environments_production_slave=(_config_environments3=config.environments)===null||_config_environments3===void 0?void 0:_config_environments3.production_slave)!==null&&_config_environments_production_slave!==void 0?_config_environments_production_slave:{};var production_master=_lodash.default.merge({},defaultKnexConfig,prodMasterOptions);var production_slave=_lodash.default.merge({},defaultKnexConfig,prodMasterOptions,prodSlaveOptions);return{test:test,fixture_local:fixture_local,fixture_remote:fixture_remote,development_master:development_master,development_slave:development_slave,production_master:production_master,production_slave:production_slave}}}]);return DBClass}();var DB=new DBClass;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"DB",{enumerable:true,get:function(){return DB}});var _knex=/*#__PURE__*/_interop_require_default(require("knex"));var _path=/*#__PURE__*/_interop_require_default(require("path"));var _lodash=/*#__PURE__*/_interop_require_default(require("lodash"));var _api=require("../api");var _soexceptions=require("../exceptions/so-exceptions");var _async_hooks=require("async_hooks");var _transactioncontext=require("./transaction-context");function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{Promise.resolve(value).then(_next,_throw)}}function _async_to_generator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value)}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err)}_next(undefined)})}}function _class_call_check(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}function _create_class(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor}function _define_property(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true})}else{obj[key]=value}return obj}function _interop_require_default(obj){return obj&&obj.__esModule?obj:{default:obj}}function _getRequireWildcardCache(nodeInterop){if(typeof WeakMap!=="function")return null;var cacheBabelInterop=new WeakMap;var cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interop_require_wildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule){return obj}if(obj===null||typeof obj!=="object"&&typeof obj!=="function"){return{default:obj}}var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj)){return cache.get(obj)}var newObj={__proto__:null};var hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj){if(key!=="default"&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;if(desc&&(desc.get||desc.set)){Object.defineProperty(newObj,key,desc)}else{newObj[key]=obj[key]}}}newObj.default=obj;if(cache){cache.set(obj,newObj)}return newObj}function _object_spread(target){for(var i=1;i<arguments.length;i++){var source=arguments[i]!=null?arguments[i]:{};var ownKeys=Object.keys(source);if(typeof Object.getOwnPropertySymbols==="function"){ownKeys=ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym){return Object.getOwnPropertyDescriptor(source,sym).enumerable}))}ownKeys.forEach(function(key){_define_property(target,key,source[key])})}return target}function _ts_generator(thisArg,body){var f,y,t,_={label:0,sent:function(){if(t[0]&1)throw t[1];return t[1]},trys:[],ops:[]},g=Object.create((typeof Iterator==="function"?Iterator:Object).prototype);return g.next=verb(0),g["throw"]=verb(1),g["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(g&&(g=0,op[0]&&(_=0)),_)try{if(f=1,y&&(t=op[0]&2?y["return"]:op[0]?y["throw"]||((t=y["return"])&&t.call(y),0):y.next)&&!(t=t.call(y,op[1])).done)return t;if(y=0,t)op=[op[0]&2,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}}}var DBClass=/*#__PURE__*/function(){"use strict";function DBClass(){_class_call_check(this,DBClass);_define_property(this,"wdb",void 0);_define_property(this,"rdb",void 0);_define_property(this,"transactionStorage",new _async_hooks.AsyncLocalStorage)}_create_class(DBClass,[{key:"runWithTransaction",value:function runWithTransaction(callback){return this.transactionStorage.run(new _transactioncontext.TransactionContext,callback)}},{key:"getTransactionContext",value:function getTransactionContext(){var _this_transactionStorage_getStore;return(_this_transactionStorage_getStore=this.transactionStorage.getStore())!==null&&_this_transactionStorage_getStore!==void 0?_this_transactionStorage_getStore:new _transactioncontext.TransactionContext}},{key:"readKnexfile",value:function readKnexfile(){return _async_to_generator(function(){var dbConfigPath,_knexfileModule_default,knexfileModule,_knexfileModule_default_default,_ref,config,e;return _ts_generator(this,function(_state){switch(_state.label){case 0:dbConfigPath=_path.default.join(_api.Sonamu.apiRootPath,"/dist/configs/db.js");_state.label=1;case 1:_state.trys.push([1,3,,4]);return[4,Promise.resolve(dbConfigPath).then(function(p){return /*#__PURE__*/_interop_require_wildcard(require(p))})];case 2:knexfileModule=_state.sent();config=(_ref=(_knexfileModule_default_default=(_knexfileModule_default=knexfileModule.default)===null||_knexfileModule_default===void 0?void 0:_knexfileModule_default.default)!==null&&_knexfileModule_default_default!==void 0?_knexfileModule_default_default:knexfileModule.default)!==null&&_ref!==void 0?_ref:knexfileModule;return[2,this.generateDBConfig(config)];case 3:e=_state.sent();return[3,4];case 4:throw new _soexceptions.ServiceUnavailableException("다음 경로에서 DB설정 파일을 찾을 수 없습니다: ".concat(dbConfigPath,". 먼저 빌드(yarn build)를 수행해주세요."))}})}).call(this)}},{key:"getDB",value:function getDB(which){var dbConfig=_api.Sonamu.dbConfig;var instanceName=which==="w"?"wdb":"rdb";if(!this[instanceName]){var config;var _process_env_NODE_ENV;switch((_process_env_NODE_ENV=process.env.NODE_ENV)!==null&&_process_env_NODE_ENV!==void 0?_process_env_NODE_ENV:"development"){case"development":case"staging":var _dbConfig_development_slave;config=which==="w"?dbConfig["development_master"]:(_dbConfig_development_slave=dbConfig["development_slave"])!==null&&_dbConfig_development_slave!==void 0?_dbConfig_development_slave:dbConfig["development_master"];break;case"production":var _dbConfig_production_slave;config=which==="w"?dbConfig["production_master"]:(_dbConfig_production_slave=dbConfig["production_slave"])!==null&&_dbConfig_production_slave!==void 0?_dbConfig_production_slave:dbConfig["production_master"];break;case"test":config=dbConfig["test"];break;default:throw new Error("현재 ENV ".concat(process.env.NODE_ENV,"에는 설정 가능한 DB설정이 없습니다."))}this[instanceName]=(0,_knex.default)(config)}return this[instanceName]}},{key:"destroy",value:function destroy(){return _async_to_generator(function(){return _ts_generator(this,function(_state){switch(_state.label){case 0:if(!(this.wdb!==undefined))return[3,2];return[4,this.wdb.destroy()];case 1:_state.sent();this.wdb=undefined;_state.label=2;case 2:if(!(this.rdb!==undefined))return[3,4];return[4,this.rdb.destroy()];case 3:_state.sent();this.rdb=undefined;_state.label=4;case 4:return[2]}})}).call(this)}},{key:"generateDBConfig",value:function generateDBConfig(config){var _config_defaultOptions,_config_defaultOptions1,_config_defaultOptions2,_config_environments,_config_environments1,_config_environments2,_config_environments3,_config_environments4;var defaultKnexConfig=_lodash.default.merge({client:"mysql2",pool:{min:1,max:5},migrations:{extension:"js",directory:"./dist/migrations"},connection:_object_spread({database:config.database},(_config_defaultOptions=config.defaultOptions)===null||_config_defaultOptions===void 0?void 0:_config_defaultOptions.connection)},config.defaultOptions);var test=_lodash.default.merge({},defaultKnexConfig,{connection:_object_spread({database:"".concat(config.database,"_test")},(_config_defaultOptions1=config.defaultOptions)===null||_config_defaultOptions1===void 0?void 0:_config_defaultOptions1.connection)});var fixture_local=_lodash.default.merge({},defaultKnexConfig,{connection:_object_spread({database:"".concat(config.database,"_fixture_local")},(_config_defaultOptions2=config.defaultOptions)===null||_config_defaultOptions2===void 0?void 0:_config_defaultOptions2.connection)});var devMasterOptions=(_config_environments=config.environments)===null||_config_environments===void 0?void 0:_config_environments.development;var devSlaveOptions=(_config_environments1=config.environments)===null||_config_environments1===void 0?void 0:_config_environments1.development_slave;var development_master=_lodash.default.merge({},defaultKnexConfig,devMasterOptions);var development_slave=_lodash.default.merge({},defaultKnexConfig,devMasterOptions,devSlaveOptions);var fixture_remote=_lodash.default.merge({},defaultKnexConfig,devMasterOptions,{connection:{database:"".concat(config.database,"_fixture_remote")}},(_config_environments2=config.environments)===null||_config_environments2===void 0?void 0:_config_environments2.remote_fixture);var _config_environments_production;var prodMasterOptions=(_config_environments_production=(_config_environments3=config.environments)===null||_config_environments3===void 0?void 0:_config_environments3.production)!==null&&_config_environments_production!==void 0?_config_environments_production:{};var _config_environments_production_slave;var prodSlaveOptions=(_config_environments_production_slave=(_config_environments4=config.environments)===null||_config_environments4===void 0?void 0:_config_environments4.production_slave)!==null&&_config_environments_production_slave!==void 0?_config_environments_production_slave:{};var production_master=_lodash.default.merge({},defaultKnexConfig,prodMasterOptions);var production_slave=_lodash.default.merge({},defaultKnexConfig,prodMasterOptions,prodSlaveOptions);return{test:test,fixture_local:fixture_local,fixture_remote:fixture_remote,development_master:development_master,development_slave:development_slave,production_master:production_master,production_slave:production_slave}}}]);return DBClass}();var DB=new DBClass;
|
|
2
2
|
//# sourceMappingURL=db.js.map
|
package/dist/database/db.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/database/db.ts"],"sourcesContent":["export type DBPreset = \"w\" | \"r\";\nimport knex, { Knex } from \"knex\";\nimport path from \"path\";\nimport _ from \"lodash\";\nimport { Sonamu } from \"../api\";\nimport { ServiceUnavailableException } from \"../exceptions/so-exceptions\";\nimport { AsyncLocalStorage } from \"async_hooks\";\nimport { TransactionContext } from \"./transaction-context\";\n\ntype MySQLConfig = Omit<Knex.Config, \"connection\"> & {\n connection?: Knex.MySql2ConnectionConfig;\n};\n\nexport type SonamuDBBaseConfig = {\n // 기본 데이터베이스 이름\n database: string;\n\n // 모든 환경에 적용될 기본 Knex 옵션\n defaultOptions?: MySQLConfig;\n\n // 환경별 설정\n environments?: {\n development?: MySQLConfig;\n development_slave?: MySQLConfig;\n production?: MySQLConfig;\n production_slave?: MySQLConfig;\n };\n};\n\nexport type SonamuDBConfig = {\n development_master: Knex.Config;\n development_slave: Knex.Config;\n test: Knex.Config;\n fixture_local: Knex.Config;\n fixture_remote: Knex.Config;\n production_master: Knex.Config;\n production_slave: Knex.Config;\n};\n\nclass DBClass {\n private wdb?: Knex;\n private rdb?: Knex;\n\n public transactionStorage = new AsyncLocalStorage<TransactionContext>();\n\n public runWithTransaction<T>(callback: () => Promise<T>): Promise<T> {\n return this.transactionStorage.run(new TransactionContext(), callback);\n }\n\n public getTransactionContext(): TransactionContext {\n return this.transactionStorage.getStore() ?? new TransactionContext();\n }\n\n async readKnexfile(): Promise<SonamuDBConfig> {\n const dbConfigPath: string = path.join(\n Sonamu.apiRootPath,\n \"/dist/configs/db.js\"\n );\n try {\n const knexfileModule = await import(dbConfigPath);\n const config =\n knexfileModule.default?.default ??\n knexfileModule.default ??\n knexfileModule;\n return this.generateDBConfig(config);\n } catch {}\n\n throw new ServiceUnavailableException(\n `다음 경로에서 DB설정 파일을 찾을 수 없습니다: ${dbConfigPath}. 먼저 빌드(yarn build)를 수행해주세요.`\n );\n }\n\n getDB(which: DBPreset): Knex {\n const dbConfig = Sonamu.dbConfig;\n\n const instanceName = which === \"w\" ? \"wdb\" : \"rdb\";\n\n if (!this[instanceName]) {\n let config: Knex.Config;\n switch (process.env.NODE_ENV ?? \"development\") {\n case \"development\":\n case \"staging\":\n config =\n which === \"w\"\n ? dbConfig[\"development_master\"]\n : dbConfig[\"development_slave\"] ?? dbConfig[\"development_master\"];\n break;\n case \"production\":\n config =\n which === \"w\"\n ? dbConfig[\"production_master\"]\n : dbConfig[\"production_slave\"] ?? dbConfig[\"production_master\"];\n break;\n case \"test\":\n config = dbConfig[\"test\"];\n break;\n default:\n throw new Error(\n `현재 ENV ${process.env.NODE_ENV}에는 설정 가능한 DB설정이 없습니다.`\n );\n }\n this[instanceName] = knex(config);\n }\n\n return this[instanceName]!;\n }\n\n async destroy(): Promise<void> {\n if (this.wdb !== undefined) {\n await this.wdb.destroy();\n this.wdb = undefined;\n }\n if (this.rdb !== undefined) {\n await this.rdb.destroy();\n this.rdb = undefined;\n }\n }\n\n private generateDBConfig(config: SonamuDBBaseConfig): SonamuDBConfig {\n const defaultKnexConfig: Partial<MySQLConfig> = _.merge(\n {\n client: \"mysql2\",\n pool: {\n min: 1,\n max: 5,\n },\n migrations: {\n extension: \"js\",\n directory: \"./dist/migrations\",\n },\n connection: {\n database: config.database,\n ...config.defaultOptions?.connection,\n },\n },\n config.defaultOptions\n );\n\n // 로컬 환경 설정\n const test: MySQLConfig = _.merge({}, defaultKnexConfig, {\n connection: {\n database: `${config.database}_test`,\n ...config.defaultOptions?.connection,\n },\n });\n\n const fixture_local = _.merge({}, defaultKnexConfig, {\n connection: {\n database: `${config.database}_fixture_local`,\n ...config.defaultOptions?.connection,\n },\n });\n\n // 개발 환경 설정\n const devMasterOptions = config.environments?.development;\n const devSlaveOptions = config.environments?.development_slave;\n const development_master = _.merge({}, defaultKnexConfig, devMasterOptions);\n const development_slave = _.merge(\n {},\n defaultKnexConfig,\n devMasterOptions,\n devSlaveOptions\n );\n const fixture_remote = _.merge({}, defaultKnexConfig, devMasterOptions, {\n connection: {\n // NOTE: fixture remote는 default connection의 DB를 override해선 안됨.\n database: `${config.database}_fixture_remote`,\n },\n });\n\n // 프로덕션 환경 설정\n const prodMasterOptions = config.environments?.production ?? {};\n const prodSlaveOptions = config.environments?.production_slave ?? {};\n const production_master = _.merge({}, defaultKnexConfig, prodMasterOptions);\n const production_slave = _.merge(\n {},\n defaultKnexConfig,\n prodMasterOptions,\n prodSlaveOptions\n );\n\n return {\n test,\n fixture_local,\n fixture_remote,\n development_master,\n development_slave,\n production_master,\n production_slave,\n };\n }\n}\nexport const DB = new DBClass();\n"],"names":["DB","DBClass","wdb","rdb","transactionStorage","AsyncLocalStorage","runWithTransaction","callback","run","TransactionContext","getTransactionContext","getStore","readKnexfile","dbConfigPath","knexfileModule","config","path","join","Sonamu","apiRootPath","default","generateDBConfig","ServiceUnavailableException","getDB","which","dbConfig","instanceName","process","env","NODE_ENV","Error","knex","destroy","undefined","defaultKnexConfig","_","merge","client","pool","min","max","migrations","extension","directory","connection","database","defaultOptions","test","fixture_local","devMasterOptions","environments","development","devSlaveOptions","development_slave","development_master","fixture_remote","prodMasterOptions","production","prodSlaveOptions","production_slave","production_master"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/database/db.ts"],"sourcesContent":["export type DBPreset = \"w\" | \"r\";\nimport knex, { Knex } from \"knex\";\nimport path from \"path\";\nimport _ from \"lodash\";\nimport { Sonamu } from \"../api\";\nimport { ServiceUnavailableException } from \"../exceptions/so-exceptions\";\nimport { AsyncLocalStorage } from \"async_hooks\";\nimport { TransactionContext } from \"./transaction-context\";\n\ntype MySQLConfig = Omit<Knex.Config, \"connection\"> & {\n connection?: Knex.MySql2ConnectionConfig;\n};\n\nexport type SonamuDBBaseConfig = {\n // 기본 데이터베이스 이름\n database: string;\n\n // 모든 환경에 적용될 기본 Knex 옵션\n defaultOptions?: MySQLConfig;\n\n // 환경별 설정\n environments?: {\n development?: MySQLConfig;\n development_slave?: MySQLConfig;\n production?: MySQLConfig;\n production_slave?: MySQLConfig;\n remote_fixture?: MySQLConfig;\n };\n};\n\nexport type SonamuDBConfig = {\n development_master: Knex.Config;\n development_slave: Knex.Config;\n test: Knex.Config;\n fixture_local: Knex.Config;\n fixture_remote: Knex.Config;\n production_master: Knex.Config;\n production_slave: Knex.Config;\n};\n\nclass DBClass {\n private wdb?: Knex;\n private rdb?: Knex;\n\n public transactionStorage = new AsyncLocalStorage<TransactionContext>();\n\n public runWithTransaction<T>(callback: () => Promise<T>): Promise<T> {\n return this.transactionStorage.run(new TransactionContext(), callback);\n }\n\n public getTransactionContext(): TransactionContext {\n return this.transactionStorage.getStore() ?? new TransactionContext();\n }\n\n async readKnexfile(): Promise<SonamuDBConfig> {\n const dbConfigPath: string = path.join(\n Sonamu.apiRootPath,\n \"/dist/configs/db.js\"\n );\n try {\n const knexfileModule = await import(dbConfigPath);\n const config =\n knexfileModule.default?.default ??\n knexfileModule.default ??\n knexfileModule;\n return this.generateDBConfig(config);\n } catch {}\n\n throw new ServiceUnavailableException(\n `다음 경로에서 DB설정 파일을 찾을 수 없습니다: ${dbConfigPath}. 먼저 빌드(yarn build)를 수행해주세요.`\n );\n }\n\n getDB(which: DBPreset): Knex {\n const dbConfig = Sonamu.dbConfig;\n\n const instanceName = which === \"w\" ? \"wdb\" : \"rdb\";\n\n if (!this[instanceName]) {\n let config: Knex.Config;\n switch (process.env.NODE_ENV ?? \"development\") {\n case \"development\":\n case \"staging\":\n config =\n which === \"w\"\n ? dbConfig[\"development_master\"]\n : dbConfig[\"development_slave\"] ?? dbConfig[\"development_master\"];\n break;\n case \"production\":\n config =\n which === \"w\"\n ? dbConfig[\"production_master\"]\n : dbConfig[\"production_slave\"] ?? dbConfig[\"production_master\"];\n break;\n case \"test\":\n config = dbConfig[\"test\"];\n break;\n default:\n throw new Error(\n `현재 ENV ${process.env.NODE_ENV}에는 설정 가능한 DB설정이 없습니다.`\n );\n }\n this[instanceName] = knex(config);\n }\n\n return this[instanceName]!;\n }\n\n async destroy(): Promise<void> {\n if (this.wdb !== undefined) {\n await this.wdb.destroy();\n this.wdb = undefined;\n }\n if (this.rdb !== undefined) {\n await this.rdb.destroy();\n this.rdb = undefined;\n }\n }\n\n private generateDBConfig(config: SonamuDBBaseConfig): SonamuDBConfig {\n const defaultKnexConfig: Partial<MySQLConfig> = _.merge(\n {\n client: \"mysql2\",\n pool: {\n min: 1,\n max: 5,\n },\n migrations: {\n extension: \"js\",\n directory: \"./dist/migrations\",\n },\n connection: {\n database: config.database,\n ...config.defaultOptions?.connection,\n },\n },\n config.defaultOptions\n );\n\n // 로컬 환경 설정\n const test: MySQLConfig = _.merge({}, defaultKnexConfig, {\n connection: {\n database: `${config.database}_test`,\n ...config.defaultOptions?.connection,\n },\n });\n\n const fixture_local = _.merge({}, defaultKnexConfig, {\n connection: {\n database: `${config.database}_fixture_local`,\n ...config.defaultOptions?.connection,\n },\n });\n\n // 개발 환경 설정\n const devMasterOptions = config.environments?.development;\n const devSlaveOptions = config.environments?.development_slave;\n const development_master = _.merge({}, defaultKnexConfig, devMasterOptions);\n const development_slave = _.merge(\n {},\n defaultKnexConfig,\n devMasterOptions,\n devSlaveOptions\n );\n // NOTE: fixture remote는 default connection의 DB를 override해선 안됨.\n const fixture_remote = _.merge({}, defaultKnexConfig, devMasterOptions, {\n connection: {\n database: `${config.database}_fixture_remote`,\n },\n }, config.environments?.remote_fixture);\n\n // 프로덕션 환경 설정\n const prodMasterOptions = config.environments?.production ?? {};\n const prodSlaveOptions = config.environments?.production_slave ?? {};\n const production_master = _.merge({}, defaultKnexConfig, prodMasterOptions);\n const production_slave = _.merge(\n {},\n defaultKnexConfig,\n prodMasterOptions,\n prodSlaveOptions\n );\n\n return {\n test,\n fixture_local,\n fixture_remote,\n development_master,\n development_slave,\n production_master,\n production_slave,\n };\n }\n}\nexport const DB = new DBClass();\n"],"names":["DB","DBClass","wdb","rdb","transactionStorage","AsyncLocalStorage","runWithTransaction","callback","run","TransactionContext","getTransactionContext","getStore","readKnexfile","dbConfigPath","knexfileModule","config","path","join","Sonamu","apiRootPath","default","generateDBConfig","ServiceUnavailableException","getDB","which","dbConfig","instanceName","process","env","NODE_ENV","Error","knex","destroy","undefined","defaultKnexConfig","_","merge","client","pool","min","max","migrations","extension","directory","connection","database","defaultOptions","test","fixture_local","devMasterOptions","environments","development","devSlaveOptions","development_slave","development_master","fixture_remote","remote_fixture","prodMasterOptions","production","prodSlaveOptions","production_slave","production_master"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sonamu",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "Sonamu — TypeScript Fullstack API Framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -24,6 +24,10 @@
|
|
|
24
24
|
"url": "https://github.com/ping-alive/sonamu.git"
|
|
25
25
|
},
|
|
26
26
|
"bin": "./dist/bin/cli-wrapper.js",
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"src"
|
|
30
|
+
],
|
|
27
31
|
"dependencies": {
|
|
28
32
|
"@aws-sdk/client-s3": "^3.921.0",
|
|
29
33
|
"@aws-sdk/s3-request-presigner": "^3.921.0",
|
|
@@ -72,11 +76,11 @@
|
|
|
72
76
|
"typescript": "^5.2.2"
|
|
73
77
|
},
|
|
74
78
|
"peerDependencies": {
|
|
79
|
+
"@sonamu-kit/react-sui": "^0.1.14",
|
|
75
80
|
"fastify": "^4.23.2",
|
|
76
81
|
"knex": "^3.1.0",
|
|
77
82
|
"mysql2": "^3.6.1",
|
|
78
83
|
"nodemon": "3.1.10",
|
|
79
|
-
"source-map-support": "^0.5.21"
|
|
80
|
-
"@sonamu-kit/react-sui": "^0.1.14"
|
|
84
|
+
"source-map-support": "^0.5.21"
|
|
81
85
|
}
|
|
82
86
|
}
|
|
@@ -400,7 +400,7 @@ export function zodTypeToZodCode(zt: z.ZodType<any>): string {
|
|
|
400
400
|
.join(",")}])`;
|
|
401
401
|
case "enum":
|
|
402
402
|
// NOTE: z.enum(["A", "B"])도 z.enum({ A: "A", B: "B" })로 처리됨.
|
|
403
|
-
return `z.enum(
|
|
403
|
+
return `z.enum({${Object.entries((zt as z.ZodEnum).def.entries)
|
|
404
404
|
.map(([key, val]) =>
|
|
405
405
|
typeof val === "string" ? `${key}: "${val}"` : `${key}: ${val}`)
|
|
406
406
|
.join(", ")}})`;
|
package/src/api/decorators.ts
CHANGED
|
@@ -40,12 +40,16 @@ export type StreamDecoratorOptions = {
|
|
|
40
40
|
guards?: GuardKey[];
|
|
41
41
|
description?: string;
|
|
42
42
|
};
|
|
43
|
+
export type UploadDecoratorOptions = {
|
|
44
|
+
mode?: "single" | "multiple";
|
|
45
|
+
};
|
|
43
46
|
export const registeredApis: {
|
|
44
47
|
modelName: string;
|
|
45
48
|
methodName: string;
|
|
46
49
|
path: string;
|
|
47
50
|
options: ApiDecoratorOptions;
|
|
48
51
|
streamOptions?: StreamDecoratorOptions;
|
|
52
|
+
uploadOptions?: UploadDecoratorOptions;
|
|
49
53
|
}[] = [];
|
|
50
54
|
export type ExtendedApi = {
|
|
51
55
|
modelName: string;
|
|
@@ -53,6 +57,7 @@ export type ExtendedApi = {
|
|
|
53
57
|
path: string;
|
|
54
58
|
options: ApiDecoratorOptions;
|
|
55
59
|
streamOptions?: StreamDecoratorOptions;
|
|
60
|
+
uploadOptions?: UploadDecoratorOptions;
|
|
56
61
|
typeParameters: ApiParamType.TypeParam[];
|
|
57
62
|
parameters: ApiParam[];
|
|
58
63
|
returnType: ApiParamType;
|
|
@@ -176,13 +181,23 @@ export function transactional(options: TransactionalOptions = {}) {
|
|
|
176
181
|
};
|
|
177
182
|
}
|
|
178
183
|
|
|
179
|
-
export function upload() {
|
|
184
|
+
export function upload(options: UploadDecoratorOptions = {}) {
|
|
180
185
|
return function (
|
|
181
186
|
_target: Object,
|
|
182
187
|
_propertyKey: string,
|
|
183
188
|
descriptor: PropertyDescriptor
|
|
184
189
|
) {
|
|
185
190
|
const originalMethod = descriptor.value;
|
|
191
|
+
const modelName = _target.constructor.name.match(/(.+)Class$/)![1];
|
|
192
|
+
const methodName = _propertyKey;
|
|
193
|
+
|
|
194
|
+
// registeredApis에서 해당 API 찾아서 uploadOptions 추가
|
|
195
|
+
const existingApi = registeredApis.find(
|
|
196
|
+
(api) => api.modelName === modelName && api.methodName === methodName
|
|
197
|
+
);
|
|
198
|
+
if (existingApi) {
|
|
199
|
+
existingApi.uploadOptions = options;
|
|
200
|
+
}
|
|
186
201
|
|
|
187
202
|
descriptor.value = async function (this: any, ...args: any[]) {
|
|
188
203
|
const { request } = Sonamu.getContext();
|
|
@@ -196,20 +211,19 @@ export function upload() {
|
|
|
196
211
|
throw new Error("Storage가 설정되지 않았습니다.");
|
|
197
212
|
}
|
|
198
213
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
if (rawFile) {
|
|
202
|
-
const { FileStorage } = await import("../file-storage/file-storage");
|
|
203
|
-
uploadContext.file = new FileStorage(rawFile, storage);
|
|
204
|
-
}
|
|
205
|
-
} else if (request.files) {
|
|
206
|
-
const { FileStorage } = await import("../file-storage/file-storage");
|
|
214
|
+
const { FileStorage } = await import("../file-storage/file-storage");
|
|
215
|
+
if (options.mode === "multiple") {
|
|
207
216
|
const rawFilesIterator = request.files();
|
|
208
217
|
for await (const rawFile of rawFilesIterator) {
|
|
209
218
|
if (rawFile) {
|
|
210
219
|
uploadContext.files.push(new FileStorage(rawFile, storage));
|
|
211
220
|
}
|
|
212
221
|
}
|
|
222
|
+
} else {
|
|
223
|
+
const rawFile = await request.file();
|
|
224
|
+
if (rawFile) {
|
|
225
|
+
uploadContext.file = new FileStorage(rawFile, storage);
|
|
226
|
+
}
|
|
213
227
|
}
|
|
214
228
|
|
|
215
229
|
return Sonamu.uploadStorage.run({ uploadContext }, () => {
|
package/src/bin/cli-wrapper.ts
CHANGED
package/src/database/db.ts
CHANGED
|
@@ -24,6 +24,7 @@ export type SonamuDBBaseConfig = {
|
|
|
24
24
|
development_slave?: MySQLConfig;
|
|
25
25
|
production?: MySQLConfig;
|
|
26
26
|
production_slave?: MySQLConfig;
|
|
27
|
+
remote_fixture?: MySQLConfig;
|
|
27
28
|
};
|
|
28
29
|
};
|
|
29
30
|
|
|
@@ -161,12 +162,12 @@ class DBClass {
|
|
|
161
162
|
devMasterOptions,
|
|
162
163
|
devSlaveOptions
|
|
163
164
|
);
|
|
165
|
+
// NOTE: fixture remote는 default connection의 DB를 override해선 안됨.
|
|
164
166
|
const fixture_remote = _.merge({}, defaultKnexConfig, devMasterOptions, {
|
|
165
167
|
connection: {
|
|
166
|
-
// NOTE: fixture remote는 default connection의 DB를 override해선 안됨.
|
|
167
168
|
database: `${config.database}_fixture_remote`,
|
|
168
169
|
},
|
|
169
|
-
});
|
|
170
|
+
}, config.environments?.remote_fixture);
|
|
170
171
|
|
|
171
172
|
// 프로덕션 환경 설정
|
|
172
173
|
const prodMasterOptions = config.environments?.production ?? {};
|
|
@@ -17,9 +17,12 @@ export type TransactionalOptions = {
|
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
export class PuriWrapper<
|
|
20
|
-
DBSchema extends DatabaseSchemaExtend = DatabaseSchemaExtend
|
|
20
|
+
DBSchema extends DatabaseSchemaExtend = DatabaseSchemaExtend,
|
|
21
21
|
> {
|
|
22
|
-
constructor(
|
|
22
|
+
constructor(
|
|
23
|
+
public knex: Knex,
|
|
24
|
+
public upsertBuilder: UpsertBuilder
|
|
25
|
+
) {}
|
|
23
26
|
|
|
24
27
|
raw(sql: string): Knex.Raw {
|
|
25
28
|
return this.knex.raw(sql);
|
|
@@ -40,14 +43,14 @@ export class PuriWrapper<
|
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
async transaction<T>(
|
|
43
|
-
callback: (trx:
|
|
46
|
+
callback: (trx: PuriTransactionWrapper) => Promise<T>,
|
|
44
47
|
options: TransactionalOptions = {}
|
|
45
48
|
): Promise<T> {
|
|
46
49
|
const { isolation, readOnly } = options;
|
|
47
50
|
|
|
48
51
|
return this.knex.transaction(
|
|
49
52
|
async (trx) => {
|
|
50
|
-
return callback(new
|
|
53
|
+
return callback(new PuriTransactionWrapper(trx, this.upsertBuilder));
|
|
51
54
|
},
|
|
52
55
|
{ isolationLevel: isolation, readOnly }
|
|
53
56
|
);
|
|
@@ -127,3 +130,20 @@ export class PuriWrapper<
|
|
|
127
130
|
}
|
|
128
131
|
}
|
|
129
132
|
}
|
|
133
|
+
|
|
134
|
+
export class PuriTransactionWrapper extends PuriWrapper {
|
|
135
|
+
constructor(
|
|
136
|
+
public trx: Knex.Transaction,
|
|
137
|
+
public upsertBuilder: UpsertBuilder
|
|
138
|
+
) {
|
|
139
|
+
super(trx, upsertBuilder);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async rollback(): Promise<void> {
|
|
143
|
+
await this.trx.rollback();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async commit(): Promise<void> {
|
|
147
|
+
await this.trx.commit();
|
|
148
|
+
}
|
|
149
|
+
}
|
package/src/database/puri.ts
CHANGED
|
@@ -224,7 +224,9 @@ export class Puri<
|
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
// WhereIn (조인된 테이블 컬럼도 지원)
|
|
227
|
-
whereIn<
|
|
227
|
+
whereIn<
|
|
228
|
+
TColumn extends AvailableColumns<TSchema, TTable, TOriginal, TJoined>,
|
|
229
|
+
>(
|
|
228
230
|
column: TColumn,
|
|
229
231
|
values: ExtractColumnType<
|
|
230
232
|
TSchema,
|
|
@@ -264,7 +266,10 @@ export class Puri<
|
|
|
264
266
|
|
|
265
267
|
whereMatch<
|
|
266
268
|
TColumn extends FulltextColumns<TSchema, TTable, TOriginal, TJoined>,
|
|
267
|
-
>(
|
|
269
|
+
>(
|
|
270
|
+
column: TColumn,
|
|
271
|
+
value: string
|
|
272
|
+
): Puri<TSchema, TTable, TOriginal, TResult, TJoined> {
|
|
268
273
|
this.knexQuery.whereRaw(`MATCH (${String(column)}) AGAINST (?)`, [value]);
|
|
269
274
|
return this;
|
|
270
275
|
}
|
|
@@ -276,7 +281,9 @@ export class Puri<
|
|
|
276
281
|
) => WhereGroup<TSchema, TTable, TOriginal, TJoined>
|
|
277
282
|
): Puri<TSchema, TTable, TOriginal, TResult, TJoined> {
|
|
278
283
|
this.knexQuery.where((builder) => {
|
|
279
|
-
const group = new WhereGroup<TSchema, TTable, TOriginal, TJoined>(
|
|
284
|
+
const group = new WhereGroup<TSchema, TTable, TOriginal, TJoined>(
|
|
285
|
+
builder
|
|
286
|
+
);
|
|
280
287
|
callback(group);
|
|
281
288
|
});
|
|
282
289
|
return this;
|
|
@@ -288,7 +295,9 @@ export class Puri<
|
|
|
288
295
|
) => WhereGroup<TSchema, TTable, TOriginal, TJoined>
|
|
289
296
|
): Puri<TSchema, TTable, TOriginal, TResult, TJoined> {
|
|
290
297
|
this.knexQuery.orWhere((builder) => {
|
|
291
|
-
const group = new WhereGroup<TSchema, TTable, TOriginal, TJoined>(
|
|
298
|
+
const group = new WhereGroup<TSchema, TTable, TOriginal, TJoined>(
|
|
299
|
+
builder
|
|
300
|
+
);
|
|
292
301
|
callback(group);
|
|
293
302
|
});
|
|
294
303
|
return this;
|
|
@@ -297,12 +306,22 @@ export class Puri<
|
|
|
297
306
|
// Join
|
|
298
307
|
join<
|
|
299
308
|
TJoinTable extends keyof TSchema,
|
|
300
|
-
TLColumn extends AvailableColumns<
|
|
301
|
-
|
|
309
|
+
TLColumn extends AvailableColumns<
|
|
310
|
+
TSchema,
|
|
311
|
+
TTable,
|
|
312
|
+
TOriginal,
|
|
313
|
+
TJoined & Record<TJoinTable, TSchema[TJoinTable]>
|
|
314
|
+
>,
|
|
315
|
+
TRColumn extends AvailableColumns<
|
|
316
|
+
TSchema,
|
|
317
|
+
TTable,
|
|
318
|
+
TOriginal,
|
|
319
|
+
TJoined & Record<TJoinTable, TSchema[TJoinTable]>
|
|
320
|
+
>,
|
|
302
321
|
>(
|
|
303
322
|
table: TJoinTable,
|
|
304
323
|
left: TLColumn,
|
|
305
|
-
right: TRColumn
|
|
324
|
+
right: TRColumn
|
|
306
325
|
): Puri<
|
|
307
326
|
TSchema,
|
|
308
327
|
TTable,
|
|
@@ -327,7 +346,13 @@ export class Puri<
|
|
|
327
346
|
alias: TAlias,
|
|
328
347
|
left: string,
|
|
329
348
|
right: string
|
|
330
|
-
): Puri<
|
|
349
|
+
): Puri<
|
|
350
|
+
TSchema,
|
|
351
|
+
TTable,
|
|
352
|
+
TOriginal,
|
|
353
|
+
TResult,
|
|
354
|
+
TJoined & Record<TAlias, TSubResult>
|
|
355
|
+
>;
|
|
331
356
|
join(
|
|
332
357
|
table: string,
|
|
333
358
|
left: string,
|
|
@@ -361,12 +386,22 @@ export class Puri<
|
|
|
361
386
|
|
|
362
387
|
leftJoin<
|
|
363
388
|
TJoinTable extends keyof TSchema,
|
|
364
|
-
TLColumn extends AvailableColumns<
|
|
365
|
-
|
|
389
|
+
TLColumn extends AvailableColumns<
|
|
390
|
+
TSchema,
|
|
391
|
+
TTable,
|
|
392
|
+
TOriginal,
|
|
393
|
+
TJoined & Record<TJoinTable, TSchema[TJoinTable]>
|
|
394
|
+
>,
|
|
395
|
+
TRColumn extends AvailableColumns<
|
|
396
|
+
TSchema,
|
|
397
|
+
TTable,
|
|
398
|
+
TOriginal,
|
|
399
|
+
TJoined & Record<TJoinTable, TSchema[TJoinTable]>
|
|
400
|
+
>,
|
|
366
401
|
>(
|
|
367
402
|
table: TJoinTable,
|
|
368
403
|
left: TLColumn,
|
|
369
|
-
right: TRColumn
|
|
404
|
+
right: TRColumn
|
|
370
405
|
): Puri<
|
|
371
406
|
TSchema,
|
|
372
407
|
TTable,
|
|
@@ -407,7 +442,15 @@ export class Puri<
|
|
|
407
442
|
}
|
|
408
443
|
|
|
409
444
|
// OrderBy
|
|
410
|
-
orderBy<
|
|
445
|
+
orderBy<
|
|
446
|
+
TColumn extends ResultAvailableColumns<
|
|
447
|
+
TSchema,
|
|
448
|
+
TTable,
|
|
449
|
+
TOriginal,
|
|
450
|
+
TResult,
|
|
451
|
+
TJoined
|
|
452
|
+
>,
|
|
453
|
+
>(
|
|
411
454
|
column: TColumn,
|
|
412
455
|
direction: "asc" | "desc"
|
|
413
456
|
): Puri<TSchema, TTable, TOriginal, TResult, TJoined>;
|
|
@@ -431,21 +474,39 @@ export class Puri<
|
|
|
431
474
|
}
|
|
432
475
|
|
|
433
476
|
// Group by (조인된 테이블 컬럼도 지원)
|
|
434
|
-
groupBy<
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
477
|
+
groupBy<
|
|
478
|
+
TColumns extends ResultAvailableColumns<
|
|
479
|
+
TSchema,
|
|
480
|
+
TTable,
|
|
481
|
+
TOriginal,
|
|
482
|
+
TResult,
|
|
483
|
+
TJoined
|
|
484
|
+
>,
|
|
485
|
+
>(...columns: TColumns[]): Puri<TSchema, TTable, TOriginal, TResult, TJoined>;
|
|
486
|
+
groupBy(
|
|
487
|
+
...columns: string[]
|
|
488
|
+
): Puri<TSchema, TTable, TOriginal, TResult, TJoined> {
|
|
438
489
|
this.knexQuery.groupBy(...(columns as string[]));
|
|
439
490
|
return this;
|
|
440
491
|
}
|
|
441
492
|
|
|
442
493
|
having(condition: string): Puri<TSchema, TTable, TOriginal, TResult, TJoined>;
|
|
443
|
-
having<
|
|
494
|
+
having<
|
|
495
|
+
TColumn extends ResultAvailableColumns<
|
|
496
|
+
TSchema,
|
|
497
|
+
TTable,
|
|
498
|
+
TOriginal,
|
|
499
|
+
TResult,
|
|
500
|
+
TJoined
|
|
501
|
+
>,
|
|
502
|
+
>(
|
|
444
503
|
condition: TColumn,
|
|
445
504
|
operator: ComparisonOperator,
|
|
446
505
|
value: any
|
|
447
506
|
): Puri<TSchema, TTable, TOriginal, TResult, TJoined>;
|
|
448
|
-
having(
|
|
507
|
+
having(
|
|
508
|
+
...conditions: string[]
|
|
509
|
+
): Puri<TSchema, TTable, TOriginal, TResult, TJoined> {
|
|
449
510
|
this.knexQuery.having(...(conditions as [string, string, string]));
|
|
450
511
|
return this;
|
|
451
512
|
}
|
|
@@ -641,6 +702,32 @@ export class Puri<
|
|
|
641
702
|
raw(): Knex.QueryBuilder {
|
|
642
703
|
return this.knexQuery;
|
|
643
704
|
}
|
|
705
|
+
|
|
706
|
+
increment<
|
|
707
|
+
TColumn extends AvailableColumns<TSchema, TTable, TOriginal, TJoined>,
|
|
708
|
+
>(
|
|
709
|
+
column: TColumn,
|
|
710
|
+
value: number
|
|
711
|
+
): Puri<TSchema, TTable, TOriginal, TResult, TJoined> {
|
|
712
|
+
if (value <= 0) {
|
|
713
|
+
throw new Error("Increment value must be greater than 0");
|
|
714
|
+
}
|
|
715
|
+
this.knexQuery.increment(column, value);
|
|
716
|
+
return this;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
decrement<
|
|
720
|
+
TColumn extends AvailableColumns<TSchema, TTable, TOriginal, TJoined>,
|
|
721
|
+
>(
|
|
722
|
+
column: TColumn,
|
|
723
|
+
value: number
|
|
724
|
+
): Puri<TSchema, TTable, TOriginal, TResult, TJoined> {
|
|
725
|
+
if (value <= 0) {
|
|
726
|
+
throw new Error("Decrement value must be greater than 0");
|
|
727
|
+
}
|
|
728
|
+
this.knexQuery.decrement(column, value);
|
|
729
|
+
return this;
|
|
730
|
+
}
|
|
644
731
|
}
|
|
645
732
|
|
|
646
733
|
// 11. Database 클래스
|
|
@@ -685,7 +772,9 @@ class WhereGroup<
|
|
|
685
772
|
orWhere(
|
|
686
773
|
conditions: WhereCondition<TSchema, TTable, TOriginal, TJoined>
|
|
687
774
|
): WhereGroup<TSchema, TTable, TOriginal, TJoined>;
|
|
688
|
-
orWhere<
|
|
775
|
+
orWhere<
|
|
776
|
+
TColumn extends AvailableColumns<TSchema, TTable, TOriginal, TJoined>,
|
|
777
|
+
>(
|
|
689
778
|
column: TColumn,
|
|
690
779
|
value: ExtractColumnType<
|
|
691
780
|
TSchema,
|
|
@@ -695,7 +784,9 @@ class WhereGroup<
|
|
|
695
784
|
TJoined
|
|
696
785
|
>
|
|
697
786
|
): WhereGroup<TSchema, TTable, TOriginal, TJoined>;
|
|
698
|
-
orWhere<
|
|
787
|
+
orWhere<
|
|
788
|
+
TColumn extends AvailableColumns<TSchema, TTable, TOriginal, TJoined>,
|
|
789
|
+
>(
|
|
699
790
|
column: TColumn,
|
|
700
791
|
operator: ComparisonOperator | "like",
|
|
701
792
|
value: ExtractColumnType<
|
|
@@ -712,7 +803,9 @@ class WhereGroup<
|
|
|
712
803
|
return this;
|
|
713
804
|
}
|
|
714
805
|
|
|
715
|
-
whereIn<
|
|
806
|
+
whereIn<
|
|
807
|
+
TColumn extends AvailableColumns<TSchema, TTable, TOriginal, TJoined>,
|
|
808
|
+
>(
|
|
716
809
|
column: TColumn,
|
|
717
810
|
values: ExtractColumnType<
|
|
718
811
|
TSchema,
|
|
@@ -789,18 +882,28 @@ export class JoinClauseGroup<
|
|
|
789
882
|
constructor(private callback: Knex.JoinClause) {}
|
|
790
883
|
|
|
791
884
|
on(
|
|
792
|
-
callback: (
|
|
885
|
+
callback: (
|
|
886
|
+
joinClause: JoinClauseGroup<TSchema, TTable, TOriginal, TJoined>
|
|
887
|
+
) => void
|
|
888
|
+
): JoinClauseGroup<TSchema, TTable, TOriginal, TJoined>;
|
|
889
|
+
on(
|
|
890
|
+
column: string,
|
|
891
|
+
value: any
|
|
793
892
|
): JoinClauseGroup<TSchema, TTable, TOriginal, TJoined>;
|
|
794
|
-
on(column: string, value: any): JoinClauseGroup<TSchema, TTable, TOriginal, TJoined>;
|
|
795
893
|
on(...args: any[]): JoinClauseGroup<TSchema, TTable, TOriginal, TJoined> {
|
|
796
894
|
this.callback.on(...(args as [string, string]));
|
|
797
895
|
return this;
|
|
798
896
|
}
|
|
799
897
|
|
|
800
898
|
orOn(
|
|
801
|
-
callback: (
|
|
899
|
+
callback: (
|
|
900
|
+
joinClause: JoinClauseGroup<TSchema, TTable, TOriginal, TJoined>
|
|
901
|
+
) => void
|
|
902
|
+
): JoinClauseGroup<TSchema, TTable, TOriginal, TJoined>;
|
|
903
|
+
orOn(
|
|
904
|
+
column: string,
|
|
905
|
+
value: any
|
|
802
906
|
): JoinClauseGroup<TSchema, TTable, TOriginal, TJoined>;
|
|
803
|
-
orOn(column: string, value: any): JoinClauseGroup<TSchema, TTable, TOriginal, TJoined>;
|
|
804
907
|
orOn(...args: any[]): JoinClauseGroup<TSchema, TTable, TOriginal, TJoined> {
|
|
805
908
|
this.callback.orOn(...(args as [string, string]));
|
|
806
909
|
return this;
|
|
@@ -1,20 +1,33 @@
|
|
|
1
1
|
export type ComparisonOperator = "=" | ">" | ">=" | "<" | "<=" | "<>" | "!=";
|
|
2
2
|
export type Expand<T> = T extends any[]
|
|
3
3
|
? { [K in keyof T[0]]: T[0][K] }[] // 배열이면 첫 번째 요소를 Expand하고 배열로 감쌈
|
|
4
|
-
: T extends object
|
|
5
|
-
|
|
4
|
+
: T extends object
|
|
5
|
+
? { [K in keyof T]: T[K] }
|
|
6
|
+
: T;
|
|
7
|
+
|
|
6
8
|
// EmptyRecord가 남아있으면 AvailableColumns 추론이 제대로 되지 않음 (EmptyRecord를 {}로 변경하면 정상 동작함)
|
|
7
|
-
export type MergeJoined<TExisting, TNew> =
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
: TExisting & TNew; // 이후 join: 누적
|
|
9
|
+
export type MergeJoined<TExisting, TNew> = TExisting extends EmptyRecord
|
|
10
|
+
? TNew // 첫 join: EmptyRecord 제거하고 대체
|
|
11
|
+
: TExisting & TNew; // 이후 join: 누적
|
|
11
12
|
|
|
12
|
-
type DeepEqual<T, U> = [T] extends [U]
|
|
13
|
-
|
|
13
|
+
type DeepEqual<T, U> = [T] extends [U]
|
|
14
|
+
? [U] extends [T]
|
|
15
|
+
? true
|
|
16
|
+
: false
|
|
17
|
+
: false;
|
|
18
|
+
type Extends<T, U> =
|
|
19
|
+
DeepEqual<T, Record<string, never>> extends true
|
|
20
|
+
? false
|
|
21
|
+
: T extends U
|
|
22
|
+
? true
|
|
23
|
+
: false;
|
|
14
24
|
type NullableToOptional<T> = {
|
|
15
|
-
[K in keyof T as T[K] extends null | undefined ? K : never]?: Exclude<
|
|
25
|
+
[K in keyof T as T[K] extends null | undefined ? K : never]?: Exclude<
|
|
26
|
+
T[K],
|
|
27
|
+
null | undefined
|
|
28
|
+
>;
|
|
16
29
|
} & Partial<{
|
|
17
|
-
[K in keyof T as T[K] extends null | undefined ? never : K]: T[K]
|
|
30
|
+
[K in keyof T as T[K] extends null | undefined ? never : K]: T[K];
|
|
18
31
|
}>;
|
|
19
32
|
|
|
20
33
|
// Join 등이 Empty 상태일 떄 {}가 아니라 EmptyRecord를 써서
|
|
@@ -27,7 +40,9 @@ export type ResultAvailableColumns<
|
|
|
27
40
|
TOriginal = any,
|
|
28
41
|
TResult = any,
|
|
29
42
|
TJoined = EmptyRecord,
|
|
30
|
-
> =
|
|
43
|
+
> =
|
|
44
|
+
| AvailableColumns<TSchema, T, TOriginal, TJoined>
|
|
45
|
+
| `${keyof TResult & string}`;
|
|
31
46
|
|
|
32
47
|
// 사용 가능한 컬럼 경로 타입 (메인 테이블 + 조인된 테이블들)
|
|
33
48
|
export type AvailableColumns<
|
|
@@ -37,14 +52,14 @@ export type AvailableColumns<
|
|
|
37
52
|
TJoined = EmptyRecord,
|
|
38
53
|
> = T extends keyof TSchema
|
|
39
54
|
? // 기존 테이블 케이스
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
55
|
+
| (Extends<TJoined, Record<string, any>> extends false
|
|
56
|
+
? // 이게 TSchema[T]에 존재하면
|
|
57
|
+
keyof TSchema[T]
|
|
58
|
+
: {
|
|
59
|
+
[K in keyof TJoined]: TJoined[K] extends Record<string, any>
|
|
60
|
+
? `${string & K}.${keyof TJoined[K] & string}`
|
|
61
|
+
: never;
|
|
62
|
+
}[keyof TJoined])
|
|
48
63
|
| `${T & string}.${keyof TSchema[T] & string}`
|
|
49
64
|
: // 서브쿼리 케이스 (T는 alias string)
|
|
50
65
|
| keyof TOriginal
|
|
@@ -156,27 +171,15 @@ export type WhereCondition<
|
|
|
156
171
|
T extends keyof TSchema | string,
|
|
157
172
|
TOriginal = any,
|
|
158
173
|
TJoined = EmptyRecord,
|
|
159
|
-
> =
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
// 조인된 테이블들의 조건들
|
|
169
|
-
(TJoined extends Record<string, any>
|
|
170
|
-
? {
|
|
171
|
-
[K in keyof TJoined as TJoined[K] extends Record<string, any>
|
|
172
|
-
? keyof TJoined[K] & string
|
|
173
|
-
: never]?: TJoined[K] extends Record<string, any>
|
|
174
|
-
?
|
|
175
|
-
| TJoined[K][K extends keyof TJoined[K] ? K : never]
|
|
176
|
-
| TJoined[K][K extends keyof TJoined[K] ? K : never][]
|
|
177
|
-
: never;
|
|
178
|
-
}
|
|
179
|
-
: Record<string, never>);
|
|
174
|
+
> = {
|
|
175
|
+
[key in AvailableColumns<TSchema, T, TOriginal, TJoined>]?: ExtractColumnType<
|
|
176
|
+
TSchema,
|
|
177
|
+
T,
|
|
178
|
+
key & string,
|
|
179
|
+
TOriginal,
|
|
180
|
+
TJoined
|
|
181
|
+
>;
|
|
182
|
+
};
|
|
180
183
|
|
|
181
184
|
// Fulltext index 컬럼 추출 타입 (메인 테이블 + 조인된 테이블)
|
|
182
185
|
export type FulltextColumns<
|
|
@@ -219,4 +222,6 @@ export type FulltextColumns<
|
|
|
219
222
|
: never);
|
|
220
223
|
|
|
221
224
|
// Insert 타입: id, created_at 제외
|
|
222
|
-
export type InsertData<T> = NullableToOptional<
|
|
225
|
+
export type InsertData<T> = NullableToOptional<
|
|
226
|
+
Omit<T, "id" | "created_at" | "__fulltext__">
|
|
227
|
+
>;
|
package/src/index.ts
CHANGED
|
@@ -16,9 +16,10 @@ export * from "./utils/controller";
|
|
|
16
16
|
export * from "./utils/model";
|
|
17
17
|
export * from "./utils/utils";
|
|
18
18
|
export * from "./testing/fixture-manager";
|
|
19
|
-
export * from "./migration/migrator";
|
|
20
19
|
export * from "./entity/entity-manager";
|
|
21
20
|
export * from "./entity/entity";
|
|
21
|
+
export * from "./migration/migrator";
|
|
22
|
+
export * from "./migration/types";
|
|
22
23
|
export * from "./file-storage/driver";
|
|
23
24
|
|
|
24
25
|
// export * from "./api/code-converters";
|
|
@@ -77,7 +77,7 @@ function genColumnDefinitions(columns: MigrationColumn[]): string[] {
|
|
|
77
77
|
columnType = "text";
|
|
78
78
|
}
|
|
79
79
|
chains.push(
|
|
80
|
-
`${
|
|
80
|
+
`${columnType}('${column.name}'${
|
|
81
81
|
column.length ? `, ${column.length}` : ""
|
|
82
82
|
}${extraType ? `, '${extraType}'` : ""})`
|
|
83
83
|
);
|
|
@@ -680,9 +680,9 @@ export async function generateAlterCode(
|
|
|
680
680
|
// boolean인 경우 기본값 정규화 (MySQL에서는 TINYINT(1)로 저장되므로 0 또는 1로 정규화)
|
|
681
681
|
// TODO: db.ts에 typeCase 설정 확인하여 처리하도록 수정 필요
|
|
682
682
|
if (col.type === "boolean" && col.defaultTo !== undefined) {
|
|
683
|
-
if (col.defaultTo === "0" || col.defaultTo === "false") {
|
|
683
|
+
if (col.defaultTo === "0" || col.defaultTo.toLowerCase() === "false") {
|
|
684
684
|
col.defaultTo = "0";
|
|
685
|
-
} else if (col.defaultTo === "1" || col.defaultTo === "true") {
|
|
685
|
+
} else if (col.defaultTo === "1" || col.defaultTo.toLowerCase() === "true") {
|
|
686
686
|
col.defaultTo = "1";
|
|
687
687
|
}
|
|
688
688
|
}
|
package/src/migration/types.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SonamuDBConfig } from "../database/db";
|
|
1
2
|
import { GenMigrationCode } from "../types/types";
|
|
2
3
|
|
|
3
4
|
export type MigrationCode = {
|
|
@@ -10,7 +11,7 @@ export type MigrationStatus = {
|
|
|
10
11
|
codes: MigrationCode[];
|
|
11
12
|
conns: {
|
|
12
13
|
name: string;
|
|
13
|
-
connKey:
|
|
14
|
+
connKey: keyof SonamuDBConfig;
|
|
14
15
|
connString: ConnString;
|
|
15
16
|
currentVersion: string;
|
|
16
17
|
status: string | number;
|
|
@@ -84,7 +84,12 @@ export class Template__generated_http extends Template {
|
|
|
84
84
|
])
|
|
85
85
|
);
|
|
86
86
|
} else if (zodType instanceof z.ZodArray) {
|
|
87
|
-
return [
|
|
87
|
+
return [
|
|
88
|
+
this.zodTypeToReqDefault(
|
|
89
|
+
(zodType as z.ZodArray<z.ZodType>).element,
|
|
90
|
+
name
|
|
91
|
+
),
|
|
92
|
+
];
|
|
88
93
|
} else if (zodType instanceof z.ZodString) {
|
|
89
94
|
if (name.endsWith("_at") || name.endsWith("_date") || name === "range") {
|
|
90
95
|
return "2000-01-01";
|
|
@@ -97,17 +102,23 @@ export class Template__generated_http extends Template {
|
|
|
97
102
|
}
|
|
98
103
|
|
|
99
104
|
const minValue = zodType.minValue ?? 0;
|
|
100
|
-
return minValue > Number.MIN_SAFE_INTEGER
|
|
105
|
+
return minValue > Number.MIN_SAFE_INTEGER ? minValue : 0;
|
|
101
106
|
} else if (zodType instanceof z.ZodBoolean) {
|
|
102
107
|
return false;
|
|
103
108
|
} else if (zodType instanceof z.ZodEnum) {
|
|
104
109
|
return zodType.options[0];
|
|
105
110
|
} else if (zodType instanceof z.ZodOptional) {
|
|
106
|
-
return this.zodTypeToReqDefault(
|
|
111
|
+
return this.zodTypeToReqDefault(
|
|
112
|
+
(zodType as z.ZodOptional<z.ZodType>).def.innerType,
|
|
113
|
+
name
|
|
114
|
+
);
|
|
107
115
|
} else if (zodType instanceof z.ZodNullable) {
|
|
108
116
|
return null;
|
|
109
117
|
} else if (zodType instanceof z.ZodUnion) {
|
|
110
|
-
return this.zodTypeToReqDefault(
|
|
118
|
+
return this.zodTypeToReqDefault(
|
|
119
|
+
(zodType as z.ZodUnion<z.ZodType[]>).def.options[0],
|
|
120
|
+
name
|
|
121
|
+
);
|
|
111
122
|
} else if (zodType instanceof z.ZodUnknown) {
|
|
112
123
|
return "unknown";
|
|
113
124
|
} else if (zodType instanceof z.ZodTuple) {
|
|
@@ -119,16 +130,29 @@ export class Template__generated_http extends Template {
|
|
|
119
130
|
} else if (zodType instanceof z.ZodLiteral) {
|
|
120
131
|
return zodType.value;
|
|
121
132
|
} else if (zodType instanceof z.ZodRecord || zodType instanceof z.ZodMap) {
|
|
122
|
-
const kvDef = (
|
|
133
|
+
const kvDef = (
|
|
134
|
+
zodType as z.ZodRecord<any, z.ZodType> | z.ZodMap<z.ZodType, z.ZodType>
|
|
135
|
+
).def;
|
|
123
136
|
const key = this.zodTypeToReqDefault(kvDef.keyType, name) as any;
|
|
124
137
|
const value = this.zodTypeToReqDefault(kvDef.valueType, name);
|
|
125
138
|
return { [key]: value };
|
|
126
139
|
} else if (zodType instanceof z.ZodSet) {
|
|
127
|
-
return [
|
|
140
|
+
return [
|
|
141
|
+
this.zodTypeToReqDefault(
|
|
142
|
+
(zodType as z.ZodSet<z.ZodType>).def.valueType,
|
|
143
|
+
name
|
|
144
|
+
),
|
|
145
|
+
];
|
|
128
146
|
} else if (zodType instanceof z.ZodIntersection) {
|
|
129
|
-
return this.zodTypeToReqDefault(
|
|
147
|
+
return this.zodTypeToReqDefault(
|
|
148
|
+
(zodType as z.ZodIntersection<z.ZodType, z.ZodType>).def.right,
|
|
149
|
+
name
|
|
150
|
+
);
|
|
130
151
|
} else if (zodType instanceof z.ZodDefault) {
|
|
131
|
-
return this.zodTypeToReqDefault(
|
|
152
|
+
return this.zodTypeToReqDefault(
|
|
153
|
+
(zodType as z.ZodDefault<z.ZodType>).def.innerType,
|
|
154
|
+
name
|
|
155
|
+
);
|
|
132
156
|
} else {
|
|
133
157
|
// console.log(zodType);
|
|
134
158
|
return `unknown-${zodType.type}`;
|
|
@@ -140,8 +164,15 @@ export class Template__generated_http extends Template {
|
|
|
140
164
|
references: { [typeName: string]: z.ZodObject<any> }
|
|
141
165
|
): { [key: string]: unknown } {
|
|
142
166
|
const reqType = getZodObjectFromApi(api, references);
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
167
|
+
try {
|
|
168
|
+
const def = this.zodTypeToReqDefault(reqType, "unknownName") as {
|
|
169
|
+
[key: string]: unknown;
|
|
170
|
+
};
|
|
171
|
+
return def;
|
|
172
|
+
} catch (error) {
|
|
173
|
+
throw new Error(
|
|
174
|
+
`Invalid zod type detected on ${api.modelName}:${api.methodName}`
|
|
175
|
+
);
|
|
176
|
+
}
|
|
146
177
|
}
|
|
147
178
|
}
|
|
@@ -89,12 +89,14 @@ export class Template__generated_sso extends Template {
|
|
|
89
89
|
} as Omit<SourceCode, "label">
|
|
90
90
|
);
|
|
91
91
|
|
|
92
|
+
const body = sourceCode.lines.join("\n");
|
|
93
|
+
const isUsingManyToManyBaseSchema = body.includes("ManyToManyBaseSchema");
|
|
92
94
|
return {
|
|
93
95
|
...this.getTargetAndPath(),
|
|
94
96
|
body: sourceCode.lines.join("\n"),
|
|
95
97
|
importKeys: sourceCode.importKeys,
|
|
96
98
|
customHeaders: [
|
|
97
|
-
`import { SubsetQuery, ManyToManyBaseSchema } from "sonamu";`,
|
|
99
|
+
`import { SubsetQuery, ${isUsingManyToManyBaseSchema ? "ManyToManyBaseSchema" : ""} } from "sonamu";`,
|
|
98
100
|
],
|
|
99
101
|
};
|
|
100
102
|
}
|
|
@@ -219,18 +219,31 @@ export async function ${methodNameAxios}${typeParamsDef}(${paramsDef}): Promise<
|
|
|
219
219
|
returnTypeDef: string,
|
|
220
220
|
paramsWithoutContext: ApiParam[]
|
|
221
221
|
) {
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
222
|
+
const isMultiple = api.uploadOptions?.mode === "multiple";
|
|
223
|
+
const fileParamName = isMultiple ? "files" : "file";
|
|
224
|
+
const fileParamType = isMultiple ? "File[]" : "File";
|
|
225
|
+
|
|
226
|
+
const formDataDef = isMultiple
|
|
227
|
+
? [
|
|
228
|
+
`${fileParamName}.forEach(f => formData.append("${fileParamName}", f));`,
|
|
229
|
+
...paramsWithoutContext.map(
|
|
230
|
+
(param) =>
|
|
231
|
+
`formData.append('${param.name}', String(${param.name}));`
|
|
232
|
+
),
|
|
233
|
+
].join("\n")
|
|
234
|
+
: [
|
|
235
|
+
`formData.append("${fileParamName}", ${fileParamName});`,
|
|
236
|
+
...paramsWithoutContext.map(
|
|
237
|
+
(param) =>
|
|
238
|
+
`formData.append('${param.name}', String(${param.name}));`
|
|
239
|
+
),
|
|
240
|
+
].join("\n");
|
|
228
241
|
|
|
229
242
|
const paramsDefComma = paramsDef !== "" ? ", " : "";
|
|
230
243
|
return `
|
|
231
244
|
export async function ${api.methodName}${typeParamsDef}(
|
|
232
245
|
${paramsDef}${paramsDefComma}
|
|
233
|
-
|
|
246
|
+
${fileParamName}: ${fileParamType},
|
|
234
247
|
onUploadProgress?: (pe:AxiosProgressEvent) => void
|
|
235
248
|
): Promise<${returnTypeDef}> {
|
|
236
249
|
const formData = new FormData();
|
|
@@ -568,6 +568,8 @@ export class FixtureManagerClass {
|
|
|
568
568
|
if (!isRelationProp(prop)) {
|
|
569
569
|
if (prop.type === "json") {
|
|
570
570
|
insertData[propName] = JSON.stringify(column.value);
|
|
571
|
+
} else if (prop.type === "timestamp" || prop.type === "datetime") {
|
|
572
|
+
insertData[propName] = new Date(column.value);
|
|
571
573
|
} else {
|
|
572
574
|
insertData[propName] = column.value;
|
|
573
575
|
}
|
package/.swcrc
DELETED
package/import-to-require.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
const fs = require("fs/promises");
|
|
2
|
-
|
|
3
|
-
export const ImportToRequirePlugin = {
|
|
4
|
-
name: "import-to-require",
|
|
5
|
-
setup(build) {
|
|
6
|
-
if (build.initialOptions.define.TSUP_FORMAT === '"cjs"') {
|
|
7
|
-
// 빌드 전에 src/database/db.ts 파일을 읽어서 변환
|
|
8
|
-
build.onLoad({ filter: /database\/db.ts/ }, async (args) => {
|
|
9
|
-
console.debug(`reading ${args.path}`);
|
|
10
|
-
let contents = await fs.readFile(args.path, "utf8");
|
|
11
|
-
|
|
12
|
-
// 'await import(' 패턴을 찾아 'require('로 변환
|
|
13
|
-
contents = contents.replace(
|
|
14
|
-
/\bawait import\(([^)]+)\)/g,
|
|
15
|
-
(_, modulePath) => {
|
|
16
|
-
return `require(${modulePath})`;
|
|
17
|
-
}
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
return {
|
|
21
|
-
contents,
|
|
22
|
-
loader: "ts", // TypeScript를 지원하도록 'ts' 로더 설정
|
|
23
|
-
};
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
};
|
package/nodemon.json
DELETED
package/tsconfig.json
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
/* Basic Options */
|
|
4
|
-
"target": "ESNext",
|
|
5
|
-
"module": "ESNext",
|
|
6
|
-
"outDir": "dist",
|
|
7
|
-
"sourceMap": true,
|
|
8
|
-
"lib": ["esnext", "dom"],
|
|
9
|
-
|
|
10
|
-
// NOTE(Haze, 251106): SSE 관련 fastify 타입 이슈로 명시적으로 추가함.
|
|
11
|
-
"types": ["fastify-sse-v2"],
|
|
12
|
-
|
|
13
|
-
"declaration": true,
|
|
14
|
-
"declarationMap": true,
|
|
15
|
-
|
|
16
|
-
/* Strict Type-Checking Options */
|
|
17
|
-
"strict": true,
|
|
18
|
-
"noImplicitAny": true,
|
|
19
|
-
"strictNullChecks": true,
|
|
20
|
-
"strictFunctionTypes": true,
|
|
21
|
-
"strictBindCallApply": true,
|
|
22
|
-
"strictPropertyInitialization": true,
|
|
23
|
-
"noImplicitThis": true,
|
|
24
|
-
"alwaysStrict": true,
|
|
25
|
-
|
|
26
|
-
/* Additional Checks */
|
|
27
|
-
"noUnusedLocals": true,
|
|
28
|
-
"noUnusedParameters": true,
|
|
29
|
-
"noImplicitReturns": true,
|
|
30
|
-
"noFallthroughCasesInSwitch": true,
|
|
31
|
-
"skipLibCheck": true,
|
|
32
|
-
// "noUncheckedIndexedAccess": true, // FIXME
|
|
33
|
-
|
|
34
|
-
/* Module Resolution Options */
|
|
35
|
-
"moduleResolution": "node",
|
|
36
|
-
"esModuleInterop": true,
|
|
37
|
-
|
|
38
|
-
/* Experimental Options */
|
|
39
|
-
"experimentalDecorators": true,
|
|
40
|
-
"emitDecoratorMetadata": true,
|
|
41
|
-
|
|
42
|
-
/* Advanced Options */
|
|
43
|
-
"forceConsistentCasingInFileNames": true,
|
|
44
|
-
"noErrorTruncation": true
|
|
45
|
-
},
|
|
46
|
-
"exclude": [
|
|
47
|
-
"node_modules",
|
|
48
|
-
"dist",
|
|
49
|
-
"src/**/*.test.ts",
|
|
50
|
-
"src/**/*.test-hold.ts",
|
|
51
|
-
"src/**/*.ignore.ts",
|
|
52
|
-
"wasted_src/**",
|
|
53
|
-
"_templates/**",
|
|
54
|
-
"**/__mocks__/**"
|
|
55
|
-
]
|
|
56
|
-
}
|
package/tsup.config.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
// tsup.config.js
|
|
2
|
-
import { defineConfig } from "tsup";
|
|
3
|
-
import { ImportToRequirePlugin } from "./import-to-require";
|
|
4
|
-
|
|
5
|
-
export default defineConfig({
|
|
6
|
-
entry: [
|
|
7
|
-
"src/index.ts",
|
|
8
|
-
"src/bin/cli.ts",
|
|
9
|
-
"src/bin/cli-wrapper.ts",
|
|
10
|
-
"src/database/drivers/knex/base-model.ts",
|
|
11
|
-
"src/database/drivers/kysely/base-model.ts",
|
|
12
|
-
],
|
|
13
|
-
dts: true,
|
|
14
|
-
format: [
|
|
15
|
-
"cjs",
|
|
16
|
-
// "esm"
|
|
17
|
-
],
|
|
18
|
-
target: "esnext",
|
|
19
|
-
clean: true,
|
|
20
|
-
sourcemap: true,
|
|
21
|
-
shims: true,
|
|
22
|
-
platform: "node",
|
|
23
|
-
splitting: true,
|
|
24
|
-
esbuildPlugins: [ImportToRequirePlugin],
|
|
25
|
-
external: [
|
|
26
|
-
"chalk",
|
|
27
|
-
"dotenv",
|
|
28
|
-
"fast-deep-equal",
|
|
29
|
-
"fastify",
|
|
30
|
-
"glob",
|
|
31
|
-
"inflection",
|
|
32
|
-
"knex",
|
|
33
|
-
"lodash",
|
|
34
|
-
"luxon",
|
|
35
|
-
"mysql2",
|
|
36
|
-
"node-sql-parser",
|
|
37
|
-
"prompts",
|
|
38
|
-
"qs",
|
|
39
|
-
"tsicli",
|
|
40
|
-
"uuid",
|
|
41
|
-
"zod",
|
|
42
|
-
"prettier",
|
|
43
|
-
"source-map-support",
|
|
44
|
-
"tsup",
|
|
45
|
-
"typescript",
|
|
46
|
-
],
|
|
47
|
-
});
|