@things-factory/integration-base 8.0.0-alpha.8 → 8.0.0-beta.1
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-server/controllers/scenario-controller.d.ts +2 -0
- package/dist-server/controllers/scenario-controller.js +16 -19
- package/dist-server/controllers/scenario-controller.js.map +1 -1
- package/dist-server/engine/connection-manager.js.map +1 -1
- package/dist-server/engine/connector/headless-connector.d.ts +23 -0
- package/dist-server/engine/connector/headless-connector.js +283 -0
- package/dist-server/engine/connector/headless-connector.js.map +1 -0
- package/dist-server/engine/connector/http-connector.js +1 -1
- package/dist-server/engine/connector/http-connector.js.map +1 -1
- package/dist-server/engine/connector/index.d.ts +1 -0
- package/dist-server/engine/connector/index.js +1 -0
- package/dist-server/engine/connector/index.js.map +1 -1
- package/dist-server/engine/connector/operato-connector.js +3 -4
- package/dist-server/engine/connector/operato-connector.js.map +1 -1
- package/dist-server/engine/index.d.ts +1 -0
- package/dist-server/engine/index.js +1 -0
- package/dist-server/engine/index.js.map +1 -1
- package/dist-server/engine/resource-pool/headless-pool.d.ts +1 -0
- package/dist-server/engine/resource-pool/headless-pool.js +121 -0
- package/dist-server/engine/resource-pool/headless-pool.js.map +1 -0
- package/dist-server/engine/resource-pool/index.d.ts +1 -0
- package/dist-server/engine/resource-pool/index.js +5 -0
- package/dist-server/engine/resource-pool/index.js.map +1 -0
- package/dist-server/engine/task/headless-post.js +19 -33
- package/dist-server/engine/task/headless-post.js.map +1 -1
- package/dist-server/engine/task/headless-scrap.js +20 -13
- package/dist-server/engine/task/headless-scrap.js.map +1 -1
- package/dist-server/engine/task/utils/headless-pool-for-scenario.js +1 -1
- package/dist-server/engine/task/utils/headless-pool-for-scenario.js.map +1 -1
- package/dist-server/service/payload-log/payload-log.js +7 -4
- package/dist-server/service/payload-log/payload-log.js.map +1 -1
- package/dist-server/service/scenario/scenario-query.d.ts +2 -1
- package/dist-server/service/scenario/scenario-query.js +10 -0
- package/dist-server/service/scenario/scenario-query.js.map +1 -1
- package/dist-server/service/scenario/scenario-type.d.ts +3 -3
- package/dist-server/service/scenario/scenario-type.js +7 -7
- package/dist-server/service/scenario/scenario-type.js.map +1 -1
- package/dist-server/service/scenario/scenario.d.ts +3 -1
- package/dist-server/service/scenario/scenario.js +9 -0
- package/dist-server/service/scenario/scenario.js.map +1 -1
- package/dist-server/service/scenario-instance/scenario-instance-type.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +12 -11
- package/server/controllers/scenario-controller.ts +27 -36
- package/server/engine/connection-manager.ts +1 -1
- package/server/engine/connector/headless-connector.ts +341 -0
- package/server/engine/connector/http-connector.ts +1 -1
- package/server/engine/connector/index.ts +1 -0
- package/server/engine/connector/operato-connector.ts +4 -7
- package/server/engine/index.ts +1 -0
- package/server/engine/resource-pool/headless-pool.ts +136 -0
- package/server/engine/resource-pool/index.ts +1 -0
- package/server/engine/task/headless-post.ts +21 -40
- package/server/engine/task/headless-scrap.ts +21 -18
- package/server/engine/task/utils/headless-pool-for-scenario.ts +1 -1
- package/server/service/payload-log/payload-log.ts +8 -4
- package/server/service/scenario/scenario-query.ts +6 -1
- package/server/service/scenario/scenario-type.ts +5 -5
- package/server/service/scenario/scenario.ts +15 -19
- package/server/service/scenario-instance/scenario-instance-type.ts +1 -1
- package/translations/en.json +12 -5
- package/translations/ja.json +12 -5
- package/translations/ko.json +12 -5
- package/translations/ms.json +12 -5
- package/translations/zh.json +12 -5
@@ -147,7 +147,7 @@ class OperatoConnector {
|
|
147
147
|
}
|
148
148
|
async runScenario(subscriptions, variables) {
|
149
149
|
var _a;
|
150
|
-
const { domain, user
|
150
|
+
const { domain, user } = this.context;
|
151
151
|
const { tag } = variables;
|
152
152
|
if (!tag) {
|
153
153
|
throw new Error(`tag is invalid - ${tag}`);
|
@@ -156,9 +156,8 @@ class OperatoConnector {
|
|
156
156
|
if (!scenario) {
|
157
157
|
throw new Error(`scenario is not found - ${tag}`);
|
158
158
|
}
|
159
|
-
if (!(await (0, auth_base_1.
|
160
|
-
|
161
|
-
throw new Error(`Unauthorized! ${category && privilege ? category + ':' + privilege + ' privilege' : 'ownership granted'} required`);
|
159
|
+
if (!(await (0, auth_base_1.checkUserHasRole)(scenario.roleId, domain, user))) {
|
160
|
+
throw new Error(`Unauthorized! ${scenario.name} doesn't have required role.`);
|
162
161
|
}
|
163
162
|
/* create a scenario instance */
|
164
163
|
const instanceName = scenario.name + '-' + String(Date.now());
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"operato-connector.js","sourceRoot":"","sources":["../../../server/engine/connector/operato-connector.ts"],"names":[],"mappings":";;;;AAAA,gCAA6B;AAE7B,8CAAwF;AACxF,yDAAwD;AAExD,oDAA0B;AAC1B,2CAAyC;AACzC,qEAAiE;AACjE,wDAA4D;AAC5D,sEAA6B;AAE7B,8DAAyD;AAIzD,8DAA0D;AAC1D,mGAAyF;AAEzF,iDAAiF;AACjF,yDAAiE;AAEjE,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,mDAAmD,CAAC,CAAA;AAEnF,MAAM,cAAc,GAAQ;IAC1B,UAAU,EAAE;QACV,WAAW,EAAE,UAAU;QACvB,WAAW,EAAE,QAAQ;KACtB;IACD,KAAK,EAAE;QACL,WAAW,EAAE,UAAU,EAAE,gBAAgB;QACzC,WAAW,EAAE,KAAK;KACnB;IACD,MAAM,EAAE;QACN,WAAW,EAAE,KAAK;KACnB;CACF,CAAA;AAEY,QAAA,WAAW,GAAG,UAAU,CAAA;AACxB,QAAA,gBAAgB,GAAG,mBAAW,CAAA;AAQ3C,MAAa,gBAAgB;IAG3B,KAAK,CAAC,KAAK,CAAC,iBAAoC;QAC9C,MAAM,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAEjE,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAA;IAC1E,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,UAA2B;QACvC,MAAM,EACJ,QAAQ,EAAE,GAAG,EACb,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,oBAAoB,GAAG,EAAE,EAAE,EACvD,GAAG,UAAU,CAAA;QAEd,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAA;QACtD,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,IAAA,qBAAa,EAAC,gBAAI,CAAC,CAAC,OAAO,CAAC;YACpD,KAAK,EAAE;gBACL,EAAE,EAAE,UAAU,CAAC,MAAM,CAAC,KAAK;aAC5B;SACF,CAAC,CAAA;QAEF,IAAI,CAAC,OAAO,GAAG;YACb,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,IAAI,EAAE,WAAW;YACjB,4FAA4F;SAC7F,CAAA;QAED,MAAM,QAAQ,GAAG,IAAA,qBAAc,EAAC;YAC9B,GAAG,EAAE,GAAG;SACT,CAAC,CAAA;QAEF;;;;;;UAME;QACF,MAAM,MAAM,GAAG,IAAI,6BAAa,CAC9B,IAAA,yBAAY,EAAC;YACX,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC;YAC/B,SAAS,EAAE,KAAM;YACjB,aAAa,EAAE,OAAS;YACxB,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI;YACtB,aAAa,EAAE,YAAS;YACxB,gBAAgB,EAAE;gBAChB,OAAO,EAAE;oBACP,yBAAyB,EAAE,MAAM;oBACjC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE;iBAClD;aACF;SACF,CAAC,CACH,CAAA;QAED,MAAM,SAAS,GAAG,IAAA,YAAK,EACrB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;YACZ,MAAM,GAAG,GAAG,IAAA,6BAAiB,EAAC,KAAK,CAAC,CAAA;YACpC,OAAO,GAAG,CAAC,IAAI,KAAK,qBAAqB,IAAI,GAAG,CAAC,SAAS,KAAK,cAAc,CAAA;QAC/E,CAAC,EACD,MAAM,EACN,IAAA,oBAAU,EAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;YAC5B,OAAO;gBACL,OAAO,kCACF,OAAO,KACV,yBAAyB,EAAE,MAAM,EACjC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,GAClD;aACF,CAAA;QACH,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CACpB,CAAA;QAED,MAAM,KAAK,GAAG,IAAI,oBAAa,CAAC;YAC9B,WAAW,EAAE,KAAK;SACnB,CAAC,CAAA;QAEF,MAAM,MAAM,GAAG,IAAI,mBAAY,CAAC;YAC9B,cAAc;YACd,KAAK;YACL,IAAI,EAAE,SAAS;SAChB,CAAC,CAAA;QAEF,MAAM,aAAa,GAAqB,EAAE,CAAA;QAC1C,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAC,GAAG,EAAC,EAAE;YACpD,IAAI,CAAC,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC;gBAAE,OAAM;YAE9C,MAAM,YAAY,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAA;YAE9C,mBAAmB;YACnB,MAAM,gBAAgB,GAAG,MAAM,IAAA,qBAAa,EAAC,mBAAQ,CAAC,CAAC,OAAO,CAAC;gBAC7D,KAAK,EAAE;oBACL,IAAI,EAAE,YAAY;iBACnB;gBACD,SAAS,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;aAC/B,CAAC,CAAA;YAEF,MAAM,YAAY,GAAG,MAAM,CAAC,SAAS,CAAC;gBACpC,KAAK,EAAE,IAAA,qBAAG,EAAA;;yBAEO,GAAG;;;;;SAKnB;aACF,CAAC,CAAA;YAEF,MAAM,oBAAoB,GAAG,YAAY,CAAC,SAAS,CAAC;gBAClD,IAAI,EAAE,KAAK,EAAC,IAAI,EAAC,EAAE;;oBACjB,KAAK,CAAC,uBAAuB,EAAE,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,IAAI,CAAC,CAAA;oBAC1C,MAAM,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,IAAI,0CAAE,IAAI,CAAC,CAAA;gBACzD,CAAC;gBACD,KAAK,EAAE,KAAK,CAAC,EAAE;oBACb,sCAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,QAAQ,sBAAsB,EAAE,KAAK,CAAC,CAAA;gBACzG,CAAC;gBACD,QAAQ,EAAE,GAAG,EAAE;oBACb,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,QAAQ,yBAAyB,CAAC,CAAA;gBACpG,CAAC;aACF,CAAC,CAAA;YAEF,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAC3B,IAAI,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,QAAQ,+BAA+B,oBAAoB,CAAC,MAAM,EAAE,CACvG,CAAA;YAED,aAAa,CAAC,IAAI,CAAC;gBACjB,GAAG;gBACH,QAAQ,EAAE,gBAAgB;gBAC1B,oBAAoB;aACrB,CAAC,CAAA;YACF,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,YAAY,+BAA+B,oBAAoB,CAAC,MAAM,EAAE,CAAC,CAAA;QACpH,CAAC,CAAC,CAAA;QAEF,MAAM,CAAC,eAAe,CAAC,GAAG,aAAa,CAAA;QACvC,sCAAiB,CAAC,qBAAqB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAA;QAE3D,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAC3B,gCAAgC,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,QAAQ,gBAAgB,CACvF,CAAA;IACH,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,UAA2B;QAC1C,MAAM,MAAM,GAAG,sCAAiB,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAA;QAClE,MAAM,aAAa,GAAqB,MAAM,CAAC,eAAe,CAAC,CAAA;QAC/D,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC,YAAY,CAAC,oBAAoB,CAAC,WAAW,EAAE,CAAC,CAAA;QACtF,MAAM,CAAC,IAAI,EAAE,CAAA;QACb,sCAAiB,CAAC,wBAAwB,CAAC,UAAU,CAAC,CAAA;QAEtD,sCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,UAAU,CAAC,IAAI,mBAAmB,CAAC,CAAA;IACnG,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,aAA+B,EAAE,SAAc;;QAC/D,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,GAAG,IAAI,CAAC,OAAO,CAAA;QACrE,MAAM,EAAE,GAAG,EAAE,GAAG,SAAS,CAAA;QAEzB,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CAAC,oBAAoB,GAAG,EAAE,CAAC,CAAA;QAC5C,CAAC;QAED,MAAM,QAAQ,GAAG,MAAA,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,KAAK,GAAG,CAAC,0CAAE,QAAQ,CAAA;QACvF,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,EAAE,CAAC,CAAA;QACnD,CAAC;QAED,IAAI,CAAC,CAAC,MAAM,IAAA,2BAAe,EAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAC,EAAE,CAAC;YAC/F,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAA;YACxD,MAAM,IAAI,KAAK,CACb,iBAAiB,QAAQ,IAAI,SAAS,CAAC,CAAC,CAAC,QAAQ,GAAG,GAAG,GAAG,SAAS,GAAG,YAAY,CAAC,CAAC,CAAC,mBAAmB,WAAW,CACpH,CAAA;QACH,CAAC;QAED,gCAAgC;QAChC,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,GAAG,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QAC7D,MAAM,QAAQ,GAAG,IAAI,yCAAgB,CAAC,YAAY,EAAE,QAAQ,EAAE;YAC5D,IAAI;YACJ,MAAM;YACN,SAAS;YACT,MAAM,EAAE,0BAAkB,CAAC,MAAM;SAClC,CAAC,CAAA;QAEF,eAAe;QACf,MAAM,QAAQ,CAAC,GAAG,EAAE,CAAA;QACpB,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,IAAI,aAAa;QACf,OAAO;YACL;gBACE,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,UAAU;aAClB;YACD;gBACE,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,QAAQ;aAChB;YACD;gBACE,IAAI,EAAE,eAAe;gBACrB,IAAI,EAAE,sBAAsB;gBAC5B,KAAK,EAAE,uBAAuB;aAC/B;SACF,CAAA;IACH,CAAC;IAED,IAAI,YAAY;QACd,OAAO,CAAC,SAAS,CAAC,CAAA;IACpB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,yCAAyC,CAAA;IAClD,CAAC;IAED,IAAI,WAAW;QACb,OAAO,2BAA2B,CAAA;IACpC,CAAC;CACF;AA1ND,4CA0NC;AAED,sCAAiB,CAAC,iBAAiB,CAAC,mBAAmB,EAAE,IAAI,gBAAgB,EAAE,CAAC,CAAA","sourcesContent":["import 'cross-fetch/polyfill'\n\nimport { ApolloClient, InMemoryCache, createHttpLink, split } from '@apollo/client/core'\nimport { setContext } from '@apollo/client/link/context'\n\nimport WebSocket from 'ws'\nimport { createClient } from 'graphql-ws'\nimport { GraphQLWsLink } from '@apollo/client/link/subscriptions'\nimport { getMainDefinition } from '@apollo/client/utilities'\nimport gql from 'graphql-tag'\n\nimport { ConnectionManager } from '../connection-manager'\nimport { Connector } from '../types'\nimport { InputConnection } from '../../service/connection/connection-type'\n\nimport { Scenario } from '../../service/scenario/scenario'\nimport { ScenarioInstance } from '../../service/scenario-instance/scenario-instance-type'\n\nimport { getRepository, GraphqlLocalClient, Domain } from '@things-factory/shell'\nimport { User, checkPermission } from '@things-factory/auth-base'\n\nconst debug = require('debug')('things-factory:integration-base:operato-connector')\n\nconst defaultOptions: any = {\n watchQuery: {\n fetchPolicy: 'no-cache',\n errorPolicy: 'ignore'\n },\n query: {\n fetchPolicy: 'no-cache', //'network-only'\n errorPolicy: 'all'\n },\n mutate: {\n errorPolicy: 'all'\n }\n}\n\nexport const GRAPHQL_URI = '/graphql'\nexport const SUBSCRIPTION_URI = GRAPHQL_URI\n\ninterface SubscriberData {\n tag: string\n scenario: any\n subscriptionObserver: any\n}\n\nexport class OperatoConnector implements Connector {\n private context: any\n\n async ready(connectionConfigs: InputConnection[]) {\n await Promise.all(connectionConfigs.map(this.connect.bind(this)))\n\n ConnectionManager.logger.info('operato-connector connections are ready')\n }\n\n async connect(connection: InputConnection) {\n const {\n endpoint: uri,\n params: { authKey, domain, subscriptionHandlers = {} }\n } = connection\n\n if (!authKey || !domain) {\n throw new Error('some connection paramter missing.')\n }\n\n const domainOwner = await getRepository(User).findOne({\n where: {\n id: connection.domain.owner\n }\n })\n\n this.context = {\n domain: connection.domain,\n user: domainOwner\n /* TODO: domainOwner 대신 특정 유저를 지정할 수 있도록 개선해야함. 모든 커넥션에 유저를 지정하는 기능으로 일반화할 필요가 있는 지 고민해야함 */\n }\n\n const httpLink = createHttpLink({\n uri: uri\n })\n\n /* \n CHECKPOINT: \n 1. GraphqQLWsLink를 사용하면 setContext를 통한 추가 헤더 설정이 무시됩니다.\n 따라서, GraphQLWsLink를 사용하려면, connectionParams를 통해 헤더를 설정해야 합니다.\n \n 2. 서버에서 실행시, webSocketImpl을 명시적으로 지정해야 합니다.\n */\n const wsLink = new GraphQLWsLink(\n createClient({\n url: uri.replace(/^http/, 'ws'),\n keepAlive: 10_000,\n retryAttempts: 1_000_000,\n shouldRetry: e => true,\n webSocketImpl: WebSocket,\n connectionParams: {\n headers: {\n 'x-things-factory-domain': domain,\n authorization: authKey ? `Bearer ${authKey}` : ''\n }\n }\n })\n )\n\n const splitLink = split(\n ({ query }) => {\n const def = getMainDefinition(query)\n return def.kind === 'OperationDefinition' && def.operation === 'subscription'\n },\n wsLink,\n setContext((_, { headers }) => {\n return {\n headers: {\n ...headers,\n 'x-things-factory-domain': domain,\n authorization: authKey ? `Bearer ${authKey}` : ''\n }\n }\n }).concat(httpLink)\n )\n\n const cache = new InMemoryCache({\n addTypename: false\n })\n\n const client = new ApolloClient({\n defaultOptions,\n cache,\n link: splitLink\n })\n\n const subscriptions: SubscriberData[] = []\n Object.keys(subscriptionHandlers).forEach(async tag => {\n if (!tag || !subscriptionHandlers[tag]) return\n\n const scenarioName = subscriptionHandlers[tag]\n\n // fetch a scenario\n const selectedScenario = await getRepository(Scenario).findOne({\n where: {\n name: scenarioName\n },\n relations: ['steps', 'domain']\n })\n\n const subscription = client.subscribe({\n query: gql`\n subscription {\n data(tag: \"${tag}\") {\n tag\n data\n }\n }\n `\n })\n\n const subscriptionObserver = subscription.subscribe({\n next: async data => {\n debug('received pubsub msg.:', data?.data)\n await this.runScenario(subscriptions, data?.data?.data)\n },\n error: error => {\n ConnectionManager.logger.error(`(${connection.name}:${connection.endpoint}) subscription error`, error)\n },\n complete: () => {\n ConnectionManager.logger.info(`(${connection.name}:${connection.endpoint}) subscription complete`)\n }\n })\n\n ConnectionManager.logger.info(\n `(${connection.name}:${connection.endpoint}) subscription closed flag: ${subscriptionObserver.closed}`\n )\n\n subscriptions.push({\n tag,\n scenario: selectedScenario,\n subscriptionObserver\n })\n ConnectionManager.logger.info(`(${tag}:${scenarioName}) subscription closed flag: ${subscriptionObserver.closed}`)\n })\n\n client['subscriptions'] = subscriptions\n ConnectionManager.addConnectionInstance(connection, client)\n\n ConnectionManager.logger.info(\n `operato-connector connection(${connection.name}:${connection.endpoint}) is connected`\n )\n }\n\n async disconnect(connection: InputConnection) {\n const client = ConnectionManager.getConnectionInstance(connection)\n const subscriptions: SubscriberData[] = client['subscriptions']\n subscriptions.forEach(subscription => subscription.subscriptionObserver.unsubscribe())\n client.stop()\n ConnectionManager.removeConnectionInstance(connection)\n\n ConnectionManager.logger.info(`operato-connector connection(${connection.name}) is disconnected`)\n }\n\n async runScenario(subscriptions: SubscriberData[], variables: any): Promise<ScenarioInstance> {\n const { domain, user, unsafeIP, prohibitedPrivileges } = this.context\n const { tag } = variables\n\n if (!tag) {\n throw new Error(`tag is invalid - ${tag}`)\n }\n\n const scenario = subscriptions.find(subscription => subscription.tag === tag)?.scenario\n if (!scenario) {\n throw new Error(`scenario is not found - ${tag}`)\n }\n\n if (!(await checkPermission(scenario.privilege, user, domain, unsafeIP, prohibitedPrivileges))) {\n const { category, privilege } = scenario.privilege || {}\n throw new Error(\n `Unauthorized! ${category && privilege ? category + ':' + privilege + ' privilege' : 'ownership granted'} required`\n )\n }\n\n /* create a scenario instance */\n const instanceName = scenario.name + '-' + String(Date.now())\n const instance = new ScenarioInstance(instanceName, scenario, {\n user,\n domain,\n variables,\n client: GraphqlLocalClient.client\n })\n\n // run scenario\n await instance.run()\n return instance\n }\n\n get parameterSpec() {\n return [\n {\n type: 'string',\n name: 'authKey',\n label: 'auth-key'\n },\n {\n type: 'string',\n name: 'domain',\n label: 'domain'\n },\n {\n type: 'tag-scenarios',\n name: 'subscriptionHandlers',\n label: 'subscription-handlers'\n }\n ]\n }\n\n get taskPrefixes() {\n return ['graphql']\n }\n\n get help() {\n return 'integration/connector/operato-connector'\n }\n\n get description() {\n return 'Operato Graphql Connector'\n }\n}\n\nConnectionManager.registerConnector('operato-connector', new OperatoConnector())\n"]}
|
1
|
+
{"version":3,"file":"operato-connector.js","sourceRoot":"","sources":["../../../server/engine/connector/operato-connector.ts"],"names":[],"mappings":"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","sourcesContent":["import 'cross-fetch/polyfill'\n\nimport { ApolloClient, InMemoryCache, createHttpLink, split } from '@apollo/client/core'\nimport { setContext } from '@apollo/client/link/context'\n\nimport WebSocket from 'ws'\nimport { createClient } from 'graphql-ws'\nimport { GraphQLWsLink } from '@apollo/client/link/subscriptions'\nimport { getMainDefinition } from '@apollo/client/utilities'\nimport gql from 'graphql-tag'\n\nimport { ConnectionManager } from '../connection-manager'\nimport { Connector } from '../types'\nimport { InputConnection } from '../../service/connection/connection-type'\n\nimport { Scenario } from '../../service/scenario/scenario'\nimport { ScenarioInstance } from '../../service/scenario-instance/scenario-instance-type'\n\nimport { getRepository, GraphqlLocalClient, Domain } from '@things-factory/shell'\nimport { User, checkUserHasRole } from '@things-factory/auth-base'\n\nconst debug = require('debug')('things-factory:integration-base:operato-connector')\n\nconst defaultOptions: any = {\n watchQuery: {\n fetchPolicy: 'no-cache',\n errorPolicy: 'ignore'\n },\n query: {\n fetchPolicy: 'no-cache', //'network-only'\n errorPolicy: 'all'\n },\n mutate: {\n errorPolicy: 'all'\n }\n}\n\nexport const GRAPHQL_URI = '/graphql'\nexport const SUBSCRIPTION_URI = GRAPHQL_URI\n\ninterface SubscriberData {\n tag: string\n scenario: any\n subscriptionObserver: any\n}\n\nexport class OperatoConnector implements Connector {\n private context: any\n\n async ready(connectionConfigs: InputConnection[]) {\n await Promise.all(connectionConfigs.map(this.connect.bind(this)))\n\n ConnectionManager.logger.info('operato-connector connections are ready')\n }\n\n async connect(connection: InputConnection) {\n const {\n endpoint: uri,\n params: { authKey, domain, subscriptionHandlers = {} }\n } = connection\n\n if (!authKey || !domain) {\n throw new Error('some connection paramter missing.')\n }\n\n const domainOwner = await getRepository(User).findOne({\n where: {\n id: connection.domain.owner\n }\n })\n\n this.context = {\n domain: connection.domain,\n user: domainOwner\n /* TODO: domainOwner 대신 특정 유저를 지정할 수 있도록 개선해야함. 모든 커넥션에 유저를 지정하는 기능으로 일반화할 필요가 있는 지 고민해야함 */\n }\n\n const httpLink = createHttpLink({\n uri: uri\n })\n\n /* \n CHECKPOINT: \n 1. GraphqQLWsLink를 사용하면 setContext를 통한 추가 헤더 설정이 무시됩니다.\n 따라서, GraphQLWsLink를 사용하려면, connectionParams를 통해 헤더를 설정해야 합니다.\n \n 2. 서버에서 실행시, webSocketImpl을 명시적으로 지정해야 합니다.\n */\n const wsLink = new GraphQLWsLink(\n createClient({\n url: uri.replace(/^http/, 'ws'),\n keepAlive: 10_000,\n retryAttempts: 1_000_000,\n shouldRetry: e => true,\n webSocketImpl: WebSocket,\n connectionParams: {\n headers: {\n 'x-things-factory-domain': domain,\n authorization: authKey ? `Bearer ${authKey}` : ''\n }\n }\n })\n )\n\n const splitLink = split(\n ({ query }) => {\n const def = getMainDefinition(query)\n return def.kind === 'OperationDefinition' && def.operation === 'subscription'\n },\n wsLink,\n setContext((_, { headers }) => {\n return {\n headers: {\n ...headers,\n 'x-things-factory-domain': domain,\n authorization: authKey ? `Bearer ${authKey}` : ''\n }\n }\n }).concat(httpLink)\n )\n\n const cache = new InMemoryCache({\n addTypename: false\n })\n\n const client = new ApolloClient({\n defaultOptions,\n cache,\n link: splitLink\n })\n\n const subscriptions: SubscriberData[] = []\n Object.keys(subscriptionHandlers).forEach(async tag => {\n if (!tag || !subscriptionHandlers[tag]) return\n\n const scenarioName = subscriptionHandlers[tag]\n\n // fetch a scenario\n const selectedScenario = await getRepository(Scenario).findOne({\n where: {\n name: scenarioName\n },\n relations: ['steps', 'domain']\n })\n\n const subscription = client.subscribe({\n query: gql`\n subscription {\n data(tag: \"${tag}\") {\n tag\n data\n }\n }\n `\n })\n\n const subscriptionObserver = subscription.subscribe({\n next: async data => {\n debug('received pubsub msg.:', data?.data)\n await this.runScenario(subscriptions, data?.data?.data)\n },\n error: error => {\n ConnectionManager.logger.error(`(${connection.name}:${connection.endpoint}) subscription error`, error)\n },\n complete: () => {\n ConnectionManager.logger.info(`(${connection.name}:${connection.endpoint}) subscription complete`)\n }\n })\n\n ConnectionManager.logger.info(\n `(${connection.name}:${connection.endpoint}) subscription closed flag: ${subscriptionObserver.closed}`\n )\n\n subscriptions.push({\n tag,\n scenario: selectedScenario,\n subscriptionObserver\n })\n ConnectionManager.logger.info(`(${tag}:${scenarioName}) subscription closed flag: ${subscriptionObserver.closed}`)\n })\n\n client['subscriptions'] = subscriptions\n ConnectionManager.addConnectionInstance(connection, client)\n\n ConnectionManager.logger.info(\n `operato-connector connection(${connection.name}:${connection.endpoint}) is connected`\n )\n }\n\n async disconnect(connection: InputConnection) {\n const client = ConnectionManager.getConnectionInstance(connection)\n const subscriptions: SubscriberData[] = client['subscriptions']\n subscriptions.forEach(subscription => subscription.subscriptionObserver.unsubscribe())\n client.stop()\n ConnectionManager.removeConnectionInstance(connection)\n\n ConnectionManager.logger.info(`operato-connector connection(${connection.name}) is disconnected`)\n }\n\n async runScenario(subscriptions: SubscriberData[], variables: any): Promise<ScenarioInstance> {\n const { domain, user } = this.context\n const { tag } = variables\n\n if (!tag) {\n throw new Error(`tag is invalid - ${tag}`)\n }\n\n const scenario = subscriptions.find(subscription => subscription.tag === tag)?.scenario\n if (!scenario) {\n throw new Error(`scenario is not found - ${tag}`)\n }\n\n if (!(await checkUserHasRole(scenario.roleId, domain, user))) {\n throw new Error(`Unauthorized! ${scenario.name} doesn't have required role.`)\n }\n\n /* create a scenario instance */\n const instanceName = scenario.name + '-' + String(Date.now())\n const instance = new ScenarioInstance(instanceName, scenario, {\n user,\n domain,\n variables,\n client: GraphqlLocalClient.client\n })\n\n // run scenario\n await instance.run()\n return instance\n }\n\n get parameterSpec() {\n return [\n {\n type: 'string',\n name: 'authKey',\n label: 'auth-key'\n },\n {\n type: 'string',\n name: 'domain',\n label: 'domain'\n },\n {\n type: 'tag-scenarios',\n name: 'subscriptionHandlers',\n label: 'subscription-handlers'\n }\n ]\n }\n\n get taskPrefixes() {\n return ['graphql']\n }\n\n get help() {\n return 'integration/connector/operato-connector'\n }\n\n get description() {\n return 'Operato Graphql Connector'\n }\n}\n\nConnectionManager.registerConnector('operato-connector', new OperatoConnector())\n"]}
|
@@ -8,4 +8,5 @@ tslib_1.__exportStar(require("./scenario-engine"), exports);
|
|
8
8
|
tslib_1.__exportStar(require("./task-registry"), exports);
|
9
9
|
tslib_1.__exportStar(require("./analyzer/analyze-integration"), exports);
|
10
10
|
tslib_1.__exportStar(require("./edge-client"), exports);
|
11
|
+
tslib_1.__exportStar(require("./resource-pool"), exports);
|
11
12
|
//# sourceMappingURL=index.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/engine/index.ts"],"names":[],"mappings":";;;AAAA,uBAAoB;AACpB,kBAAe;AAEf,+DAAoC;AACpC,4DAAiC;AACjC,0DAA+B;AAC/B,yEAA8C;AAC9C,wDAA6B","sourcesContent":["import './connector'\nimport './task'\n\nexport * from './connection-manager'\nexport * from './scenario-engine'\nexport * from './task-registry'\nexport * from './analyzer/analyze-integration'\nexport * from './edge-client'\n\nexport { Connector, Context, TaskHandler } from './types'\n"]}
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/engine/index.ts"],"names":[],"mappings":";;;AAAA,uBAAoB;AACpB,kBAAe;AAEf,+DAAoC;AACpC,4DAAiC;AACjC,0DAA+B;AAC/B,yEAA8C;AAC9C,wDAA6B;AAC7B,0DAA+B","sourcesContent":["import './connector'\nimport './task'\n\nexport * from './connection-manager'\nexport * from './scenario-engine'\nexport * from './task-registry'\nexport * from './analyzer/analyze-integration'\nexport * from './edge-client'\nexport * from './resource-pool'\n\nexport { Connector, Context, TaskHandler } from './types'\n"]}
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare function getHeadlessPool(): any;
|
@@ -0,0 +1,121 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.getHeadlessPool = getHeadlessPool;
|
4
|
+
const tslib_1 = require("tslib");
|
5
|
+
const genericPool = tslib_1.__importStar(require("generic-pool"));
|
6
|
+
const env_1 = require("@things-factory/env");
|
7
|
+
try {
|
8
|
+
var puppeteer = require('puppeteer');
|
9
|
+
}
|
10
|
+
catch (err) {
|
11
|
+
env_1.logger.error(err);
|
12
|
+
}
|
13
|
+
let headlessPool;
|
14
|
+
function getHeadlessPool() {
|
15
|
+
if (!headlessPool) {
|
16
|
+
headlessPool = createHeadlessPool({ min: 2, max: 20, acquireTimeoutMillis: 15000, testOnBorrow: true });
|
17
|
+
}
|
18
|
+
return headlessPool;
|
19
|
+
}
|
20
|
+
function createHeadlessPool(options) {
|
21
|
+
return genericPool.createPool({
|
22
|
+
create() {
|
23
|
+
console.log('headless instance in headless-pool-integration about to create');
|
24
|
+
return initializeChromium();
|
25
|
+
},
|
26
|
+
validate(browser) {
|
27
|
+
return Promise.race([
|
28
|
+
new Promise(res => setTimeout(() => res(false), 1500)),
|
29
|
+
browser
|
30
|
+
//@ts-ignore
|
31
|
+
.version()
|
32
|
+
.then(() => true)
|
33
|
+
.catch(() => false)
|
34
|
+
]);
|
35
|
+
},
|
36
|
+
destroy(browser) {
|
37
|
+
//@ts-ignore
|
38
|
+
return browser.close();
|
39
|
+
}
|
40
|
+
}, options);
|
41
|
+
}
|
42
|
+
async function destroyHeadlessPool() {
|
43
|
+
if (headlessPool) {
|
44
|
+
console.log('headless-pool-integration about to destroy');
|
45
|
+
try {
|
46
|
+
await Promise.race([
|
47
|
+
headlessPool.drain().then(() => headlessPool.clear()), // 정리 작업
|
48
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('Destroy timeout')), 5000) // 5초 타임아웃 설정
|
49
|
+
)
|
50
|
+
]);
|
51
|
+
console.log('Headless pool destroyed');
|
52
|
+
}
|
53
|
+
catch (err) {
|
54
|
+
env_1.logger.error('Failed to destroy headless pool:', err);
|
55
|
+
}
|
56
|
+
}
|
57
|
+
}
|
58
|
+
const CHROMIUM_PATH = env_1.config.get('CHROMIUM_PATH');
|
59
|
+
async function initializeChromium() {
|
60
|
+
try {
|
61
|
+
if (!puppeteer) {
|
62
|
+
return;
|
63
|
+
}
|
64
|
+
const launchSetting = {
|
65
|
+
args: ['--hide-scrollbars', '--mute-audio', '--no-sandbox', '--use-gl=egl'],
|
66
|
+
headless: 'shell'
|
67
|
+
};
|
68
|
+
if (CHROMIUM_PATH) {
|
69
|
+
launchSetting['executablePath'] = CHROMIUM_PATH;
|
70
|
+
}
|
71
|
+
const browser = await puppeteer.launch(launchSetting);
|
72
|
+
return browser;
|
73
|
+
}
|
74
|
+
catch (err) {
|
75
|
+
env_1.logger.error(err);
|
76
|
+
}
|
77
|
+
}
|
78
|
+
// Graceful shutdown logic
|
79
|
+
function setupProcessExitHandlers() {
|
80
|
+
let isCleaningUp = false; // 중복 정리를 방지
|
81
|
+
const cleanup = async () => {
|
82
|
+
if (isCleaningUp)
|
83
|
+
return; // 이미 정리 중이면 무시
|
84
|
+
isCleaningUp = true;
|
85
|
+
console.log('Application is shutting down. Cleaning up resources...');
|
86
|
+
try {
|
87
|
+
// Pool 정리 작업 실행
|
88
|
+
await destroyHeadlessPool();
|
89
|
+
}
|
90
|
+
catch (err) {
|
91
|
+
env_1.logger.error('Error during cleanup:', err);
|
92
|
+
}
|
93
|
+
finally {
|
94
|
+
console.log('Cleanup completed.');
|
95
|
+
}
|
96
|
+
};
|
97
|
+
const onExit = async (signal) => {
|
98
|
+
console.log(`Received signal: ${signal || 'unknown'}`);
|
99
|
+
await cleanup();
|
100
|
+
// 다른 핸들러가 실행될 수 있도록 exit 호출을 지연
|
101
|
+
process.nextTick(() => process.exit(0)); // Tick 뒤에 종료
|
102
|
+
};
|
103
|
+
// Handle termination signals
|
104
|
+
process.once('SIGINT', () => onExit('SIGINT')); // Ctrl+C
|
105
|
+
process.once('SIGTERM', () => onExit('SIGTERM')); // Termination signal
|
106
|
+
// Handle uncaught exceptions
|
107
|
+
process.once('uncaughtException', async (err) => {
|
108
|
+
env_1.logger.error('Uncaught Exception:', err);
|
109
|
+
await cleanup();
|
110
|
+
process.nextTick(() => process.exit(1)); // Tick 뒤에 종료
|
111
|
+
});
|
112
|
+
// Handle unhandled promise rejections
|
113
|
+
process.once('unhandledRejection', async (reason) => {
|
114
|
+
env_1.logger.error('Unhandled Rejection:', reason);
|
115
|
+
await cleanup();
|
116
|
+
process.nextTick(() => process.exit(1)); // Tick 뒤에 종료
|
117
|
+
});
|
118
|
+
}
|
119
|
+
// Initialize process exit handlers
|
120
|
+
setupProcessExitHandlers();
|
121
|
+
//# sourceMappingURL=headless-pool.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"headless-pool.js","sourceRoot":"","sources":["../../../server/engine/resource-pool/headless-pool.ts"],"names":[],"mappings":"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","sourcesContent":["import * as genericPool from 'generic-pool'\nimport { config, logger } from '@things-factory/env'\n\ntry {\n var puppeteer = require('puppeteer')\n} catch (err) {\n logger.error(err)\n}\n\nlet headlessPool\n\nexport function getHeadlessPool() {\n if (!headlessPool) {\n headlessPool = createHeadlessPool({ min: 2, max: 20, acquireTimeoutMillis: 15000, testOnBorrow: true })\n }\n\n return headlessPool\n}\n\nfunction createHeadlessPool(options: genericPool.Options) {\n return genericPool.createPool(\n {\n create() {\n console.log('headless instance in headless-pool-integration about to create')\n return initializeChromium()\n },\n validate(browser) {\n return Promise.race([\n new Promise(res => setTimeout(() => res(false), 1500)),\n browser\n //@ts-ignore\n .version()\n .then(() => true)\n .catch(() => false)\n ])\n },\n destroy(browser) {\n //@ts-ignore\n return browser.close()\n }\n } as genericPool.Factory<any>,\n options\n )\n}\n\nasync function destroyHeadlessPool() {\n if (headlessPool) {\n console.log('headless-pool-integration about to destroy')\n\n try {\n await Promise.race([\n headlessPool.drain().then(() => headlessPool.clear()), // 정리 작업\n new Promise(\n (_, reject) => setTimeout(() => reject(new Error('Destroy timeout')), 5000) // 5초 타임아웃 설정\n )\n ])\n console.log('Headless pool destroyed')\n } catch (err) {\n logger.error('Failed to destroy headless pool:', err)\n }\n }\n}\n\nconst CHROMIUM_PATH = config.get('CHROMIUM_PATH')\n\nasync function initializeChromium() {\n try {\n if (!puppeteer) {\n return\n }\n\n const launchSetting = {\n args: ['--hide-scrollbars', '--mute-audio', '--no-sandbox', '--use-gl=egl'],\n headless: 'shell'\n }\n\n if (CHROMIUM_PATH) {\n launchSetting['executablePath'] = CHROMIUM_PATH\n }\n\n const browser = await puppeteer.launch(launchSetting)\n\n return browser\n } catch (err) {\n logger.error(err)\n }\n}\n\n// Graceful shutdown logic\nfunction setupProcessExitHandlers() {\n let isCleaningUp = false // 중복 정리를 방지\n\n const cleanup = async () => {\n if (isCleaningUp) return // 이미 정리 중이면 무시\n isCleaningUp = true\n\n console.log('Application is shutting down. Cleaning up resources...')\n try {\n // Pool 정리 작업 실행\n await destroyHeadlessPool()\n } catch (err) {\n logger.error('Error during cleanup:', err)\n } finally {\n console.log('Cleanup completed.')\n }\n }\n\n const onExit = async (signal?: string) => {\n console.log(`Received signal: ${signal || 'unknown'}`)\n await cleanup()\n\n // 다른 핸들러가 실행될 수 있도록 exit 호출을 지연\n process.nextTick(() => process.exit(0)) // Tick 뒤에 종료\n }\n\n // Handle termination signals\n process.once('SIGINT', () => onExit('SIGINT')) // Ctrl+C\n process.once('SIGTERM', () => onExit('SIGTERM')) // Termination signal\n\n // Handle uncaught exceptions\n process.once('uncaughtException', async err => {\n logger.error('Uncaught Exception:', err)\n await cleanup()\n process.nextTick(() => process.exit(1)) // Tick 뒤에 종료\n })\n\n // Handle unhandled promise rejections\n process.once('unhandledRejection', async reason => {\n logger.error('Unhandled Rejection:', reason)\n await cleanup()\n process.nextTick(() => process.exit(1)) // Tick 뒤에 종료\n })\n}\n\n// Initialize process exit handlers\nsetupProcessExitHandlers()\n"]}
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './headless-pool';
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/engine/resource-pool/index.ts"],"names":[],"mappings":";;;AAAA,0DAA+B","sourcesContent":["export * from './headless-pool'\n"]}
|
@@ -6,17 +6,16 @@ const url_1 = require("url");
|
|
6
6
|
const utils_1 = require("@things-factory/utils");
|
7
7
|
const task_registry_1 = require("../task-registry");
|
8
8
|
const connection_manager_1 = require("../connection-manager");
|
9
|
-
const headless_pool_for_scenario_1 = require("./utils/headless-pool-for-scenario");
|
10
9
|
async function HeadlessPost(step, { logger, data, domain }) {
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
const { connection: connectionName, params: stepOptions } = step;
|
11
|
+
const { headers: requestHeaders, contentType, path, accessor } = stepOptions || {};
|
12
|
+
const connection = connection_manager_1.ConnectionManager.getConnectionInstanceByName(domain, connectionName);
|
14
13
|
if (!connection) {
|
15
|
-
throw new Error(`
|
14
|
+
throw new Error(`Connection '${connectionName}' is not established.`);
|
16
15
|
}
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
const { endpoint, params: connectionParams, acquireSessionPage, releasePage } = connection;
|
17
|
+
const headers = Object.assign({}, requestHeaders);
|
18
|
+
let body = (0, utils_1.access)(accessor, data);
|
20
19
|
if (contentType && body) {
|
21
20
|
headers['content-type'] = contentType;
|
22
21
|
switch (contentType) {
|
@@ -31,24 +30,23 @@ async function HeadlessPost(step, { logger, data, domain }) {
|
|
31
30
|
for (const prop in body) {
|
32
31
|
searchParams.set(prop, body[prop]);
|
33
32
|
}
|
34
|
-
body = searchParams;
|
33
|
+
body = searchParams.toString();
|
35
34
|
break;
|
36
35
|
}
|
37
36
|
}
|
38
|
-
|
37
|
+
const options = {
|
39
38
|
method: 'POST',
|
40
39
|
headers,
|
41
40
|
body
|
42
41
|
};
|
43
|
-
|
42
|
+
const { rejectUnauthorized } = connectionParams;
|
44
43
|
if (!rejectUnauthorized) {
|
45
44
|
const httpsAgent = new https_1.default.Agent({
|
46
45
|
rejectUnauthorized
|
47
46
|
});
|
48
47
|
options.agent = httpsAgent;
|
49
48
|
}
|
50
|
-
const
|
51
|
-
const page = await browser.newPage();
|
49
|
+
const page = await acquireSessionPage();
|
52
50
|
try {
|
53
51
|
page.on('console', async (msg) => {
|
54
52
|
console.log(`[browser ${msg.type()}] ${msg.text()}`);
|
@@ -70,12 +68,12 @@ async function HeadlessPost(step, { logger, data, domain }) {
|
|
70
68
|
data: response
|
71
69
|
};
|
72
70
|
}
|
73
|
-
catch (
|
74
|
-
|
71
|
+
catch (error) {
|
72
|
+
logger.error('Error in HeadlessPost:', error);
|
73
|
+
throw error;
|
75
74
|
}
|
76
75
|
finally {
|
77
|
-
page
|
78
|
-
(0, headless_pool_for_scenario_1.getHeadlessPool)().release(browser);
|
76
|
+
await releasePage(page);
|
79
77
|
}
|
80
78
|
}
|
81
79
|
HeadlessPost.parameterSpec = [
|
@@ -95,22 +93,10 @@ HeadlessPost.parameterSpec = [
|
|
95
93
|
label: 'content-type',
|
96
94
|
property: {
|
97
95
|
options: [
|
98
|
-
{
|
99
|
-
|
100
|
-
|
101
|
-
}
|
102
|
-
{
|
103
|
-
display: 'application/json',
|
104
|
-
value: 'application/json'
|
105
|
-
},
|
106
|
-
{
|
107
|
-
display: 'text/plain',
|
108
|
-
value: 'text/plain'
|
109
|
-
},
|
110
|
-
{
|
111
|
-
display: 'application/x-www-form-urlencoded',
|
112
|
-
value: 'application/x-www-form-urlencoded'
|
113
|
-
}
|
96
|
+
{ display: '', value: '' },
|
97
|
+
{ display: 'application/json', value: 'application/json' },
|
98
|
+
{ display: 'text/plain', value: 'text/plain' },
|
99
|
+
{ display: 'application/x-www-form-urlencoded', value: 'application/x-www-form-urlencoded' }
|
114
100
|
]
|
115
101
|
}
|
116
102
|
},
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"headless-post.js","sourceRoot":"","sources":["../../../server/engine/task/headless-post.ts"],"names":[],"mappings":";;;AAAA,0DAAyB;AACzB,6BAAyB;AAEzB,iDAA8C;AAC9C,oDAA+C;AAC/C,8DAAyD;AAEzD,
|
1
|
+
{"version":3,"file":"headless-post.js","sourceRoot":"","sources":["../../../server/engine/task/headless-post.ts"],"names":[],"mappings":"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","sourcesContent":["import https from 'https'\nimport { URL } from 'url'\n\nimport { access } from '@things-factory/utils'\nimport { TaskRegistry } from '../task-registry'\nimport { ConnectionManager } from '../connection-manager'\n\nasync function HeadlessPost(step, { logger, data, domain }) {\n const { connection: connectionName, params: stepOptions } = step\n const { headers: requestHeaders, contentType, path, accessor } = stepOptions || {}\n\n const connection = ConnectionManager.getConnectionInstanceByName(domain, connectionName)\n\n if (!connection) {\n throw new Error(`Connection '${connectionName}' is not established.`)\n }\n\n const { endpoint, params: connectionParams, acquireSessionPage, releasePage } = connection\n\n const headers = {\n ...requestHeaders\n }\n\n let body = access(accessor, data)\n if (contentType && body) {\n headers['content-type'] = contentType\n switch (contentType) {\n case 'text/plain':\n body = JSON.stringify(body)\n break\n case 'application/json':\n body = JSON.stringify(body)\n break\n case 'application/x-www-form-urlencoded':\n const searchParams = new URLSearchParams()\n for (const prop in body) {\n searchParams.set(prop, body[prop])\n }\n body = searchParams.toString()\n break\n }\n }\n\n const options = {\n method: 'POST',\n headers,\n body\n } as any\n\n const { rejectUnauthorized } = connectionParams\n\n if (!rejectUnauthorized) {\n const httpsAgent = new https.Agent({\n rejectUnauthorized\n })\n options.agent = httpsAgent\n }\n\n const page = await acquireSessionPage()\n\n try {\n page.on('console', async msg => {\n console.log(`[browser ${msg.type()}] ${msg.text()}`)\n })\n\n page.on('requestfailed', request => {\n console.log('Request failed:', request.url())\n })\n\n await page.goto(endpoint, { waitUntil: 'networkidle2' })\n\n const response = await page.evaluate(\n async (urlString, options) => {\n const response = await fetch(urlString, options)\n\n if (response.ok && response.headers.get('content-type').includes('application/json')) {\n return await response.json()\n } else {\n return await response.text()\n }\n },\n new URL(path, endpoint),\n options\n )\n\n return {\n data: response\n }\n } catch (error) {\n logger.error('Error in HeadlessPost:', error)\n throw error\n } finally {\n await releasePage(page)\n }\n}\n\nHeadlessPost.parameterSpec = [\n {\n type: 'string',\n name: 'path',\n label: 'path'\n },\n {\n type: 'http-headers',\n name: 'headers',\n label: 'headers'\n },\n {\n type: 'select',\n name: 'contentType',\n label: 'content-type',\n property: {\n options: [\n { display: '', value: '' },\n { display: 'application/json', value: 'application/json' },\n { display: 'text/plain', value: 'text/plain' },\n { display: 'application/x-www-form-urlencoded', value: 'application/x-www-form-urlencoded' }\n ]\n }\n },\n {\n type: 'scenario-step-input',\n name: 'accessor',\n label: 'accessor'\n }\n]\n\nTaskRegistry.registerTaskHandler('headless-post', HeadlessPost)\n"]}
|
@@ -3,24 +3,31 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const url_1 = require("url");
|
4
4
|
const task_registry_1 = require("../task-registry");
|
5
5
|
const connection_manager_1 = require("../connection-manager");
|
6
|
-
const headless_pool_for_scenario_1 = require("./utils/headless-pool-for-scenario");
|
7
6
|
async function HeadlessScrap(step, { logger, data, domain }) {
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
const { connection: connectionName, params: stepOptions } = step;
|
8
|
+
const { headers: requestHeaders, path, selectors = [] } = stepOptions || {};
|
9
|
+
const connection = connection_manager_1.ConnectionManager.getConnectionInstanceByName(domain, connectionName);
|
11
10
|
if (!connection) {
|
12
|
-
throw new Error(`
|
11
|
+
throw new Error(`Connection '${connectionName}' is not established.`);
|
13
12
|
}
|
14
|
-
|
15
|
-
|
16
|
-
const
|
17
|
-
const page = await browser.newPage();
|
13
|
+
const { endpoint, params: connectionParams, acquireSessionPage, releasePage } = connection;
|
14
|
+
const headers = Object.assign({}, requestHeaders);
|
15
|
+
const page = await acquireSessionPage();
|
18
16
|
try {
|
19
17
|
page.on('console', async (msg) => {
|
20
18
|
console.log(`[browser ${msg.type()}] ${msg.text()}`);
|
21
19
|
});
|
22
20
|
page.on('requestfailed', request => {
|
23
|
-
|
21
|
+
var _a;
|
22
|
+
console.log('Request failed:');
|
23
|
+
console.log(`- URL: ${request.url()}`);
|
24
|
+
console.log(`- Method: ${request.method()}`);
|
25
|
+
console.log(`- Failure Text: ${(_a = request.failure()) === null || _a === void 0 ? void 0 : _a.errorText}`);
|
26
|
+
console.log(`- Headers:`, request.headers());
|
27
|
+
// POST 데이터 (필요한 경우)
|
28
|
+
if (request.postData()) {
|
29
|
+
console.log(`- Post Data: ${request.postData()}`);
|
30
|
+
}
|
24
31
|
});
|
25
32
|
await page.setExtraHTTPHeaders(headers);
|
26
33
|
await page.goto(new url_1.URL(path, endpoint), { waitUntil: 'networkidle2' });
|
@@ -36,11 +43,11 @@ async function HeadlessScrap(step, { logger, data, domain }) {
|
|
36
43
|
};
|
37
44
|
}
|
38
45
|
catch (e) {
|
39
|
-
|
46
|
+
logger.error('Error in HeadlessScrap:', e);
|
47
|
+
throw e;
|
40
48
|
}
|
41
49
|
finally {
|
42
|
-
page
|
43
|
-
(0, headless_pool_for_scenario_1.getHeadlessPool)().release(browser);
|
50
|
+
await releasePage(page);
|
44
51
|
}
|
45
52
|
}
|
46
53
|
HeadlessScrap.parameterSpec = [
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"headless-scrap.js","sourceRoot":"","sources":["../../../server/engine/task/headless-scrap.ts"],"names":[],"mappings":";;AAAA,6BAAyB;AAEzB,oDAA+C;AAC/C,8DAAyD;AAEzD,
|
1
|
+
{"version":3,"file":"headless-scrap.js","sourceRoot":"","sources":["../../../server/engine/task/headless-scrap.ts"],"names":[],"mappings":"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","sourcesContent":["import { URL } from 'url'\n\nimport { TaskRegistry } from '../task-registry'\nimport { ConnectionManager } from '../connection-manager'\n\nasync function HeadlessScrap(step, { logger, data, domain }) {\n const { connection: connectionName, params: stepOptions } = step\n const { headers: requestHeaders, path, selectors = [] } = stepOptions || {}\n\n const connection = ConnectionManager.getConnectionInstanceByName(domain, connectionName)\n\n if (!connection) {\n throw new Error(`Connection '${connectionName}' is not established.`)\n }\n\n const { endpoint, params: connectionParams, acquireSessionPage, releasePage } = connection\n\n const headers = {\n ...requestHeaders\n }\n\n const page = await acquireSessionPage()\n\n try {\n page.on('console', async msg => {\n console.log(`[browser ${msg.type()}] ${msg.text()}`)\n })\n\n page.on('requestfailed', request => {\n console.log('Request failed:')\n console.log(`- URL: ${request.url()}`)\n console.log(`- Method: ${request.method()}`)\n console.log(`- Failure Text: ${request.failure()?.errorText}`)\n console.log(`- Headers:`, request.headers())\n\n // POST 데이터 (필요한 경우)\n if (request.postData()) {\n console.log(`- Post Data: ${request.postData()}`)\n }\n })\n\n await page.setExtraHTTPHeaders(headers)\n await page.goto(new URL(path, endpoint), { waitUntil: 'networkidle2' })\n\n const result = {}\n\n for (const selector of selectors) {\n const { text, value } = selector\n result[text] = await page.$$eval(value, elements => {\n return elements.map(element => element.textContent.trim())\n })\n }\n\n return {\n data: result\n }\n } catch (e) {\n logger.error('Error in HeadlessScrap:', e)\n throw e\n } finally {\n await releasePage(page)\n }\n}\n\nHeadlessScrap.parameterSpec = [\n {\n type: 'string',\n name: 'path',\n label: 'path'\n },\n {\n type: 'http-headers',\n name: 'headers',\n label: 'headers'\n },\n {\n type: 'options',\n name: 'selectors',\n label: 'selectors'\n }\n]\n\nTaskRegistry.registerTaskHandler('headless-scrap', HeadlessScrap)\n"]}
|
@@ -15,7 +15,7 @@ function getHeadlessPool() {
|
|
15
15
|
if (!headlessPool) {
|
16
16
|
headlessPool = genericPool.createPool({
|
17
17
|
create() {
|
18
|
-
console.log('headless-pool-for-scensrio about to create');
|
18
|
+
console.log('headless instance in headless-pool-for-scensrio about to create');
|
19
19
|
return initializeChromium();
|
20
20
|
},
|
21
21
|
validate(browser) {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"headless-pool-for-scenario.js","sourceRoot":"","sources":["../../../../server/engine/task/utils/headless-pool-for-scenario.ts"],"names":[],"mappings":";;AAYA,0CAiCC;;AA7CD,kEAA2C;AAE3C,6CAAoD;AAEpD,IAAI,CAAC;IACH,IAAI,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;AACtC,CAAC;AAAC,OAAO,GAAG,EAAE,CAAC;IACb,YAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;AACnB,CAAC;AAED,IAAI,YAAY,CAAA;AAEhB,SAAgB,eAAe;IAC7B,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,YAAY,GAAG,WAAW,CAAC,UAAU,CACnC;YACE,MAAM;gBACJ,OAAO,CAAC,GAAG,CAAC,
|
1
|
+
{"version":3,"file":"headless-pool-for-scenario.js","sourceRoot":"","sources":["../../../../server/engine/task/utils/headless-pool-for-scenario.ts"],"names":[],"mappings":";;AAYA,0CAiCC;;AA7CD,kEAA2C;AAE3C,6CAAoD;AAEpD,IAAI,CAAC;IACH,IAAI,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;AACtC,CAAC;AAAC,OAAO,GAAG,EAAE,CAAC;IACb,YAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;AACnB,CAAC;AAED,IAAI,YAAY,CAAA;AAEhB,SAAgB,eAAe;IAC7B,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,YAAY,GAAG,WAAW,CAAC,UAAU,CACnC;YACE,MAAM;gBACJ,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAA;gBAC9E,OAAO,kBAAkB,EAAE,CAAA;YAC7B,CAAC;YACD,QAAQ,CAAC,OAAO;gBACd,OAAO,OAAO,CAAC,IAAI,CAAC;oBAClB,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;oBACtD,OAAO;wBACL,YAAY;yBACX,OAAO,EAAE;yBACT,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC;yBACf,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;iBACrB,CAAC,CAAA;YACJ,CAAC;YACD,OAAO,CAAC,OAAO;gBACb,YAAY;gBACZ,OAAO,OAAO,CAAC,KAAK,EAAE,CAAA;YACxB,CAAC;SACF,EACD;YACE,GAAG,EAAE,CAAC;YACN,GAAG,EAAE,EAAE;YACP,YAAY,EAAE,IAAI;YAClB,oBAAoB,EAAE,KAAK;SAC5B,CACF,CAAA;IACH,CAAC;IAED,OAAO,YAAY,CAAA;AACrB,CAAC;AAED,MAAM,aAAa,GAAG,YAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;AAEjD,KAAK,UAAU,kBAAkB;IAC/B,IAAI,CAAC;QACH,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAM;QACR,CAAC;QAED,IAAI,aAAa,GAAG;YAClB,IAAI,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC;YACtC,QAAQ,EAAE,OAAO;SAClB,CAAA;QAED,IAAI,aAAa,EAAE,CAAC;YAClB,aAAa,CAAC,gBAAgB,CAAC,GAAG,aAAa,CAAA;QACjD,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;QAErD,OAAO,OAAO,CAAA;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,YAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACnB,CAAC;AACH,CAAC","sourcesContent":["import * as genericPool from 'generic-pool'\n\nimport { config, logger } from '@things-factory/env'\n\ntry {\n var puppeteer = require('puppeteer')\n} catch (err) {\n logger.error(err)\n}\n\nvar headlessPool\n\nexport function getHeadlessPool() {\n if (!headlessPool) {\n headlessPool = genericPool.createPool(\n {\n create() {\n console.log('headless instance in headless-pool-for-scensrio about to create')\n return initializeChromium()\n },\n validate(browser) {\n return Promise.race([\n new Promise(res => setTimeout(() => res(false), 1500)),\n browser\n //@ts-ignore\n .version()\n .then(_ => true)\n .catch(_ => false)\n ])\n },\n destroy(browser) {\n //@ts-ignore\n return browser.close()\n }\n },\n {\n min: 2,\n max: 10,\n testOnBorrow: true,\n acquireTimeoutMillis: 15000\n }\n )\n }\n\n return headlessPool\n}\n\nconst CHROMIUM_PATH = config.get('CHROMIUM_PATH')\n\nasync function initializeChromium() {\n try {\n if (!puppeteer) {\n return\n }\n\n var launchSetting = {\n args: ['--mute-audio', '--no-sandbox'],\n headless: 'shell'\n }\n\n if (CHROMIUM_PATH) {\n launchSetting['executablePath'] = CHROMIUM_PATH\n }\n\n const browser = await puppeteer.launch(launchSetting)\n\n return browser\n } catch (err) {\n logger.error(err)\n }\n}\n"]}
|
@@ -38,14 +38,17 @@ tslib_1.__decorate([
|
|
38
38
|
], PayloadLog.prototype, "name", void 0);
|
39
39
|
tslib_1.__decorate([
|
40
40
|
(0, typeorm_1.Column)({
|
41
|
+
nullable: true,
|
41
42
|
type: DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
|
42
43
|
? 'enum'
|
43
44
|
: DATABASE_TYPE == 'oracle'
|
44
45
|
? 'varchar2'
|
45
|
-
: '
|
46
|
-
|
47
|
-
|
48
|
-
|
46
|
+
: DATABASE_TYPE == 'mssql'
|
47
|
+
? 'nvarchar'
|
48
|
+
: 'varchar',
|
49
|
+
enum: DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb' ? PayloadType : undefined,
|
50
|
+
length: DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb' ? undefined : 32,
|
51
|
+
default: PayloadType.EGESTION
|
49
52
|
}),
|
50
53
|
(0, type_graphql_1.Field)(type => String),
|
51
54
|
tslib_1.__metadata("design:type", String)
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"payload-log.js","sourceRoot":"","sources":["../../../server/service/payload-log/payload-log.ts"],"names":[],"mappings":";;;;AAAA,qCASgB;AAChB,+CAA2E;AAE3E,6CAA4C;AAE5C,iDAA8C;AAC9C,yDAAgD;AAEhD,MAAM,SAAS,GAAG,YAAM,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;AAC7C,MAAM,aAAa,GAAG,SAAS,CAAC,IAAI,CAAA;AAEpC,IAAY,WAGX;AAHD,WAAY,WAAW;IACrB,sCAAuB,CAAA;IACvB,oCAAqB,CAAA;AACvB,CAAC,EAHW,WAAW,2BAAX,WAAW,QAGtB;AAKM,IAAM,UAAU,GAAhB,MAAM,UAAU;
|
1
|
+
{"version":3,"file":"payload-log.js","sourceRoot":"","sources":["../../../server/service/payload-log/payload-log.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CreateDateColumn,\n UpdateDateColumn,\n Entity,\n Index,\n Column,\n RelationId,\n ManyToOne,\n PrimaryGeneratedColumn\n} from 'typeorm'\nimport { ObjectType, Field, Int, ID, registerEnumType } from 'type-graphql'\n\nimport { config } from '@things-factory/env'\nimport { Bizplace } from '@things-factory/biz-base'\nimport { Domain } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\n\nconst ORMCONFIG = config.get('ormconfig', {})\nconst DATABASE_TYPE = ORMCONFIG.type\n\nexport enum PayloadType {\n INGESTION = 'ingestion',\n EGESTION = 'egestion'\n}\n@Entity()\n@Index('ix_payload_log_0', (payloadLog: PayloadLog) => [payloadLog.domain])\n@Index('ix_payload_log_1', (payloadLog: PayloadLog) => [payloadLog.domain, payloadLog.endpoint])\n@ObjectType({ description: 'Entity for PayloadLog' })\nexport class PayloadLog {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID)\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain)\n domain?: Domain\n\n @RelationId((payloadLog: PayloadLog) => payloadLog.domain)\n domainId?: string\n\n @Column()\n @Field()\n name: string\n\n @Column({\n nullable: true,\n type:\n DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'\n ? 'enum'\n : DATABASE_TYPE == 'oracle'\n ? 'varchar2'\n : DATABASE_TYPE == 'mssql'\n ? 'nvarchar'\n : 'varchar',\n enum:\n DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb' ? PayloadType : undefined,\n length: DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb' ? undefined : 32,\n default: PayloadType.EGESTION\n })\n @Field(type => String)\n type: PayloadType\n\n @Column({ nullable: true })\n @Field({ nullable: true })\n src: string\n\n @Column()\n @Field()\n endpoint: string\n\n @Column()\n @Field()\n request: string\n\n @Column()\n @Field()\n response: string\n\n @CreateDateColumn()\n @Field({ nullable: true })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true })\n updatedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n creator?: User\n\n @RelationId((payloadLog: PayloadLog) => payloadLog.creator)\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n updater?: User\n\n @RelationId((payloadLog: PayloadLog) => payloadLog.updater)\n updaterId?: string\n}\n"]}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { User } from '@things-factory/auth-base';
|
1
|
+
import { User, Role } from '@things-factory/auth-base';
|
2
2
|
import { Domain, ListParam } from '@things-factory/shell';
|
3
3
|
import { ScenarioInstance } from '../scenario-instance/scenario-instance-type';
|
4
4
|
import { Step } from '../step/step-type';
|
@@ -15,4 +15,5 @@ export declare class ScenarioQuery {
|
|
15
15
|
publishTags(scenario: Scenario, context: ResolverContext): Promise<any[]>;
|
16
16
|
state(scenario: Scenario, context: ResolverContext): Promise<string>;
|
17
17
|
instances(scenario: Scenario, context: ResolverContext): Promise<ScenarioInstance[]>;
|
18
|
+
role(scenario: Scenario): Promise<Role>;
|
18
19
|
}
|
@@ -70,6 +70,9 @@ let ScenarioQuery = class ScenarioQuery {
|
|
70
70
|
const { domain } = context.state;
|
71
71
|
return engine_1.ScenarioEngine.getScenarioInstances(domain, scenario.name);
|
72
72
|
}
|
73
|
+
async role(scenario) {
|
74
|
+
return scenario.roleId && (await (0, shell_1.getRepository)(auth_base_1.Role).findOneBy({ id: scenario.roleId }));
|
75
|
+
}
|
73
76
|
};
|
74
77
|
exports.ScenarioQuery = ScenarioQuery;
|
75
78
|
tslib_1.__decorate([
|
@@ -151,6 +154,13 @@ tslib_1.__decorate([
|
|
151
154
|
tslib_1.__metadata("design:paramtypes", [scenario_1.Scenario, Object]),
|
152
155
|
tslib_1.__metadata("design:returntype", Promise)
|
153
156
|
], ScenarioQuery.prototype, "instances", null);
|
157
|
+
tslib_1.__decorate([
|
158
|
+
(0, type_graphql_1.FieldResolver)(type => auth_base_1.Role),
|
159
|
+
tslib_1.__param(0, (0, type_graphql_1.Root)()),
|
160
|
+
tslib_1.__metadata("design:type", Function),
|
161
|
+
tslib_1.__metadata("design:paramtypes", [scenario_1.Scenario]),
|
162
|
+
tslib_1.__metadata("design:returntype", Promise)
|
163
|
+
], ScenarioQuery.prototype, "role", null);
|
154
164
|
exports.ScenarioQuery = ScenarioQuery = tslib_1.__decorate([
|
155
165
|
(0, type_graphql_1.Resolver)(scenario_1.Scenario)
|
156
166
|
], ScenarioQuery);
|