🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Book a DemoInstallSign in
Socket

json-api-models

Package Overview
Dependencies
Maintainers
0
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

json-api-models - npm Package Compare versions

Comparing version

to
0.2.0-beta.6

2

dist/index.es.js

@@ -1,1 +0,1 @@

const e=class{constructor(e){Object.defineProperty(this,"type",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"id",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"attributes",{enumerable:!0,configurable:!0,writable:!0,value:{}}),Object.defineProperty(this,"relationships",{enumerable:!0,configurable:!0,writable:!0,value:{}}),Object.defineProperty(this,"meta",{enumerable:!0,configurable:!0,writable:!0,value:{}}),Object.defineProperty(this,"links",{enumerable:!0,configurable:!0,writable:!0,value:{}}),this.type=e.type,this.id=e.id,this.merge(e)}identifier(){return{id:this.id,type:this.type}}merge(e){this.links=e.links??this.links,this.meta=e.meta??this.meta,e.attributes&&Object.assign(this.attributes,e.attributes),e.relationships&&Object.entries(e.relationships).forEach((([e,t])=>{this.relationships[e]=this.relationships[e]||{},Object.assign(this.relationships[e],t)}))}};class t{constructor(e={}){Object.defineProperty(this,"models",{enumerable:!0,configurable:!0,writable:!0,value:e}),Object.defineProperty(this,"graph",{enumerable:!0,configurable:!0,writable:!0,value:{}})}find(e,t){return null===e?null:Array.isArray(e)?e.map((e=>this.find(e))):"object"==typeof e?this.find(e.type,e.id):t&&this.graph[e]?.[t]||null}findAll(e){return this.graph[e]?Object.keys(this.graph[e]).map((t=>this.graph[e][t])):[]}sync(e){return e.included?.map((e=>this.syncResource(e))),Array.isArray(e.data)?e.data.map((e=>this.syncResource(e))):e.data?this.syncResource(e.data):null}syncResource(e){const{type:t,id:i}=e;return this.graph[t]=this.graph[t]||{},this.graph[t][i]?this.graph[t][i].merge(e):this.graph[t][i]=this.createModel(e),this.graph[t][i]}createModel(t){const i=this.models[t.type]||e;return new Proxy(new i(t),{get:(e,t,i)=>{if("string"==typeof t){if(void 0!==e.attributes?.[t])return e.attributes[t];const i=e.relationships?.[t]?.data;if(void 0!==i)return Array.isArray(i),this.find(i)}return Reflect.get(e,t,i)}})}forget(e){delete this.graph[e.type][e.id]}reset(){this.graph={}}}export{e as Model,t as Store};
const e=class{constructor(e,t){Object.defineProperty(this,"store",{enumerable:!0,configurable:!0,writable:!0,value:t}),Object.defineProperty(this,"type",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"id",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"attributes",{enumerable:!0,configurable:!0,writable:!0,value:{}}),Object.defineProperty(this,"relationships",{enumerable:!0,configurable:!0,writable:!0,value:{}}),Object.defineProperty(this,"meta",{enumerable:!0,configurable:!0,writable:!0,value:{}}),Object.defineProperty(this,"links",{enumerable:!0,configurable:!0,writable:!0,value:{}}),this.type=e.type,this.id=e.id,this.merge(e)}identifier(){return{id:this.id,type:this.type}}merge(e){this.links=e.links??this.links,this.meta=e.meta??this.meta,e.attributes&&(Object.assign(this.attributes,e.attributes),Object.keys(e.attributes).forEach((e=>{Object.getOwnPropertyDescriptor(Object.getPrototypeOf(this),e)||Object.getOwnPropertyDescriptor(this,e)||Object.defineProperty(this,e,{get:()=>this.attributes[e],configurable:!0,enumerable:!0})}))),e.relationships&&Object.entries(e.relationships).forEach((([e,t])=>{this.relationships[e]=this.relationships[e]||{},Object.assign(this.relationships[e],t),Object.getOwnPropertyDescriptor(Object.getPrototypeOf(this),e)||Object.getOwnPropertyDescriptor(this,e)||Object.defineProperty(this,e,{get:()=>this.getRelationship(e),configurable:!0,enumerable:!0})}))}getRelationship(e){const t=this.relationships[e].data;return Array.isArray(t)||t?this.store.find(t):void 0}};class t{constructor(e={}){Object.defineProperty(this,"models",{enumerable:!0,configurable:!0,writable:!0,value:e}),Object.defineProperty(this,"graph",{enumerable:!0,configurable:!0,writable:!0,value:{}})}find(e,t){return null===e?null:Array.isArray(e)?e.map((e=>this.find(e))):"object"==typeof e?this.find(e.type,e.id):t&&this.graph[e]?.[t]||null}findAll(e){return this.graph[e]?Object.keys(this.graph[e]).map((t=>this.graph[e][t])):[]}sync(e){return e.included?.map((e=>this.syncResource(e))),Array.isArray(e.data)?e.data.map((e=>this.syncResource(e))):e.data?this.syncResource(e.data):null}syncResource(e){const{type:t,id:r}=e;return this.graph[t]=this.graph[t]||{},this.graph[t][r]?this.graph[t][r].merge(e):this.graph[t][r]=this.createModel(e),this.graph[t][r]}createModel(t){return new(this.models[t.type]||e)(t,this)}forget(e){delete this.graph[e.type][e.id]}reset(){this.graph={}}}export{e as Model,t as Store};
import { JsonApiResource, ModelForType, SchemaCollection } from './types';
type PartialJsonApiResource<T extends JsonApiResource> = {
[P in keyof T]?: Partial<T[P]>;
};
import { Store } from './store.ts';
declare class ModelBase<Schema extends JsonApiResource = JsonApiResource> {
protected store: Store;
type: Schema['type'];

@@ -12,3 +11,3 @@ id: Schema['id'];

links: Schema['links'];
constructor(data: Schema);
constructor(data: Schema, store: Store);
/**

@@ -24,6 +23,7 @@ * Make a resource identifier object for this model.

*/
merge(data: PartialJsonApiResource<Schema>): void;
merge(data: Omit<JsonApiResource<Schema['type']>, 'type' | 'id'>): void;
private getRelationship;
}
type ProxiedModel<Schema extends JsonApiResource, Schemas extends Record<string, JsonApiResource>> = Schema & Schema['attributes'] & {
[Property in keyof NonNullable<Schema['relationships']>]: NonNullable<NonNullable<Schema['relationships']>[Property]> extends {
[Property in keyof NonNullable<Schema['relationships']>]?: NonNullable<NonNullable<Schema['relationships']>[Property]> extends {
data?: infer Data;

@@ -37,3 +37,3 @@ } ? Data extends {

export type Model<Schema extends JsonApiResource = JsonApiResource, Schemas extends SchemaCollection = SchemaCollection> = JsonApiResource<Schema['type']> & ModelBase<Schema> & ProxiedModel<Schema, Schemas>;
export declare const Model: new <Schema extends JsonApiResource = JsonApiResource, Schemas extends SchemaCollection = SchemaCollection>(data: JsonApiResource<Schema['type']>) => Model<Schema, Schemas>;
export declare const Model: new <Schema extends JsonApiResource = JsonApiResource, Schemas extends SchemaCollection = SchemaCollection>(data: JsonApiResource<Schema['type']>, store: Store<Schemas>) => Model<Schema, Schemas>;
export {};
import { Model } from './model.ts';
import { Store } from './store.ts';
export interface JsonApiDocument<Type extends string = string> {

@@ -34,4 +35,4 @@ data: JsonApiResource<Type> | JsonApiResource<Type>[] | null;

export type ModelMap<Schemas extends SchemaCollection = SchemaCollection> = {
[Type in keyof Schemas & string]?: new (data: JsonApiResource<Type>) => Schemas[Type];
[Type in keyof Schemas & string]?: new (data: JsonApiResource<Type>, store: Store<Schemas>) => Schemas[Type];
};
export type ModelForType<Type extends string, Schemas> = Type extends keyof Schemas ? Schemas[Type] : Model<JsonApiResource<Type>>;
export type ModelForType<Type extends string, Schemas extends SchemaCollection> = Type extends keyof Schemas ? Model<Schemas[Type], Schemas> : Model<JsonApiResource<Type>, Schemas>;
{
"name": "json-api-models",
"description": "A lightweight layer for working with JSON:API data.",
"version": "0.2.0-beta.5",
"version": "0.2.0-beta.6",
"author": "Toby Zerner",

@@ -6,0 +6,0 @@ "license": "MIT",

import { JsonApiResource, ModelForType, SchemaCollection } from './types';
import { Store } from './store.ts';
type PartialJsonApiResource<T extends JsonApiResource> = {
[P in keyof T]?: Partial<T[P]>;
};
class ModelBase<Schema extends JsonApiResource = JsonApiResource> {

@@ -15,3 +12,6 @@ public type: Schema['type'];

constructor(data: Schema) {
constructor(
data: Schema,
protected store: Store,
) {
this.type = data.type;

@@ -36,3 +36,5 @@ this.id = data.id;

*/
public merge(data: PartialJsonApiResource<Schema>): void {
public merge(
data: Omit<JsonApiResource<Schema['type']>, 'type' | 'id'>,
): void {
this.links = data.links ?? this.links;

@@ -43,2 +45,20 @@ this.meta = data.meta ?? this.meta;

Object.assign(this.attributes, data.attributes);
Object.keys(data.attributes).forEach((name) => {
if (
Object.getOwnPropertyDescriptor(
Object.getPrototypeOf(this),
name,
) ||
Object.getOwnPropertyDescriptor(this, name)
) {
return;
}
Object.defineProperty(this, name, {
get: () => this.attributes[name],
configurable: true,
enumerable: true,
});
});
}

@@ -50,3 +70,20 @@

this.relationships[name] = this.relationships[name] || {};
Object.assign(this.relationships[name], relationship);
if (
Object.getOwnPropertyDescriptor(
Object.getPrototypeOf(this),
name,
) ||
Object.getOwnPropertyDescriptor(this, name)
) {
return;
}
Object.defineProperty(this, name, {
get: () => this.getRelationship(name),
configurable: true,
enumerable: true,
});
},

@@ -56,2 +93,15 @@ );

}
private getRelationship(name: string) {
const data = this.relationships[name].data;
// https://github.com/microsoft/TypeScript/issues/14107
if (Array.isArray(data)) {
return this.store.find(data);
}
if (data) {
return this.store.find(data);
}
}
}

@@ -64,3 +114,3 @@

Schema['attributes'] & {
[Property in keyof NonNullable<Schema['relationships']>]: NonNullable<
[Property in keyof NonNullable<Schema['relationships']>]?: NonNullable<
NonNullable<Schema['relationships']>[Property]

@@ -88,2 +138,3 @@ > extends { data?: infer Data }

data: JsonApiResource<Schema['type']>,
store: Store<Schemas>,
) => Model<Schema, Schemas> = ModelBase as any;

@@ -96,18 +96,3 @@ import { Model } from './model';

return new Proxy(new ModelClass(data), {
get: (target, prop, receiver) => {
if (typeof prop === 'string') {
if (target.attributes?.[prop] !== undefined) {
return target.attributes[prop];
}
const data = target.relationships?.[prop]?.data;
if (data !== undefined) {
return Array.isArray(data)
? this.find(data)
: this.find(data);
}
}
return Reflect.get(target, prop, receiver);
},
}) as ModelForType<Type, Schemas>;
return new ModelClass(data, this) as ModelForType<Type, Schemas>;
}

@@ -114,0 +99,0 @@

import { Model } from './model.ts';
import { Store } from './store.ts';

@@ -46,2 +47,3 @@ export interface JsonApiDocument<Type extends string = string> {

data: JsonApiResource<Type>,
store: Store<Schemas>,
) => Schemas[Type];

@@ -52,3 +54,5 @@ };

Type extends string,
Schemas,
> = Type extends keyof Schemas ? Schemas[Type] : Model<JsonApiResource<Type>>;
Schemas extends SchemaCollection,
> = Type extends keyof Schemas
? Model<Schemas[Type], Schemas>
: Model<JsonApiResource<Type>, Schemas>;