@tinacms/core
Advanced tools
Comparing version 0.6.0 to 0.6.1-alpha.0
@@ -18,10 +18,103 @@ /** | ||
*/ | ||
import { PluginManager } from './plugins'; | ||
/** | ||
* This package contains the [[CMS]] class which is the core | ||
* piece of any content management system. | ||
* | ||
* @packageDocumentation | ||
*/ | ||
import { PluginTypeManager } from './plugins'; | ||
/** | ||
* A [[CMS]] is the core object of any content management system. | ||
* | ||
* The responsibility of the [[CMS]] keeps track of two broad types of objects: | ||
* | ||
* - [[Plugin|Plugins]] which extend or change the behaviour of the content management system.. | ||
* - [[api|APIs]] which allow the CMS to integrate with third party services. | ||
* | ||
* The name [[CMS]] is a bit misleading. This object knows nothing of the user | ||
* interface or the data storage layer. The purpose of a [[CMS]] instance is to | ||
* provide a common connection point for the various aspects of a content | ||
* management system. The [[CMS]] object effectively a vehicle for dependency injection. | ||
* | ||
* #### Creating a CMS | ||
* | ||
* ```ts | ||
* import { CMS } from "@tinacms/core" | ||
* | ||
* const cms = new CMS() | ||
* ``` | ||
* | ||
* #### Extending the CMS | ||
* | ||
* The [[CMS]] class provides low-level interfaces for interacting with APIs and Plugins. | ||
* Creating a subclass is great way to facilitate these interactions: | ||
* | ||
* ```ts | ||
* import { CMS } from "@tinacms/core" | ||
* | ||
* class MyCMS extends CMS { | ||
* get colors() { | ||
* return this.plugins.findOrCreateMap("color") | ||
* } | ||
* } | ||
* | ||
* const cms = new MyCMS() | ||
* | ||
* cms.colors.all() | ||
* ``` | ||
*/ | ||
export declare class CMS { | ||
plugins: PluginManager; | ||
/** | ||
* An object for managing CMSs plugins. | ||
* | ||
* [[Plugin|Plugins]] are used to extend or modify the CMSs feature set. | ||
* | ||
*/ | ||
plugins: PluginTypeManager; | ||
/** | ||
* The set of APIs registered with the CMS. | ||
* | ||
* API objects are the preferred way to interact with external APIs over a network. | ||
* | ||
* The preferred way to register new APIs is through the [[registerApi]] method. | ||
* | ||
* #### Example: Fetching Data Through an API | ||
* | ||
* ```ts | ||
* import { CMS } from "@tinacms/core" | ||
* import { CoolApi } from "cool-api" | ||
* | ||
* const cms = new CMS() | ||
* | ||
* cms.registerApi("coolApi", new CoolApi()) | ||
* | ||
* cms.api.coolApi.fetchCoolThings().then(coolThings => { | ||
* console.log(coolThings) | ||
* }) | ||
* ``` | ||
* | ||
*/ | ||
api: { | ||
[key: string]: any; | ||
}; | ||
/** | ||
* @hidden | ||
*/ | ||
constructor(); | ||
/** | ||
* Registers a new external API with the CMS. | ||
* | ||
* #### Example | ||
* | ||
* | ||
* ```ts | ||
* import { CoolApi } from "cool-api" | ||
* | ||
* cms.registerApi("coolApi", new CoolApi()) | ||
* ``` | ||
* | ||
* @param name The name used to lookup the external API. | ||
* @param api An object for interacting with an external API. | ||
*/ | ||
registerApi(name: string, api: any): void; | ||
} |
@@ -1,1 +0,1 @@ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self)["@tinacms/core"]={})}(this,function(t){"use strict";var i=function(t,e){return(i=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i])})(t,e)};var e=(n.prototype.subscribe=function(t){var e=this;return this.__subscribers.push(t),function(){return e.unsubscribe(t)}},n.prototype.unsubscribe=function(t){var e=this.__subscribers.indexOf(t);this.__subscribers.splice(e,1)},n.prototype.notifiySubscribers=function(){this.__subscribers.forEach(function(t){return t()})},n);function n(){this.__subscribers=[]}var r=(o.prototype.findOrCreateMap=function(t){return this.plugins[t]=this.plugins[t]||new c(t)},o.prototype.add=function(t){this.findOrCreateMap(t.__type).add(t)},o.prototype.remove=function(t){this.findOrCreateMap(t.__type).remove(t)},o.prototype.all=function(t){return this.findOrCreateMap(t).all()},o);function o(){this.plugins={}}var s,u,p,c=(i(s=_,u=p=e),void(s.prototype=null===u?Object.create(u):(f.prototype=u.prototype,new f)),_.prototype.add=function(t){var e=t;e.__type||(e.__type=this.__type),this.__plugins[e.name]=e,this.notifiySubscribers()},_.prototype.all=function(){var e=this;return Object.keys(this.__plugins).map(function(t){return e.__plugins[t]})},_.prototype.find=function(t){return this.__plugins[t]},_.prototype.remove=function(t){var e="string"==typeof t?t:t.name,i=this.__plugins[e];return delete this.__plugins[e],this.notifiySubscribers(),i},_);function f(){this.constructor=s}function _(t){var e=p.call(this)||this;return e.__type=t,e.__plugins={},e}var a=(y.prototype.registerApi=function(t,e){this.api[t]=e},y);function y(){this.api={},this.plugins=new r}t.CMS=a,t.PluginManager=r,t.PluginType=c,t.Subscribable=e,Object.defineProperty(t,"__esModule",{value:!0})}); | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self)["@tinacms/core"]={})}(this,function(t){"use strict";var n=function(t,e){return(n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(t,e)};var e=(i.prototype.subscribe=function(t){var e=this;return this.__subscribers.push(t),function(){return e.unsubscribe(t)}},i.prototype.unsubscribe=function(t){var e=this.__subscribers.indexOf(t);this.__subscribers.splice(e,1)},i.prototype.notifiySubscribers=function(){this.__subscribers.forEach(function(t){return t()})},i);function i(){this.__subscribers=[]}var r=(o.prototype.getType=function(t){return this.plugins[t]=this.plugins[t]||new c(t)},o.prototype.findOrCreateMap=function(t){return this.getType(t)},o.prototype.add=function(t){this.findOrCreateMap(t.__type).add(t)},o.prototype.remove=function(t){this.findOrCreateMap(t.__type).remove(t)},o.prototype.all=function(t){return this.findOrCreateMap(t).all()},o);function o(){this.plugins={}}var s,p,u,c=(n(s=_,p=u=e),void(s.prototype=null===p?Object.create(p):(f.prototype=p.prototype,new f)),_.prototype.add=function(t){var e=t;e.__type||(e.__type=this.__type),this.__plugins[e.name]=e,this.notifiySubscribers()},_.prototype.all=function(){var e=this;return Object.keys(this.__plugins).map(function(t){return e.__plugins[t]})},_.prototype.find=function(t){return this.__plugins[t]},_.prototype.remove=function(t){var e="string"==typeof t?t:t.name,n=this.__plugins[e];return delete this.__plugins[e],this.notifiySubscribers(),n},_);function f(){this.constructor=s}function _(t){var e=u.call(this)||this;return e.__type=t,e.__plugins={},e}var a=(y.prototype.registerApi=function(t,e){this.api[t]=e},y);function y(){this.api={},this.plugins=new r}t.CMS=a,t.PluginType=c,t.PluginTypeManager=r,t.Subscribable=e,Object.defineProperty(t,"__esModule",{value:!0})}); |
@@ -18,28 +18,246 @@ /** | ||
*/ | ||
/** | ||
* This package defines the plugin system of TinaCMS. | ||
* | ||
* The management of plugins is a core part of a content | ||
* management system. The API for managing plugins in TinaCMS is quite | ||
* powerful, although the implementation is a bit awkward. | ||
* | ||
* [[Plugin|Plugins]] are objects used to extend and modify the | ||
* behaviour of the CMS. Each plugin has a `__type` field that is used | ||
* to group plugins by their purpose. | ||
* | ||
* The [[PluginType]] class is responsible for managing a collection of | ||
* plugins with the same `__type` value. Plugins can be added and removed from | ||
* the `PluginType` over the life of the application. | ||
* | ||
* A new [[CMS]] is not initialized with any `PluginTypes`. | ||
* Instead it has a single [[PluginTypeManager]] which is responsible for | ||
* creating and managing different `PluginType` instances. | ||
* | ||
* Although somewhat confusing from the maintainers perspective, this | ||
* structure results in a pretty easy to use interface for the clients. | ||
* The concept of `PluginType` and `PluginTypeManager` are not really | ||
* meant to be exposed to developers using TinaCMS in their projects. | ||
* | ||
* @packageDocumentation | ||
*/ | ||
import { Subscribable } from './subscribable'; | ||
/** | ||
* An object used to extend or modify the behaviour of the content management system. | ||
*/ | ||
export interface Plugin { | ||
/** | ||
* Used to organize plugins with a common purpose. | ||
*/ | ||
__type: string; | ||
/** | ||
* A unique identifier for the plugin. | ||
* | ||
* @todo Rename to `id`. | ||
*/ | ||
name: string; | ||
/** | ||
* A string referencing an icon. | ||
* | ||
* ### !DEPRECATED! | ||
* | ||
* This shouldn't be here. Please assume it isn't. | ||
*/ | ||
icon?: string; | ||
} | ||
export declare class PluginManager { | ||
/** | ||
* Manages all of the [[PluginType|PluginTypes]] on a [[CMS]]. | ||
*/ | ||
export declare class PluginTypeManager { | ||
/** | ||
* @ignore | ||
*/ | ||
private plugins; | ||
findOrCreateMap<T extends Plugin = Plugin>(type: T['__type']): PluginType<T>; | ||
add(view: Plugin): void; | ||
remove(view: Plugin): void; | ||
all<T extends Plugin = Plugin>(type: string): T[]; | ||
/** | ||
* Gets the [[PluginType|collection of plugins]] for the given type. | ||
* | ||
* #### Example: Basic Usage | ||
* | ||
* ```ts | ||
* const colorPlugins = cms.plugins.get("color") | ||
* ``` | ||
* | ||
* #### Example: Advanced Types | ||
* | ||
* A type param can be added to specify the kind of Plugin | ||
* that is being listed. | ||
* | ||
* ```ts | ||
* const colorPlugins = cms.plugins.get<ColorPlugin>("color") | ||
* ``` | ||
* | ||
* @param type The type of plugins to be retrieved | ||
* @typeparam P A subclass of Plugin. Optional. | ||
*/ | ||
getType<P extends Plugin = Plugin>(type: P['__type']): PluginType<P>; | ||
/** | ||
* An alias to [[get]] | ||
* | ||
* ### !DEPRECATED! | ||
* | ||
* This name is unnecessarily verbose and weird. | ||
*/ | ||
findOrCreateMap<P extends Plugin = Plugin>(type: P['__type']): PluginType<P>; | ||
/** | ||
* Adds a Plugin to the CMS. | ||
* | ||
* #### Example: Basic Usage | ||
* | ||
* ```js | ||
* cms.plugins.add({ __type: "color", name: "red" }) | ||
* ``` | ||
* | ||
* #### Example: Advanced Types | ||
* | ||
* ```ts | ||
* interface ColorPlugin extends Plugin { | ||
* __type: "color" | ||
* hex: string | ||
* rgb: string | ||
* } | ||
* | ||
* cms.plugins.add<ColorPlugin>({ | ||
* __type: "color", | ||
* name: "red", | ||
* hex: "#FF0000", | ||
* rgb: "RGBA(255, 0, 0, 1)" | ||
* }) | ||
* ``` | ||
* | ||
* @typeparam P A subclass of Plugin. Optional. | ||
* @param plugin | ||
* @todo Consider returning the plugin which was just added. | ||
*/ | ||
add<P extends Plugin = Plugin>(plugin: P): void; | ||
/** | ||
* Removes the given plugin from the CMS. | ||
* | ||
* #### Example | ||
* | ||
* In this example a plugin is added to the CMS and removed | ||
* 5 seconds later. | ||
* | ||
* ```ts | ||
* const redPlugin = { | ||
* __type: "color", | ||
* name: "red", | ||
* hex: "#FF0000", | ||
* rgb: "RGBA(255, 0, 0, 1)" | ||
* } | ||
* | ||
* cms.plugins.add(redPlugin) | ||
* | ||
* setTimeout(() => { | ||
* cms.plugins.remove(redPlugin) | ||
* }, 5000) | ||
* ``` | ||
* | ||
* @typeparam P A subclass of Plugin. Optional. | ||
* @param plugin The plugin to be removed from the CMS. | ||
*/ | ||
remove<P extends Plugin = Plugin>(plugin: P): void; | ||
/** | ||
* Returns a list of all the plugins of the given type. | ||
* | ||
* #### Example: Basic Usage | ||
* | ||
* ```ts | ||
* cms.plugins.all("color").forEach(color => { | ||
* console.log(color.name) | ||
* }) | ||
* ``` | ||
* | ||
* #### Example: Advanced Types | ||
* | ||
* A generic can be added to specify the type of plugins | ||
* that are being retrieved. | ||
* | ||
* ```ts | ||
* cms.plugins.all<ColorPlugin>("color").forEach(color => { | ||
* console.log(color.name, color.hex) | ||
* }) | ||
* ``` | ||
* | ||
* @typeparam P A subclass of Plugin. Optional. | ||
* @param type The name of the plugin | ||
* @returns An array of all plugins of the given type. | ||
*/ | ||
all<P extends Plugin = Plugin>(type: string): P[]; | ||
} | ||
/** | ||
* @ignore | ||
*/ | ||
interface Map<T> { | ||
[key: string]: T; | ||
} | ||
/** | ||
* @ignore | ||
*/ | ||
declare type PluginMap<T extends Plugin = Plugin> = Map<T>; | ||
/** | ||
* A collection of plugins with the same `__type` value. | ||
*/ | ||
export declare class PluginType<T extends Plugin = Plugin> extends Subscribable { | ||
private __type; | ||
/** | ||
* @ignore | ||
*/ | ||
__plugins: PluginMap<T>; | ||
/** | ||
* | ||
* @param __type The `__type` of plugin being managed. | ||
*/ | ||
constructor(__type: string); | ||
/** | ||
* Adds a new plugin to the collection. | ||
* | ||
* ### Example | ||
* | ||
* ```ts | ||
* interface ColorPlugin extends Plugin { | ||
* hex: string | ||
* } | ||
* | ||
* const colorPlugins = new PluginType<ColorPlugin>("color") | ||
* | ||
* colorPlugins.add({ name: "red", hex: "#f00" }) | ||
* ``` | ||
* | ||
* @param plugin A new plugin. The `__type` is optional and will be added if it's missing. | ||
*/ | ||
add(plugin: T | Omit<T, '__type'>): void; | ||
all(): T[]; | ||
/** | ||
* | ||
* Looks up a plugin by it's `name`. | ||
* | ||
* ### Example | ||
* | ||
* ```ts | ||
* const colorPlugins = new PluginType<ColorPlugin>("color") | ||
* | ||
* colorPlugins.add({ name: "red", hex: "#f00" }) | ||
* | ||
* colorPlugins.find("red") // { __type: "color", name: "red", hex: "#f00" } | ||
* colorPlugin.find("large") // undefined | ||
* ``` | ||
* | ||
* @param name The `name` of the plugin to be retrieved. | ||
*/ | ||
find(name: string): T | undefined; | ||
/** | ||
* Pass this function a plugin or the `name` of a plugin to have | ||
* it be removed from the CMS. | ||
* | ||
* @param pluginOrName The `name` of a plugin, or the plugin itself. | ||
* @returns The plugin that was removed, or `undefined` if it was not found. | ||
*/ | ||
remove(pluginOrName: string | T): T | undefined; | ||
} | ||
export {}; |
@@ -18,8 +18,73 @@ /** | ||
*/ | ||
/** | ||
* This package provides an abstract class for making objects Subscribable. | ||
* | ||
* @packageDocumentation | ||
*/ | ||
/** | ||
* @ignore | ||
*/ | ||
export declare type Unsubscribe = () => void; | ||
/** | ||
* A basic class that can be subscribed to. | ||
*/ | ||
export declare class Subscribable { | ||
/** | ||
* @ignore | ||
*/ | ||
protected __subscribers: Function[]; | ||
/** | ||
* Adds a listener to the Subscribable object. | ||
* | ||
* ### Example | ||
* | ||
* ```ts | ||
* const unsubscribe = someSubscribable.add(() => { | ||
* console.log("Update Received") | ||
* }) | ||
* | ||
* setTimeout(unsubscribe, 5000) | ||
* ``` | ||
* | ||
* | ||
* @param listener A function to be called when the `Subscribable` is updated. | ||
* @returns A function that will unsubscribe the listener. | ||
*/ | ||
subscribe(listener: Function): Unsubscribe; | ||
/** | ||
* Removes the given listener from the `Subscribable` object. | ||
* | ||
* @param listener The functioni to be removed. | ||
*/ | ||
unsubscribe(listener: Function): void; | ||
/** | ||
* Notifies subscribers that the `Subscribable` has changed. | ||
* | ||
* ### Example | ||
* | ||
* ```ts | ||
* class Cup extends Subscribable { | ||
* isFull: boolean = false | ||
* | ||
* fill() { | ||
* this.isFull = true | ||
* this.notifySubscribers() | ||
* } | ||
* | ||
* empty() { | ||
* this.isFull = false | ||
* this.notifySubscribers() | ||
* } | ||
* | ||
* } | ||
* | ||
* const cup = new Cup() | ||
* | ||
* cup.subscribe(() => console.log(cup.isFull)) | ||
* | ||
* cup.fill() // Logs: true | ||
* cup.empty() // Logs: false | ||
* ``` | ||
*/ | ||
protected notifiySubscribers(): void; | ||
} |
@@ -6,2 +6,10 @@ # Change Log | ||
## [0.6.1-alpha.0](https://github.com/tinacms/tinacms/compare/@tinacms/core@0.6.0...@tinacms/core@0.6.1-alpha.0) (2020-01-16) | ||
**Note:** Version bump only for package @tinacms/core | ||
# [0.6.0](https://github.com/tinacms/tinacms/compare/@tinacms/core@0.6.0-alpha.0...@tinacms/core@0.6.0) (2020-01-13) | ||
@@ -8,0 +16,0 @@ |
{ | ||
"name": "@tinacms/core", | ||
"version": "0.6.0", | ||
"version": "0.6.1-alpha.0", | ||
"main": "build/index.js", | ||
@@ -26,2 +26,3 @@ "types": "build/index.d.ts", | ||
"dev": "tinacms-scripts dev", | ||
"docs": "npx typedoc", | ||
"build": "tinacms-scripts build" | ||
@@ -36,3 +37,3 @@ }, | ||
}, | ||
"gitHead": "d5a2dc3e216a101ec0efdb8178bc82ab38a81370" | ||
"gitHead": "710e6175b9ce80d34966053b85f56d275bf090c3" | ||
} |
@@ -25,2 +25,3 @@ # @tinacms/core | ||
If you have any other questions, go to the [TinaCMS Community](https://tinacms.org/community/) page to join our Slack or open an issue on Github! | ||
Every question you ask helps us make working with TinaCMS even better :) | ||
@@ -34,4 +35,2 @@ ### What does the CMS do? | ||
Every question you ask helps us make working with TinaCMS even better :) | ||
### What? That doesn't seem like a CMS | ||
@@ -38,0 +37,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
33518
504
73
1