Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export const ERROR_CODE_MESSAGES: Record<ErrorCode, string> = {
"Authorization required. Find your API Key in the 'Local REST API' section of your Obsidian settings.",
[ErrorCode.ContentTypeSpecificationRequired]:
"Content-Type header required; this API accepts data in multiple content-types and you must indicate the content-type of your request body via the Content-Type header.",
[ErrorCode.InvalidContentType]:
"Unknown or invalid Content-Type specified in Content-Type header.",
[ErrorCode.InvalidContentInsertionPositionValue]:
"Invalid 'Content-Insertion-Position' header value.",
[ErrorCode.InvalidContentForContentType]:
Expand Down Expand Up @@ -40,6 +42,9 @@ export const ERROR_CODE_MESSAGES: Record<ErrorCode, string> = {
"The 'Operation' header you provided was invalid.",
[ErrorCode.PatchFailed]:
"The patch you provided could not be applied to the target content.",
[ErrorCode.InvalidSearch]: "The search query you provided is not valid.",
[ErrorCode.ErrorPreparingSimpleSearch]:
"Error encountered while calling Obsidian `prepareSimpleSearch` API.",
};

export enum ContentTypes {
Expand Down
24 changes: 22 additions & 2 deletions src/requestHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -991,9 +991,24 @@ export default class RequestHandler {
const results: SearchResponseItem[] = [];

const query: string = req.query.query as string;
if (!(typeof query === "string")) {
return this.returnCannedResponse(res, {
message: "A single '?query=' parameter is required.",
errorCode: ErrorCode.InvalidSearch,
});
}
const contextLength: number =
parseInt(req.query.contextLength as string, 10) ?? 100;
const search = prepareSimpleSearch(query);
let search: ReturnType<typeof prepareSimpleSearch>;
try {
search = prepareSimpleSearch(query);
} catch (e) {
console.error("Could not prepare simple search: ", e);
return this.returnCannedResponse(res, {
message: `${e}`,
errorCode: ErrorCode.ErrorPreparingSimpleSearch,
});
}

for (const file of this.app.vault.getMarkdownFiles()) {
const cachedContents = await this.app.vault.cachedRead(file);
Expand Down Expand Up @@ -1099,11 +1114,16 @@ export default class RequestHandler {
};
const contentType = req.headers["content-type"];

if (!handlers[contentType]) {
if (!contentType) {
this.returnCannedResponse(res, {
errorCode: ErrorCode.ContentTypeSpecificationRequired,
});
return;
} else if (!handlers[contentType]) {
this.returnCannedResponse(res, {
errorCode: ErrorCode.InvalidContentType,
});
return;
}

try {
Expand Down
3 changes: 3 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { IPeriodicNoteSettings } from "obsidian-daily-notes-interface";
export enum ErrorCode {
TextContentEncodingRequired = 40010,
ContentTypeSpecificationRequired = 40011,
InvalidContentType = 40012,
InvalidContentForContentType = 40015,
InvalidContentInsertionPositionValue = 40050,
MissingHeadingHeader = 40051,
Expand All @@ -17,10 +18,12 @@ export enum ErrorCode {
PeriodIsNotEnabled = 40060,
InvalidFilterQuery = 40070,
PatchFailed = 40080,
InvalidSearch = 40090,
ApiKeyAuthorizationRequired = 40101,
PeriodDoesNotExist = 40460,
PeriodicNoteDoesNotExist = 40461,
RequestMethodValidOnlyForFiles = 40510,
ErrorPreparingSimpleSearch = 50010,
}

export interface LocalRestApiSettings {
Expand Down