astro-loader-pocketbase 2.10.1 → 3.0.0-astro-v6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -34
- package/package.json +19 -17
- package/src/index.ts +8 -11
- package/src/loader/cleanup-entries.ts +2 -2
- package/src/loader/fetch-collection.ts +2 -2
- package/src/loader/fetch-entry.ts +2 -2
- package/src/loader/live-collection-loader.ts +4 -6
- package/src/loader/live-entry-loader.ts +2 -2
- package/src/loader/parse-live-entry.ts +2 -2
- package/src/pocketbase-loader.ts +23 -20
- package/src/schema/generate-schema.ts +6 -7
- package/src/schema/generate-type.ts +19 -0
- package/src/schema/parse-schema.ts +4 -5
- package/src/types/pocketbase-entry.type.ts +2 -12
- package/src/types/pocketbase-live-loader-filter.type.ts +3 -7
- package/src/types/pocketbase-loader-options.type.ts +3 -16
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@ This package is a simple loader to load data from a PocketBase database into Ast
|
|
|
15
15
|
|
|
16
16
|
| Loader | Astro | PocketBase |
|
|
17
17
|
| ------ | ----- | ---------- |
|
|
18
|
+
| 3.0.0 | 6.0.0 | >= 0.23.0 |
|
|
18
19
|
| 2.0.0 | 5.0.0 | >= 0.23.0 |
|
|
19
20
|
| 1.0.0 | 5.0.0 | <= 0.22.0 |
|
|
20
21
|
|
|
@@ -42,7 +43,7 @@ If you want to update your deployed site with new entries, you need to rebuild i
|
|
|
42
43
|
<sub>When running the dev server, you can trigger a reload by using `s + enter`.</sub>
|
|
43
44
|
|
|
44
45
|
> [!TIP]
|
|
45
|
-
> If you need live data on your production site, you can use the
|
|
46
|
+
> If you need live data on your production site, you can use the live content loader described below.
|
|
46
47
|
|
|
47
48
|
## Incremental builds
|
|
48
49
|
|
|
@@ -201,23 +202,6 @@ When superuser credentials are provided, the loader will **always use the remote
|
|
|
201
202
|
If you don't want to use the automatic type generation, you can also [provide your own schema manually](https://docs.astro.build/en/guides/content-collections/#defining-the-collection-schema).
|
|
202
203
|
This manual schema will **always override the automatic type generation**.
|
|
203
204
|
|
|
204
|
-
### Improved types
|
|
205
|
-
|
|
206
|
-
By default PocketBase reports `number` and `boolean` fields as not required, even though the API will always return `0` and `false` respectively if no value is set.
|
|
207
|
-
This means that the loader will add `undefined` to the type of these fields.
|
|
208
|
-
If you want to enforce that these fields are always present, you can set the `improveTypes` option to `true`.
|
|
209
|
-
|
|
210
|
-
```ts
|
|
211
|
-
const blog = defineCollection({
|
|
212
|
-
loader: pocketbaseLoader({
|
|
213
|
-
...options,
|
|
214
|
-
improveTypes: true
|
|
215
|
-
})
|
|
216
|
-
});
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
This will remove `undefined` from the type of these fields and mark them as required.
|
|
220
|
-
|
|
221
205
|
## All options
|
|
222
206
|
|
|
223
207
|
| Option | Type | Required | Description |
|
|
@@ -230,16 +214,9 @@ This will remove `undefined` from the type of these fields and mark them as requ
|
|
|
230
214
|
| `filter` | `string` | | Custom filter to use when fetching entries. Used to filter the entries by specific conditions. |
|
|
231
215
|
| `superuserCredentials` | `{ email: string, password: string } \| { impersonateToken: string }` | | The email and password or impersonate token of a superuser of the PocketBase instance. This is used for automatic type generation. |
|
|
232
216
|
| `localSchema` | `string` | | The path to a local schema file. This is used for automatic type generation. |
|
|
233
|
-
| `jsonSchemas` | `Record<string,
|
|
234
|
-
| `improveTypes` | `boolean` | | Whether to improve the types of `number` and `boolean` fields, removing `undefined` from them. |
|
|
235
|
-
|
|
236
|
-
## Experimental live content loader
|
|
237
|
-
|
|
238
|
-
> [!WARNING]
|
|
239
|
-
> Live content collections are still experimental and may change in the future.
|
|
240
|
-
> This means that this packages live content loader is also experimental and may include breaking changes with every release.
|
|
217
|
+
| `jsonSchemas` | `Record<string, ZodType>` | | A record of Zod schemas to use for type generation of `json` fields. |
|
|
241
218
|
|
|
242
|
-
|
|
219
|
+
## Live content loader
|
|
243
220
|
|
|
244
221
|
### General usage
|
|
245
222
|
|
|
@@ -249,7 +226,7 @@ The options for this packages loader are similar to the regular PocketBase loade
|
|
|
249
226
|
|
|
250
227
|
```ts
|
|
251
228
|
const blogLive = defineLiveCollection({
|
|
252
|
-
loader:
|
|
229
|
+
loader: pocketbaseLiveLoader({
|
|
253
230
|
url: "https://<your-pocketbase-url>",
|
|
254
231
|
collectionName: "<collection-in-pocketbase>"
|
|
255
232
|
})
|
|
@@ -302,7 +279,7 @@ If you also want to use the `lastModified` hint, just tell the loader which fiel
|
|
|
302
279
|
|
|
303
280
|
```ts
|
|
304
281
|
const blogLive = defineLiveCollection({
|
|
305
|
-
loader:
|
|
282
|
+
loader: pocketbaseLiveLoader({
|
|
306
283
|
...options,
|
|
307
284
|
updatedField: "<field-in-collection>"
|
|
308
285
|
})
|
|
@@ -311,7 +288,7 @@ const blogLive = defineLiveCollection({
|
|
|
311
288
|
|
|
312
289
|
### Error handling
|
|
313
290
|
|
|
314
|
-
The live content loader follows Astro's standard error handling conventions for live collections. For more information on how to handle errors in your components, see the [Astro documentation on error handling](https://docs.astro.build/en/reference/
|
|
291
|
+
The live content loader follows Astro's standard error handling conventions for live collections. For more information on how to handle errors in your components, see the [Astro documentation on error handling](https://docs.astro.build/en/reference/content-loader-reference/#error-handling-in-live-loaders).
|
|
315
292
|
|
|
316
293
|
| Error | When it's returned |
|
|
317
294
|
| ------------------------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
@@ -340,10 +317,7 @@ const blogTypes = defineCollection({
|
|
|
340
317
|
});
|
|
341
318
|
|
|
342
319
|
const blogLive = defineLiveCollection({
|
|
343
|
-
loader:
|
|
344
|
-
experimentalPocketbaseLiveLoader<CollectionEntry<"blogTypes">["data"]>(
|
|
345
|
-
options
|
|
346
|
-
)
|
|
320
|
+
loader: pocketbaseLiveLoader<CollectionEntry<"blogTypes">["data"]>(options)
|
|
347
321
|
});
|
|
348
322
|
```
|
|
349
323
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro-loader-pocketbase",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-astro-v6.2",
|
|
4
4
|
"description": "A content loader for Astro that uses the PocketBase API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"astro",
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"src"
|
|
28
28
|
],
|
|
29
29
|
"scripts": {
|
|
30
|
-
"format": "
|
|
31
|
-
"format:check": "
|
|
32
|
-
"lint": "oxlint --type-aware",
|
|
33
|
-
"lint:fix": "oxlint --type-aware --fix",
|
|
30
|
+
"format": "prettier . --write --cache --cache-location=./.prettier-cache --experimental-cli",
|
|
31
|
+
"format:check": "prettier . --check --cache --cache-location=./.prettier-cache --experimental-cli",
|
|
32
|
+
"lint": "oxlint --type-aware --type-check",
|
|
33
|
+
"lint:fix": "oxlint --type-aware --type-check --fix",
|
|
34
34
|
"prepare": "husky",
|
|
35
35
|
"test": "vitest run",
|
|
36
36
|
"test:e2e": "vitest run $(find test -name '*.e2e-spec.ts')",
|
|
@@ -40,27 +40,29 @@
|
|
|
40
40
|
"test:unit": "vitest run $(find test -name '*.spec.ts')",
|
|
41
41
|
"test:unit:watch": "vitest watch $(find test -name '*.spec.ts')",
|
|
42
42
|
"test:watch": "vitest watch",
|
|
43
|
-
"typecheck": "
|
|
43
|
+
"typecheck": "tsc --noEmit"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@commitlint/cli": "20.
|
|
47
|
-
"@commitlint/config-conventional": "20.
|
|
46
|
+
"@commitlint/cli": "20.3.1",
|
|
47
|
+
"@commitlint/config-conventional": "20.3.1",
|
|
48
48
|
"@types/node": "24.10.1",
|
|
49
|
-
"@vitest/coverage-v8": "4.0.
|
|
50
|
-
"astro": "
|
|
51
|
-
"globals": "
|
|
49
|
+
"@vitest/coverage-v8": "4.0.17",
|
|
50
|
+
"astro": "6.0.0-beta.1",
|
|
51
|
+
"globals": "17.0.0",
|
|
52
52
|
"husky": "9.1.7",
|
|
53
53
|
"lint-staged": "16.2.7",
|
|
54
|
-
"oxlint": "1.
|
|
55
|
-
"oxlint-tsgolint": "0.
|
|
56
|
-
"prettier": "3.
|
|
54
|
+
"oxlint": "1.39.0",
|
|
55
|
+
"oxlint-tsgolint": "0.11.1",
|
|
56
|
+
"prettier": "3.8.0",
|
|
57
57
|
"prettier-plugin-organize-imports": "4.3.0",
|
|
58
|
-
"prettier-plugin-packagejson": "2.5.
|
|
58
|
+
"prettier-plugin-packagejson": "2.5.21",
|
|
59
59
|
"typescript": "5.9.3",
|
|
60
|
-
"vitest": "4.0.
|
|
60
|
+
"vitest": "4.0.17",
|
|
61
|
+
"zod-to-ts": "2.0.0"
|
|
61
62
|
},
|
|
62
63
|
"peerDependencies": {
|
|
63
|
-
"astro": "^
|
|
64
|
+
"astro": "^6.0.0",
|
|
65
|
+
"zod-to-ts": "^2.0.0"
|
|
64
66
|
},
|
|
65
67
|
"packageManager": "npm@11.7.0",
|
|
66
68
|
"publishConfig": {
|
package/src/index.ts
CHANGED
|
@@ -1,27 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
experimentalPocketbaseLiveLoader,
|
|
3
|
-
pocketbaseLoader
|
|
4
|
-
} from "./pocketbase-loader";
|
|
1
|
+
import { pocketbaseLiveLoader, pocketbaseLoader } from "./pocketbase-loader";
|
|
5
2
|
import { transformFileUrl } from "./schema/transform-files";
|
|
6
3
|
import { PocketBaseAuthenticationError } from "./types/errors";
|
|
7
4
|
import type {
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
PocketBaseLiveLoaderCollectionFilter,
|
|
6
|
+
PocketBaseLiveLoaderEntryFilter
|
|
10
7
|
} from "./types/pocketbase-live-loader-filter.type";
|
|
11
8
|
import type {
|
|
12
|
-
|
|
9
|
+
PocketBaseLiveLoaderOptions,
|
|
13
10
|
PocketBaseLoaderOptions
|
|
14
11
|
} from "./types/pocketbase-loader-options.type";
|
|
15
12
|
|
|
16
13
|
export {
|
|
17
|
-
experimentalPocketbaseLiveLoader,
|
|
18
14
|
PocketBaseAuthenticationError,
|
|
15
|
+
pocketbaseLiveLoader,
|
|
19
16
|
pocketbaseLoader,
|
|
20
17
|
transformFileUrl
|
|
21
18
|
};
|
|
22
19
|
export type {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
PocketBaseLiveLoaderCollectionFilter,
|
|
21
|
+
PocketBaseLiveLoaderEntryFilter,
|
|
22
|
+
PocketBaseLiveLoaderOptions,
|
|
26
23
|
PocketBaseLoaderOptions
|
|
27
24
|
};
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
pocketBaseListResponse
|
|
6
6
|
} from "../types/pocketbase-api-response.type";
|
|
7
7
|
import type { PocketBaseEntry } from "../types/pocketbase-entry.type";
|
|
8
|
-
import {
|
|
8
|
+
import { pocketBaseEntry } from "../types/pocketbase-entry.type";
|
|
9
9
|
import type { PocketBaseLoaderBaseOptions } from "../types/pocketbase-loader-options.type";
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -133,5 +133,5 @@ export async function cleanupEntries(
|
|
|
133
133
|
const cleanUpEntriesResponse = pocketBaseListResponse
|
|
134
134
|
.omit({ items: true })
|
|
135
135
|
.extend({
|
|
136
|
-
items: z.array(
|
|
136
|
+
items: z.array(pocketBaseEntry.pick({ id: true }))
|
|
137
137
|
});
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
pocketBaseListResponse
|
|
9
9
|
} from "../types/pocketbase-api-response.type";
|
|
10
10
|
import type { PocketBaseEntry } from "../types/pocketbase-entry.type";
|
|
11
|
-
import type {
|
|
11
|
+
import type { PocketBaseLiveLoaderCollectionFilter } from "../types/pocketbase-live-loader-filter.type";
|
|
12
12
|
import type { PocketBaseLoaderBaseOptions } from "../types/pocketbase-loader-options.type";
|
|
13
13
|
import { combineFieldsForRequest } from "../utils/combine-fields-for-request";
|
|
14
14
|
import { formatFields } from "../utils/format-fields";
|
|
@@ -22,7 +22,7 @@ export type CollectionFilter = {
|
|
|
22
22
|
* If not provided, all entries will be fetched.
|
|
23
23
|
*/
|
|
24
24
|
lastModified?: string;
|
|
25
|
-
} &
|
|
25
|
+
} & PocketBaseLiveLoaderCollectionFilter;
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Fetches entries from a PocketBase collection, optionally filtering by modification date and supporting pagination.
|
|
@@ -6,7 +6,7 @@ import { PocketBaseAuthenticationError } from "../types/errors";
|
|
|
6
6
|
import { pocketBaseErrorResponse } from "../types/pocketbase-api-response.type";
|
|
7
7
|
import type { PocketBaseEntry } from "../types/pocketbase-entry.type";
|
|
8
8
|
import { pocketBaseEntry } from "../types/pocketbase-entry.type";
|
|
9
|
-
import type {
|
|
9
|
+
import type { PocketBaseLiveLoaderOptions } from "../types/pocketbase-loader-options.type";
|
|
10
10
|
import { combineFieldsForRequest } from "../utils/combine-fields-for-request";
|
|
11
11
|
import { formatFields } from "../utils/format-fields";
|
|
12
12
|
|
|
@@ -15,7 +15,7 @@ import { formatFields } from "../utils/format-fields";
|
|
|
15
15
|
*/
|
|
16
16
|
export async function fetchEntry<TEntry extends PocketBaseEntry>(
|
|
17
17
|
id: string,
|
|
18
|
-
options:
|
|
18
|
+
options: PocketBaseLiveLoaderOptions,
|
|
19
19
|
token: string | undefined
|
|
20
20
|
): Promise<TEntry> {
|
|
21
21
|
// Build the URL for the entry endpoint
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { LiveDataCollection, LiveDataEntry } from "astro";
|
|
2
2
|
import { LiveCollectionError } from "astro/content/runtime";
|
|
3
3
|
import type { PocketBaseEntry } from "../types/pocketbase-entry.type";
|
|
4
|
-
import type {
|
|
5
|
-
import type {
|
|
4
|
+
import type { PocketBaseLiveLoaderCollectionFilter } from "../types/pocketbase-live-loader-filter.type";
|
|
5
|
+
import type { PocketBaseLiveLoaderOptions } from "../types/pocketbase-loader-options.type";
|
|
6
6
|
import { fetchCollection } from "./fetch-collection";
|
|
7
7
|
import { parseLiveEntry } from "./parse-live-entry";
|
|
8
8
|
|
|
@@ -10,10 +10,8 @@ import { parseLiveEntry } from "./parse-live-entry";
|
|
|
10
10
|
* Loads and parses a PocketBase collection for live data, returning entries or an error.
|
|
11
11
|
*/
|
|
12
12
|
export async function liveCollectionLoader<TEntry extends PocketBaseEntry>(
|
|
13
|
-
collectionFilter:
|
|
14
|
-
|
|
15
|
-
| undefined,
|
|
16
|
-
options: ExperimentalPocketBaseLiveLoaderOptions,
|
|
13
|
+
collectionFilter: PocketBaseLiveLoaderCollectionFilter | undefined,
|
|
14
|
+
options: PocketBaseLiveLoaderOptions,
|
|
17
15
|
token: string | undefined
|
|
18
16
|
): Promise<LiveDataCollection<TEntry> | { error: LiveCollectionError }> {
|
|
19
17
|
const entries: Array<LiveDataEntry<TEntry>> = [];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { LiveDataEntry } from "astro";
|
|
2
2
|
import { LiveCollectionError } from "astro/content/runtime";
|
|
3
3
|
import type { PocketBaseEntry } from "../types/pocketbase-entry.type";
|
|
4
|
-
import type {
|
|
4
|
+
import type { PocketBaseLiveLoaderOptions } from "../types/pocketbase-loader-options.type";
|
|
5
5
|
import { fetchEntry } from "./fetch-entry";
|
|
6
6
|
import { parseLiveEntry } from "./parse-live-entry";
|
|
7
7
|
|
|
@@ -10,7 +10,7 @@ import { parseLiveEntry } from "./parse-live-entry";
|
|
|
10
10
|
*/
|
|
11
11
|
export async function liveEntryLoader<TEntry extends PocketBaseEntry>(
|
|
12
12
|
id: string,
|
|
13
|
-
options:
|
|
13
|
+
options: PocketBaseLiveLoaderOptions,
|
|
14
14
|
token: string | undefined
|
|
15
15
|
): Promise<LiveDataEntry<TEntry> | { error: LiveCollectionError }> {
|
|
16
16
|
try {
|
|
@@ -2,14 +2,14 @@ import type { LiveDataEntry } from "astro";
|
|
|
2
2
|
import { LiveCollectionValidationError } from "astro/content/runtime";
|
|
3
3
|
import { z } from "astro/zod";
|
|
4
4
|
import type { PocketBaseEntry } from "../types/pocketbase-entry.type";
|
|
5
|
-
import type {
|
|
5
|
+
import type { PocketBaseLiveLoaderOptions } from "../types/pocketbase-loader-options.type";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Converts a PocketBase entry into a LiveDataEntry for Astro, extracting content and cache metadata.
|
|
9
9
|
*/
|
|
10
10
|
export function parseLiveEntry<TEntry extends PocketBaseEntry>(
|
|
11
11
|
entry: TEntry,
|
|
12
|
-
options:
|
|
12
|
+
options: PocketBaseLiveLoaderOptions
|
|
13
13
|
): LiveDataEntry<TEntry> {
|
|
14
14
|
// Build a cache tag
|
|
15
15
|
const tag = `${options.collectionName}-${entry.id}`;
|
package/src/pocketbase-loader.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import type { LiveDataCollection, LiveDataEntry } from "astro";
|
|
2
2
|
import type { LiveCollectionError } from "astro/content/runtime";
|
|
3
|
-
import type { LiveLoader, Loader } from "astro/loaders";
|
|
4
|
-
import type { ZodSchema } from "astro/zod";
|
|
3
|
+
import type { LiveLoader, Loader, LoaderContext } from "astro/loaders";
|
|
5
4
|
import { liveCollectionLoader } from "./loader/live-collection-loader";
|
|
6
5
|
import { liveEntryLoader } from "./loader/live-entry-loader";
|
|
7
6
|
import { loader } from "./loader/loader";
|
|
8
7
|
import { generateSchema } from "./schema/generate-schema";
|
|
8
|
+
import { generateType } from "./schema/generate-type";
|
|
9
9
|
import type { PocketBaseEntry } from "./types/pocketbase-entry.type";
|
|
10
10
|
import type {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
PocketBaseLiveLoaderCollectionFilter,
|
|
12
|
+
PocketBaseLiveLoaderEntryFilter
|
|
13
13
|
} from "./types/pocketbase-live-loader-filter.type";
|
|
14
14
|
import type {
|
|
15
|
-
|
|
15
|
+
PocketBaseLiveLoaderOptions,
|
|
16
16
|
PocketBaseLoaderOptions
|
|
17
17
|
} from "./types/pocketbase-loader-options.type";
|
|
18
18
|
import { createTokenPromise } from "./utils/create-token-promise";
|
|
@@ -22,13 +22,14 @@ import { createTokenPromise } from "./utils/create-token-promise";
|
|
|
22
22
|
*
|
|
23
23
|
* @param options Options for the loader. See {@link PocketBaseLoaderOptions} for more details.
|
|
24
24
|
*/
|
|
25
|
-
|
|
25
|
+
// oxlint-disable-next-line explicit-module-boundary-types
|
|
26
|
+
export function pocketbaseLoader(options: PocketBaseLoaderOptions) {
|
|
26
27
|
// Create shared promise for the superuser token, which can be reused
|
|
27
28
|
const tokenPromise = createTokenPromise(options);
|
|
28
29
|
|
|
29
30
|
return {
|
|
30
31
|
name: "pocketbase-loader",
|
|
31
|
-
load: async (context): Promise<void> => {
|
|
32
|
+
load: async (context: LoaderContext): Promise<void> => {
|
|
32
33
|
if (options.experimental?.liveTypesOnly) {
|
|
33
34
|
context.logger.label = `pocketbase-loader:${options.collectionName}`;
|
|
34
35
|
context.logger.info(
|
|
@@ -42,31 +43,33 @@ export function pocketbaseLoader(options: PocketBaseLoaderOptions): Loader {
|
|
|
42
43
|
// Load the entries from the collection
|
|
43
44
|
await loader(context, options, token);
|
|
44
45
|
},
|
|
45
|
-
|
|
46
|
+
// oxlint-disable-next-line explicit-module-boundary-types
|
|
47
|
+
createSchema: async () => {
|
|
46
48
|
const token = await tokenPromise;
|
|
47
49
|
|
|
48
50
|
// Generate the schema for the collection according to the API
|
|
49
|
-
|
|
51
|
+
const schema = await generateSchema(options, token);
|
|
52
|
+
const types = generateType(schema);
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
schema,
|
|
56
|
+
types
|
|
57
|
+
};
|
|
50
58
|
}
|
|
51
|
-
};
|
|
59
|
+
} satisfies Loader;
|
|
52
60
|
}
|
|
53
61
|
|
|
54
62
|
/**
|
|
55
63
|
* Live loader for collections stored in PocketBase.
|
|
56
|
-
* This loader is currently experimental and may change in any future release.
|
|
57
|
-
*
|
|
58
|
-
* @param options Options for the live loader. See {@link ExperimentalPocketBaseLiveLoaderOptions} for more details.
|
|
59
64
|
*
|
|
60
|
-
* @
|
|
65
|
+
* @param options Options for the live loader. See {@link PocketBaseLiveLoaderOptions} for more details.
|
|
61
66
|
*/
|
|
62
|
-
export function
|
|
63
|
-
|
|
64
|
-
>(
|
|
65
|
-
options: ExperimentalPocketBaseLiveLoaderOptions
|
|
67
|
+
export function pocketbaseLiveLoader<TEntry extends PocketBaseEntry>(
|
|
68
|
+
options: PocketBaseLiveLoaderOptions
|
|
66
69
|
): LiveLoader<
|
|
67
70
|
TEntry,
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
PocketBaseLiveLoaderEntryFilter,
|
|
72
|
+
PocketBaseLiveLoaderCollectionFilter,
|
|
70
73
|
LiveCollectionError
|
|
71
74
|
> {
|
|
72
75
|
// Create shared promise for the superuser token, which can be reused
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { ZodSchema } from "astro/zod";
|
|
2
1
|
import { z } from "astro/zod";
|
|
3
2
|
import type { PocketBaseLoaderOptions } from "../types/pocketbase-loader-options.type";
|
|
4
3
|
import type { PocketBaseCollection } from "../types/pocketbase-schema.type";
|
|
@@ -13,11 +12,11 @@ import { transformFiles } from "./transform-files";
|
|
|
13
12
|
/**
|
|
14
13
|
* Basic schema for every PocketBase collection.
|
|
15
14
|
*/
|
|
16
|
-
const BASIC_SCHEMA = {
|
|
15
|
+
const BASIC_SCHEMA = z.object({
|
|
17
16
|
id: z.string(),
|
|
18
17
|
collectionId: z.string(),
|
|
19
18
|
collectionName: z.string()
|
|
20
|
-
};
|
|
19
|
+
});
|
|
21
20
|
|
|
22
21
|
/**
|
|
23
22
|
* Types of fields that can be used as an ID.
|
|
@@ -33,10 +32,11 @@ const VALID_ID_TYPES = ["text", "number", "email", "url", "date"];
|
|
|
33
32
|
* @param options Options for the loader. See {@link PocketBaseLoaderOptions} for more details.
|
|
34
33
|
* @param token The superuser token to authenticate the request.
|
|
35
34
|
*/
|
|
35
|
+
// oxlint-disable-next-line explicit-module-boundary-types
|
|
36
36
|
export async function generateSchema(
|
|
37
37
|
options: PocketBaseLoaderOptions,
|
|
38
38
|
token: string | undefined
|
|
39
|
-
)
|
|
39
|
+
) {
|
|
40
40
|
let collection: PocketBaseCollection | undefined;
|
|
41
41
|
|
|
42
42
|
if (token) {
|
|
@@ -60,7 +60,7 @@ export async function generateSchema(
|
|
|
60
60
|
`No schema available for "${options.collectionName}". Only basic types are available. Please check your configuration and provide a valid schema file or superuser credentials.`
|
|
61
61
|
);
|
|
62
62
|
// Return the basic schema since every collection has at least these fields
|
|
63
|
-
return
|
|
63
|
+
return BASIC_SCHEMA;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
// Get fields to include from options
|
|
@@ -71,7 +71,6 @@ export async function generateSchema(
|
|
|
71
71
|
// Parse the schema with optional field filtering
|
|
72
72
|
const fields = parseSchema(collection, options.jsonSchemas, {
|
|
73
73
|
hasSuperuserRights,
|
|
74
|
-
improveTypes: options.improveTypes,
|
|
75
74
|
fieldsToInclude,
|
|
76
75
|
experimentalLiveTypesOnly: options.experimental?.liveTypesOnly
|
|
77
76
|
});
|
|
@@ -83,7 +82,7 @@ export async function generateSchema(
|
|
|
83
82
|
|
|
84
83
|
// Combine the basic schema with the parsed fields
|
|
85
84
|
const schema = z.object({
|
|
86
|
-
...BASIC_SCHEMA,
|
|
85
|
+
...BASIC_SCHEMA.shape,
|
|
87
86
|
...fields
|
|
88
87
|
});
|
|
89
88
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ZodType } from "astro/zod";
|
|
2
|
+
import {
|
|
3
|
+
createAuxiliaryTypeStore,
|
|
4
|
+
createTypeAlias,
|
|
5
|
+
printNode,
|
|
6
|
+
zodToTs
|
|
7
|
+
} from "zod-to-ts";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Generate a TypeScript type from a Zod schema.
|
|
11
|
+
*/
|
|
12
|
+
export function generateType(schema: ZodType): string {
|
|
13
|
+
const { node } = zodToTs(schema, {
|
|
14
|
+
auxiliaryTypeStore: createAuxiliaryTypeStore()
|
|
15
|
+
});
|
|
16
|
+
const typeAlias = createTypeAlias(node, "Entry");
|
|
17
|
+
|
|
18
|
+
return `export ${printNode(typeAlias)}`;
|
|
19
|
+
}
|
|
@@ -6,7 +6,6 @@ import type {
|
|
|
6
6
|
|
|
7
7
|
export interface ParseSchemaOptions {
|
|
8
8
|
hasSuperuserRights: boolean;
|
|
9
|
-
improveTypes?: boolean;
|
|
10
9
|
fieldsToInclude?: Array<string>;
|
|
11
10
|
experimentalLiveTypesOnly?: boolean;
|
|
12
11
|
}
|
|
@@ -43,7 +42,7 @@ export function parseSchema(
|
|
|
43
42
|
continue;
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
let fieldType;
|
|
45
|
+
let fieldType: z.ZodType;
|
|
47
46
|
|
|
48
47
|
// Determine the field type and create the corresponding Zod type
|
|
49
48
|
// oxlint-disable-next-line switch-exhaustiveness-check
|
|
@@ -113,9 +112,9 @@ export function parseSchema(
|
|
|
113
112
|
field.required ||
|
|
114
113
|
// `onCreate autodate` fields are always set
|
|
115
114
|
(field.type === "autodate" && field.onCreate) ||
|
|
116
|
-
//
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
// number and bool fields are always set
|
|
116
|
+
field.type === "number" ||
|
|
117
|
+
field.type === "bool";
|
|
119
118
|
|
|
120
119
|
// If the field is not required, mark it as optional
|
|
121
120
|
if (!isRequired) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { z } from "astro/zod";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Schema for a PocketBase entry.
|
|
5
5
|
*/
|
|
6
|
-
export const
|
|
6
|
+
export const pocketBaseEntry = z.looseObject({
|
|
7
7
|
/**
|
|
8
8
|
* ID of the entry.
|
|
9
9
|
*/
|
|
@@ -18,16 +18,6 @@ export const pocketBaseBaseEntry = z.object({
|
|
|
18
18
|
collectionName: z.string()
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
/**
|
|
22
|
-
* Base interface for all PocketBase entries.
|
|
23
|
-
*/
|
|
24
|
-
export type PocketBaseBaseEntry = z.infer<typeof pocketBaseBaseEntry>;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Schema for a PocketBase entry.
|
|
28
|
-
*/
|
|
29
|
-
export const pocketBaseEntry = pocketBaseBaseEntry.passthrough();
|
|
30
|
-
|
|
31
21
|
/**
|
|
32
22
|
* Type for a PocketBase entry.
|
|
33
23
|
*/
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Filter for a single entry
|
|
3
|
-
*
|
|
4
|
-
* @experimental Live content collections are still experimental
|
|
5
3
|
*/
|
|
6
|
-
export interface
|
|
4
|
+
export interface PocketBaseLiveLoaderEntryFilter {
|
|
7
5
|
/**
|
|
8
6
|
* Id of the entry.
|
|
9
7
|
*/
|
|
@@ -12,13 +10,11 @@ export interface ExperimentalPocketBaseLiveLoaderEntryFilter {
|
|
|
12
10
|
|
|
13
11
|
/**
|
|
14
12
|
* Filter for a collection of entries.
|
|
15
|
-
*
|
|
16
|
-
* @experimental Live content collections are still experimental
|
|
17
13
|
*/
|
|
18
|
-
export interface
|
|
14
|
+
export interface PocketBaseLiveLoaderCollectionFilter {
|
|
19
15
|
/**
|
|
20
16
|
* Additional filter to apply to the collection.
|
|
21
|
-
* This will be added to the filter supplied in the {@link
|
|
17
|
+
* This will be added to the filter supplied in the {@link PocketBaseLiveLoaderOptions}.
|
|
22
18
|
*
|
|
23
19
|
* Example:
|
|
24
20
|
* ```ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ZodType } from "astro/zod";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Options for both build time and live collection loader
|
|
@@ -125,15 +125,7 @@ export type PocketBaseLoaderOptions = PocketBaseLoaderBaseOptions & {
|
|
|
125
125
|
*
|
|
126
126
|
* Note that this will only be used for fields of type `json`.
|
|
127
127
|
*/
|
|
128
|
-
jsonSchemas?: Record<string,
|
|
129
|
-
/**
|
|
130
|
-
* Whether to improve the types of the generated schema.
|
|
131
|
-
* With this option enabled, the schema will not include `undefined` as possible value for number and boolean fields and mark them as required.
|
|
132
|
-
*
|
|
133
|
-
* Why do we need this option?
|
|
134
|
-
* The PocketBase API does always return at least `0` or `false` as the default values, even though the fields are not marked as required in the schema.
|
|
135
|
-
*/
|
|
136
|
-
improveTypes?: boolean;
|
|
128
|
+
jsonSchemas?: Record<string, ZodType>;
|
|
137
129
|
/**
|
|
138
130
|
* Experimental options for the loader.
|
|
139
131
|
*
|
|
@@ -143,8 +135,6 @@ export type PocketBaseLoaderOptions = PocketBaseLoaderBaseOptions & {
|
|
|
143
135
|
/**
|
|
144
136
|
* Whether to only create types for the live loader.
|
|
145
137
|
* This will not load any data, but only generate types that can be used with the live loader.
|
|
146
|
-
*
|
|
147
|
-
* @experimental Live content collections are still experimental
|
|
148
138
|
*/
|
|
149
139
|
liveTypesOnly?: boolean;
|
|
150
140
|
};
|
|
@@ -152,8 +142,5 @@ export type PocketBaseLoaderOptions = PocketBaseLoaderBaseOptions & {
|
|
|
152
142
|
|
|
153
143
|
/**
|
|
154
144
|
* Options for the PocketBase live loader.
|
|
155
|
-
*
|
|
156
|
-
* @experimental Live content collections are still experimental
|
|
157
145
|
*/
|
|
158
|
-
export type
|
|
159
|
-
PocketBaseLoaderBaseOptions;
|
|
146
|
+
export type PocketBaseLiveLoaderOptions = PocketBaseLoaderBaseOptions;
|