diff --git a/src/electron/main.ts b/src/electron/main.ts index ad98376..85fbdee 100644 --- a/src/electron/main.ts +++ b/src/electron/main.ts @@ -16,20 +16,26 @@ app.on('ready', async () => { } ipcMain.handle('ping', () => { - const req = new ProdressConnection( - { + const req = new ProdressConnection({ + header: { port: 4788, host: 'localhost', database: 'test', handler: 'Shopify', action: 'artikelSync', }, - [['string', 'HalloWelt']], - [ - ['line1', 'string'], - ['line2', 'string'], - ], - ); + body: { + additionalInformation: [], + arguments: [[['string', 'HalloWelt']]], + }, + response: { + isStatic: true, + responseTupel: [ + ['line1', 'string'], + ['line2', 'string'], + ], + }, + }); return req.handleRequest(); }); }); diff --git a/src/electron/pdr2com/connection.ts b/src/electron/pdr2com/connection.ts index dfcf83f..9e0cdfb 100644 --- a/src/electron/pdr2com/connection.ts +++ b/src/electron/pdr2com/connection.ts @@ -1,15 +1,7 @@ import {RequestLeser as ProdressListener, type R2AnfrageBlaupause} from '@prodress/pdr2com'; -import {type ResponseTupel, type ResponseObject, ProdressRequest, type RequestTupel} from './wrapper.js'; import {Socket} from 'node:net'; import {stringifyError} from '../utils.js'; - -export interface ProdressHeader { - port?: number; - host?: string; - database: string; - handler: string; - action: string; -} +import {ProdressRequest} from './wrapper.js'; /** * Initializes a TCP Socket, sends a ProdressRequest and listens to this Socket for one Response @@ -22,26 +14,27 @@ export class ProdressConnection { private socket: Socket; private request: ProdressRequest; private listener: ProdressListener; - private requestTupelList: RequestTupel[]; - private responseTupelList: ResponseTupel[]; + private requestBody: Pdr2_RequestBody; + private responseSchema: Pdr2_ResponseSchema; /** * @param header Headerdata to initialize the the TCP Socket and the ProdressRequest - * @param requestTupelList Requestdata as list of tupel - * @param responseTupelList Expected Responsedata as list of tupel + * @param body Requestdata as list of tupel + * @param response Expected Responsedata as list of tupel */ - public constructor(header: ProdressHeader, requestTupelList: RequestTupel[], responseTupelList: ResponseTupel[]) { + public constructor({header, body, response}: Pdr2_Request) { this.port = header.port ?? 4788; this.host = header.host ?? 'localhost'; this.socket = new Socket(); this.request = new ProdressRequest(header.database, header.handler, header.action); this.listener = new ProdressListener(); - this.requestTupelList = requestTupelList; - this.responseTupelList = responseTupelList; + this.requestBody = body; + this.responseSchema = response; } /** * Handels the request- and response-flow + * @returns the stringified response */ public async handleRequest(): Promise { let response: string = ''; @@ -61,7 +54,7 @@ export class ProdressConnection { // Sends the writes and sends the request when the connecting is established this.socket.once('connect', () => { try { - this.request.writeEntries(this.requestTupelList); + this.request.writeEntries(this.requestBody); this.request.sende(this.socket); } catch (error) { response = stringifyError(error as Error); @@ -116,30 +109,36 @@ export class ProdressConnection { * @param responseInstance The Listener Instance of the active TCP Socket * @returns ResponseObject */ - private readResponse(responseInstance: R2AnfrageBlaupause): ResponseObject { - const response: ResponseObject = {}; + private readResponse(responseInstance: R2AnfrageBlaupause): Pdr2_ResponseObject { + const response: Pdr2_ResponseObject = {}; + let amountOfEntries = 1; - for (const [key, type] of this.responseTupelList) { - switch (type) { - case 'string': - response[key] = responseInstance.nächsterText(); - break; - case 'integer': - response[key] = responseInstance.nächsteGanzzahl(); - break; - case 'float': - response[key] = responseInstance.nächsteDezimalzahl(); - break; - case 'date': - response[key] = responseInstance.nächstesDatum(); - break; - case 'date_time': - //@todo missing method in lib - response[key] = responseInstance.nächstesDatum(); - break; - } + if (!this.responseSchema.isStatic) { + amountOfEntries = responseInstance.nächsteGanzzahl(); } + for (let i = 1; i <= amountOfEntries; i++) { + for (const [key, type] of this.responseSchema.responseTupel) { + switch (type) { + case 'string': + response[key] = responseInstance.nächsterText(); + break; + case 'integer': + response[key] = responseInstance.nächsteGanzzahl(); + break; + case 'float': + response[key] = responseInstance.nächsteDezimalzahl(); + break; + case 'date': + response[key] = responseInstance.nächstesDatum(); + break; + case 'date_time': + //@todo missing method in lib + response[key] = responseInstance.nächstesDatum(); + break; + } + } + } return response; } } diff --git a/src/electron/pdr2com/wrapper.ts b/src/electron/pdr2com/wrapper.ts index 6b12b35..dac5953 100644 --- a/src/electron/pdr2com/wrapper.ts +++ b/src/electron/pdr2com/wrapper.ts @@ -1,23 +1,5 @@ import {Request} from '@prodress/pdr2com'; -export interface DataTypeConversion { - string: () => string; - integer: () => number; - float: () => number; - date: () => Date | null; - date_time: () => Date | null; -} - -export interface ResponseObject { - [key: string]: ReturnType; -} - -export type ResponseTupel = [string, keyof DataTypeConversion]; - -export type RequestTupel = { - [K in keyof DataTypeConversion]: [K, NonNullable>]; -}[keyof DataTypeConversion]; - export class ProdressRequest extends Request { public constructor(db: string, handler: string, action: string) { super( @@ -45,19 +27,30 @@ export class ProdressRequest extends Request { /** * writes entries based on the provided requestTupelList into the request - * @param requestTupelList + * @param requestBody */ - public writeEntries(requestTupelList: RequestTupel[]): void { - for (const tupel of requestTupelList) { + public writeEntries(requestBody: Pdr2_RequestBody): void { + // write additionalInformation + for (const tupel of requestBody.additionalInformation) { this.writeEntry(tupel); } + + // write amount of argument entries + this.writeEntry(['integer', requestBody.arguments.length]); + + // write arguments + for (const args of requestBody.arguments) { + for (const tupel of args) { + this.writeEntry(tupel); + } + } } /** * writes an entry based on the provided requestTupel into the request * @param requestTupel */ - public writeEntry(requestTupel: RequestTupel): void { + public writeEntry(requestTupel: Pdr2_RequestTupel): void { const [type, value] = requestTupel; switch (type) { case 'string': diff --git a/types.d.ts b/types.d.ts index 80fa0fb..96af780 100644 --- a/types.d.ts +++ b/types.d.ts @@ -11,3 +11,89 @@ interface Window { type UnsubscribeFunction = () => void; type SubscribeFunction = (payload: EventPayloadMapping[Event]) => void; + +// --- Prodress R2 Request --- + +/** + * structure of a handler based prodress r2 request schema + */ +type Pdr2_Schema = { + handler: string; + actions: Pdr2_ActionSchema[]; +}; + +/** + * structure of an action based prodress r2 request subschema + */ +type Pdr2_ActionSchema = { + action: string; + additionalInformation: Pdr2_RequestTupel[]; + arguments: Pdr2_RequestTupel[]; + response: Pdr2_ResponseSchema; +}; + +/** + * structure of the prodressd r2 request header + */ +interface Pdr2_Header { + port?: number; + host?: string; + database: string; + handler: string; + action: string; +} + +/** + * mapping for string alias to scalar type with pdr2 read and write methods + */ +interface Pdr2_DataTypeConversion { + string: () => string; + integer: () => number; + float: () => number; + date: () => Date | null; + date_time: () => Date | null; +} + +/** + * structrue of a response object which is already read + */ +interface Pdr2_ResponseObject { + [key: string]: ReturnType; +} + +/** + * structure of a response tupel used inside of the response schema + */ +type Pdr2_ResponseTupel = [string, keyof Pdr2_DataTypeConversion]; + +/** + * strucutre of a request tupel used inside the request body and schema + */ +type Pdr2_RequestTupel = { + [K in keyof Pdr2_DataTypeConversion]: [K, NonNullable>]; +}[keyof Pdr2_DataTypeConversion]; + +/** + * structure of a prodress r2 request object recieved by the user + */ +type Pdr2_Request = { + header: Pdr2_Header; + body: Pdr2_RequestBody; + response: Pdr2_ResponseSchema; +}; + +/** + * structure of a prodress r2 request body + */ +type Pdr2_RequestBody = { + additionalInformation: Pdr2_RequestTupel[]; + arguments: Pdr2_RequestTupel[][]; +}; + +/** + * structure of a prodress r2 response schema + */ +type Pdr2_ResponseSchema = { + isStatic: boolean; + responseTupel: Pdr2_ResponseTupel[]; +};