-
Notifications
You must be signed in to change notification settings - Fork 4
feat(expand): Enables the use of Pocketbases 'Expand' property #41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 6 commits
6b3284e
4134e77
75d2917
258f04d
9d20391
3933c35
e6b541f
bc1cca0
0f342cb
3f51a05
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,9 +1,12 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import type { ZodSchema } from "astro/zod"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import type { ZodObject, ZodSchema } from "astro/zod"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import { z } from "astro/zod"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import type { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ExpandedFields, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| PocketBaseCollection | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } from "../types/pocketbase-collection.type"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import type { PocketBaseLoaderOptions } from "../types/pocketbase-loader-options.type"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import type { PocketBaseCollection } from "../types/pocketbase-schema.type"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import { getRemoteSchema } from "./get-remote-schema"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import { parseSchema } from "./parse-schema"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import { parseExpandedSchemaField, parseSchema } from "./parse-schema"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import { readLocalSchema } from "./read-local-schema"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import { transformFiles } from "./transform-files"; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -33,6 +36,7 @@ export async function generateSchema( | |||||||||||||||||||||||||||||||||||||||||||||||||
| options: PocketBaseLoaderOptions | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ): Promise<ZodSchema> { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| let collection: PocketBaseCollection | undefined; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const expandedFields: ExpandedFields = {}; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| // Try to get the schema directly from the PocketBase instance | ||||||||||||||||||||||||||||||||||||||||||||||||||
| collection = await getRemoteSchema(options); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -129,10 +133,54 @@ export async function generateSchema( | |||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| // Combine the basic schema with the parsed fields | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if (options.expand && options.expand.length > 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| for (const expandedFieldName of options.expand) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| const [currentLevelFieldName, ...deeperExpandFields] = | ||||||||||||||||||||||||||||||||||||||||||||||||||
| getCurrentLevelExpandedFieldName(expandedFieldName); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| const expandedFieldDefinition = collection.fields.find( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| (field) => field.name === currentLevelFieldName | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!expandedFieldDefinition) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| throw new Error( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| `The provided field in the expand property "${expandedFieldName}" is not present in the schema of the collection "${options.collectionName}".\nThis will lead to use unable to provide a definition for this field.` | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!expandedFieldDefinition.collectionId) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| throw new Error( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| `The provided field in the expand property "${expandedFieldName}" does not have an associated collection linked to it, we need this in order to know the shape of the related schema.` | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+146
to
+156
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Like with the fields above, I'd keep this as a console error and don't throw an error. We can still get the base data of the current collection, but the expanded object will just be empty.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| const isRequired = expandedFieldDefinition.required; | ||||||||||||||||||||||||||||||||||||||||||||||||||
cf-david-easton marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| const expandedSchema = await generateSchema({ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| collectionName: expandedFieldDefinition.collectionId, | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| superuserCredentials: options.superuserCredentials, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| expand: deeperExpandFields.length ? deeperExpandFields : undefined, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| localSchema: options.localSchema, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| jsonSchemas: options.jsonSchemas, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| improveTypes: options.improveTypes, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| url: options.url | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| collectionName: expandedFieldDefinition.collectionId, | |
| superuserCredentials: options.superuserCredentials, | |
| expand: deeperExpandFields.length ? deeperExpandFields : undefined, | |
| localSchema: options.localSchema, | |
| jsonSchemas: options.jsonSchemas, | |
| improveTypes: options.improveTypes, | |
| url: options.url | |
| ...options, | |
| collectionName: expandedFieldDefinition.collectionId, | |
| expand: deeperExpandFields.length ? deeperExpandFields : undefined |
cf-david-easton marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need this? My assumption would be that the transformation for expanded collections is already done it the recursive call 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes probably, not sure why I added this originally, reverted
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is the purpose of this function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was when I was still trying to figure out how to get the conditional shapes of array or singular elements. It was a core misunderstanding by me that I could read the maxSelect property of the field to understand if its a singular or multiple select, have removed and simplified the expanded property.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| function getCurrentLevelExpandedFieldName(s: string): Array<string> { | |
| /** | |
| * Splits the given expandedField name at the collection split string. | |
| * The first element represents the expandedField name of the current collection, | |
| * the following elements represent deeper nested expanded fields. | |
| */ | |
| function splitExpandedFieldByCollection(expandedField: string): Array<string> { |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| import type { ZodSchema } from "astro/zod"; | ||
| import type { PocketBaseSchemaEntry } from "./pocketbase-schema.type"; | ||
|
|
||
| /** | ||
| * Base interface for all PocketBase entries. | ||
cf-david-easton marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| */ | ||
| interface PocketBaseBaseCollection { | ||
| /** | ||
| * ID of the collection. | ||
| */ | ||
| id: string; | ||
| /** | ||
| * Name of the collection | ||
| */ | ||
| name: string; | ||
| /** | ||
| * Type of the collection. | ||
| */ | ||
| type: "base" | "view" | "auth"; | ||
| /** | ||
| * Schema of the collection. | ||
| */ | ||
| fields: Array<PocketBaseSchemaEntry>; | ||
| } | ||
|
|
||
| /** | ||
| * Type for a PocketBase entry. | ||
| */ | ||
| export type PocketBaseCollection = PocketBaseBaseCollection & | ||
| Record<string, unknown>; | ||
cf-david-easton marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| export type ExpandedFields = Record<string, ZodSchema | Array<ZodSchema>>; | ||
cf-david-easton marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
Uh oh!
There was an error while loading. Please reload this page.