diff --git a/.gitignore b/.gitignore index 9266bf1d..eb3eae65 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,4 @@ yarn.lock public/robots.txt public/sitemap.xml public/sitemap-*.xml +api.json \ No newline at end of file diff --git a/docs/articles/key-value-store.md b/docs/articles/key-value-store.md deleted file mode 100644 index 340deebe..00000000 --- a/docs/articles/key-value-store.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: Key Value Store -sidebar_label: Key Value Store ---- - -Zuplo has a globally distributed key-value store called `KeyValueStore`. When -running in developer mode (e.g. in the portal at portal.zuplo.com) your cache -will reset with each build. When running in production mode at the edge the -cache will support edge distribution - it can take up to ~1 minute for writes to -sync across all nodes globally (though is usually much quicker). - - - -## Example - -```ts -import { ZuploContext, ZuploRequest, KeyValueStore } from "@zuplo/runtime"; - -export async function setCache(request: ZuploRequest, context: ZuploContext) { - const cache = new KeyValueStore(context); - // This cache entry will expire in 60s - await cache.put("string-key", "some-value", { expirationSecondsTtl: 60 }); - return "OK"; -} - -export async function getCache(request: ZuploRequest, context: ZuploContext) { - const cache = new KeyValueStore(context); - const value = await cache.get("string-key"); - return value; -} -``` - -## Constructing the KeyValueStore - -```ts -// This creates a new instance of the KeyValueStore. This should be performed inside the lifecycle of a request (it's an inexpensive operation that just creates a reference to the real store) -const cache = new KeyValueStore(context); -``` - -## Writing to the KeyValueStore - -```ts -// This cache entry will expire in 60s -await cache.put("string-key", "some-value", { expirationSecondsTtl: 60 }); -``` - -## Reading from the KeyValueStore - -```ts -const data = await cache.get("string-key"); -``` - -## Deleting from the KeyValueStore - -```ts -await cache.delete("string-key"); -``` diff --git a/docs/articles/policies.md b/docs/articles/policies.md index d6d21988..0520e1d4 100644 --- a/docs/articles/policies.md +++ b/docs/articles/policies.md @@ -1,5 +1,5 @@ --- -title: Policies +title: Policy Fundamentals --- Policies are modules that can intercept an incoming request. You can have diff --git a/package.json b/package.json index 7998ffab..2807c7c4 100644 --- a/package.json +++ b/package.json @@ -14,9 +14,10 @@ "build": "zudoku build", "format": "prettier --write .", "typecheck": "tsc", - "postinstall": "npm run policies:get && npm run policies:generate && npm run errors:generate", + "postinstall": "npm run policies:get && npm run policies:generate && npm run errors:generate && npm run api:get", "policies:get": "sh ./scripts/get-policies.sh", "policies:generate": "tsx scripts/generate-policies.ts", + "api:get": "curl -o ./api.json https://dev.zuplo.com/openapi", "errors:generate": "tsx scripts/generate-errors.ts" }, "dependencies": { diff --git a/scripts/generate-policies.ts b/scripts/generate-policies.ts index b018dbfd..ad1ea1fa 100644 --- a/scripts/generate-policies.ts +++ b/scripts/generate-policies.ts @@ -1,8 +1,8 @@ +import { glob } from "glob"; +import type { JSONSchema7, JSONSchema7Definition } from "json-schema"; import fs from "node:fs/promises"; import path from "node:path"; import prettier from "prettier"; -import { glob } from "glob"; -import type { JSONSchema7, JSONSchema7Definition } from "json-schema"; import { fixMarkdown } from "./fix-markdown.js"; const projectDir = path.join(import.meta.dirname, ".."); @@ -195,6 +195,10 @@ Read more about [how policies work](/articles/policies) } const policyIndex = ` +--- +title: Policy Catalog +--- + {/* This file is auto-generated by generate-policies.ts. Do not edit manually! Re-run with \`generate:policies\` script. */} Zuplo includes policies for any solution you need for securing and sharing your API. See the [policy introduction](/docs/articles/policies) to learn about using policies. diff --git a/sidebar.ts b/sidebar.ts index a4cbfcd4..7beec10f 100644 --- a/sidebar.ts +++ b/sidebar.ts @@ -1,7 +1,7 @@ import type { SidebarEntry } from "zudoku"; import { errors } from "./generated/errors"; -export const sidebar: SidebarEntry = [ +export const docs: SidebarEntry = [ { type: "category", label: "Introduction", @@ -222,36 +222,6 @@ export const sidebar: SidebarEntry = [ "articles/convert-urls-to-openapi", ], }, - { - type: "category", - label: "Programming API", - items: [ - "articles/zuplo-request", - "articles/zuplo-context", - "articles/context-data", - "articles/route-raw", - "articles/background-loader", - "articles/background-dispatcher", - "articles/web-standard-apis", - "articles/web-crypto-apis", - "articles/cache", - "articles/node-modules", - "articles/http-problems", - "articles/reusing-code", - "articles/zone-cache", - "articles/key-value-store", - "articles/zuplo-id-token", - "articles/safely-clone-a-request-or-response", - "articles/runtime-behaviors", - "articles/zp-body-removed", - "articles/audit-log", - "articles/hooks", - "articles/custom-cors-policy", - "articles/runtime-extensions", - "articles/not-found-handler", - "articles/zuplo-json", - ], - }, { type: "category", label: "Zuplo CLI", @@ -333,11 +303,6 @@ export const sidebar: SidebarEntry = [ type: "doc", id: "articles/support", }, - { - type: "doc", - id: "articles/developer-api", - }, - "ask", { type: "link", label: "Trust & Compliance", @@ -352,12 +317,60 @@ export const sidebar: SidebarEntry = [ }, ]; +export const programming: SidebarEntry = [ + { + type: "category", + label: "Core Concepts", + items: [ + "articles/zuplo-request", + "articles/zuplo-context", + "articles/web-standard-apis", + "articles/web-crypto-apis", + "articles/node-modules", + + "articles/context-data", + "articles/route-raw", + + "articles/reusing-code", + + "articles/zuplo-id-token", + "articles/safely-clone-a-request-or-response", + "articles/runtime-behaviors", + "articles/zp-body-removed", + "articles/audit-log", + + "articles/custom-cors-policy", + + "articles/zuplo-json", + ], + }, + { + type: "category", + label: "Error Handling", + items: ["articles/http-problems", "articles/not-found-handler"], + }, + { + type: "category", + label: "Extensions & Hooks", + items: ["articles/hooks", "articles/runtime-extensions"], + }, + { + type: "category", + label: "Cache & Data Loading", + items: [ + "articles/cache", + "articles/zone-cache", + "articles/background-loader", + "articles/background-dispatcher", + ], + }, +]; + export const policies: SidebarEntry = [ { - type: "doc", - // this file is auto-generated, see generate-policies.ts - id: "policies/index", + type: "category", label: "Overview", + items: ["policies/index", "articles/policies"], }, { type: "category", diff --git a/src/PolicyOverview.tsx b/src/PolicyOverview.tsx index 12467c78..3b332d18 100644 --- a/src/PolicyOverview.tsx +++ b/src/PolicyOverview.tsx @@ -1,4 +1,4 @@ -import React, { type CSSProperties } from "react"; +import { type CSSProperties } from "react"; import { Link } from "zudoku/components"; export const PolicyOverview = ({ @@ -19,12 +19,14 @@ export const PolicyOverview = ({ key={policy.policyId} className="flex items-center gap-4 rounded-lg border border-border shadow-sm p-4 transition-colors hover:bg-accent md:h-36 md:flex-col md:justify-center md:px-5 md:py-6 md:text-center no-underline" > -
+
); }, - BundlesTables: () => , + BundlesTable: () => , }; const config: ZudokuConfig = { @@ -89,21 +89,26 @@ const config: ZudokuConfig = { id: "policies", label: "Policies & Handlers", }, + { + id: "programming", + label: "Programming API", + }, { id: "api", - label: "API Reference", + label: "REST API", }, ], sidebar: { - docs: sidebar, - policies: policies, + docs, + policies, + programming, }, mdx: { components: mdxComponents, }, apis: { - type: "url", - input: "https://developer-api-main-5b4bb7c.d2.zuplo.dev/openapi", + type: "file", + input: "./api.json", navigationId: "api", }, docs: [