@ivfuture/ecomm-orchestration
Advanced tools
Comparing version 1.1.0 to 1.1.1-cibo.0
export * from "./joiner"; | ||
export * from "./transaction"; | ||
export * from "./workflow"; |
@@ -18,4 +18,2 @@ "use strict"; | ||
__exportStar(require("./joiner"), exports); | ||
__exportStar(require("./transaction"), exports); | ||
__exportStar(require("./workflow"), exports); | ||
//# sourceMappingURL=index.js.map |
import { RemoteJoinerQuery } from "@ivfuture/ecomm-types"; | ||
declare class GraphQLParser { | ||
private variables; | ||
private variables?; | ||
private ast; | ||
constructor(input: string, variables?: Record<string, unknown>); | ||
constructor(input: string, variables?: { | ||
[key: string]: unknown; | ||
} | undefined); | ||
private parseValueNode; | ||
private parseArguments; | ||
private parseDirectives; | ||
private createDirectivesMap; | ||
private extractEntities; | ||
@@ -11,0 +11,0 @@ parseQuery(): RemoteJoinerQuery; |
"use strict"; | ||
var __values = (this && this.__values) || function(o) { | ||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; | ||
if (m) return m.call(o); | ||
if (o && typeof o.length === "number") return { | ||
next: function () { | ||
if (o && i >= o.length) o = void 0; | ||
return { value: o && o[i++], done: !o }; | ||
} | ||
}; | ||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { | ||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { | ||
if (ar || !(i in from)) { | ||
if (!ar) ar = Array.prototype.slice.call(from, 0, i); | ||
ar[i] = from[i]; | ||
} | ||
} | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const graphql_1 = require("graphql"); | ||
class GraphQLParser { | ||
constructor(input, variables = {}) { | ||
var graphql_1 = require("graphql"); | ||
var GraphQLParser = /** @class */ (function () { | ||
function GraphQLParser(input, variables) { | ||
this.variables = variables; | ||
this.ast = (0, graphql_1.parse)(input); | ||
this.variables = variables; | ||
this.variables = variables || {}; | ||
} | ||
parseValueNode(valueNode) { | ||
GraphQLParser.prototype.parseValueNode = function (valueNode) { | ||
var e_1, _a; | ||
var _this = this; | ||
switch (valueNode.kind) { | ||
case graphql_1.Kind.VARIABLE: | ||
const variableName = valueNode.name.value; | ||
var variableName = valueNode.name.value; | ||
return this.variables ? this.variables[variableName] : undefined; | ||
@@ -27,8 +65,18 @@ case graphql_1.Kind.INT: | ||
case graphql_1.Kind.LIST: | ||
return valueNode.values.map((v) => this.parseValueNode(v)); | ||
return valueNode.values.map(function (v) { return _this.parseValueNode(v); }); | ||
case graphql_1.Kind.OBJECT: | ||
let obj = {}; | ||
for (const field of valueNode.fields) { | ||
obj[field.name.value] = this.parseValueNode(field.value); | ||
var obj = {}; | ||
try { | ||
for (var _b = __values(valueNode.fields), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
var field = _c.value; | ||
obj[field.name.value] = this.parseValueNode(field.value); | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
return obj; | ||
@@ -38,9 +86,10 @@ default: | ||
} | ||
} | ||
parseArguments(args) { | ||
}; | ||
GraphQLParser.prototype.parseArguments = function (args) { | ||
var _this = this; | ||
if (!args.length) { | ||
return; | ||
} | ||
return args.map((arg) => { | ||
const value = this.parseValueNode(arg.value); | ||
return args.map(function (arg) { | ||
var value = _this.parseValueNode(arg.value); | ||
return { | ||
@@ -51,54 +100,36 @@ name: arg.name.value, | ||
}); | ||
} | ||
parseDirectives(directives) { | ||
return directives.map((directive) => ({ | ||
name: directive.name.value, | ||
args: this.parseArguments(directive.arguments || []), | ||
})); | ||
} | ||
createDirectivesMap(selectionSet) { | ||
const directivesMap = {}; | ||
let hasDirectives = false; | ||
selectionSet.selections.forEach((field) => { | ||
const fieldName = field.name.value; | ||
const fieldDirectives = this.parseDirectives(field.directives || []); | ||
if (fieldDirectives.length > 0) { | ||
hasDirectives = true; | ||
directivesMap[fieldName] = fieldDirectives; | ||
} | ||
}); | ||
return hasDirectives ? directivesMap : undefined; | ||
} | ||
extractEntities(node, parentName = "", mainService = "") { | ||
const entities = []; | ||
node.selections.forEach((selection) => { | ||
}; | ||
GraphQLParser.prototype.extractEntities = function (node, parentName, mainService) { | ||
var _this = this; | ||
if (parentName === void 0) { parentName = ""; } | ||
if (mainService === void 0) { mainService = ""; } | ||
var entities = []; | ||
node.selections.forEach(function (selection) { | ||
if (selection.kind === "Field") { | ||
const fieldNode = selection; | ||
if (!fieldNode.selectionSet) { | ||
return; | ||
var fieldNode = selection; | ||
if (fieldNode.selectionSet) { | ||
var entityName = parentName | ||
? "".concat(parentName, ".").concat(fieldNode.name.value) | ||
: fieldNode.name.value; | ||
var nestedEntity = { | ||
property: entityName.replace("".concat(mainService, "."), ""), | ||
fields: fieldNode.selectionSet.selections.map(function (field) { return field.name.value; }), | ||
args: _this.parseArguments(fieldNode.arguments), | ||
}; | ||
entities.push(nestedEntity); | ||
entities.push.apply(entities, __spreadArray([], __read(_this.extractEntities(fieldNode.selectionSet, entityName, mainService)), false)); | ||
} | ||
const propName = fieldNode.name.value; | ||
const entityName = parentName ? `${parentName}.${propName}` : propName; | ||
const nestedEntity = { | ||
property: entityName.replace(`${mainService}.`, ""), | ||
fields: fieldNode.selectionSet.selections.map((field) => field.name.value), | ||
args: this.parseArguments(fieldNode.arguments || []), | ||
directives: this.createDirectivesMap(fieldNode.selectionSet), | ||
}; | ||
entities.push(nestedEntity); | ||
entities.push(...this.extractEntities(fieldNode.selectionSet, entityName, mainService)); | ||
} | ||
}); | ||
return entities; | ||
} | ||
parseQuery() { | ||
const queryDefinition = this.ast.definitions.find((definition) => definition.kind === "OperationDefinition"); | ||
}; | ||
GraphQLParser.prototype.parseQuery = function () { | ||
var queryDefinition = this.ast.definitions.find(function (definition) { return definition.kind === "OperationDefinition"; }); | ||
if (!queryDefinition) { | ||
throw new Error("No query found"); | ||
} | ||
const rootFieldNode = queryDefinition.selectionSet | ||
var rootFieldNode = queryDefinition.selectionSet | ||
.selections[0]; | ||
const propName = rootFieldNode.name.value; | ||
const remoteJoinConfig = { | ||
alias: propName, | ||
var remoteJoinConfig = { | ||
service: rootFieldNode.name.value, | ||
fields: [], | ||
@@ -111,10 +142,10 @@ expands: [], | ||
if (rootFieldNode.selectionSet) { | ||
remoteJoinConfig.fields = rootFieldNode.selectionSet.selections.map((field) => field.name.value); | ||
remoteJoinConfig.directives = this.createDirectivesMap(rootFieldNode.selectionSet); | ||
remoteJoinConfig.expands = this.extractEntities(rootFieldNode.selectionSet, propName, propName); | ||
remoteJoinConfig.fields = rootFieldNode.selectionSet.selections.map(function (field) { return field.name.value; }); | ||
remoteJoinConfig.expands = this.extractEntities(rootFieldNode.selectionSet, rootFieldNode.name.value, rootFieldNode.name.value); | ||
} | ||
return remoteJoinConfig; | ||
} | ||
} | ||
}; | ||
return GraphQLParser; | ||
}()); | ||
exports.default = GraphQLParser; | ||
//# sourceMappingURL=graphql-ast.js.map |
@@ -1,2 +0,1 @@ | ||
export * from "./helpers"; | ||
export * from "./remote-joiner"; |
@@ -17,4 +17,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
__exportStar(require("./helpers"), exports); | ||
__exportStar(require("./remote-joiner"), exports); | ||
//# sourceMappingURL=index.js.map |
@@ -1,24 +0,19 @@ | ||
import { ModuleJoinerConfig, RemoteExpandProperty, RemoteJoinerQuery } from "@ivfuture/ecomm-types"; | ||
export type RemoteFetchDataCallback = (expand: RemoteExpandProperty, keyField: string, ids?: (unknown | unknown[])[], relationship?: any) => Promise<{ | ||
data: unknown[] | { | ||
[path: string]: unknown; | ||
}; | ||
path?: string; | ||
}>; | ||
import { JoinerServiceConfig, RemoteExpandProperty, RemoteJoinerQuery } from "@ivfuture/ecomm-types"; | ||
export declare class RemoteJoiner { | ||
private remoteFetchData; | ||
private serviceConfigs; | ||
private remoteFetchData; | ||
private serviceConfigCache; | ||
private implodeMapping; | ||
private static filterFields; | ||
private static getNestedItems; | ||
private static createRelatedDataMap; | ||
static parseQuery(graphqlQuery: string, variables?: Record<string, unknown>): RemoteJoinerQuery; | ||
constructor(serviceConfigs: ModuleJoinerConfig[], remoteFetchData: RemoteFetchDataCallback); | ||
setFetchDataCallback(remoteFetchData: RemoteFetchDataCallback): void; | ||
static parseQuery(graphqlQuery: string, variables?: any): RemoteJoinerQuery; | ||
constructor(serviceConfigs: JoinerServiceConfig[], remoteFetchData: (expand: RemoteExpandProperty, pkField: string, ids?: (unknown | unknown[])[], relationship?: any) => Promise<{ | ||
data: unknown[] | { | ||
[path: string]: unknown[]; | ||
}; | ||
path?: string; | ||
}>); | ||
private buildReferences; | ||
private getServiceConfig; | ||
private cacheServiceConfig; | ||
private findServiceConfig; | ||
private fetchData; | ||
private handleFieldAliases; | ||
private handleExpands; | ||
@@ -25,0 +20,0 @@ private expandProperty; |
"use strict"; | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
var __values = (this && this.__values) || function(o) { | ||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; | ||
if (m) return m.call(o); | ||
if (o && typeof o.length === "number") return { | ||
next: function () { | ||
if (o && i >= o.length) o = void 0; | ||
return { value: o && o[i++], done: !o }; | ||
} | ||
}; | ||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { | ||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { | ||
if (ar || !(i in from)) { | ||
if (!ar) ar = Array.prototype.slice.call(from, 0, i); | ||
ar[i] = from[i]; | ||
} | ||
} | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -7,43 +90,49 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
exports.RemoteJoiner = void 0; | ||
const ecomm_utils_1 = require("@ivfuture/ecomm-utils"); | ||
const graphql_ast_1 = __importDefault(require("./graphql-ast")); | ||
const BASE_PATH = "_root"; | ||
class RemoteJoiner { | ||
static filterFields(data, fields, expands) { | ||
if (!fields || !data) { | ||
var ecomm_utils_1 = require("@ivfuture/ecomm-utils"); | ||
var graphql_ast_1 = __importDefault(require("./graphql-ast")); | ||
var BASE_PATH = "_root"; | ||
var RemoteJoiner = /** @class */ (function () { | ||
function RemoteJoiner(serviceConfigs, remoteFetchData) { | ||
this.remoteFetchData = remoteFetchData; | ||
this.serviceConfigCache = new Map(); | ||
this.serviceConfigs = this.buildReferences(serviceConfigs); | ||
} | ||
RemoteJoiner.filterFields = function (data, fields, expands) { | ||
if (!fields) { | ||
return data; | ||
} | ||
const filteredData = fields.reduce((acc, field) => { | ||
const fieldValue = data?.[field]; | ||
if ((0, ecomm_utils_1.isDefined)(fieldValue)) { | ||
acc[field] = data?.[field]; | ||
} | ||
var filteredData = fields.reduce(function (acc, field) { | ||
acc[field] = data === null || data === void 0 ? void 0 : data[field]; | ||
return acc; | ||
}, {}); | ||
if (expands) { | ||
for (const key in expands) { | ||
const expand = expands[key]; | ||
var _loop_1 = function (key) { | ||
var expand = expands[key]; | ||
if (expand) { | ||
if (Array.isArray(data[key])) { | ||
filteredData[key] = data[key].map((item) => RemoteJoiner.filterFields(item, expand.fields, expand.expands)); | ||
filteredData[key] = data[key].map(function (item) { | ||
return RemoteJoiner.filterFields(item, expand.fields, expand.expands); | ||
}); | ||
} | ||
else { | ||
const filteredFields = RemoteJoiner.filterFields(data[key], expand.fields, expand.expands); | ||
if ((0, ecomm_utils_1.isDefined)(filteredFields)) { | ||
filteredData[key] = RemoteJoiner.filterFields(data[key], expand.fields, expand.expands); | ||
} | ||
filteredData[key] = RemoteJoiner.filterFields(data[key], expand.fields, expand.expands); | ||
} | ||
} | ||
}; | ||
for (var key in expands) { | ||
_loop_1(key); | ||
} | ||
} | ||
return (Object.keys(filteredData).length && filteredData) || undefined; | ||
} | ||
static getNestedItems(items, property) { | ||
return items.flatMap((item) => item?.[property]); | ||
} | ||
static createRelatedDataMap(relatedDataArray, joinFields) { | ||
return relatedDataArray.reduce((acc, data) => { | ||
const joinValues = joinFields.map((field) => data[field]); | ||
const key = joinValues.length === 1 ? joinValues[0] : joinValues.join(","); | ||
let isArray = Array.isArray(acc[key]); | ||
return filteredData; | ||
}; | ||
RemoteJoiner.getNestedItems = function (items, property) { | ||
return items | ||
.flatMap(function (item) { return item[property]; }) | ||
.filter(function (item) { return item !== undefined; }); | ||
}; | ||
RemoteJoiner.createRelatedDataMap = function (relatedDataArray, joinFields) { | ||
return relatedDataArray.reduce(function (acc, data) { | ||
var joinValues = joinFields.map(function (field) { return data[field]; }); | ||
var key = joinValues.length === 1 ? joinValues[0] : joinValues.join(","); | ||
var isArray = Array.isArray(acc[key]); | ||
if ((0, ecomm_utils_1.isDefined)(acc[key]) && !isArray) { | ||
@@ -61,477 +150,476 @@ acc[key] = [acc[key]]; | ||
}, {}); | ||
} | ||
static parseQuery(graphqlQuery, variables) { | ||
const parser = new graphql_ast_1.default(graphqlQuery, variables); | ||
}; | ||
RemoteJoiner.parseQuery = function (graphqlQuery, variables) { | ||
var parser = new graphql_ast_1.default(graphqlQuery, variables); | ||
return parser.parseQuery(); | ||
} | ||
constructor(serviceConfigs, remoteFetchData) { | ||
this.serviceConfigs = serviceConfigs; | ||
this.remoteFetchData = remoteFetchData; | ||
this.serviceConfigCache = new Map(); | ||
this.implodeMapping = []; | ||
this.serviceConfigs = this.buildReferences(serviceConfigs); | ||
} | ||
setFetchDataCallback(remoteFetchData) { | ||
this.remoteFetchData = remoteFetchData; | ||
} | ||
buildReferences(serviceConfigs) { | ||
const expandedRelationships = new Map(); | ||
for (const service of serviceConfigs) { | ||
if (this.serviceConfigCache.has(service.serviceName)) { | ||
throw new Error(`Service "${service.serviceName}" is already defined.`); | ||
} | ||
service.fieldAlias ?? (service.fieldAlias = {}); | ||
service.relationships ?? (service.relationships = []); | ||
service.extends ?? (service.extends = []); | ||
// add aliases | ||
const isReadOnlyDefinition = service.serviceName === undefined || service.isReadOnlyLink; | ||
if (!isReadOnlyDefinition) { | ||
if (!service.alias) { | ||
service.alias = [{ name: service.serviceName.toLowerCase() }]; | ||
}; | ||
RemoteJoiner.prototype.buildReferences = function (serviceConfigs) { | ||
var e_1, _a, e_2, _b, e_3, _c; | ||
var _d, _e; | ||
var expandedRelationships = new Map(); | ||
try { | ||
for (var serviceConfigs_1 = __values(serviceConfigs), serviceConfigs_1_1 = serviceConfigs_1.next(); !serviceConfigs_1_1.done; serviceConfigs_1_1 = serviceConfigs_1.next()) { | ||
var service = serviceConfigs_1_1.value; | ||
// self-reference | ||
var propName = service.serviceName.toLowerCase(); | ||
if (!service.relationships) { | ||
service.relationships = []; | ||
} | ||
else if (!Array.isArray(service.alias)) { | ||
service.alias = [service.alias]; | ||
(_d = service.relationships) === null || _d === void 0 ? void 0 : _d.push({ | ||
alias: propName, | ||
foreignKey: propName + "_id", | ||
primaryKey: "id", | ||
serviceName: service.serviceName, | ||
}); | ||
this.serviceConfigCache.set(service.serviceName, service); | ||
if (!service.extends) { | ||
continue; | ||
} | ||
// self-reference | ||
for (const alias of service.alias) { | ||
if (this.serviceConfigCache.has(`alias_${alias.name}}`)) { | ||
const defined = this.serviceConfigCache.get(`alias_${alias.name}}`); | ||
throw new Error(`Cannot add alias "${alias.name}" for "${service.serviceName}". It is already defined for Service "${defined?.serviceName}".`); | ||
try { | ||
for (var _f = (e_2 = void 0, __values(service.extends)), _g = _f.next(); !_g.done; _g = _f.next()) { | ||
var extend = _g.value; | ||
if (!expandedRelationships.has(extend.serviceName)) { | ||
expandedRelationships.set(extend.serviceName, []); | ||
} | ||
expandedRelationships.get(extend.serviceName).push(extend.resolve); | ||
} | ||
const args = service.args || alias.args | ||
? { ...service.args, ...alias.args } | ||
: undefined; | ||
service.relationships?.push({ | ||
alias: alias.name, | ||
foreignKey: alias.name + "_id", | ||
primaryKey: "id", | ||
serviceName: service.serviceName, | ||
args, | ||
}); | ||
this.cacheServiceConfig(serviceConfigs, undefined, alias.name); | ||
} | ||
this.cacheServiceConfig(serviceConfigs, service.serviceName); | ||
} | ||
for (const extend of service.extends) { | ||
if (!expandedRelationships.has(extend.serviceName)) { | ||
expandedRelationships.set(extend.serviceName, { | ||
fieldAlias: {}, | ||
relationships: [], | ||
}); | ||
catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
finally { | ||
try { | ||
if (_g && !_g.done && (_b = _f.return)) _b.call(_f); | ||
} | ||
finally { if (e_2) throw e_2.error; } | ||
} | ||
const service_ = expandedRelationships.get(extend.serviceName); | ||
service_.relationships.push(extend.relationship); | ||
Object.assign(service_.fieldAlias ?? {}, extend.fieldAlias); | ||
} | ||
} | ||
for (const [serviceName, { fieldAlias, relationships },] of expandedRelationships) { | ||
if (!this.serviceConfigCache.has(serviceName)) { | ||
// If true, the relationship is an internal service from the medusa core | ||
// If modules are being used ouside of the core, we should not be throwing | ||
// errors when the core services are not found in cache. | ||
// TODO: Remove when there are no more "internal" services | ||
const isInternalServicePresent = relationships.some((rel) => rel.isInternalService === true); | ||
if (isInternalServicePresent) | ||
continue; | ||
throw new Error(`Service "${serviceName}" was not found`); | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (serviceConfigs_1_1 && !serviceConfigs_1_1.done && (_a = serviceConfigs_1.return)) _a.call(serviceConfigs_1); | ||
} | ||
const service_ = this.serviceConfigCache.get(serviceName); | ||
service_.relationships?.push(...relationships); | ||
Object.assign(service_.fieldAlias, fieldAlias ?? {}); | ||
if (Object.keys(service_.fieldAlias).length) { | ||
const conflictAliases = service_.relationships.filter((relationship) => { | ||
return fieldAlias[relationship.alias]; | ||
}); | ||
if (conflictAliases.length) { | ||
throw new Error(`Conflict configuration for service "${serviceName}". The following aliases are already defined as relationships: ${conflictAliases | ||
.map((relationship) => relationship.alias) | ||
.join(", ")}`); | ||
} | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
return serviceConfigs; | ||
} | ||
getServiceConfig(serviceName, serviceAlias) { | ||
if (serviceAlias) { | ||
const name = `alias_${serviceAlias}`; | ||
return this.serviceConfigCache.get(name); | ||
} | ||
return this.serviceConfigCache.get(serviceName); | ||
} | ||
cacheServiceConfig(serviceConfigs, serviceName, serviceAlias) { | ||
if (serviceAlias) { | ||
const name = `alias_${serviceAlias}`; | ||
if (!this.serviceConfigCache.has(name)) { | ||
let aliasConfig; | ||
const config = serviceConfigs.find((conf) => { | ||
const aliases = conf.alias; | ||
const hasArgs = aliases?.find((alias) => alias.name === serviceAlias); | ||
aliasConfig = hasArgs; | ||
return hasArgs; | ||
}); | ||
if (config) { | ||
const serviceConfig = { ...config }; | ||
if (aliasConfig) { | ||
serviceConfig.args = { ...config?.args, ...aliasConfig?.args }; | ||
} | ||
this.serviceConfigCache.set(name, serviceConfig); | ||
try { | ||
for (var expandedRelationships_1 = __values(expandedRelationships), expandedRelationships_1_1 = expandedRelationships_1.next(); !expandedRelationships_1_1.done; expandedRelationships_1_1 = expandedRelationships_1.next()) { | ||
var _h = __read(expandedRelationships_1_1.value, 2), serviceName = _h[0], relationships = _h[1]; | ||
if (!this.serviceConfigCache.has(serviceName)) { | ||
throw new Error("Service ".concat(serviceName, " not found")); | ||
} | ||
var service = this.serviceConfigCache.get(serviceName); | ||
(_e = service.relationships) === null || _e === void 0 ? void 0 : _e.push.apply(_e, __spreadArray([], __read(relationships), false)); | ||
} | ||
return; | ||
} | ||
const config = serviceConfigs.find((config) => config.serviceName === serviceName); | ||
this.serviceConfigCache.set(serviceName, config); | ||
} | ||
async fetchData(expand, pkField, ids, relationship) { | ||
let uniqueIds = Array.isArray(ids) ? ids : ids ? [ids] : undefined; | ||
if (uniqueIds) { | ||
const isCompositeKey = Array.isArray(uniqueIds[0]); | ||
if (isCompositeKey) { | ||
const seen = new Set(); | ||
uniqueIds = uniqueIds.filter((idArray) => { | ||
const key = JSON.stringify(idArray); | ||
const isNew = !seen.has(key); | ||
seen.add(key); | ||
return isNew; | ||
}); | ||
catch (e_3_1) { e_3 = { error: e_3_1 }; } | ||
finally { | ||
try { | ||
if (expandedRelationships_1_1 && !expandedRelationships_1_1.done && (_c = expandedRelationships_1.return)) _c.call(expandedRelationships_1); | ||
} | ||
else { | ||
uniqueIds = Array.from(new Set(uniqueIds.flat())); | ||
} | ||
uniqueIds = uniqueIds.filter((id) => id !== undefined); | ||
finally { if (e_3) throw e_3.error; } | ||
} | ||
if (relationship) { | ||
pkField = relationship.inverse | ||
? relationship.foreignKey.split(".").pop() | ||
: relationship.primaryKey; | ||
return serviceConfigs; | ||
}; | ||
RemoteJoiner.prototype.findServiceConfig = function (serviceName) { | ||
if (!this.serviceConfigCache.has(serviceName)) { | ||
var config = this.serviceConfigs.find(function (config) { return config.serviceName === serviceName; }); | ||
this.serviceConfigCache.set(serviceName, config); | ||
} | ||
const response = await this.remoteFetchData(expand, pkField, uniqueIds, relationship); | ||
const isObj = (0, ecomm_utils_1.isDefined)(response.path); | ||
const resData = isObj ? response.data[response.path] : response.data; | ||
const filteredDataArray = resData.map((data) => RemoteJoiner.filterFields(data, expand.fields, expand.expands)); | ||
if (isObj) { | ||
response.data[response.path] = filteredDataArray; | ||
} | ||
else { | ||
response.data = filteredDataArray; | ||
} | ||
return response; | ||
} | ||
handleFieldAliases(items, parsedExpands) { | ||
const getChildren = (item, prop) => { | ||
if (Array.isArray(item)) { | ||
return item.flatMap((currentItem) => currentItem[prop]); | ||
} | ||
else { | ||
return item[prop]; | ||
} | ||
}; | ||
const removeChildren = (item, prop) => { | ||
if (Array.isArray(item)) { | ||
item.forEach((currentItem) => delete currentItem[prop]); | ||
} | ||
else { | ||
delete item[prop]; | ||
} | ||
}; | ||
const cleanup = []; | ||
for (const alias of this.implodeMapping) { | ||
const propPath = alias.path; | ||
let itemsLocation = items; | ||
for (const locationProp of alias.location) { | ||
propPath.shift(); | ||
itemsLocation = RemoteJoiner.getNestedItems(itemsLocation, locationProp); | ||
} | ||
itemsLocation.forEach((locationItem) => { | ||
if (!locationItem) { | ||
return; | ||
return this.serviceConfigCache.get(serviceName); | ||
}; | ||
RemoteJoiner.prototype.fetchData = function (expand, pkField, ids, relationship) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var uniqueIds, isCompositeKey, seen_1, response, isObj, resData, filteredDataArray; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
uniqueIds = Array.isArray(ids) ? ids : ids ? [ids] : undefined; | ||
if (uniqueIds) { | ||
isCompositeKey = Array.isArray(uniqueIds[0]); | ||
if (isCompositeKey) { | ||
seen_1 = new Set(); | ||
uniqueIds = uniqueIds.filter(function (idArray) { | ||
var key = JSON.stringify(idArray); | ||
var isNew = !seen_1.has(key); | ||
seen_1.add(key); | ||
return isNew; | ||
}); | ||
} | ||
else { | ||
uniqueIds = Array.from(new Set(uniqueIds.flat())); | ||
} | ||
} | ||
if (relationship) { | ||
pkField = relationship.inverse | ||
? relationship.foreignKey.split(".").pop() | ||
: relationship.primaryKey; | ||
} | ||
return [4 /*yield*/, this.remoteFetchData(expand, pkField, uniqueIds, relationship)]; | ||
case 1: | ||
response = _a.sent(); | ||
isObj = (0, ecomm_utils_1.isDefined)(response.path); | ||
resData = isObj ? response.data[response.path] : response.data; | ||
filteredDataArray = resData.map(function (data) { | ||
return RemoteJoiner.filterFields(data, expand.fields, expand.expands); | ||
}); | ||
if (isObj) { | ||
response.data[response.path] = filteredDataArray; | ||
} | ||
else { | ||
response.data = filteredDataArray; | ||
} | ||
return [2 /*return*/, response]; | ||
} | ||
let currentItems = locationItem; | ||
let parentRemoveItems = null; | ||
const curPath = [BASE_PATH].concat(alias.location); | ||
for (const prop of propPath) { | ||
if (currentItems === undefined) { | ||
break; | ||
} | ||
curPath.push(prop); | ||
const config = parsedExpands.get(curPath.join(".")); | ||
if (config?.isAliasMapping && parentRemoveItems === null) { | ||
parentRemoveItems = [currentItems, prop]; | ||
} | ||
currentItems = getChildren(currentItems, prop); | ||
}); | ||
}); | ||
}; | ||
RemoteJoiner.prototype.handleExpands = function (items, query, parsedExpands) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function () { | ||
var stack, _b, currentItems, currentQuery, currentParsedExpands, basePath, resolvedPaths, _loop_2, this_1, _c, _d, _e, expandedPath, expand, e_4_1; | ||
var e_4, _f; | ||
return __generator(this, function (_g) { | ||
switch (_g.label) { | ||
case 0: | ||
if (!parsedExpands) { | ||
return [2 /*return*/]; | ||
} | ||
stack = [[items, query, parsedExpands, "", new Set()]]; | ||
_g.label = 1; | ||
case 1: | ||
if (!(stack.length > 0)) return [3 /*break*/, 10]; | ||
_b = __read(stack.pop(), 5), currentItems = _b[0], currentQuery = _b[1], currentParsedExpands = _b[2], basePath = _b[3], resolvedPaths = _b[4]; | ||
_loop_2 = function (expandedPath, expand) { | ||
var isImmediateChildPath, property, parentServiceConfig, relationship, nestedItems, nextProp; | ||
return __generator(this, function (_h) { | ||
switch (_h.label) { | ||
case 0: | ||
isImmediateChildPath = expandedPath.startsWith(basePath) && | ||
expandedPath.split(".").length === basePath.split(".").length + 1; | ||
if (!isImmediateChildPath || resolvedPaths.has(expandedPath)) { | ||
return [2 /*return*/, "continue"]; | ||
} | ||
resolvedPaths.add(expandedPath); | ||
property = expand.property || ""; | ||
parentServiceConfig = this_1.findServiceConfig(currentQuery.service); | ||
return [4 /*yield*/, this_1.expandProperty(currentItems, parentServiceConfig, expand)]; | ||
case 1: | ||
_h.sent(); | ||
relationship = (_a = parentServiceConfig === null || parentServiceConfig === void 0 ? void 0 : parentServiceConfig.relationships) === null || _a === void 0 ? void 0 : _a.find(function (relation) { return relation.alias === property; }); | ||
nestedItems = RemoteJoiner.getNestedItems(currentItems, property); | ||
if (nestedItems.length > 0) { | ||
nextProp = relationship | ||
? __assign(__assign({}, currentQuery), { service: relationship.serviceName }) : currentQuery; | ||
stack.push([ | ||
nestedItems, | ||
nextProp, | ||
currentParsedExpands, | ||
expandedPath, | ||
new Set(), | ||
]); | ||
} | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}; | ||
this_1 = this; | ||
_g.label = 2; | ||
case 2: | ||
_g.trys.push([2, 7, 8, 9]); | ||
_c = (e_4 = void 0, __values(currentParsedExpands.entries())), _d = _c.next(); | ||
_g.label = 3; | ||
case 3: | ||
if (!!_d.done) return [3 /*break*/, 6]; | ||
_e = __read(_d.value, 2), expandedPath = _e[0], expand = _e[1]; | ||
return [5 /*yield**/, _loop_2(expandedPath, expand)]; | ||
case 4: | ||
_g.sent(); | ||
_g.label = 5; | ||
case 5: | ||
_d = _c.next(); | ||
return [3 /*break*/, 3]; | ||
case 6: return [3 /*break*/, 9]; | ||
case 7: | ||
e_4_1 = _g.sent(); | ||
e_4 = { error: e_4_1 }; | ||
return [3 /*break*/, 9]; | ||
case 8: | ||
try { | ||
if (_d && !_d.done && (_f = _c.return)) _f.call(_c); | ||
} | ||
finally { if (e_4) throw e_4.error; } | ||
return [7 /*endfinally*/]; | ||
case 9: return [3 /*break*/, 1]; | ||
case 10: return [2 /*return*/]; | ||
} | ||
if (Array.isArray(currentItems)) { | ||
if (currentItems.length < 2) { | ||
locationItem[alias.property] = currentItems.shift(); | ||
} | ||
else { | ||
locationItem[alias.property] = currentItems; | ||
} | ||
}); | ||
}); | ||
}; | ||
RemoteJoiner.prototype.expandProperty = function (items, parentServiceConfig, expand) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function () { | ||
var relationship; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
if (!expand) { | ||
return [2 /*return*/]; | ||
} | ||
relationship = (_a = parentServiceConfig === null || parentServiceConfig === void 0 ? void 0 : parentServiceConfig.relationships) === null || _a === void 0 ? void 0 : _a.find(function (relation) { return relation.alias === expand.property; }); | ||
if (!relationship) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, this.expandRelationshipProperty(items, expand, relationship)]; | ||
case 1: | ||
_b.sent(); | ||
_b.label = 2; | ||
case 2: return [2 /*return*/]; | ||
} | ||
else { | ||
locationItem[alias.property] = currentItems; | ||
} | ||
if (parentRemoveItems !== null) { | ||
cleanup.push(parentRemoveItems); | ||
} | ||
}); | ||
} | ||
for (const parentRemoveItems of cleanup) { | ||
const [remItems, path] = parentRemoveItems; | ||
removeChildren(remItems, path); | ||
} | ||
} | ||
async handleExpands(items, parsedExpands) { | ||
if (!parsedExpands) { | ||
return; | ||
} | ||
for (const [expandedPath, expand] of parsedExpands.entries()) { | ||
if (expandedPath === BASE_PATH) { | ||
continue; | ||
} | ||
let nestedItems = items; | ||
const expandedPathLevels = expandedPath.split("."); | ||
for (let idx = 1; idx < expandedPathLevels.length - 1; idx++) { | ||
nestedItems = RemoteJoiner.getNestedItems(nestedItems, expandedPathLevels[idx]); | ||
} | ||
if (nestedItems.length > 0) { | ||
await this.expandProperty(nestedItems, expand.parentConfig, expand); | ||
} | ||
} | ||
this.handleFieldAliases(items, parsedExpands); | ||
} | ||
async expandProperty(items, parentServiceConfig, expand) { | ||
if (!expand) { | ||
return; | ||
} | ||
const relationship = parentServiceConfig?.relationships?.find((relation) => relation.alias === expand.property); | ||
if (relationship) { | ||
await this.expandRelationshipProperty(items, expand, relationship); | ||
} | ||
} | ||
async expandRelationshipProperty(items, expand, relationship) { | ||
const field = relationship.inverse | ||
? relationship.primaryKey | ||
: relationship.foreignKey.split(".").pop(); | ||
const fieldsArray = field.split(","); | ||
const idsToFetch = []; | ||
items.forEach((item) => { | ||
const values = fieldsArray.map((field) => item?.[field]); | ||
if (values.length === fieldsArray.length && !item?.[relationship.alias]) { | ||
if (fieldsArray.length === 1) { | ||
if (!idsToFetch.includes(values[0])) { | ||
idsToFetch.push(values[0]); | ||
} | ||
} | ||
else { | ||
// composite key | ||
const valuesString = values.join(","); | ||
if (!idsToFetch.some((id) => id.join(",") === valuesString)) { | ||
idsToFetch.push(values); | ||
} | ||
} | ||
} | ||
}); | ||
if (idsToFetch.length === 0) { | ||
return; | ||
} | ||
const relatedDataArray = await this.fetchData(expand, field, idsToFetch, relationship); | ||
const joinFields = relationship.inverse | ||
? relationship.foreignKey.split(",") | ||
: relationship.primaryKey.split(","); | ||
const relData = relatedDataArray.path | ||
? relatedDataArray.data[relatedDataArray.path] | ||
: relatedDataArray.data; | ||
const relatedDataMap = RemoteJoiner.createRelatedDataMap(relData, joinFields); | ||
items.forEach((item) => { | ||
if (!item || item[relationship.alias]) { | ||
return; | ||
} | ||
const itemKey = fieldsArray.map((field) => item[field]).join(","); | ||
if (Array.isArray(item[field])) { | ||
item[relationship.alias] = item[field].map((id) => { | ||
if (relationship.isList && !Array.isArray(relatedDataMap[id])) { | ||
relatedDataMap[id] = | ||
relatedDataMap[id] !== undefined ? [relatedDataMap[id]] : []; | ||
} | ||
return relatedDataMap[id]; | ||
}); | ||
} | ||
else { | ||
if (relationship.isList && !Array.isArray(relatedDataMap[itemKey])) { | ||
relatedDataMap[itemKey] = | ||
relatedDataMap[itemKey] !== undefined | ||
? [relatedDataMap[itemKey]] | ||
: []; | ||
}; | ||
RemoteJoiner.prototype.expandRelationshipProperty = function (items, expand, relationship) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var field, fieldsArray, idsToFetch, relatedDataArray, joinFields, relData, relatedDataMap; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
field = relationship.inverse | ||
? relationship.primaryKey | ||
: relationship.foreignKey.split(".").pop(); | ||
fieldsArray = field.split(","); | ||
idsToFetch = []; | ||
items.forEach(function (item) { | ||
var values = fieldsArray | ||
.map(function (field) { return item[field]; }) | ||
.filter(function (value) { return value !== undefined; }); | ||
if (values.length === fieldsArray.length && !item[relationship.alias]) { | ||
if (fieldsArray.length === 1) { | ||
if (!idsToFetch.includes(values[0])) { | ||
idsToFetch.push(values[0]); | ||
} | ||
} | ||
else { | ||
// composite key | ||
var valuesString_1 = values.join(","); | ||
if (!idsToFetch.some(function (id) { return id.join(",") === valuesString_1; })) { | ||
idsToFetch.push(values); | ||
} | ||
} | ||
} | ||
}); | ||
if (idsToFetch.length === 0) { | ||
return [2 /*return*/]; | ||
} | ||
return [4 /*yield*/, this.fetchData(expand, field, idsToFetch, relationship)]; | ||
case 1: | ||
relatedDataArray = _a.sent(); | ||
joinFields = relationship.inverse | ||
? relationship.foreignKey.split(",") | ||
: relationship.primaryKey.split(","); | ||
relData = relatedDataArray.path | ||
? relatedDataArray.data[relatedDataArray.path] | ||
: relatedDataArray.data; | ||
relatedDataMap = RemoteJoiner.createRelatedDataMap(relData, joinFields); | ||
items.forEach(function (item) { | ||
if (!item[relationship.alias]) { | ||
var itemKey = fieldsArray.map(function (field) { return item[field]; }).join(","); | ||
if (Array.isArray(item[field])) { | ||
item[relationship.alias] = item[field] | ||
.map(function (id) { return relatedDataMap[id]; }) | ||
.filter(function (relatedItem) { return relatedItem !== undefined; }); | ||
} | ||
else { | ||
item[relationship.alias] = relatedDataMap[itemKey]; | ||
} | ||
} | ||
}); | ||
return [2 /*return*/]; | ||
} | ||
item[relationship.alias] = relatedDataMap[itemKey]; | ||
} | ||
}); | ||
}); | ||
} | ||
parseExpands(initialService, query, serviceConfig, expands) { | ||
const parsedExpands = this.parseProperties(initialService, query, serviceConfig, expands); | ||
const groupedExpands = this.groupExpands(parsedExpands); | ||
}; | ||
RemoteJoiner.prototype.parseExpands = function (initialService, query, serviceConfig, expands) { | ||
var parsedExpands = this.parseProperties(initialService, query, serviceConfig, expands); | ||
var groupedExpands = this.groupExpands(parsedExpands); | ||
return groupedExpands; | ||
} | ||
parseProperties(initialService, query, serviceConfig, expands) { | ||
const parsedExpands = new Map(); | ||
}; | ||
RemoteJoiner.prototype.parseProperties = function (initialService, query, serviceConfig, expands) { | ||
var e_5, _a, e_6, _b; | ||
var parsedExpands = new Map(); | ||
parsedExpands.set(BASE_PATH, initialService); | ||
let forwardArgumentsOnPath = []; | ||
for (const expand of expands || []) { | ||
const properties = expand.property.split("."); | ||
let currentServiceConfig = serviceConfig; | ||
const currentPath = []; | ||
for (const prop of properties) { | ||
const fieldAlias = currentServiceConfig.fieldAlias ?? {}; | ||
if (fieldAlias[prop]) { | ||
const alias = fieldAlias[prop]; | ||
const path = (0, ecomm_utils_1.isString)(alias) ? alias : alias.path; | ||
const fullPath = [...new Set(currentPath.concat(path.split(".")))]; | ||
forwardArgumentsOnPath = forwardArgumentsOnPath.concat((alias?.forwardArgumentsOnPath || []).map((forPath) => BASE_PATH + "." + currentPath.concat(forPath).join("."))); | ||
this.implodeMapping.push({ | ||
location: currentPath, | ||
property: prop, | ||
path: fullPath, | ||
}); | ||
const extMapping = expands; | ||
const middlePath = path.split(".").slice(0, -1); | ||
let curMiddlePath = currentPath; | ||
for (const path of middlePath) { | ||
curMiddlePath = curMiddlePath.concat(path); | ||
extMapping.push({ | ||
args: expand.args, | ||
property: curMiddlePath.join("."), | ||
isAliasMapping: true, | ||
try { | ||
for (var _c = __values(expands || []), _d = _c.next(); !_d.done; _d = _c.next()) { | ||
var expand = _d.value; | ||
var properties = expand.property.split("."); | ||
var currentServiceConfig = serviceConfig; | ||
var currentPath = []; | ||
var _loop_3 = function (prop) { | ||
var fullPath = __spreadArray(__spreadArray([BASE_PATH], __read(currentPath), false), [prop], false).join("."); | ||
var relationship = currentServiceConfig.relationships.find(function (relation) { return relation.alias === prop; }); | ||
var fields = fullPath === BASE_PATH + "." + expand.property | ||
? expand.fields | ||
: undefined; | ||
var args = fullPath === BASE_PATH + "." + expand.property | ||
? expand.args | ||
: undefined; | ||
if (relationship) { | ||
var parentExpand = parsedExpands.get(__spreadArray([BASE_PATH], __read(currentPath), false).join(".")) || query; | ||
if (parentExpand) { | ||
if (parentExpand.fields) { | ||
var relField = relationship.inverse | ||
? relationship.primaryKey | ||
: relationship.foreignKey.split(".").pop(); | ||
parentExpand.fields = parentExpand.fields | ||
.concat(relField.split(",")) | ||
.filter(function (field) { return field !== relationship.alias; }); | ||
parentExpand.fields = __spreadArray([], __read(new Set(parentExpand.fields)), false); | ||
} | ||
if (fields) { | ||
var relField = relationship.inverse | ||
? relationship.foreignKey.split(".").pop() | ||
: relationship.primaryKey; | ||
fields = fields.concat(relField.split(",")); | ||
fields = __spreadArray([], __read(new Set(fields)), false); | ||
} | ||
} | ||
currentServiceConfig = this_2.findServiceConfig(relationship.serviceName); | ||
if (!currentServiceConfig) { | ||
throw new Error("Target service not found: ".concat(relationship.serviceName)); | ||
} | ||
} | ||
if (!parsedExpands.has(fullPath)) { | ||
parsedExpands.set(fullPath, { | ||
property: prop, | ||
serviceConfig: currentServiceConfig, | ||
fields: fields, | ||
args: args, | ||
}); | ||
} | ||
extMapping.push({ | ||
...expand, | ||
property: fullPath.join("."), | ||
isAliasMapping: true, | ||
}); | ||
continue; | ||
} | ||
const fullPath = [BASE_PATH, ...currentPath, prop].join("."); | ||
const relationship = currentServiceConfig.relationships?.find((relation) => relation.alias === prop); | ||
let fields = fullPath === BASE_PATH + "." + expand.property | ||
? expand.fields ?? [] | ||
: undefined; | ||
const args = fullPath === BASE_PATH + "." + expand.property | ||
? expand.args | ||
: undefined; | ||
if (relationship) { | ||
const parentExpand = parsedExpands.get([BASE_PATH, ...currentPath].join(".")) || query; | ||
if (parentExpand) { | ||
const relField = relationship.inverse | ||
? relationship.primaryKey | ||
: relationship.foreignKey.split(".").pop(); | ||
parentExpand.fields ?? (parentExpand.fields = []); | ||
parentExpand.fields = parentExpand.fields | ||
.concat(relField.split(",")) | ||
.filter((field) => field !== relationship.alias); | ||
parentExpand.fields = [...new Set(parentExpand.fields)]; | ||
if (fields) { | ||
const relField = relationship.inverse | ||
? relationship.foreignKey.split(".").pop() | ||
: relationship.primaryKey; | ||
fields = fields.concat(relField.split(",")); | ||
} | ||
currentPath.push(prop); | ||
}; | ||
var this_2 = this; | ||
try { | ||
for (var properties_1 = (e_6 = void 0, __values(properties)), properties_1_1 = properties_1.next(); !properties_1_1.done; properties_1_1 = properties_1.next()) { | ||
var prop = properties_1_1.value; | ||
_loop_3(prop); | ||
} | ||
currentServiceConfig = this.getServiceConfig(relationship.serviceName); | ||
if (!currentServiceConfig) { | ||
throw new Error(`Target service not found: ${relationship.serviceName}`); | ||
} | ||
} | ||
const isAliasMapping = expand.isAliasMapping; | ||
if (!parsedExpands.has(fullPath)) { | ||
const parentPath = [BASE_PATH, ...currentPath].join("."); | ||
parsedExpands.set(fullPath, { | ||
property: prop, | ||
serviceConfig: currentServiceConfig, | ||
fields, | ||
args: isAliasMapping | ||
? forwardArgumentsOnPath.includes(fullPath) | ||
? args | ||
: undefined | ||
: args, | ||
isAliasMapping: isAliasMapping, | ||
parent: parentPath, | ||
parentConfig: parsedExpands.get(parentPath).serviceConfig, | ||
}); | ||
} | ||
else { | ||
const exp = parsedExpands.get(fullPath); | ||
if (forwardArgumentsOnPath.includes(fullPath) && args) { | ||
exp.args = (exp.args || []).concat(args); | ||
catch (e_6_1) { e_6 = { error: e_6_1 }; } | ||
finally { | ||
try { | ||
if (properties_1_1 && !properties_1_1.done && (_b = properties_1.return)) _b.call(properties_1); | ||
} | ||
if (fields) { | ||
exp.fields = (exp.fields || []).concat(fields); | ||
} | ||
finally { if (e_6) throw e_6.error; } | ||
} | ||
currentPath.push(prop); | ||
} | ||
} | ||
catch (e_5_1) { e_5 = { error: e_5_1 }; } | ||
finally { | ||
try { | ||
if (_d && !_d.done && (_a = _c.return)) _a.call(_c); | ||
} | ||
finally { if (e_5) throw e_5.error; } | ||
} | ||
return parsedExpands; | ||
} | ||
groupExpands(parsedExpands) { | ||
var _a; | ||
const mergedExpands = new Map(parsedExpands); | ||
const mergedPaths = new Map(); | ||
for (const [path, expand] of mergedExpands.entries()) { | ||
const currentServiceName = expand.serviceConfig.serviceName; | ||
let parentPath = expand.parent; | ||
while (parentPath) { | ||
const parentExpand = mergedExpands.get(parentPath) ?? mergedPaths.get(parentPath); | ||
if (!parentExpand || | ||
parentExpand.serviceConfig.serviceName !== currentServiceName) { | ||
break; | ||
}; | ||
RemoteJoiner.prototype.groupExpands = function (parsedExpands) { | ||
var e_7, _a, e_8, _b; | ||
var sortedParsedExpands = new Map(Array.from(parsedExpands.entries()).sort()); | ||
var mergedExpands = new Map(sortedParsedExpands); | ||
var mergedPaths = new Map(); | ||
var lastServiceName = ""; | ||
try { | ||
for (var _c = __values(sortedParsedExpands.entries()), _d = _c.next(); !_d.done; _d = _c.next()) { | ||
var _e = __read(_d.value, 2), path = _e[0], expand = _e[1]; | ||
var currentServiceName = expand.serviceConfig.serviceName; | ||
var parentPath = path.split(".").slice(0, -1).join("."); | ||
// Check if the parentPath was merged before | ||
while (mergedPaths.has(parentPath)) { | ||
parentPath = mergedPaths.get(parentPath); | ||
} | ||
// Merge the current expand into its parent | ||
const nestedKeys = path.split(".").slice(parentPath.split(".").length); | ||
let targetExpand = parentExpand; | ||
for (const key of nestedKeys) { | ||
targetExpand.expands ?? (targetExpand.expands = {}); | ||
targetExpand = (_a = targetExpand.expands)[key] ?? (_a[key] = {}); | ||
var canMerge = currentServiceName === lastServiceName; | ||
if (mergedExpands.has(parentPath) && canMerge) { | ||
var parentExpand = mergedExpands.get(parentPath); | ||
if (parentExpand.serviceConfig.serviceName === currentServiceName) { | ||
var nestedKeys = path.split(".").slice(parentPath.split(".").length); | ||
var targetExpand = parentExpand; | ||
try { | ||
for (var nestedKeys_1 = (e_8 = void 0, __values(nestedKeys)), nestedKeys_1_1 = nestedKeys_1.next(); !nestedKeys_1_1.done; nestedKeys_1_1 = nestedKeys_1.next()) { | ||
var key = nestedKeys_1_1.value; | ||
if (!targetExpand.expands) { | ||
targetExpand.expands = {}; | ||
} | ||
if (!targetExpand.expands[key]) { | ||
targetExpand.expands[key] = {}; | ||
} | ||
targetExpand = targetExpand.expands[key]; | ||
} | ||
} | ||
catch (e_8_1) { e_8 = { error: e_8_1 }; } | ||
finally { | ||
try { | ||
if (nestedKeys_1_1 && !nestedKeys_1_1.done && (_b = nestedKeys_1.return)) _b.call(nestedKeys_1); | ||
} | ||
finally { if (e_8) throw e_8.error; } | ||
} | ||
targetExpand.fields = expand.fields; | ||
targetExpand.args = expand.args; | ||
mergedPaths.set(path, parentPath); | ||
} | ||
} | ||
targetExpand.fields = [...new Set(expand.fields)]; | ||
targetExpand.args = expand.args; | ||
mergedExpands.delete(path); | ||
mergedPaths.set(path, expand); | ||
parentPath = parentExpand.parent; | ||
else { | ||
lastServiceName = currentServiceName; | ||
} | ||
} | ||
} | ||
return mergedExpands; | ||
} | ||
async query(queryObj) { | ||
const serviceConfig = this.getServiceConfig(queryObj.service, queryObj.alias); | ||
if (!serviceConfig) { | ||
if (queryObj.alias) { | ||
throw new Error(`Service with alias "${queryObj.alias}" was not found.`); | ||
catch (e_7_1) { e_7 = { error: e_7_1 }; } | ||
finally { | ||
try { | ||
if (_d && !_d.done && (_a = _c.return)) _a.call(_c); | ||
} | ||
throw new Error(`Service "${queryObj.service}" was not found.`); | ||
finally { if (e_7) throw e_7.error; } | ||
} | ||
let pkName = serviceConfig.primaryKeys[0]; | ||
const primaryKeyArg = queryObj.args?.find((arg) => { | ||
const inc = serviceConfig.primaryKeys.includes(arg.name); | ||
if (inc) { | ||
pkName = arg.name; | ||
} | ||
return inc; | ||
return mergedExpands; | ||
}; | ||
RemoteJoiner.prototype.query = function (queryObj) { | ||
var _a, _b; | ||
return __awaiter(this, void 0, void 0, function () { | ||
var serviceConfig, pkName, primaryKeyArg, otherArgs, parsedExpands, root, response, data; | ||
return __generator(this, function (_c) { | ||
switch (_c.label) { | ||
case 0: | ||
queryObj.service = (0, ecomm_utils_1.toPascalCase)(queryObj.service); | ||
serviceConfig = this.findServiceConfig(queryObj.service); | ||
if (!serviceConfig) { | ||
throw new Error("Service not found: ".concat(queryObj.service)); | ||
} | ||
pkName = serviceConfig.primaryKeys[0]; | ||
primaryKeyArg = (_a = queryObj.args) === null || _a === void 0 ? void 0 : _a.find(function (arg) { | ||
var inc = serviceConfig.primaryKeys.includes(arg.name); | ||
if (inc) { | ||
pkName = arg.name; | ||
} | ||
return inc; | ||
}); | ||
otherArgs = (_b = queryObj.args) === null || _b === void 0 ? void 0 : _b.filter(function (arg) { return !serviceConfig.primaryKeys.includes(arg.name); }); | ||
parsedExpands = this.parseExpands({ | ||
property: "", | ||
serviceConfig: serviceConfig, | ||
fields: queryObj.fields, | ||
args: otherArgs, | ||
}, queryObj, serviceConfig, queryObj.expands); | ||
root = parsedExpands.get(BASE_PATH); | ||
return [4 /*yield*/, this.fetchData(root, pkName, primaryKeyArg === null || primaryKeyArg === void 0 ? void 0 : primaryKeyArg.value, undefined)]; | ||
case 1: | ||
response = _c.sent(); | ||
data = response.path ? response.data[response.path] : response.data; | ||
return [4 /*yield*/, this.handleExpands(Array.isArray(data) ? data : [data], queryObj, parsedExpands)]; | ||
case 2: | ||
_c.sent(); | ||
return [2 /*return*/, response.data]; | ||
} | ||
}); | ||
}); | ||
const otherArgs = queryObj.args?.filter((arg) => !serviceConfig.primaryKeys.includes(arg.name)); | ||
const parsedExpands = this.parseExpands({ | ||
property: "", | ||
parent: "", | ||
serviceConfig: serviceConfig, | ||
fields: queryObj.fields, | ||
args: otherArgs, | ||
}, queryObj, serviceConfig, queryObj.expands); | ||
const root = parsedExpands.get(BASE_PATH); | ||
const response = await this.fetchData(root, pkName, primaryKeyArg?.value, undefined); | ||
const data = response.path ? response.data[response.path] : response.data; | ||
await this.handleExpands(Array.isArray(data) ? data : [data], parsedExpands); | ||
return response.data; | ||
} | ||
} | ||
}; | ||
return RemoteJoiner; | ||
}()); | ||
exports.RemoteJoiner = RemoteJoiner; | ||
//# sourceMappingURL=remote-joiner.js.map |
{ | ||
"name": "@ivfuture/ecomm-orchestration", | ||
"version": "1.1.0", | ||
"version": "1.1.1-cibo.0", | ||
"description": "Medusa utilities to orchestrate modules", | ||
@@ -20,21 +20,19 @@ "main": "dist/index.js", | ||
"devDependencies": { | ||
"@ivfuture/ecomm-types": "^1.1.0", | ||
"@ivfuture/ecomm-types": "1.1.0-cibo.0", | ||
"cross-env": "^5.2.1", | ||
"jest": "^29.6.3", | ||
"rimraf": "^5.0.1", | ||
"ts-jest": "^29.1.1", | ||
"typescript": "^5.1.6" | ||
"jest": "^25.5.4", | ||
"ts-jest": "^25.5.1", | ||
"typescript": "^4.4.4" | ||
}, | ||
"dependencies": { | ||
"@ivfuture/ecomm-types": "^1.1.0", | ||
"@ivfuture/ecomm-utils": "^1.2.0", | ||
"awilix": "^8.0.0", | ||
"@ivfuture/ecomm-utils": "^1.2.1-cibo.0", | ||
"graphql": "^16.6.0" | ||
}, | ||
"scripts": { | ||
"prepublishOnly": "cross-env NODE_ENV=production tsc --build", | ||
"build": "rimraf dist && tsc --build", | ||
"build:prod": "cross-env NODE_ENV=production yarn run build", | ||
"build": "tsc --build", | ||
"watch": "tsc --build --watch", | ||
"test": "jest --runInBand --bail --forceExit" | ||
} | ||
"test": "jest" | ||
}, | ||
"gitHead": "8173a3d22c59738b3b2702157f2982195680ec6a" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
2
5
62951
14
843
2
- Removed@ivfuture/ecomm-types@^1.1.0
- Removedawilix@^8.0.0
- Removed@ivfuture/ecomm-types@1.56.3(transitive)
- Removed@nodelib/fs.scandir@2.1.5(transitive)
- Removed@nodelib/fs.stat@2.0.5(transitive)
- Removed@nodelib/fs.walk@1.2.8(transitive)
- Removedawilix@8.0.1(transitive)
- Removedbraces@3.0.3(transitive)
- Removedcamel-case@4.1.2(transitive)
- Removedfast-glob@3.3.2(transitive)
- Removedfastq@1.17.1(transitive)
- Removedfill-range@7.1.1(transitive)
- Removedglob-parent@5.1.2(transitive)
- Removedis-extglob@2.1.1(transitive)
- Removedis-glob@4.0.3(transitive)
- Removedis-number@7.0.0(transitive)
- Removedlower-case@2.0.2(transitive)
- Removedmerge2@1.4.1(transitive)
- Removedmicromatch@4.0.8(transitive)
- Removedno-case@3.0.4(transitive)
- Removedpascal-case@3.1.2(transitive)
- Removedpicomatch@2.3.1(transitive)
- Removedqueue-microtask@1.2.3(transitive)
- Removedreusify@1.0.4(transitive)
- Removedrun-parallel@1.2.0(transitive)
- Removedto-regex-range@5.0.1(transitive)
- Removedtslib@2.8.1(transitive)