@rainbow-o23/n3 1.0.40 → 1.0.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -13
- package/index.cjs +15 -101
- package/index.js +16 -100
- package/lib/http/fetch-step.d.ts +1 -1
- package/lib/typeorm-step/abstract-typeorm-step.d.ts +2 -4
- package/lib/typeorm-step/index.d.ts +1 -3
- package/lib/typeorm-step/types.d.ts +0 -1
- package/package.json +2 -2
- package/src/lib/http/fetch-step.ts +17 -10
- package/src/lib/typeorm-step/abstract-typeorm-step.ts +2 -24
- package/src/lib/typeorm-step/index.ts +1 -3
- package/src/lib/typeorm-step/types.ts +0 -1
- package/lib/typeorm-step/typeorm-load-entity-by-id-step.d.ts +0 -12
- package/lib/typeorm-step/typeorm-save-entity-step.d.ts +0 -33
- package/src/lib/typeorm-step/typeorm-load-entity-by-id-step.ts +0 -35
- package/src/lib/typeorm-step/typeorm-save-entity-step.ts +0 -112
- /package/lib/typeorm-step/{type-orm-transactional-step-sets.d.ts → typeorm-transactional-step-sets.d.ts} +0 -0
- /package/src/lib/typeorm-step/{type-orm-transactional-step-sets.ts → typeorm-transactional-step-sets.ts} +0 -0
package/README.md
CHANGED
|
@@ -386,7 +386,7 @@ Autonomous transactions take precedence over the transaction name, meaning that
|
|
|
386
386
|
specified by the transaction name will be ignored. If you need to use the transaction name, you must nest the pipeline steps within
|
|
387
387
|
transactional step sets, and ensure that the datasource name and transaction name remain the same.
|
|
388
388
|
|
|
389
|
-
### By Entity
|
|
389
|
+
### By Entity (Deprecated, not recommended)
|
|
390
390
|
|
|
391
391
|
#### Load Entity by ID
|
|
392
392
|
|
|
@@ -602,18 +602,18 @@ CFG_ENDPOINTS_ORDER_PAYMENT_URL=https://order.com/payment
|
|
|
602
602
|
|
|
603
603
|
#### Constructor Parameters
|
|
604
604
|
|
|
605
|
-
| Name | Type
|
|
606
|
-
|
|
607
|
-
| endpointSystemCode | string
|
|
608
|
-
| endpointName | string
|
|
609
|
-
| urlGenerate | ScriptFuncOrBody\<HttpGenerateUrl>
|
|
610
|
-
| method | string
|
|
611
|
-
| timeout | number
|
|
612
|
-
| headersGenerate | ScriptFuncOrBody\<HttpGenerateHeaders>
|
|
613
|
-
| bodyUsed | boolean
|
|
614
|
-
| bodyGenerate | ScriptFuncOrBody\<HttpGenerateBody>
|
|
615
|
-
| responseGenerate | ScriptFuncOrBody\<HttpGenerateResponse>
|
|
616
|
-
| responseErrorHandles | {[key: HttpErrorCode]: ScriptFuncOrBody\<HttpHandleError>} | | Endpoint response error handlers. |
|
|
605
|
+
| Name | Type | Default Value | Comments |
|
|
606
|
+
|----------------------|--------------------------------------------------------------------------------------------------------|---------------|----------------------------------------------------------------------------------------------------------------------|
|
|
607
|
+
| endpointSystemCode | string | | Endpoint system code. |
|
|
608
|
+
| endpointName | string | | Endpoint name. |
|
|
609
|
+
| urlGenerate | ScriptFuncOrBody\<HttpGenerateUrl> | | Endpoint url generator, `$endpointUrl`. |
|
|
610
|
+
| method | string | | Http method, default `post`. |
|
|
611
|
+
| timeout | number | | Endpoint timeout, in seconds. |
|
|
612
|
+
| headersGenerate | ScriptFuncOrBody\<HttpGenerateHeaders> | | Endpoint request headers generator. |
|
|
613
|
+
| bodyUsed | boolean | | Send request with body or not, or automatically disregards the body when sending a `get` request when not specified. |
|
|
614
|
+
| bodyGenerate | ScriptFuncOrBody\<HttpGenerateBody> | | Endpoint request body generator. |
|
|
615
|
+
| responseGenerate | ScriptFuncOrBody\<HttpGenerateResponse> | | Endpoint response body generator, `$response`. |
|
|
616
|
+
| responseErrorHandles | ScriptFuncOrBody\<HttpHandleError><br>or<br>{[key: HttpErrorCode]: ScriptFuncOrBody\<HttpHandleError>} | | Endpoint response error handlers. |
|
|
617
617
|
|
|
618
618
|
## Installation
|
|
619
619
|
|
package/index.cjs
CHANGED
|
@@ -1297,12 +1297,21 @@ class FetchPipelineStep extends AbstractFragmentaryPipelineStep {
|
|
|
1297
1297
|
throw e;
|
|
1298
1298
|
}
|
|
1299
1299
|
});
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1300
|
+
const defaultHandler = async (options, _$helpers, _$) => {
|
|
1301
|
+
throw new n1.UncatchableError(ERR_FETCH_ERROR, `Error[${options.$errorCode}] caught when fetch data from remote[${options.$url}].`);
|
|
1302
|
+
};
|
|
1303
|
+
const createDefaultHandler = () => defaultHandler;
|
|
1304
|
+
const getVariableNames = () => this.getErrorHandlerVariableName();
|
|
1305
|
+
if (typeof options.responseErrorHandles === 'string' || typeof options.responseErrorHandles === 'function') {
|
|
1306
|
+
this._responseErrorHandleFunc = Utils.createAsyncFunction(options.responseErrorHandles, {
|
|
1307
|
+
createDefault: createDefaultHandler, getVariableNames,
|
|
1308
|
+
error: (e) => {
|
|
1309
|
+
this.getLogger().error(`Failed on create function for response error handler, snippet is [${options.responseErrorHandles}].`);
|
|
1310
|
+
throw e;
|
|
1311
|
+
}
|
|
1312
|
+
});
|
|
1313
|
+
}
|
|
1314
|
+
else if (options.responseErrorHandles != null) {
|
|
1306
1315
|
const handlers = Object.keys(options.responseErrorHandles).reduce((handlers, status) => {
|
|
1307
1316
|
handlers[status] = Utils.createAsyncFunction(options.responseErrorHandles[status], {
|
|
1308
1317
|
createDefault: createDefaultHandler, getVariableNames,
|
|
@@ -1609,99 +1618,6 @@ class AbstractTypeOrmPipelineStep extends AbstractFragmentaryPipelineStep {
|
|
|
1609
1618
|
}
|
|
1610
1619
|
}
|
|
1611
1620
|
}
|
|
1612
|
-
async findMetadata(name, request) {
|
|
1613
|
-
const runner = await this.createRunner(request);
|
|
1614
|
-
const dataSource = runner.connection;
|
|
1615
|
-
const metadata = (dataSource.entityMetadatas || []).find(metadata => metadata.name == name);
|
|
1616
|
-
if (metadata == null) {
|
|
1617
|
-
throw new n1.UncatchableError(ERR_TYPEORM_ENTITY_NOT_FOUND, `Entity[${name}] in data source[${this.getDataSourceName()}] not found.`);
|
|
1618
|
-
}
|
|
1619
|
-
const column = metadata.columns.find(column => column.isPrimary);
|
|
1620
|
-
const repository = runner.manager.getRepository(metadata.target);
|
|
1621
|
-
return [metadata, column, repository, dataSource];
|
|
1622
|
-
}
|
|
1623
|
-
}
|
|
1624
|
-
|
|
1625
|
-
class TypeOrmLoadEntityByIdPipelineStep extends AbstractTypeOrmPipelineStep {
|
|
1626
|
-
_entityName;
|
|
1627
|
-
constructor(options) {
|
|
1628
|
-
super(options);
|
|
1629
|
-
this._entityName = options.entityName;
|
|
1630
|
-
}
|
|
1631
|
-
getEntityName() {
|
|
1632
|
-
return this._entityName;
|
|
1633
|
-
}
|
|
1634
|
-
async doPerform(id, request) {
|
|
1635
|
-
const [, column, repository] = await this.findMetadata(this.getEntityName(), request);
|
|
1636
|
-
const loaded = await repository.findOneBy({ [column.propertyName]: id });
|
|
1637
|
-
if (loaded == null) {
|
|
1638
|
-
return (void 0);
|
|
1639
|
-
}
|
|
1640
|
-
else {
|
|
1641
|
-
return loaded;
|
|
1642
|
-
}
|
|
1643
|
-
}
|
|
1644
|
-
}
|
|
1645
|
-
|
|
1646
|
-
class TypeOrmSaveEntityPipelineStep extends AbstractTypeOrmPipelineStep {
|
|
1647
|
-
_entityName;
|
|
1648
|
-
_fillIdBySnowflake;
|
|
1649
|
-
_snowflakeShardId;
|
|
1650
|
-
_uniquenessCheckSnippet;
|
|
1651
|
-
_uniquenessCheckFunc;
|
|
1652
|
-
constructor(options) {
|
|
1653
|
-
super(options);
|
|
1654
|
-
const config = this.getConfig();
|
|
1655
|
-
this._entityName = options.entityName;
|
|
1656
|
-
this._fillIdBySnowflake = options.fillIdBySnowflake ?? false;
|
|
1657
|
-
this._snowflakeShardId = config.getNumber(`snowflake.shard.id`);
|
|
1658
|
-
this._uniquenessCheckSnippet = options.uniquenessCheckSnippet;
|
|
1659
|
-
this._uniquenessCheckFunc = Utils.createSyncFunction(this.getUniquenessCheckSnippet(), {
|
|
1660
|
-
createDefault: () => (void 0),
|
|
1661
|
-
getVariableNames: () => this.generateUniquenessCheckVariableNames(),
|
|
1662
|
-
error: (e) => {
|
|
1663
|
-
this.getLogger().error(`Failed on create function for uniqueness check, snippet is [${this.getUniquenessCheckSnippet()}].`);
|
|
1664
|
-
throw e;
|
|
1665
|
-
}
|
|
1666
|
-
});
|
|
1667
|
-
}
|
|
1668
|
-
getEntityName() {
|
|
1669
|
-
return this._entityName;
|
|
1670
|
-
}
|
|
1671
|
-
isFillIdBySnowflake() {
|
|
1672
|
-
return this._fillIdBySnowflake;
|
|
1673
|
-
}
|
|
1674
|
-
getUniquenessCheckSnippet() {
|
|
1675
|
-
return this._uniquenessCheckSnippet;
|
|
1676
|
-
}
|
|
1677
|
-
needUniquenessCheck() {
|
|
1678
|
-
return this._uniquenessCheckFunc != null;
|
|
1679
|
-
}
|
|
1680
|
-
generateUniquenessCheckVariableNames() {
|
|
1681
|
-
return ['given', 'existing'];
|
|
1682
|
-
}
|
|
1683
|
-
async doPerform(entity, request) {
|
|
1684
|
-
const [, column, repository] = await this.findMetadata(this.getEntityName(), request);
|
|
1685
|
-
if (this.needUniquenessCheck()) {
|
|
1686
|
-
const id = entity[column.propertyName];
|
|
1687
|
-
if (`${id ?? ''}`.trim().length !== 0) {
|
|
1688
|
-
const existing = await repository.findOneBy({ [column.propertyName]: id });
|
|
1689
|
-
if (existing != null) {
|
|
1690
|
-
const checked = this._uniquenessCheckFunc(entity, existing);
|
|
1691
|
-
if (checked.pass !== true) {
|
|
1692
|
-
throw new n1.CatchableError(checked.code, checked.message);
|
|
1693
|
-
}
|
|
1694
|
-
}
|
|
1695
|
-
}
|
|
1696
|
-
}
|
|
1697
|
-
if (this.isFillIdBySnowflake()) {
|
|
1698
|
-
const id = entity[column.propertyName];
|
|
1699
|
-
if (id == null || `${id ?? ''}`.trim().length === 0) {
|
|
1700
|
-
entity[column.propertyName] = Snowflake.generate({ shardId: this._snowflakeShardId });
|
|
1701
|
-
}
|
|
1702
|
-
}
|
|
1703
|
-
return await repository.save(entity);
|
|
1704
|
-
}
|
|
1705
1621
|
}
|
|
1706
1622
|
|
|
1707
1623
|
class TypeOrmBySnippetPipelineStep extends AbstractTypeOrmPipelineStep {
|
|
@@ -2416,11 +2332,9 @@ exports.TypeOrmBulkSaveBySQLPipelineStep = TypeOrmBulkSaveBySQLPipelineStep;
|
|
|
2416
2332
|
exports.TypeOrmBySnippetPipelineStep = TypeOrmBySnippetPipelineStep;
|
|
2417
2333
|
exports.TypeOrmDataSourceHelper = TypeOrmDataSourceHelper;
|
|
2418
2334
|
exports.TypeOrmDataSourceManager = TypeOrmDataSourceManager;
|
|
2419
|
-
exports.TypeOrmLoadEntityByIdPipelineStep = TypeOrmLoadEntityByIdPipelineStep;
|
|
2420
2335
|
exports.TypeOrmLoadManyBySQLPipelineStep = TypeOrmLoadManyBySQLPipelineStep;
|
|
2421
2336
|
exports.TypeOrmLoadOneBySQLPipelineStep = TypeOrmLoadOneBySQLPipelineStep;
|
|
2422
2337
|
exports.TypeOrmParsedSQLCache = TypeOrmParsedSQLCache;
|
|
2423
2338
|
exports.TypeOrmSaveBySQLPipelineStep = TypeOrmSaveBySQLPipelineStep;
|
|
2424
|
-
exports.TypeOrmSaveEntityPipelineStep = TypeOrmSaveEntityPipelineStep;
|
|
2425
2339
|
exports.TypeOrmTransactionalPipelineStepSets = TypeOrmTransactionalPipelineStepSets;
|
|
2426
2340
|
exports.Utils = Utils;
|
package/index.js
CHANGED
|
@@ -1295,12 +1295,21 @@ class FetchPipelineStep extends AbstractFragmentaryPipelineStep {
|
|
|
1295
1295
|
throw e;
|
|
1296
1296
|
}
|
|
1297
1297
|
});
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1298
|
+
const defaultHandler = async (options, _$helpers, _$) => {
|
|
1299
|
+
throw new UncatchableError(ERR_FETCH_ERROR, `Error[${options.$errorCode}] caught when fetch data from remote[${options.$url}].`);
|
|
1300
|
+
};
|
|
1301
|
+
const createDefaultHandler = () => defaultHandler;
|
|
1302
|
+
const getVariableNames = () => this.getErrorHandlerVariableName();
|
|
1303
|
+
if (typeof options.responseErrorHandles === 'string' || typeof options.responseErrorHandles === 'function') {
|
|
1304
|
+
this._responseErrorHandleFunc = Utils.createAsyncFunction(options.responseErrorHandles, {
|
|
1305
|
+
createDefault: createDefaultHandler, getVariableNames,
|
|
1306
|
+
error: (e) => {
|
|
1307
|
+
this.getLogger().error(`Failed on create function for response error handler, snippet is [${options.responseErrorHandles}].`);
|
|
1308
|
+
throw e;
|
|
1309
|
+
}
|
|
1310
|
+
});
|
|
1311
|
+
}
|
|
1312
|
+
else if (options.responseErrorHandles != null) {
|
|
1304
1313
|
const handlers = Object.keys(options.responseErrorHandles).reduce((handlers, status) => {
|
|
1305
1314
|
handlers[status] = Utils.createAsyncFunction(options.responseErrorHandles[status], {
|
|
1306
1315
|
createDefault: createDefaultHandler, getVariableNames,
|
|
@@ -1607,99 +1616,6 @@ class AbstractTypeOrmPipelineStep extends AbstractFragmentaryPipelineStep {
|
|
|
1607
1616
|
}
|
|
1608
1617
|
}
|
|
1609
1618
|
}
|
|
1610
|
-
async findMetadata(name, request) {
|
|
1611
|
-
const runner = await this.createRunner(request);
|
|
1612
|
-
const dataSource = runner.connection;
|
|
1613
|
-
const metadata = (dataSource.entityMetadatas || []).find(metadata => metadata.name == name);
|
|
1614
|
-
if (metadata == null) {
|
|
1615
|
-
throw new UncatchableError(ERR_TYPEORM_ENTITY_NOT_FOUND, `Entity[${name}] in data source[${this.getDataSourceName()}] not found.`);
|
|
1616
|
-
}
|
|
1617
|
-
const column = metadata.columns.find(column => column.isPrimary);
|
|
1618
|
-
const repository = runner.manager.getRepository(metadata.target);
|
|
1619
|
-
return [metadata, column, repository, dataSource];
|
|
1620
|
-
}
|
|
1621
|
-
}
|
|
1622
|
-
|
|
1623
|
-
class TypeOrmLoadEntityByIdPipelineStep extends AbstractTypeOrmPipelineStep {
|
|
1624
|
-
_entityName;
|
|
1625
|
-
constructor(options) {
|
|
1626
|
-
super(options);
|
|
1627
|
-
this._entityName = options.entityName;
|
|
1628
|
-
}
|
|
1629
|
-
getEntityName() {
|
|
1630
|
-
return this._entityName;
|
|
1631
|
-
}
|
|
1632
|
-
async doPerform(id, request) {
|
|
1633
|
-
const [, column, repository] = await this.findMetadata(this.getEntityName(), request);
|
|
1634
|
-
const loaded = await repository.findOneBy({ [column.propertyName]: id });
|
|
1635
|
-
if (loaded == null) {
|
|
1636
|
-
return (void 0);
|
|
1637
|
-
}
|
|
1638
|
-
else {
|
|
1639
|
-
return loaded;
|
|
1640
|
-
}
|
|
1641
|
-
}
|
|
1642
|
-
}
|
|
1643
|
-
|
|
1644
|
-
class TypeOrmSaveEntityPipelineStep extends AbstractTypeOrmPipelineStep {
|
|
1645
|
-
_entityName;
|
|
1646
|
-
_fillIdBySnowflake;
|
|
1647
|
-
_snowflakeShardId;
|
|
1648
|
-
_uniquenessCheckSnippet;
|
|
1649
|
-
_uniquenessCheckFunc;
|
|
1650
|
-
constructor(options) {
|
|
1651
|
-
super(options);
|
|
1652
|
-
const config = this.getConfig();
|
|
1653
|
-
this._entityName = options.entityName;
|
|
1654
|
-
this._fillIdBySnowflake = options.fillIdBySnowflake ?? false;
|
|
1655
|
-
this._snowflakeShardId = config.getNumber(`snowflake.shard.id`);
|
|
1656
|
-
this._uniquenessCheckSnippet = options.uniquenessCheckSnippet;
|
|
1657
|
-
this._uniquenessCheckFunc = Utils.createSyncFunction(this.getUniquenessCheckSnippet(), {
|
|
1658
|
-
createDefault: () => (void 0),
|
|
1659
|
-
getVariableNames: () => this.generateUniquenessCheckVariableNames(),
|
|
1660
|
-
error: (e) => {
|
|
1661
|
-
this.getLogger().error(`Failed on create function for uniqueness check, snippet is [${this.getUniquenessCheckSnippet()}].`);
|
|
1662
|
-
throw e;
|
|
1663
|
-
}
|
|
1664
|
-
});
|
|
1665
|
-
}
|
|
1666
|
-
getEntityName() {
|
|
1667
|
-
return this._entityName;
|
|
1668
|
-
}
|
|
1669
|
-
isFillIdBySnowflake() {
|
|
1670
|
-
return this._fillIdBySnowflake;
|
|
1671
|
-
}
|
|
1672
|
-
getUniquenessCheckSnippet() {
|
|
1673
|
-
return this._uniquenessCheckSnippet;
|
|
1674
|
-
}
|
|
1675
|
-
needUniquenessCheck() {
|
|
1676
|
-
return this._uniquenessCheckFunc != null;
|
|
1677
|
-
}
|
|
1678
|
-
generateUniquenessCheckVariableNames() {
|
|
1679
|
-
return ['given', 'existing'];
|
|
1680
|
-
}
|
|
1681
|
-
async doPerform(entity, request) {
|
|
1682
|
-
const [, column, repository] = await this.findMetadata(this.getEntityName(), request);
|
|
1683
|
-
if (this.needUniquenessCheck()) {
|
|
1684
|
-
const id = entity[column.propertyName];
|
|
1685
|
-
if (`${id ?? ''}`.trim().length !== 0) {
|
|
1686
|
-
const existing = await repository.findOneBy({ [column.propertyName]: id });
|
|
1687
|
-
if (existing != null) {
|
|
1688
|
-
const checked = this._uniquenessCheckFunc(entity, existing);
|
|
1689
|
-
if (checked.pass !== true) {
|
|
1690
|
-
throw new CatchableError(checked.code, checked.message);
|
|
1691
|
-
}
|
|
1692
|
-
}
|
|
1693
|
-
}
|
|
1694
|
-
}
|
|
1695
|
-
if (this.isFillIdBySnowflake()) {
|
|
1696
|
-
const id = entity[column.propertyName];
|
|
1697
|
-
if (id == null || `${id ?? ''}`.trim().length === 0) {
|
|
1698
|
-
entity[column.propertyName] = Snowflake.generate({ shardId: this._snowflakeShardId });
|
|
1699
|
-
}
|
|
1700
|
-
}
|
|
1701
|
-
return await repository.save(entity);
|
|
1702
|
-
}
|
|
1703
1619
|
}
|
|
1704
1620
|
|
|
1705
1621
|
class TypeOrmBySnippetPipelineStep extends AbstractTypeOrmPipelineStep {
|
|
@@ -2364,4 +2280,4 @@ class TypeOrmTransactionalPipelineStepSets extends PipelineStepSets {
|
|
|
2364
2280
|
}
|
|
2365
2281
|
}
|
|
2366
2282
|
|
|
2367
|
-
export { AbstractFragmentaryPipelineStep, AbstractTypeOrmBySQLPipelineStep, AbstractTypeOrmDataSource, AbstractTypeOrmLoadBySQLPipelineStep, AbstractTypeOrmPipelineStep, AsyncPipelineStepSets, BetterSqlite3TypeOrmDatasource, ConditionalPipelineStepSets, DEFAULT_TRANSACTION_NAME, DeletePropertyPipelineStep, ERR_EACH_FRAGMENT_NOT_ANY_ARRAY, ERR_FETCH_ERROR, ERR_PIPELINE_REF_NOT_EMPTY, ERR_PIPELINE_REF_NOT_FOUND, ERR_PIPELINE_SNIPPET_CANNOT_USE_EVAL, ERR_PIPELINE_SNIPPET_CANNOT_USE_FUNCTION, ERR_PIPELINE_SNIPPET_CANNOT_USE_GLOBAL, ERR_PIPELINE_SNIPPET_CANNOT_USE_PROCESS, ERR_PIPELINE_STEP_CONDITIONAL_SNIPPET_NOT_EMPTY, ERR_PIPELINE_STEP_METHOD_NOT_SUPPORTED, ERR_PIPELINE_STEP_REF_NOT_EMPTY, ERR_PIPELINE_STEP_REF_NOT_FOUND, ERR_PIPELINE_STEP_SNIPPET_NOT_EMPTY, ERR_TYPEORM_DATASOURCE_CREATOR_NOT_FOUND, ERR_TYPEORM_DATASOURCE_NOT_FOUND, ERR_TYPEORM_DATASOURCE_TYPE_NOT_FOUND, ERR_TYPEORM_ENTITY_NOT_FOUND, ERR_TYPEORM_SQL_NOT_EMPTY, ERR_TYPEORM_STEP_SNIPPET_NOT_EMPTY, ERR_TYPEORM_TRANSACTION_NOT_FOUND, EachPipelineStepSets, FetchPipelineStep, GetPropertyPipelineStep, HttpAbortErrorCode, HttpUnknownErrorCode, MssqlTypeOrmDatasource, MysqlTypeOrmDatasource, OracleTypeOrmDatasource, ParallelPipelineStepSets, ParsedSqlSegmentType, PgsqlTypeOrmDatasource, PipelineStepSets, RefPipelinePipelineStep, RefStepPipelineStep, RoutesPipelineStepSets, SnippetPipelineStep, SnowflakePipelineStep, SupportedDataSourceTypes, TypeOrmBulkSaveBySQLPipelineStep, TypeOrmBySnippetPipelineStep, TypeOrmDataSourceHelper, TypeOrmDataSourceManager,
|
|
2283
|
+
export { AbstractFragmentaryPipelineStep, AbstractTypeOrmBySQLPipelineStep, AbstractTypeOrmDataSource, AbstractTypeOrmLoadBySQLPipelineStep, AbstractTypeOrmPipelineStep, AsyncPipelineStepSets, BetterSqlite3TypeOrmDatasource, ConditionalPipelineStepSets, DEFAULT_TRANSACTION_NAME, DeletePropertyPipelineStep, ERR_EACH_FRAGMENT_NOT_ANY_ARRAY, ERR_FETCH_ERROR, ERR_PIPELINE_REF_NOT_EMPTY, ERR_PIPELINE_REF_NOT_FOUND, ERR_PIPELINE_SNIPPET_CANNOT_USE_EVAL, ERR_PIPELINE_SNIPPET_CANNOT_USE_FUNCTION, ERR_PIPELINE_SNIPPET_CANNOT_USE_GLOBAL, ERR_PIPELINE_SNIPPET_CANNOT_USE_PROCESS, ERR_PIPELINE_STEP_CONDITIONAL_SNIPPET_NOT_EMPTY, ERR_PIPELINE_STEP_METHOD_NOT_SUPPORTED, ERR_PIPELINE_STEP_REF_NOT_EMPTY, ERR_PIPELINE_STEP_REF_NOT_FOUND, ERR_PIPELINE_STEP_SNIPPET_NOT_EMPTY, ERR_TYPEORM_DATASOURCE_CREATOR_NOT_FOUND, ERR_TYPEORM_DATASOURCE_NOT_FOUND, ERR_TYPEORM_DATASOURCE_TYPE_NOT_FOUND, ERR_TYPEORM_ENTITY_NOT_FOUND, ERR_TYPEORM_SQL_NOT_EMPTY, ERR_TYPEORM_STEP_SNIPPET_NOT_EMPTY, ERR_TYPEORM_TRANSACTION_NOT_FOUND, EachPipelineStepSets, FetchPipelineStep, GetPropertyPipelineStep, HttpAbortErrorCode, HttpUnknownErrorCode, MssqlTypeOrmDatasource, MysqlTypeOrmDatasource, OracleTypeOrmDatasource, ParallelPipelineStepSets, ParsedSqlSegmentType, PgsqlTypeOrmDatasource, PipelineStepSets, RefPipelinePipelineStep, RefStepPipelineStep, RoutesPipelineStepSets, SnippetPipelineStep, SnowflakePipelineStep, SupportedDataSourceTypes, TypeOrmBulkSaveBySQLPipelineStep, TypeOrmBySnippetPipelineStep, TypeOrmDataSourceHelper, TypeOrmDataSourceManager, TypeOrmLoadManyBySQLPipelineStep, TypeOrmLoadOneBySQLPipelineStep, TypeOrmParsedSQLCache, TypeOrmSaveBySQLPipelineStep, TypeOrmTransactionalPipelineStepSets, Utils };
|
package/lib/http/fetch-step.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export interface FetchPipelineStepOptions<In = PipelineStepPayload, Out = Pipeli
|
|
|
11
11
|
bodyUsed?: boolean;
|
|
12
12
|
bodyGenerate?: ScriptFuncOrBody<HttpGenerateBody<In, InFragment>>;
|
|
13
13
|
responseGenerate?: ScriptFuncOrBody<HttpGenerateResponse<In, InFragment>>;
|
|
14
|
-
responseErrorHandles?: {
|
|
14
|
+
responseErrorHandles?: ScriptFuncOrBody<HttpHandleError<In, InFragment, OutFragment>> | {
|
|
15
15
|
[key: HttpErrorCode]: ScriptFuncOrBody<HttpHandleError<In, InFragment, OutFragment>>;
|
|
16
16
|
};
|
|
17
17
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { PipelineStepData, PipelineStepPayload, Undefinable } from '@rainbow-o23/n1';
|
|
2
|
-
import {
|
|
3
|
-
import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata.js';
|
|
2
|
+
import { QueryRunner } from 'typeorm';
|
|
4
3
|
import { AbstractFragmentaryPipelineStep, FragmentaryPipelineStepOptions } from '../step';
|
|
5
4
|
import { DataSourceType, TypeOrmDataSource } from '../typeorm';
|
|
6
|
-
import { TypeOrmDataSourceName,
|
|
5
|
+
import { TypeOrmDataSourceName, TypeOrmTransactionKey, TypeOrmTransactionName } from './types';
|
|
7
6
|
export interface TypeOrmPipelineStepOptions<In = PipelineStepPayload, Out = PipelineStepPayload, InFragment = In, OutFragment = Out> extends FragmentaryPipelineStepOptions<In, Out, InFragment, OutFragment> {
|
|
8
7
|
dataSourceName: TypeOrmDataSourceName;
|
|
9
8
|
transactionName?: TypeOrmTransactionName;
|
|
@@ -26,5 +25,4 @@ export declare abstract class AbstractTypeOrmPipelineStep<In = PipelineStepPaylo
|
|
|
26
25
|
protected createRunner(request: PipelineStepData<In>): Promise<QueryRunner>;
|
|
27
26
|
protected trans<R>(run: (runner: QueryRunner) => Promise<R>, handleRollbackError: (err: Error) => Undefinable<Error>, request: PipelineStepData<In>): Promise<R>;
|
|
28
27
|
protected autoTrans<R>(run: (runner: QueryRunner) => Promise<R>, request: PipelineStepData<In>): Promise<R>;
|
|
29
|
-
protected findMetadata<E extends ObjectLiteral>(name: TypeOrmEntityName, request: PipelineStepData<In>): Promise<[EntityMetadata, ColumnMetadata, Repository<E>, DataSource]>;
|
|
30
28
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
export * from './types';
|
|
2
2
|
export * from './abstract-typeorm-step';
|
|
3
|
-
export * from './typeorm-load-entity-by-id-step';
|
|
4
|
-
export * from './typeorm-save-entity-step';
|
|
5
3
|
export * from './typeorm-by-snippet-step';
|
|
6
4
|
export * from './abstract-typeorm-by-sql-step';
|
|
7
5
|
export * from './abstract-typeorm-load-by-sql-step';
|
|
@@ -9,4 +7,4 @@ export * from './typeorm-load-one-by-sql-step';
|
|
|
9
7
|
export * from './typeorm-load-many-by-sql-step';
|
|
10
8
|
export * from './typeorm-save-by-sql-step';
|
|
11
9
|
export * from './typeorm-bulk-save-by-sql-step';
|
|
12
|
-
export * from './
|
|
10
|
+
export * from './typeorm-transactional-step-sets';
|
|
@@ -5,7 +5,6 @@ export type TypeOrmIdType = string | number | bigint;
|
|
|
5
5
|
export type TypeOrmDataSourceName = string;
|
|
6
6
|
export type TypeOrmTransactionName = string;
|
|
7
7
|
export type TypeOrmTransactionKey = `${TypeOrmDataSourceName}.${TypeOrmTransactionName}`;
|
|
8
|
-
export type TypeOrmEntityName = string;
|
|
9
8
|
export type TypeOrmEntityValue = string | number | bigint | boolean | Date | null | undefined;
|
|
10
9
|
export type TypeOrmEntityToLoad = DeepPartial<ObjectLiteral>;
|
|
11
10
|
export type TypeOrmEntityToSave = DeepPartial<ObjectLiteral>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rainbow-o23/n3",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.42",
|
|
4
4
|
"description": "o23 pipelines",
|
|
5
5
|
"main": "index.cjs",
|
|
6
6
|
"module": "index.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"url": "https://github.com/InsureMO/rainbow-o23/issues"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@rainbow-o23/n1": "1.0.
|
|
24
|
+
"@rainbow-o23/n1": "1.0.42",
|
|
25
25
|
"node-fetch": "2.6.7",
|
|
26
26
|
"typeorm": "^0.3.17"
|
|
27
27
|
},
|
|
@@ -26,9 +26,8 @@ export interface FetchPipelineStepOptions<In = PipelineStepPayload, Out = Pipeli
|
|
|
26
26
|
bodyUsed?: boolean;
|
|
27
27
|
bodyGenerate?: ScriptFuncOrBody<HttpGenerateBody<In, InFragment>>;
|
|
28
28
|
responseGenerate?: ScriptFuncOrBody<HttpGenerateResponse<In, InFragment>>;
|
|
29
|
-
responseErrorHandles?:
|
|
30
|
-
[key: HttpErrorCode]: ScriptFuncOrBody<HttpHandleError<In, InFragment, OutFragment>>;
|
|
31
|
-
};
|
|
29
|
+
responseErrorHandles?: ScriptFuncOrBody<HttpHandleError<In, InFragment, OutFragment>>
|
|
30
|
+
| { [key: HttpErrorCode]: ScriptFuncOrBody<HttpHandleError<In, InFragment, OutFragment>>; };
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
export class FetchPipelineStep<In = PipelineStepPayload, Out = PipelineStepPayload, InFragment = In, OutFragment = Out>
|
|
@@ -112,13 +111,21 @@ export class FetchPipelineStep<In = PipelineStepPayload, Out = PipelineStepPaylo
|
|
|
112
111
|
throw e;
|
|
113
112
|
}
|
|
114
113
|
});
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
114
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
115
|
+
const defaultHandler = async (options: HttpErrorHandleOptions<In, InFragment>, _$helpers: PipelineStepHelpers, _$: PipelineStepHelpers): Promise<OutFragment> | never => {
|
|
116
|
+
throw new UncatchableError(ERR_FETCH_ERROR, `Error[${options.$errorCode}] caught when fetch data from remote[${options.$url}].`);
|
|
117
|
+
};
|
|
118
|
+
const createDefaultHandler = () => defaultHandler;
|
|
119
|
+
const getVariableNames = () => this.getErrorHandlerVariableName();
|
|
120
|
+
if (typeof options.responseErrorHandles === 'string' || typeof options.responseErrorHandles === 'function') {
|
|
121
|
+
this._responseErrorHandleFunc = Utils.createAsyncFunction(options.responseErrorHandles, {
|
|
122
|
+
createDefault: createDefaultHandler, getVariableNames,
|
|
123
|
+
error: (e: Error) => {
|
|
124
|
+
this.getLogger().error(`Failed on create function for response error handler, snippet is [${options.responseErrorHandles}].`);
|
|
125
|
+
throw e;
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
} else if (options.responseErrorHandles != null) {
|
|
122
129
|
const handlers: Record<HttpErrorCode, HttpHandleError<In, InFragment, OutFragment>> = Object.keys(options.responseErrorHandles).reduce((handlers, status) => {
|
|
123
130
|
handlers[status] = Utils.createAsyncFunction(options.responseErrorHandles[status], {
|
|
124
131
|
createDefault: createDefaultHandler, getVariableNames,
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import {PipelineStepData, PipelineStepPayload, UncatchableError, Undefinable} from '@rainbow-o23/n1';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
ERR_TYPEORM_DATASOURCE_NOT_FOUND,
|
|
6
|
-
ERR_TYPEORM_ENTITY_NOT_FOUND,
|
|
7
|
-
ERR_TYPEORM_TRANSACTION_NOT_FOUND
|
|
8
|
-
} from '../error-codes';
|
|
2
|
+
import {QueryRunner} from 'typeorm';
|
|
3
|
+
import {ERR_TYPEORM_DATASOURCE_NOT_FOUND, ERR_TYPEORM_TRANSACTION_NOT_FOUND} from '../error-codes';
|
|
9
4
|
import {AbstractFragmentaryPipelineStep, FragmentaryPipelineStepOptions} from '../step';
|
|
10
5
|
import {DataSourceType, TypeOrmDataSource, TypeOrmDataSourceManager} from '../typeorm';
|
|
11
6
|
import {
|
|
12
7
|
DEFAULT_TRANSACTION_NAME,
|
|
13
8
|
TypeOrmDataSourceName,
|
|
14
|
-
TypeOrmEntityName,
|
|
15
9
|
TypeOrmTransactionalContext,
|
|
16
10
|
TypeOrmTransactionKey,
|
|
17
11
|
TypeOrmTransactionName
|
|
@@ -222,20 +216,4 @@ export abstract class AbstractTypeOrmPipelineStep<In = PipelineStepPayload, Out
|
|
|
222
216
|
}
|
|
223
217
|
}
|
|
224
218
|
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* find metadata by given name. throw error when data source or metadata not found.
|
|
228
|
-
*/
|
|
229
|
-
protected async findMetadata<E extends ObjectLiteral>(name: TypeOrmEntityName, request: PipelineStepData<In>): Promise<[EntityMetadata, ColumnMetadata, Repository<E>, DataSource]> {
|
|
230
|
-
const runner = await this.createRunner(request);
|
|
231
|
-
const dataSource = runner.connection;
|
|
232
|
-
const metadata = (dataSource.entityMetadatas || []).find(metadata => metadata.name == name);
|
|
233
|
-
if (metadata == null) {
|
|
234
|
-
throw new UncatchableError(ERR_TYPEORM_ENTITY_NOT_FOUND,
|
|
235
|
-
`Entity[${name}] in data source[${this.getDataSourceName()}] not found.`);
|
|
236
|
-
}
|
|
237
|
-
const column = metadata.columns.find(column => column.isPrimary);
|
|
238
|
-
const repository = runner.manager.getRepository(metadata.target);
|
|
239
|
-
return [metadata, column, repository as Repository<E>, dataSource];
|
|
240
|
-
}
|
|
241
219
|
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
export * from './types';
|
|
2
2
|
|
|
3
3
|
export * from './abstract-typeorm-step';
|
|
4
|
-
export * from './typeorm-load-entity-by-id-step';
|
|
5
|
-
export * from './typeorm-save-entity-step';
|
|
6
4
|
|
|
7
5
|
export * from './typeorm-by-snippet-step';
|
|
8
6
|
export * from './abstract-typeorm-by-sql-step';
|
|
@@ -14,4 +12,4 @@ export * from './typeorm-load-many-by-sql-step';
|
|
|
14
12
|
export * from './typeorm-save-by-sql-step';
|
|
15
13
|
export * from './typeorm-bulk-save-by-sql-step';
|
|
16
14
|
|
|
17
|
-
export * from './
|
|
15
|
+
export * from './typeorm-transactional-step-sets';
|
|
@@ -6,7 +6,6 @@ export type TypeOrmIdType = string | number | bigint;
|
|
|
6
6
|
export type TypeOrmDataSourceName = string;
|
|
7
7
|
export type TypeOrmTransactionName = string;
|
|
8
8
|
export type TypeOrmTransactionKey = `${TypeOrmDataSourceName}.${TypeOrmTransactionName}`;
|
|
9
|
-
export type TypeOrmEntityName = string;
|
|
10
9
|
export type TypeOrmEntityValue = string | number | bigint | boolean | Date | null | undefined;
|
|
11
10
|
export type TypeOrmEntityToLoad = DeepPartial<ObjectLiteral>;
|
|
12
11
|
export type TypeOrmEntityToSave = DeepPartial<ObjectLiteral>;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { PipelineStepData, PipelineStepPayload, Undefinable } from '@rainbow-o23/n1';
|
|
2
|
-
import { AbstractTypeOrmPipelineStep, TypeOrmPipelineStepOptions } from './abstract-typeorm-step';
|
|
3
|
-
import { TypeOrmEntityName, TypeOrmEntityToLoad, TypeOrmIdType } from './types';
|
|
4
|
-
export interface TypeOrmLoadEntityByIdPipelineStepOptions<In = PipelineStepPayload, Out = PipelineStepPayload, InFragment = TypeOrmIdType, OutFragment = Out> extends TypeOrmPipelineStepOptions<In, Out, InFragment, OutFragment> {
|
|
5
|
-
entityName: TypeOrmEntityName;
|
|
6
|
-
}
|
|
7
|
-
export declare class TypeOrmLoadEntityByIdPipelineStep<In = PipelineStepPayload, Out = PipelineStepPayload, OutFragment = TypeOrmEntityToLoad> extends AbstractTypeOrmPipelineStep<In, Out, TypeOrmIdType, OutFragment> {
|
|
8
|
-
private readonly _entityName;
|
|
9
|
-
constructor(options: TypeOrmLoadEntityByIdPipelineStepOptions<In, Out, TypeOrmIdType, OutFragment>);
|
|
10
|
-
getEntityName(): TypeOrmEntityName;
|
|
11
|
-
protected doPerform(id: TypeOrmIdType, request: PipelineStepData<In>): Promise<Undefinable<OutFragment>>;
|
|
12
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { O23ExternalErrorCode, PipelineStepData, PipelineStepPayload, Undefinable } from '@rainbow-o23/n1';
|
|
2
|
-
import { DeepPartial, ObjectLiteral } from 'typeorm';
|
|
3
|
-
import { ScriptFuncOrBody } from '../step';
|
|
4
|
-
import { AbstractTypeOrmPipelineStep, TypeOrmPipelineStepOptions } from './abstract-typeorm-step';
|
|
5
|
-
import { TypeOrmEntityName } from './types';
|
|
6
|
-
export type EntityToSave = DeepPartial<ObjectLiteral>;
|
|
7
|
-
export type UniquenessCheckResult = {
|
|
8
|
-
pass: true;
|
|
9
|
-
} | {
|
|
10
|
-
pass: false;
|
|
11
|
-
code: O23ExternalErrorCode;
|
|
12
|
-
message: string;
|
|
13
|
-
};
|
|
14
|
-
export type UniquenessCheckFunc<EntityToSave> = (given: EntityToSave, existing: EntityToSave) => UniquenessCheckResult;
|
|
15
|
-
export interface TypeOrmSaveEntityPipelineStepOptions<In = PipelineStepPayload, Out = PipelineStepPayload, InFragment = EntityToSave, OutFragment = EntityToSave> extends TypeOrmPipelineStepOptions<In, Out, InFragment, OutFragment> {
|
|
16
|
-
entityName: TypeOrmEntityName;
|
|
17
|
-
fillIdBySnowflake?: boolean;
|
|
18
|
-
uniquenessCheckSnippet?: ScriptFuncOrBody<UniquenessCheckFunc<InFragment>>;
|
|
19
|
-
}
|
|
20
|
-
export declare class TypeOrmSaveEntityPipelineStep<In = PipelineStepPayload, Out = PipelineStepPayload, InFragment = EntityToSave, OutFragment = EntityToSave> extends AbstractTypeOrmPipelineStep<In, Out, InFragment, OutFragment> {
|
|
21
|
-
private readonly _entityName;
|
|
22
|
-
private readonly _fillIdBySnowflake;
|
|
23
|
-
private readonly _snowflakeShardId;
|
|
24
|
-
private readonly _uniquenessCheckSnippet?;
|
|
25
|
-
private readonly _uniquenessCheckFunc?;
|
|
26
|
-
constructor(options: TypeOrmSaveEntityPipelineStepOptions<In, Out, InFragment, OutFragment>);
|
|
27
|
-
getEntityName(): TypeOrmEntityName;
|
|
28
|
-
isFillIdBySnowflake(): boolean;
|
|
29
|
-
getUniquenessCheckSnippet(): Undefinable<ScriptFuncOrBody<UniquenessCheckFunc<InFragment>>>;
|
|
30
|
-
needUniquenessCheck(): boolean;
|
|
31
|
-
protected generateUniquenessCheckVariableNames(): Array<string>;
|
|
32
|
-
protected doPerform(entity: InFragment, request: PipelineStepData<In>): Promise<OutFragment>;
|
|
33
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import {PipelineStepData, PipelineStepPayload, Undefinable} from '@rainbow-o23/n1';
|
|
2
|
-
import {AbstractTypeOrmPipelineStep, TypeOrmPipelineStepOptions} from './abstract-typeorm-step';
|
|
3
|
-
import {TypeOrmEntityName, TypeOrmEntityToLoad, TypeOrmIdType} from './types';
|
|
4
|
-
|
|
5
|
-
export interface TypeOrmLoadEntityByIdPipelineStepOptions<In = PipelineStepPayload, Out = PipelineStepPayload, InFragment = TypeOrmIdType, OutFragment = Out>
|
|
6
|
-
extends TypeOrmPipelineStepOptions<In, Out, InFragment, OutFragment> {
|
|
7
|
-
entityName: TypeOrmEntityName;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* no transaction here
|
|
12
|
-
*/
|
|
13
|
-
export class TypeOrmLoadEntityByIdPipelineStep<In = PipelineStepPayload, Out = PipelineStepPayload, OutFragment = TypeOrmEntityToLoad>
|
|
14
|
-
extends AbstractTypeOrmPipelineStep<In, Out, TypeOrmIdType, OutFragment> {
|
|
15
|
-
private readonly _entityName: TypeOrmEntityName;
|
|
16
|
-
|
|
17
|
-
public constructor(options: TypeOrmLoadEntityByIdPipelineStepOptions<In, Out, TypeOrmIdType, OutFragment>) {
|
|
18
|
-
super(options);
|
|
19
|
-
this._entityName = options.entityName;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
public getEntityName(): TypeOrmEntityName {
|
|
23
|
-
return this._entityName;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
protected async doPerform(id: TypeOrmIdType, request: PipelineStepData<In>): Promise<Undefinable<OutFragment>> {
|
|
27
|
-
const [, column, repository] = await this.findMetadata(this.getEntityName(), request);
|
|
28
|
-
const loaded = await repository.findOneBy({[column.propertyName]: id}) as OutFragment;
|
|
29
|
-
if (loaded == null) {
|
|
30
|
-
return (void 0);
|
|
31
|
-
} else {
|
|
32
|
-
return loaded;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CatchableError,
|
|
3
|
-
O23ExternalErrorCode,
|
|
4
|
-
PipelineStepData,
|
|
5
|
-
PipelineStepPayload,
|
|
6
|
-
Undefinable
|
|
7
|
-
} from '@rainbow-o23/n1';
|
|
8
|
-
import {DeepPartial, ObjectLiteral} from 'typeorm';
|
|
9
|
-
import {ScriptFuncOrBody, Utils} from '../step';
|
|
10
|
-
import {Snowflake} from '../utils';
|
|
11
|
-
import {AbstractTypeOrmPipelineStep, TypeOrmPipelineStepOptions} from './abstract-typeorm-step';
|
|
12
|
-
import {TypeOrmEntityName} from './types';
|
|
13
|
-
|
|
14
|
-
export type EntityToSave = DeepPartial<ObjectLiteral>;
|
|
15
|
-
|
|
16
|
-
export type UniquenessCheckResult = { pass: true } | { pass: false, code: O23ExternalErrorCode, message: string };
|
|
17
|
-
/**
|
|
18
|
-
* parameter names could be change {@link TypeOrmSaveEntityPipelineStep#generateUniquenessCheckVariableNames}
|
|
19
|
-
*/
|
|
20
|
-
export type UniquenessCheckFunc<EntityToSave> = (given: EntityToSave, existing: EntityToSave) => UniquenessCheckResult;
|
|
21
|
-
|
|
22
|
-
export interface TypeOrmSaveEntityPipelineStepOptions<In = PipelineStepPayload, Out = PipelineStepPayload, InFragment = EntityToSave, OutFragment = EntityToSave>
|
|
23
|
-
extends TypeOrmPipelineStepOptions<In, Out, InFragment, OutFragment> {
|
|
24
|
-
entityName: TypeOrmEntityName;
|
|
25
|
-
fillIdBySnowflake?: boolean;
|
|
26
|
-
uniquenessCheckSnippet?: ScriptFuncOrBody<UniquenessCheckFunc<InFragment>>;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* no transaction here
|
|
31
|
-
*/
|
|
32
|
-
export class TypeOrmSaveEntityPipelineStep<In = PipelineStepPayload, Out = PipelineStepPayload, InFragment = EntityToSave, OutFragment = EntityToSave>
|
|
33
|
-
extends AbstractTypeOrmPipelineStep<In, Out, InFragment, OutFragment> {
|
|
34
|
-
private readonly _entityName: TypeOrmEntityName;
|
|
35
|
-
private readonly _fillIdBySnowflake: boolean;
|
|
36
|
-
private readonly _snowflakeShardId: number;
|
|
37
|
-
private readonly _uniquenessCheckSnippet?: ScriptFuncOrBody<UniquenessCheckFunc<InFragment>>;
|
|
38
|
-
private readonly _uniquenessCheckFunc?: UniquenessCheckFunc<InFragment>;
|
|
39
|
-
|
|
40
|
-
public constructor(options: TypeOrmSaveEntityPipelineStepOptions<In, Out, InFragment, OutFragment>) {
|
|
41
|
-
super(options);
|
|
42
|
-
const config = this.getConfig();
|
|
43
|
-
this._entityName = options.entityName;
|
|
44
|
-
this._fillIdBySnowflake = options.fillIdBySnowflake ?? false;
|
|
45
|
-
this._snowflakeShardId = config.getNumber(`snowflake.shard.id`);
|
|
46
|
-
this._uniquenessCheckSnippet = options.uniquenessCheckSnippet;
|
|
47
|
-
this._uniquenessCheckFunc = Utils.createSyncFunction(this.getUniquenessCheckSnippet(), {
|
|
48
|
-
createDefault: () => (void 0),
|
|
49
|
-
getVariableNames: () => this.generateUniquenessCheckVariableNames(),
|
|
50
|
-
error: (e: Error) => {
|
|
51
|
-
this.getLogger().error(`Failed on create function for uniqueness check, snippet is [${this.getUniquenessCheckSnippet()}].`);
|
|
52
|
-
throw e;
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
public getEntityName(): TypeOrmEntityName {
|
|
58
|
-
return this._entityName;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
public isFillIdBySnowflake(): boolean {
|
|
62
|
-
return this._fillIdBySnowflake;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
public getUniquenessCheckSnippet(): Undefinable<ScriptFuncOrBody<UniquenessCheckFunc<InFragment>>> {
|
|
66
|
-
return this._uniquenessCheckSnippet;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
public needUniquenessCheck(): boolean {
|
|
70
|
-
return this._uniquenessCheckFunc != null;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
protected generateUniquenessCheckVariableNames(): Array<string> {
|
|
74
|
-
return ['given', 'existing'];
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* 1. check uniqueness of given entity,
|
|
79
|
-
* - only when need it, see {@link needUniquenessCheck}
|
|
80
|
-
* - load entity by id, which get from given entity,
|
|
81
|
-
* - compare given and existing by uniqueness check snippet (see {@link _uniquenessCheckFunc}), only when existing loaded from database,
|
|
82
|
-
* - throw catchable error if failed on uniqueness check,
|
|
83
|
-
* 2. generate snowflake id and set into given entity,
|
|
84
|
-
* - only when need it, see {@link isFillIdBySnowflake}
|
|
85
|
-
* 3. save it.
|
|
86
|
-
*/
|
|
87
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
88
|
-
protected async doPerform(entity: InFragment, request: PipelineStepData<In>): Promise<OutFragment> {
|
|
89
|
-
const [, column, repository] = await this.findMetadata(this.getEntityName(), request);
|
|
90
|
-
if (this.needUniquenessCheck()) {
|
|
91
|
-
const id = entity[column.propertyName];
|
|
92
|
-
if (`${id ?? ''}`.trim().length !== 0) {
|
|
93
|
-
const existing = await repository.findOneBy({[column.propertyName]: id}) as InFragment;
|
|
94
|
-
if (existing != null) {
|
|
95
|
-
const checked = this._uniquenessCheckFunc(entity, existing);
|
|
96
|
-
if (checked.pass !== true) {
|
|
97
|
-
throw new CatchableError(checked.code, checked.message);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
if (this.isFillIdBySnowflake()) {
|
|
103
|
-
// fill id if not exists
|
|
104
|
-
const id = entity[column.propertyName];
|
|
105
|
-
if (id == null || `${id ?? ''}`.trim().length === 0) {
|
|
106
|
-
entity[column.propertyName] = Snowflake.generate({shardId: this._snowflakeShardId}) as unknown as number;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return await repository.save(entity) as OutFragment;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
File without changes
|
|
File without changes
|