Skip to content

Commit

Permalink
(fix): add docs cache invalidation endpoint (#854)
Browse files Browse the repository at this point in the history
  • Loading branch information
dsinghvi authored May 13, 2024
1 parent e4462a5 commit 4e5a0f1
Show file tree
Hide file tree
Showing 30 changed files with 305 additions and 0 deletions.
15 changes: 15 additions & 0 deletions fern/apis/fdr/definition/docsCache.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
imports:
commons: commons.yml

service:
base-path: /docs-cache
auth: true
endpoints:
invalidate:
method: POST
path: /invalidate
request:
name: InvalidateCachedDocsRequest
body:
properties:
url: string
7 changes: 7 additions & 0 deletions packages/fdr-sdk/src/client/generated/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as core from "./core";
import { Api } from "./api/resources/api/client/Client";
import { Docs } from "./api/resources/docs/client/Client";
import { Diff } from "./api/resources/diff/client/Client";
import { DocsCache } from "./api/resources/docsCache/client/Client";
import { SnippetsFactory } from "./api/resources/snippetsFactory/client/Client";
import { Snippets } from "./api/resources/snippets/client/Client";
import { Templates } from "./api/resources/templates/client/Client";
Expand Down Expand Up @@ -44,6 +45,12 @@ export class FernRegistryClient {
return (this._diff ??= new Diff(this._options));
}

protected _docsCache: DocsCache | undefined;

public get docsCache(): DocsCache {
return (this._docsCache ??= new DocsCache(this._options));
}

protected _snippetsFactory: SnippetsFactory | undefined;

public get snippetsFactory(): SnippetsFactory {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* This file was auto-generated by Fern from our API Definition.
*/

import * as environments from "../../../../environments";
import * as core from "../../../../core";
import * as FernRegistry from "../../..";
import urlJoin from "url-join";

export declare namespace DocsCache {
interface Options {
environment?: core.Supplier<environments.FernRegistryEnvironment | string>;
token?: core.Supplier<core.BearerToken | undefined>;
}

interface RequestOptions {
timeoutInSeconds?: number;
maxRetries?: number;
}
}

export class DocsCache {
constructor(protected readonly _options: DocsCache.Options = {}) {}

public async invalidate(
request: FernRegistry.InvalidateCachedDocsRequest,
requestOptions?: DocsCache.RequestOptions
): Promise<core.APIResponse<void, FernRegistry.docsCache.invalidate.Error>> {
const _response = await core.fetcher({
url: urlJoin(
(await core.Supplier.get(this._options.environment)) ?? environments.FernRegistryEnvironment.Dev,
"/docs-cache/invalidate"
),
method: "POST",
headers: {
Authorization: await this._getAuthorizationHeader(),
"X-Fern-Language": "JavaScript",
"X-Fern-Runtime": core.RUNTIME.type,
"X-Fern-Runtime-Version": core.RUNTIME.version,
},
contentType: "application/json",
body: request,
timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : undefined,
maxRetries: requestOptions?.maxRetries,
});
if (_response.ok) {
return {
ok: true,
body: undefined,
};
}

return {
ok: false,
error: FernRegistry.docsCache.invalidate.Error._unknown(_response.error),
};
}

protected async _getAuthorizationHeader() {
const bearer = await core.Supplier.get(this._options.token);
if (bearer != null) {
return `Bearer ${bearer}`;
}

return undefined;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./requests";
export * as invalidate from "./invalidate";
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* This file was auto-generated by Fern from our API Definition.
*/

import * as FernRegistry from "../../..";
import * as core from "../../../../core";

export type Error = FernRegistry.docsCache.invalidate.Error._Unknown;

export declare namespace Error {
interface _Unknown {
error: void;
content: core.Fetcher.Error;
}

interface _Visitor<_Result> {
_other: (value: core.Fetcher.Error) => _Result;
}
}

export const Error = {
_unknown: (fetcherError: core.Fetcher.Error): FernRegistry.docsCache.invalidate.Error._Unknown => {
return {
error: undefined,
content: fetcherError,
};
},

_visit: <_Result>(
value: FernRegistry.docsCache.invalidate.Error,
visitor: FernRegistry.docsCache.invalidate.Error._Visitor<_Result>
): _Result => {
switch (value.error) {
default:
return visitor._other(value as any);
}
},
} as const;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* This file was auto-generated by Fern from our API Definition.
*/

export interface InvalidateCachedDocsRequest {
url: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { InvalidateCachedDocsRequest } from "./InvalidateCachedDocsRequest";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./client";
2 changes: 2 additions & 0 deletions packages/fdr-sdk/src/client/generated/api/resources/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ export * as snippets from "./snippets";
export * from "./snippets/types";
export * as templates from "./templates";
export * from "./templates/types";
export * as docsCache from "./docsCache";
export * from "./diff/client/requests";
export * from "./docsCache/client/requests";
export * from "./snippetsFactory/client/requests";
export * from "./snippets/client/requests";
export * from "./templates/client/requests";
35 changes: 35 additions & 0 deletions servers/fdr/src/__test__/local/services/docsCache.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { DocsV1Write } from "@fern-api/fdr-sdk";
import { inject } from "vitest";
import { getAPIResponse, getClient } from "../util";

export const WRITE_DOCS_REGISTER_DEFINITION: DocsV1Write.DocsDefinition = {
pages: {},
config: {
navigation: {
items: [],
},
},
};

it("docs invalidate cache", async () => {
const fdr = getClient({ authed: true, url: inject("url") });
const domain = `docs-${Math.random()}.fern.com`;

// register docs
const startDocsRegisterResponse = getAPIResponse(
await fdr.docs.v1.write.startDocsRegister({
orgId: "fern",
domain,
filepaths: ["logo.png", "guides/guide.mdx"],
}),
);
await fdr.docs.v1.write.finishDocsRegister(startDocsRegisterResponse.docsRegistrationId, {
docsDefinition: WRITE_DOCS_REGISTER_DEFINITION,
});

const response = await fdr.docsCache.invalidate({
url: `https://${domain}`,
});

expect(response.ok).toEqual(true);
});
2 changes: 2 additions & 0 deletions servers/fdr/src/__test__/local/setupMockFdr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { FdrApplication, FdrConfig } from "../../app";
import { getReadApiService } from "../../controllers/api/getApiReadService";
import { getRegisterApiService } from "../../controllers/api/getRegisterApiService";
import { getApiDiffService } from "../../controllers/diff/getApiDiffService";
import { getDocsCacheService } from "../../controllers/docs-cache/getDocsCacheService";
import { getDocsReadService } from "../../controllers/docs/v1/getDocsReadService";
import { getDocsWriteService } from "../../controllers/docs/v1/getDocsWriteService";
import { getDocsReadV2Service } from "../../controllers/docs/v2/getDocsReadV2Service";
Expand Down Expand Up @@ -100,6 +101,7 @@ async function runMockFdr(port: number): Promise<MockFdr.Instance> {
snippetsFactory: getSnippetsFactoryService(fdrApplication),
templates: getTemplatesService(fdrApplication),
diff: getApiDiffService(fdrApplication),
docsCache: getDocsCacheService(fdrApplication),
});
const server = app.listen(port);
console.log(`Mock FDR server running on http://localhost:${port}/`);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./service";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./service";
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* This file was auto-generated by Fern from our API Definition.
*/
import * as FernRegistry from "../../..";
import express from "express";
export interface DocsCacheServiceMethods {
invalidate(req: express.Request<never, never, FernRegistry.InvalidateCachedDocsRequest, never>, res: {
send: () => Promise<void>;
cookie: (cookie: string, value: string, options?: express.CookieOptions) => void;
locals: any;
}): void | Promise<void>;
}
export declare class DocsCacheService {
private readonly methods;
private router;
constructor(methods: DocsCacheServiceMethods, middleware?: express.RequestHandler[]);
addMiddleware(handler: express.RequestHandler): this;
toRouter(): express.Router;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* This file was auto-generated by Fern from our API Definition.
*/
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());
});
};
import express from "express";
import * as errors from "../../../../errors";
export class DocsCacheService {
constructor(methods, middleware = []) {
this.methods = methods;
this.router = express.Router({ mergeParams: true }).use(express.json({
strict: false,
}), ...middleware);
}
addMiddleware(handler) {
this.router.use(handler);
return this;
}
toRouter() {
this.router.post("/invalidate", (req, res, next) => __awaiter(this, void 0, void 0, function* () {
try {
yield this.methods.invalidate(req, {
send: () => __awaiter(this, void 0, void 0, function* () {
res.sendStatus(204);
}),
cookie: res.cookie.bind(res),
locals: res.locals,
});
next();
}
catch (error) {
console.error(error);
if (error instanceof errors.FernRegistryError) {
console.warn(`Endpoint 'invalidate' unexpectedly threw ${error.constructor.name}.` +
` If this was intentional, please add ${error.constructor.name} to` +
" the endpoint's errors list in your Fern Definition.");
yield error.send(res);
}
else {
res.status(500).json("Internal Server Error");
}
next(error);
}
}));
return this.router;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./requests";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./requests";
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* This file was auto-generated by Fern from our API Definition.
*/
export interface InvalidateCachedDocsRequest {
url: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/**
* This file was auto-generated by Fern from our API Definition.
*/
export {};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { InvalidateCachedDocsRequest } from "./InvalidateCachedDocsRequest";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
2 changes: 2 additions & 0 deletions servers/fdr/src/api/generated/api/resources/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export * as snippets from "./snippets";
export * from "./snippets/types";
export * as templates from "./templates";
export * from "./templates/types";
export * as docsCache from "./docsCache";
export * from "./docsCache/service/requests";
export * from "./snippetsFactory/service/requests";
export * from "./snippets/service/requests";
export * from "./templates/service/requests";
Expand Down
2 changes: 2 additions & 0 deletions servers/fdr/src/api/generated/api/resources/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export * as snippets from "./snippets";
export * from "./snippets/types";
export * as templates from "./templates";
export * from "./templates/types";
export * as docsCache from "./docsCache";
export * from "./docsCache/service/requests";
export * from "./snippetsFactory/service/requests";
export * from "./snippets/service/requests";
export * from "./templates/service/requests";
Expand Down
2 changes: 2 additions & 0 deletions servers/fdr/src/api/generated/register.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
import express from "express";
import { DiffService } from "./api/resources/diff/service/DiffService";
import { DocsCacheService } from "./api/resources/docsCache/service/DocsCacheService";
import { SnippetsFactoryService } from "./api/resources/snippetsFactory/service/SnippetsFactoryService";
import { SnippetsService } from "./api/resources/snippets/service/SnippetsService";
import { TemplatesService } from "./api/resources/templates/service/TemplatesService";
Expand All @@ -14,6 +15,7 @@ import { ReadService as docs_v2_read_RootService } from "./api/resources/docs/re
import { WriteService as docs_v2_write_RootService } from "./api/resources/docs/resources/v2/resources/write/service/WriteService";
export declare function register(expressApp: express.Express | express.Router, services: {
diff: DiffService;
docsCache: DocsCacheService;
snippetsFactory: SnippetsFactoryService;
snippets: SnippetsService;
templates: TemplatesService;
Expand Down
1 change: 1 addition & 0 deletions servers/fdr/src/api/generated/register.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export function register(expressApp, services) {
expressApp.use("/v2/registry/docs", services.docs.v2.read._root.toRouter());
expressApp.use("/v2/registry/docs", services.docs.v2.write._root.toRouter());
expressApp.use("/registry", services.diff.toRouter());
expressApp.use("/docs-cache", services.docsCache.toRouter());
expressApp.use("/snippets", services.snippetsFactory.toRouter());
expressApp.use("/snippets", services.snippets.toRouter());
expressApp.use("/snippet-template", services.templates.toRouter());
Expand Down
12 changes: 12 additions & 0 deletions servers/fdr/src/controllers/docs-cache/getDocsCacheService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { DocsCacheService } from "../../api/generated/api/resources/docsCache/service/DocsCacheService";
import { type FdrApplication } from "../../app";
import { ParsedBaseUrl } from "../../util/ParsedBaseUrl";

export function getDocsCacheService(app: FdrApplication): DocsCacheService {
return new DocsCacheService({
invalidate: async (req, res) => {
await app.docsDefinitionCache.invalidateCache(ParsedBaseUrl.parse(req.body.url).toURL());
return res.send();
},
});
}
2 changes: 2 additions & 0 deletions servers/fdr/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { registerBackgroundTasks } from "./background";
import { getReadApiService } from "./controllers/api/getApiReadService";
import { getRegisterApiService } from "./controllers/api/getRegisterApiService";
import { getApiDiffService } from "./controllers/diff/getApiDiffService";
import { getDocsCacheService } from "./controllers/docs-cache/getDocsCacheService";
import { getDocsReadService } from "./controllers/docs/v1/getDocsReadService";
import { getDocsWriteService } from "./controllers/docs/v1/getDocsWriteService";
import { getDocsReadV2Service } from "./controllers/docs/v2/getDocsReadV2Service";
Expand Down Expand Up @@ -109,6 +110,7 @@ async function startServer(): Promise<void> {
snippetsFactory: getSnippetsFactoryService(app),
templates: getTemplatesService(app),
diff: getApiDiffService(app),
docsCache: getDocsCacheService(app),
});
registerBackgroundTasks(app);
app.logger.info(`Listening for requests on port ${PORT}`);
Expand Down
Loading

0 comments on commit 4e5a0f1

Please sign in to comment.