diff --git a/.gitignore b/.gitignore index f2d365f..20ed673 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ package-lock.json +pnpm-lock.yaml node_modules dist test \ No newline at end of file diff --git a/package.json b/package.json index 2c58a83..3bf2fd0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "marcsync", - "version": "1.1.4-dev", + "version": "1.2.0", "description": "A NodeJS MarcSync Client to communicate with MarcSync's API", "main": "dist/marcsync.js", "types": "dist/index.d.ts", diff --git a/src/Collection.ts b/src/Collection.ts index 084e072..e297360 100644 --- a/src/Collection.ts +++ b/src/Collection.ts @@ -1,7 +1,7 @@ import { Entry, EntryData, EntryNotFound } from "./Entry"; import { Unauthorized } from "./marcsync"; -export class Collection { +export class Collection { private _accessToken: string; private _collectionName: string; @@ -149,7 +149,7 @@ export class Collection { * }); * */ - async createEntry(data: EntryData): Promise { + async createEntry(data: T): Promise> { try { const result = await fetch(`https://api.marcsync.dev/v0/entries/${this._collectionName}`, { method: "POST", @@ -185,7 +185,7 @@ export class Collection { * * const entry = await collection.getEntryById("my-entry-id"); */ - async getEntryById(id: string): Promise { + async getEntryById(id: string): Promise> { try { const result = await fetch(`https://api.marcsync.dev/v1/entries/${this._collectionName}?methodOverwrite=GET`, { method: "PATCH", @@ -203,7 +203,7 @@ export class Collection { const json = await result.json(); if (!json.success) throw new Error(); if(json.entries.length === 0) throw new EntryNotFound(); - return new Entry(this._accessToken, this._collectionName, json.entries[0]); + return new Entry(this._accessToken, this._collectionName, json.entries[0]); } catch (e) { if(e instanceof Unauthorized) throw new Unauthorized(); if(e instanceof EntryNotFound) throw new EntryNotFound(); @@ -236,7 +236,7 @@ export class Collection { * @see {@link EntryData} for more information about entry data. * */ - async getEntries(filter: EntryData={}): Promise { + async getEntries(filter?: Partial<{ [K in keyof T]: T[K] }>): Promise[]> { try { const result = await fetch(`https://api.marcsync.dev/v1/entries/${this._collectionName}?methodOverwrite=GET`, { method: "PATCH", @@ -245,7 +245,7 @@ export class Collection { "content-type": "application/json" }, body: JSON.stringify({ - filters: filter + filters: filter || {} }) }) if (result.status === 401) throw new Unauthorized(); @@ -297,7 +297,7 @@ export class Collection { * **__warning: Will delete the entries from the collection. This action cannot be undone.__** * */ - async deleteEntries(filter: EntryData): Promise { + async deleteEntries(filter?: Partial<{ [K in keyof T]: T[K] }>): Promise { try { const result = await fetch(`https://api.marcsync.dev/v1/entries/${this._collectionName}`, { method: "DELETE", @@ -324,7 +324,7 @@ export class Collection { * @returns The Id of the updated entry * */ - async updateEntryById(id: string, data: EntryData): Promise { + async updateEntryById(id: string, data: Partial<{ [K in keyof T]: T[K] }>): Promise { try { const result = await fetch(`https://api.marcsync.dev/v1/entries/${this._collectionName}`, { method: "PUT", @@ -355,7 +355,7 @@ export class Collection { * @returns The amount of updated entries * */ - async updateEntries(filter: EntryData, data: EntryData): Promise { + async updateEntries(filter: Partial<{ [K in keyof T]: T[K] }>, data: Partial<{ [K in keyof T]: T[K] }>): Promise { try { const result = await fetch(`https://api.marcsync.dev/v1/entries/${this._collectionName}`, { method: "PUT", diff --git a/src/Entry.ts b/src/Entry.ts index 1755fc2..96bebd3 100644 --- a/src/Entry.ts +++ b/src/Entry.ts @@ -1,9 +1,13 @@ -export class BaseEntry { +type WithDefaultId = T['_id'] extends string + ? T + : T & { _id: string }; - private _data: EntryData; +export class BaseEntry { + + private _data: T; private _collectionName: string; - constructor(private data: EntryData, private collectionName: string) { + constructor(private data: T, private collectionName: string) { this._data = data; this._collectionName = collectionName; } @@ -31,36 +35,8 @@ export class BaseEntry { * @see {@link EntryData} for more information about entry data. * */ - getValues(): EntryData { - return this._data; - } - - /** - * - * @param key - The key of the value to get - * @returns The value of the specified key - * - * @example - * - * import { Client } from "marcsync"; - * - * const client = new Client(""); - * const collection = client.getCollection("my-collection"); - * - * const entry = await collection.getEntryById("my-entry-id"); - * - * const name = entry.getValueAs("name"); - * - * console.log(name); - * - * @remarks - * This method is useful if you want to get the value of a specific key as a specific type. - * - * @see {@link EntryData} for more information about entry data. - * - */ - getValueAs(key: string): T { - return this._data[key]; + getValues(): WithDefaultId { + return this._data as WithDefaultId; } /** @@ -87,8 +63,8 @@ export class BaseEntry { * @see {@link EntryData} for more information about entry data. * */ - getValue(key: string): any { - return this._data[key]; + getValue>(key: K): WithDefaultId[K] { + return (this._data as WithDefaultId)[key]; } /** @@ -100,20 +76,20 @@ export class BaseEntry { return this._collectionName; } - protected _setData(data: EntryData) { + protected _setData(data: T) { this._data = data; } } -export class Entry extends BaseEntry { +export class Entry extends BaseEntry { private _accessToken: string; private _entryId: string; - constructor(accessToken: string, collectionName: string, data: EntryData) { + constructor(accessToken: string, collectionName: string, data: T) { super(data, collectionName); this._accessToken = accessToken; - this._entryId = data._id; + this._entryId = data._id!; } /** @@ -139,7 +115,7 @@ export class Entry extends BaseEntry { * This method is useful if you want to update the value of a specific key. * */ - async updateValue(key: string, value: any): Promise { + async updateValue>(key: K, value: WithDefaultId[K]): Promise> { try { const result = await fetch(`https://api.marcsync.dev/v1/entries/${this.getCollectionName()}`, { method: "PUT", @@ -193,7 +169,7 @@ export class Entry extends BaseEntry { * @see {@link updateValue} for more information about updating a single value. * */ - async updateValues(values: EntryData): Promise { + async updateValues(values: Partial<{ [K in keyof WithDefaultId]: WithDefaultId[K] }>): Promise> { try { const result = await fetch(`https://api.marcsync.dev/v1/entries/${this.getCollectionName()}`, { method: "PUT", @@ -215,7 +191,7 @@ export class Entry extends BaseEntry { } const data = this.getValues(); for (const key in values) { - data[key] = values[key]; + data[key] = values[key]!; } this._setData(data); return data; @@ -249,6 +225,7 @@ export class Entry extends BaseEntry { } export interface EntryData { + _id?: string [key: string]: any; } diff --git a/src/marcsync.ts b/src/marcsync.ts index 7ec8382..bafb8b2 100644 --- a/src/marcsync.ts +++ b/src/marcsync.ts @@ -1,5 +1,5 @@ import { Collection, CollectionAlreadyExists, CollectionNotFound } from "./Collection"; -import { BaseEntry, Entry } from "./Entry"; +import { BaseEntry, Entry, EntryData } from "./Entry"; import { SubscriptionManager } from "./SubscriptionManager"; export class Client { @@ -31,8 +31,8 @@ export class Client { * const collection = client.getCollection("my-collection"); * */ - getCollection(collectionName: string) { - return new Collection(this._accessToken, collectionName); + getCollection(collectionName: string): Collection { + return new Collection(this._accessToken, collectionName); } /** @@ -51,7 +51,7 @@ export class Client { * This method is useful if you want to fetch the collection from the server to check if it exists before using it. * */ - async fetchCollection(collectionName: string): Promise { + async fetchCollection(collectionName: string): Promise> { try { const result = await fetch(`https://api.marcsync.dev/v0/collection/${collectionName}`, { method: "GET", @@ -66,7 +66,7 @@ export class Client { if (e instanceof Unauthorized) throw new Unauthorized(); throw new CollectionNotFound(); } - return new Collection(this._accessToken, collectionName); + return new Collection(this._accessToken, collectionName); } /** @@ -83,7 +83,7 @@ export class Client { * * @remarks */ - async createCollection(collectionName: string): Promise { + async createCollection(collectionName: string): Promise> { try { const result = await fetch(`https://api.marcsync.dev/v0/collection/${collectionName}`, { method: "POST", @@ -121,7 +121,7 @@ export class Unauthorized extends Error { } export interface ClientEvents { - entryCreated: [entry: Entry, databaseId: string, timestamp: number]; - entryUpdated: [oldEntry: BaseEntry, newEntry: Entry, databaseId: string, timestamp: number]; - entryDeleted: [entry: BaseEntry, databaseId: string, timestamp: number]; + entryCreated: [entry: Entry, databaseId: string, timestamp: number]; + entryUpdated: [oldEntry: BaseEntry, newEntry: Entry, databaseId: string, timestamp: number]; + entryDeleted: [entry: BaseEntry, databaseId: string, timestamp: number]; } \ No newline at end of file