init
This commit is contained in:
1
package/.gitignore
vendored
Normal file
1
package/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
dist
|
||||
184
package/CHANGELOG.md
Normal file
184
package/CHANGELOG.md
Normal file
@@ -0,0 +1,184 @@
|
||||
# astro-pocketbase
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- middleware is externalized in src/lib/pocketbase/middleware.ts
|
||||
|
||||
## 0.10.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- update zod-pocketbase
|
||||
|
||||
## 0.10.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- avoid the need of path in tsconfig.json for locals declaration
|
||||
|
||||
## 0.10.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- update zod-pocketbase
|
||||
|
||||
## 0.10.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- c258a34: update zod-pocketbase
|
||||
|
||||
## 0.10.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- c558cce: upgrade zod-pocketbase
|
||||
|
||||
## 0.10.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- add zod-pocketbase to exports
|
||||
|
||||
## 0.9.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- remove magic "pocketbase:astro" and generate schemas and loader directly in "src/lib/pocketbase"
|
||||
- refactor with zod-pocketbase
|
||||
|
||||
## 0.8.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 0c3e99c: add type and function helpers
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 0c3e99c: change default naming from Model to Record as pocketbase calls it
|
||||
|
||||
## 0.7.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 23c9e7f: remove eleventy fetch in favoi of pocketbase sdk and refine the way content is updated
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 23c9e7f: secure toolbar app use in astro v4
|
||||
|
||||
## 0.6.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- a981658: fix toolbar app that was called during routing with ClientRouter
|
||||
|
||||
## 0.6.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- c1027d0: add cacheDir option for fetching
|
||||
|
||||
## 0.5.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 5e7a9ef: Fix empty relation case
|
||||
|
||||
## 0.5.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 98693e2: fix enum type
|
||||
|
||||
## 0.5.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f72ee99: refine select field schema with enum
|
||||
- f72ee99: pass collection name to stringigyFieldSchema
|
||||
|
||||
## 0.5.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 88e1af6: fix enum property name
|
||||
|
||||
## 0.5.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- fc843fe: fix options schema
|
||||
|
||||
## 0.5.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 8dbbc6c: fix enum naming function used
|
||||
|
||||
## 0.5.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- fba429f: add naming enum options
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- cee8216: add ignore option
|
||||
|
||||
## 0.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 756b35e: fix loader id for refreshContent
|
||||
|
||||
## 0.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 257edb1: add a dev toolbar app to clear cache and refresh collections
|
||||
|
||||
## 0.2.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 120e5f5: remove useless code
|
||||
- 9b462a1: add RecordRef type
|
||||
|
||||
## 0.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 295f9ee: add Collection type
|
||||
|
||||
## 0.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- aeeb739: add eleventy-fetch as peer dependency
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- bfe58e2: replace pocketbase sdk in the loader by eleventy fetch to ease caching
|
||||
- c993dff: add cache duration option and disable cache in production
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b05e991: change astro reference to zod transform
|
||||
- b05e991: correct schema type for dates
|
||||
- f91a9ae: use input instead of output schema types for pocketbase sdk type
|
||||
- f7c285f: replace biome by eslint and prettier
|
||||
- f91a9ae: replace zod date coercion by transform to respect pocketbase sdk types
|
||||
- f1e177a: correct date schema
|
||||
|
||||
## 0.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- df2b603: project initialisation
|
||||
17
package/README.md
Normal file
17
package/README.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# `astro-pocketbase`
|
||||
|
||||
This is an [Astro integration](https://docs.astro.build/en/guides/integrations-guide/) that ease the use of PocketBase in your Astro projects
|
||||
|
||||
## Usage
|
||||
|
||||
To see how to get started, check out the [docs](https://astro-pocketbase-five.vercel.app)
|
||||
|
||||
## Licensing
|
||||
|
||||
[MIT Licensed](https://github.com/gbouteiller/astro-pocketbase/blob/main/LICENSE). Made with ❤️ by [Gregory Bouteiller](https://github.com/gbouteiller).
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
- [`astro-integration-kit`](https://github.com/florian-lefebvre/astro-integration-kit) by Florian Lefebvre
|
||||
- [`pocketbase`](https://github.com/pocketbase/js-sdk) by Gani Georgiev
|
||||
|
||||
14
package/assets/env.d.ts
vendored
Normal file
14
package/assets/env.d.ts
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import type { TypedPocketbase } from "../../../src/lib/pocketbase/schemas";
|
||||
import type { helpersFrom } from "astro-pocketbase";
|
||||
|
||||
declare global {
|
||||
namespace App {
|
||||
interface Locals {
|
||||
pocketbase: TypedPocketbase;
|
||||
getRecord: ReturnType<typeof helpersFrom>["getRecord"];
|
||||
getRecords: ReturnType<typeof helpersFrom>["getRecords"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
||||
57
package/assets/loader.ts
Normal file
57
package/assets/loader.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
// This file was automatically generated by Astro PocketBase.
|
||||
|
||||
import type { Collection, TypedPocketbase } from "./schemas";
|
||||
import type { LoaderContext } from "astro/loaders";
|
||||
import Pocketbase, { type AdminAuthResponse } from "pocketbase";
|
||||
|
||||
let pocketbase: TypedPocketbase;
|
||||
let auth: Promise<AdminAuthResponse>;
|
||||
let isAuthenticating = false;
|
||||
|
||||
export function pocketbaseLoader({ collection }: PocketbaseLoaderOptions) {
|
||||
return {
|
||||
name: "pocketbase-loader",
|
||||
load: async ({ store, logger, meta, parseData }: LoaderContext) => {
|
||||
const { ASTRO_POCKETBASE_ADMIN_EMAIL, ASTRO_POCKETBASE_ADMIN_PASSWORD, PUBLIC_ASTRO_POCKETBASE_URL } = import.meta.env;
|
||||
if (!ASTRO_POCKETBASE_ADMIN_EMAIL || !ASTRO_POCKETBASE_ADMIN_PASSWORD || !PUBLIC_ASTRO_POCKETBASE_URL)
|
||||
return logger.error("Environment variables not set");
|
||||
|
||||
logger.info(`Loading ${collection}`);
|
||||
|
||||
if (!pocketbase) pocketbase = new Pocketbase(PUBLIC_ASTRO_POCKETBASE_URL);
|
||||
|
||||
try {
|
||||
if (!isAuthenticating && !pocketbase.authStore.isValid) {
|
||||
isAuthenticating = true;
|
||||
auth = pocketbase.admins.authWithPassword(ASTRO_POCKETBASE_ADMIN_EMAIL, ASTRO_POCKETBASE_ADMIN_PASSWORD);
|
||||
}
|
||||
await auth;
|
||||
|
||||
const lastUpdatedItems = await pocketbase
|
||||
.collection(collection)
|
||||
.getList(1, 1, { fields: "updated", skipTotal: true, sort: "updated", order: "desc" });
|
||||
const lastUpdated = lastUpdatedItems.items[0]?.updated;
|
||||
|
||||
if (lastUpdated !== meta.get("last-updated")) {
|
||||
logger.info(`Refreshing ${collection}`);
|
||||
|
||||
meta.set("last-updated", lastUpdated);
|
||||
const items = await pocketbase.collection(collection).getFullList();
|
||||
for (const { id, updated, ...rest } of items) {
|
||||
const data = await parseData({ id, data: { id, updated, ...rest } });
|
||||
store.set({ data, digest: updated, id });
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(`Loaded ${collection}`);
|
||||
} catch (error) {
|
||||
logger.error(`Error fetching ${collection}: ${error}`);
|
||||
return;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export type PocketbaseLoaderOptions = {
|
||||
collection: Collection;
|
||||
};
|
||||
17
package/assets/middleware.ts
Normal file
17
package/assets/middleware.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
// This file was automatically generated by Astro PocketBase.
|
||||
|
||||
import { defineMiddleware } from "astro:middleware";
|
||||
import { helpersFrom } from "astro-pocketbase";
|
||||
import PocketBase from "pocketbase";
|
||||
|
||||
const middleware = defineMiddleware((context, next) => {
|
||||
const pocketbase = new PocketBase(import.meta.env.PUBLIC_ASTRO_POCKETBASE_URL);
|
||||
const { getRecord, getRecords } = helpersFrom({ pocketbase });
|
||||
context.locals.pocketbase = pocketbase;
|
||||
context.locals.getRecord = getRecord;
|
||||
context.locals.getRecords = getRecords;
|
||||
return next();
|
||||
});
|
||||
|
||||
// You should NOT change the exported name as it is used by the Astro PocketBase integration.
|
||||
export { middleware as onRequest };
|
||||
17
package/assets/toolbar.ts
Normal file
17
package/assets/toolbar.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { defineToolbarApp } from "astro/toolbar";
|
||||
|
||||
export default defineToolbarApp({
|
||||
init(_canvas, app, server) {
|
||||
let pending = false;
|
||||
|
||||
// const button = document.querySelector("astro-dev-toolbar")?.shadowRoot.querySelector("button[data-app-id='astro-pocketbase']");
|
||||
|
||||
app.onToggled(({ state }) => {
|
||||
if (!state) return;
|
||||
app.toggleNotification({ level: "error", state: true });
|
||||
if (pending) return;
|
||||
pending = true;
|
||||
server.send("astro-pocketbase:refresh", undefined);
|
||||
});
|
||||
},
|
||||
});
|
||||
1
package/env.d.ts
vendored
Normal file
1
package/env.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/// <reference types="astro/client" />
|
||||
54
package/package.json
Normal file
54
package/package.json
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"name": "astro-pocketbase",
|
||||
"version": "0.11.0",
|
||||
"description": "Astro integration to ease the use of PocketBase in your Astro projects",
|
||||
"author": {
|
||||
"email": "gregory.bouteiller@niama.re",
|
||||
"name": "Gregory Bouteiller",
|
||||
"url": "https://github.com/gbouteiller"
|
||||
},
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"astro-integration",
|
||||
"astro-component",
|
||||
"withastro",
|
||||
"astro",
|
||||
"pocketbase"
|
||||
],
|
||||
"homepage": "https://github.com/gbouteiller/astro-pocketbase",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"assets"
|
||||
],
|
||||
"scripts": {
|
||||
"dev": "tsup --watch",
|
||||
"build": "tsup"
|
||||
},
|
||||
"type": "module",
|
||||
"peerDependencies": {
|
||||
"astro": "^4.15.1",
|
||||
"pocketbase": "<0.22.0",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro-integration-kit": "^0.18.0",
|
||||
"dotenv": "^16.4.7",
|
||||
"es-toolkit": "^1.30.1",
|
||||
"zod-pocketbase": "^0.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"pocketbase": "<0.22.0",
|
||||
"tsup": "^8.3.5",
|
||||
"zod": "^3.24.1"
|
||||
}
|
||||
}
|
||||
4
package/src/index.ts
Normal file
4
package/src/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { integration } from "./integration.js";
|
||||
export * from "zod-pocketbase";
|
||||
|
||||
export default integration;
|
||||
75
package/src/integration.ts
Normal file
75
package/src/integration.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { createResolver, defineIntegration } from "astro-integration-kit";
|
||||
import dotenv from "dotenv";
|
||||
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
||||
import type { CollectionModel } from "pocketbase";
|
||||
import { Config, Credentials, defaultConfig, fetchCollections } from "zod-pocketbase";
|
||||
import { generate } from "zod-pocketbase/server";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
export const integration = defineIntegration({
|
||||
name: "astro-pocketbase",
|
||||
optionsSchema: Config.omit({ adminEmail: true, adminPassword: true, output: true, url: true }).default(defaultConfig),
|
||||
setup({ options }) {
|
||||
const { resolve } = createResolver(import.meta.url);
|
||||
|
||||
let collections: CollectionModel[] = [];
|
||||
|
||||
return {
|
||||
hooks: {
|
||||
"astro:config:setup": async (params) => {
|
||||
const { addDevToolbarApp, addMiddleware, config, logger } = params;
|
||||
const { srcDir } = config;
|
||||
|
||||
const {
|
||||
ASTRO_POCKETBASE_ADMIN_EMAIL: adminEmail,
|
||||
ASTRO_POCKETBASE_ADMIN_PASSWORD: adminPassword,
|
||||
PUBLIC_ASTRO_POCKETBASE_URL: url,
|
||||
} = process.env;
|
||||
|
||||
try {
|
||||
const output = `${srcDir.pathname}lib/pocketbase/schemas.ts`;
|
||||
const config = Config.parse({ ...options, adminEmail, adminPassword, url, output });
|
||||
const credentials = Credentials.parse(config);
|
||||
const allCollections = await fetchCollections(credentials);
|
||||
collections = allCollections.filter(({ name }) => !config.ignore.includes(name));
|
||||
await generate(collections, config);
|
||||
} catch (error) {
|
||||
logger.error(error instanceof Error ? error.message : "unknown error");
|
||||
}
|
||||
|
||||
if (!existsSync(new URL("lib/pocketbase/loader.ts", srcDir))) {
|
||||
const loaderContent = readFileSync(resolve("../assets/loader.ts"), "utf-8");
|
||||
writeFileSync(new URL("lib/pocketbase/loader.ts", srcDir), loaderContent);
|
||||
}
|
||||
|
||||
if (!existsSync(new URL("lib/pocketbase/middleware.ts", srcDir))) {
|
||||
const middlewareContent = readFileSync(resolve("../assets/middleware.ts"), "utf-8");
|
||||
writeFileSync(new URL("lib/pocketbase/middleware.ts", srcDir), middlewareContent);
|
||||
}
|
||||
addMiddleware({ entrypoint: new URL("lib/pocketbase/middleware.ts", srcDir), order: "pre" });
|
||||
|
||||
addDevToolbarApp({
|
||||
id: "astro-pocketbase",
|
||||
name: "Astro PocketBase",
|
||||
icon: `<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>PocketBase</title><path fill="currentColor" d="M5.684 12a.632.632 0 0 1-.631-.632V4.421c0-.349.282-.632.631-.632h2.37c.46 0 .889.047 1.287.139.407.084.758.23 1.053.44.303.202.541.475.715.82.173.335.26.75.26 1.246 0 .479-.092.894-.273 1.247a2.373 2.373 0 0 1-.715.869 3.11 3.11 0 0 1-1.053.503c-.398.11-.823.164-1.273.164h-.46a.632.632 0 0 0-.632.632v1.52a.632.632 0 0 1-.632.631Zm1.279-4.888c0 .349.283.632.632.632h.343c1.04 0 1.56-.437 1.56-1.31 0-.428-.135-.73-.404-.907-.26-.176-.645-.264-1.156-.264h-.343a.632.632 0 0 0-.632.631Zm6.3 13.098a.632.632 0 0 1-.631-.631v-6.947a.63.63 0 0 1 .631-.632h2.203c.44 0 .845.034 1.216.1.38.06.708.169.984.328.276.16.492.37.647.63.164.26.246.587.246.982 0 .185-.03.37-.09.554a1.537 1.537 0 0 1-.26.516 1.857 1.857 0 0 1-1.076.7.031.031 0 0 0-.023.03c0 .015.01.028.025.03.591.111 1.04.32 1.346.626.311.31.466.743.466 1.297 0 .42-.082.78-.246 1.083a2.153 2.153 0 0 1-.685.755 3.4 3.4 0 0 1-1.036.441 5.477 5.477 0 0 1-1.268.139zm1.271-5.542c0 .349.283.631.632.631h.21c.465 0 .802-.088 1.009-.264.207-.176.31-.424.31-.743 0-.302-.107-.516-.323-.642-.207-.135-.535-.202-.984-.202h-.222a.632.632 0 0 0-.632.632Zm0 3.463c0 .349.283.631.632.631h.39c1.019 0 1.528-.369 1.528-1.108 0-.36-.125-.621-.376-.78-.241-.16-.625-.24-1.152-.24h-.39a.632.632 0 0 0-.632.632zM1.389 0C.629 0 0 .629 0 1.389V15.03a1.4 1.4 0 0 0 1.389 1.39H8.21a.632.632 0 0 0 .63-.632.632.632 0 0 0-.63-.63H1.389c-.078 0-.125-.05-.125-.128V1.39c0-.078.047-.125.125-.125H15.03c.078 0 .127.047.127.125v6.82a.632.632 0 0 0 .631.63.632.632 0 0 0 .633-.63V1.389A1.4 1.4 0 0 0 15.032 0ZM15.79 7.578a.632.632 0 0 0-.632.633.632.632 0 0 0 .631.63h6.822c.078 0 .125.05.125.128V22.61c0 .078-.047.125-.125.125H8.97c-.077 0-.127-.047-.127-.125v-6.82a.632.632 0 0 0-.631-.63.632.632 0 0 0-.633.63v6.822A1.4 1.4 0 0 0 8.968 24h13.643c.76 0 1.389-.629 1.389-1.389V8.97a1.4 1.4 0 0 0-1.389-1.39Z"/></svg>`,
|
||||
entrypoint: resolve("../assets/toolbar.ts"),
|
||||
});
|
||||
},
|
||||
|
||||
"astro:config:done": ({ injectTypes }) => {
|
||||
const content = readFileSync(resolve("../assets/env.d.ts"), "utf-8");
|
||||
injectTypes({ filename: "env.d.ts", content });
|
||||
},
|
||||
|
||||
//@ts-ignore
|
||||
"astro:server:setup": ({ refreshContent, toolbar }) => {
|
||||
toolbar.on("astro-pocketbase:refresh", async () => {
|
||||
if (!refreshContent) console.warn("Content can only be refreshed in Astro v5.0.0 or higher");
|
||||
await refreshContent?.({ loaders: ["pocketbase-loader"] });
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
9
package/tsconfig.json
Normal file
9
package/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "astro/tsconfigs/strictest",
|
||||
"compilerOptions": {
|
||||
"module": "Node16",
|
||||
"moduleResolution": "Node16",
|
||||
"jsx": "preserve"
|
||||
},
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
19
package/tsup.config.ts
Normal file
19
package/tsup.config.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { defineConfig } from "tsup";
|
||||
import { peerDependencies } from "./package.json";
|
||||
|
||||
export default defineConfig((options) => {
|
||||
const dev = !!options.watch;
|
||||
return {
|
||||
entry: ["src/**/*.(ts|js)"],
|
||||
format: ["esm"],
|
||||
target: "node18",
|
||||
bundle: true,
|
||||
dts: true,
|
||||
sourcemap: true,
|
||||
clean: true,
|
||||
splitting: false,
|
||||
minify: !dev,
|
||||
external: [...Object.keys(peerDependencies)],
|
||||
tsconfig: "tsconfig.json",
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user