Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
async handleApiRequest(encodedHttpRequest: EncodedHttpRequest) {
let responseData: GeneralResponseData;
// This line casts restApiHandler to supertype so that it should receive pre-sanitized data.
const restApiHandler: GeneralRestApiHandler = this.restApiHandler;
try {
// 1. Decoding Request
const requestData = decodeRequest(encodedHttpRequest);
// 2. Invoking PhenylRestApi
responseData = await restApiHandler.handleRequestData(requestData);
} catch (err) {
responseData = {
type: "error",
payload: createServerError(err)
};
}
// 3. Encoding Response
return encodeResponse(responseData);
}
>(
reqData: RequestDataWithTypeMapForResponse
): Promise | ErrorResponseData> {
// TODO: use HandlerRequest Type instead of Promise
try {
assertValidRequestData(reqData);
const session = await this.sessionClient.get(reqData.sessionId!);
const executor = this.getExecutor(
reqData.method,
this.extractName(reqData)
);
const isAccessible = await executor.authorize(reqData, session);
if (!isAccessible) {
return {
type: "error",
payload: createServerError("Authorization Required.", "Unauthorized")
};
}
const normalizedReqData = await executor.normalize(reqData, session);
try {
await executor.validate(normalizedReqData, session);
} catch (validationError) {
validationError.message = `Validation Failed. ${
validationError.mesage
}`;
return {
type: "error",
payload: createServerError(validationError, "BadRequest")
};
}
async getByIds>(
query: IdsQuery
): Promise>> {
const { entityName, ids } = query;
const coll = this.conn.collection(entityName);
// $FlowIssue(find-operation)
const result = await coll.find({ _id: { $in: ids.map(ObjectID) } });
if (result.length === 0) {
throw createServerError(
'"PhenylMongodbClient#getByIds()" failed. Could not find any entity with the given query.',
"NotFound"
);
}
// @ts-ignore @TODO: improve the types in MongoDbCollection
return result.map(filterOutputEntity);
}
throw createServerError(
`Entity has been locked. entityName:${entityName}, id: ${id}`
);
}
const operation = PhenylStateUpdater.updateById(
this.entityState,
command
);
// @ts-ignore operation is nonbreaking
this.entityState = update(this.entityState, operation);
return PhenylStateFinder.get(this.entityState, {
entityName,
id
});
} catch (error) {
throw createServerError(
'"PhenylMemoryClient#updateAndGet()" failed. Could not find any entity with the given query.',
"NotFound"
);
}
}
/**
async execute(
reqData: GeneralUserEntityRequestData,
session?: Session
): Promise {
// TODO: use HandlerRequest Type instead of Promise
if (reqData.method == "logout") {
return this.logout(reqData.payload);
}
if (reqData.method == "login") {
return this.login(reqData.payload, session);
}
if (session === undefined) {
const errorResult: ErrorResponseData = {
type: "error",
payload: createServerError(
`Method ${reqData.method} requires an active session`,
"Unauthorized"
)
};
return errorResult;
}
return this.definition.wrapExecution!(
reqData,
session,
executeEntityRequestData.bind(this, this.client)
);
}
async updateAndGet>(
command: IdUpdateCommand
): Promise {
const { entityName, id, filter } = command;
try {
const entity = PhenylStateFinder.get(this.entityState, {
entityName,
id
});
const matched = filter ? retrieve([entity], filter).length === 1 : true;
if (!matched) {
throw createServerError(
`Entity has been locked. entityName:${entityName}, id: ${id}`
);
}
const operation = PhenylStateUpdater.updateById(
this.entityState,
command
);
// @ts-ignore operation is nonbreaking
this.entityState = update(this.entityState, operation);
return PhenylStateFinder.get(this.entityState, {
entityName,
id
});
} catch (error) {
throw createServerError(
'"PhenylMemoryClient#updateAndGet()" failed. Could not find any entity with the given query.',
async insertAndGet>(
command: SingleInsertCommand>
): Promise {
const { entityName, value } = command;
// @ts-ignore newValue must contain id
const newValue: M[N] = value.id
? value
: update(value, {
id: timeStampWithRandomString()
});
const operation = PhenylStateUpdater.register(
this.entityState,
entityName,
newValue
);
// @ts-ignore operation is nonbreaking
this.entityState = update(this.entityState, operation);
return newValue;
}
/**
async handleCustomRequest(encodedHttpRequest: EncodedHttpRequest) {
try {
const restApiClient = new PhenylRestApiDirectClient(this.restApiHandler);
const customResponse = await this.customRequestHandler(
encodedHttpRequest,
restApiClient
);
return customResponse;
} catch (err) {
// TODO: Show error in development environment.
const body = "Internal Server Error.";
return createPlainTextResponse(body, 500);
}
}
}
async wrapExecution(
reqData: GeneralUserEntityRequestData,
session: Session,
execution: RestApiExecution
): Promise {
const resData = await execution(reqData, session);
return await switchByRequestMethod(reqData, {
find: async (query: ForeignWhereQuery) => {
if (resData.type !== "find" || query.foreign == null) return resData;
const foreignEntitiesById = await this.getForeignEntities(
resData.payload.entities,
query.foreign
);
const { $set, $docPath } = $bind();
return update(
resData,
// @ts-ignore: has no foreign key
$set($docPath("payload", "foreign", "entities"), foreignEntitiesById)
);
},
findOne: async (query: ForeignWhereQuery) => {
if (resData.type !== "findOne" || query.foreign == null) return resData;
async validation(
reqData: GeneralRequestData,
): Promise {
// eslint-disable-line no-unused-vars
return switchByRequestMethod(reqData, {
async find(query: ForeignWhereQuery) {
assertValidForeignQuery(query.foreign, "ForeignWhereQuery");
},
async findOne(query: ForeignWhereQuery) {
assertValidForeignQuery(query.foreign, "ForeignWhereQuery");
},
async get(query: ForeignIdQuery) {
assertValidForeignQuery(query.foreign, "ForeignIdQuery");
},
async getByIds(query: ForeignIdsQuery) {
assertValidForeignQuery(query.foreign, "ForeignIdsQuery");
},
async handleDefault() {
// eslint-disable-line no-unused-vars
return;
}