Browse Source

Add preliminary resource relationship support

Define resource methods for adding relationships to other resources.
master
TheoryOfNekomata 7 months ago
parent
commit
b845b96f88
1 changed files with 31 additions and 9 deletions
  1. +31
    -9
      packages/core/src/common/resource.ts

+ 31
- 9
packages/core/src/common/resource.ts View File

@@ -13,12 +13,19 @@ export const PATCH_CONTENT_MAP_TYPE: Record<PatchContentType, CanPatchSpec> = {


type CanPatchObject = Record<CanPatchSpec, boolean>; type CanPatchObject = Record<CanPatchSpec, boolean>;


export interface Relationship<SubjectSchema extends v.BaseSchema, ObjectSchema extends v.BaseSchema> {
objectResource: Resource<BaseResourceType & { schema: ObjectSchema }>,
name: string;
// points to object ID
subjectAttr: string;
}

export interface ResourceState< export interface ResourceState<
ItemName extends string = string, ItemName extends string = string,
RouteName extends string = string RouteName extends string = string
> { > {
shared: Map<string, unknown>; shared: Map<string, unknown>;
relationships: Set<Resource>;
relationships: Map<string, Relationship<any, any>>;
itemName: ItemName; itemName: ItemName;
routeName: RouteName; routeName: RouteName;
canCreate: boolean; canCreate: boolean;
@@ -52,12 +59,17 @@ export interface Resource<ResourceType extends BaseResourceType = BaseResourceTy
canPatch(b?: CanPatch): this; canPatch(b?: CanPatch): this;
canEmplace(b?: boolean): this; canEmplace(b?: boolean): this;
canDelete(b?: boolean): this; canDelete(b?: boolean): this;
relatedTo<RelatedSchema extends v.BaseSchema>(resource: Resource<ResourceType & { schema: RelatedSchema }>): this;
relatesTo<RelatedSchema extends v.BaseSchema>(
resource: Resource<ResourceType & { schema: RelatedSchema }>,
relationshipParams: Relationship<ResourceType['schema'], RelatedSchema>,
): this;
dataSource?: DataSource; dataSource?: DataSource;
id<NewIdAttr extends ResourceType['idAttr'], TheIdSchema extends ResourceType['idSchema']>( id<NewIdAttr extends ResourceType['idAttr'], TheIdSchema extends ResourceType['idSchema']>(
newIdAttr: NewIdAttr, newIdAttr: NewIdAttr,
params: ResourceIdConfig<TheIdSchema> params: ResourceIdConfig<TheIdSchema>
): Resource<ResourceType & { idAttr: NewIdAttr, idSchema: TheIdSchema }>; ): Resource<ResourceType & { idAttr: NewIdAttr, idSchema: TheIdSchema }>;
addMetadata(id: string, value: unknown): this;
setMetadata(id: string, value: unknown): this;
createdAt<NewCreatedAtAttr extends ResourceType['createdAtAttr']>(n: NewCreatedAtAttr): Resource<ResourceType & { createdAtAttr: NewCreatedAtAttr }>; createdAt<NewCreatedAtAttr extends ResourceType['createdAtAttr']>(n: NewCreatedAtAttr): Resource<ResourceType & { createdAtAttr: NewCreatedAtAttr }>;
updatedAt<NewUpdatedAtAttr extends ResourceType['updatedAtAttr']>(n: NewUpdatedAtAttr): Resource<ResourceType & { updatedAtAttr: NewUpdatedAtAttr }>; updatedAt<NewUpdatedAtAttr extends ResourceType['updatedAtAttr']>(n: NewUpdatedAtAttr): Resource<ResourceType & { updatedAtAttr: NewUpdatedAtAttr }>;
} }
@@ -65,7 +77,7 @@ export interface Resource<ResourceType extends BaseResourceType = BaseResourceTy
export const resource = <ResourceType extends BaseResourceType = BaseResourceType>(schema: ResourceType['schema']): Resource<ResourceType> => { export const resource = <ResourceType extends BaseResourceType = BaseResourceType>(schema: ResourceType['schema']): Resource<ResourceType> => {
const resourceState = { const resourceState = {
shared: new Map(), shared: new Map(),
relationships: new Set<Resource>(),
relationships: new Map<string, Relationship<any, any>>(),
canCreate: false, canCreate: false,
canFetchCollection: false, canFetchCollection: false,
canFetchItem: false, canFetchItem: false,
@@ -131,10 +143,14 @@ export const resource = <ResourceType extends BaseResourceType = BaseResourceTyp
resourceState.shared.set('idConfig', config); resourceState.shared.set('idConfig', config);
return this; return this;
}, },
fullText(attrName: string) {
const fullTextAttrs = (resourceState.shared.get('fullText') ?? new Set()) as Set<string>;
fullTextAttrs.add(attrName);
resourceState.shared.set('fullText', fullTextAttrs);
addMetadata(key: string, value: unknown) {
const fullTextAttrs = (resourceState.shared.get(key) ?? new Set()) as Set<unknown>;
fullTextAttrs.add(value);
this.setMetadata(key, fullTextAttrs);
return this;
},
setMetadata(key: string, value: unknown) {
resourceState.shared.set(key, value);
return this; return this;
}, },
name<NewName extends ResourceType['name']>(n: NewName) { name<NewName extends ResourceType['name']>(n: NewName) {
@@ -154,8 +170,14 @@ export const resource = <ResourceType extends BaseResourceType = BaseResourceTyp
get schema() { get schema() {
return schema; return schema;
}, },
relatedTo<RelatedSchema extends v.BaseSchema>(resource: Resource<ResourceType & { schema: RelatedSchema }>) {
resourceState.relationships.add(resource);
relatesTo<RelatedSchema extends v.BaseSchema>(
objectResource: Resource<ResourceType & { schema: RelatedSchema }>,
relationshipParams: Relationship<ResourceType['schema'], RelatedSchema>,
) {
resourceState.relationships.set(relationshipParams.name, {
...relationshipParams,
objectResource,
});
return this; return this;
}, },
createdAt<NewCreatedAtAttr extends ResourceType['createdAtAttr']>(n: NewCreatedAtAttr) { createdAt<NewCreatedAtAttr extends ResourceType['createdAtAttr']>(n: NewCreatedAtAttr) {


Loading…
Cancel
Save