diff --git a/Design:-Library-Sidebar.md b/Design:-Library-Sidebar.md index 4d03e70..6197cdc 100644 --- a/Design:-Library-Sidebar.md +++ b/Design:-Library-Sidebar.md @@ -20,30 +20,164 @@ Some notes on what is needed: We don't currently document the library API as part of the admin http api. That gives us some small amount of freedom to redesign it. -The Storage API does expose get/set library functions - they should not have to change. +The current library http API is inconsistent; `flows` have a slightly different behaviour to other library types. This change will ensure the API is consistent for all types. -The current library http API is inconsistent; `flows` have a slightly different behaviour to other library types. +### GET `/library/[type]` +This returns a full listing of the given types in the library. -### `/library/[type]/[path]` -> directory - -If a `path` resolves to a directory, a list of the files contained therein is returned: +The format of the response is a recursive structure of entry objects with `path` and `name` elements. If it represents a directory, it also has a `children` property that is an array of entry objects: ``` -["b",{"fn":"dave"},{"fn":"steve"},{"fn":"test2.json"}] +{ + "path": "the full path this level represents", + "name": "the name of this entity" + "children": [ + { + "path": ... + "name": ... + "children": [ ] + } + ] +} ``` -Entries are a string if they represent directories, or an object for files with a `fn` property containing the filename. +### GET `/library/[type]/[path]` -**Note**: `path` can be empty to get the top most directory listing - except for when `type` is `flows`. See the later section for what that does. +`path` must resolve to an entry in the library. -### `/library/[type]/[path]` -> file +The response is an object with the following properties: -If a path resolves to a file, the json is returned. +``` +{ + path: "/full/path/to/the/entryName, + name: "entryName" + meta: { + a: "optional meta data about the entry" + }, + body: "the main body of the entry" +} +``` +### POST `/library/[type]/[path]` -**TODO:** write-up what a Function/Template file response looks like. +Saves the provided entry to the library. The format is the same as that for the GET request above. The `path` entry is taken from the url, not the request body. -### `/library/flows` +--- + +## Storage API + +The underlying Storage API needs to change to accommodate these changes. + +The problem is with [`Storage.getLibraryEntry(type,name)`](http://nodered.org/docs/api/storage/methods/#storagegetlibraryentrytypename). + +In its current form, if `name` is a directory, it is expected to return a listing of the files and directories, *including any metadata about the files*. This is a problem as that metadata (such as `outputs` count on Functions) is contained inside the file; in order to return the listing, every file must be read in part to retrieve its metadata. + +We need three functions: + +1. return a listing of all items of a given type +2. return the contents of a given type +3. save a type + +That means adding a new function that returns the full listing. + +To ensure backwards compatibility, the storage layer will inspect to see what functions the plugin provides and drive them appropriately. + +### `Storage.getLibraryEntries(type)` + +_New_: Returns the full listing of the give types in the library in the format described above. + +### `Storage.getLibraryEntry(type,path)` + +_Changed_: Get a type-specific library entry. Unlike the current version, `path` is expected to be a specific entry - not a directory. + +It will return an object: + + { + path: "/full/path/to/the/entryName, + name: "entryName" + meta: { + a: "optional meta data about the entry" + }, + body: "the main body of the entry" + } + + +### `Storage.saveLibraryEntry(type,name,meta,body)` + +_Unchanged_: save a type-specific library entry + + + + + +--- + +# Library Sidebar + +Some ascii art for the sidebar layout. + +``` ++-+-------------------------+ +| | source libraries | ++-+-------------------------+ + ++-+-------------------------+ +| | types | ++-+-------------------------+ + ++---------------------------+ +| path1 | +| path2 | +| path3 | +| path4 | +| | ++---------------------------+ +| | +| file1 | +| file2 | +| file3 | +| file4 | +| | +| | +| | +| | +| | ++---------------------------+ + ++--------+ +| import | ++--------+ +``` + +1. library select - so when there are multiple sources, one can be picked. +2. type select - the type of entity to browse. Will offer up types available for the chosen library. +3. path/file select boxes - normal file browser type behaviour +4. import button - when clicked will import the selected entry. + +**ToDo:** should there be a preview pane? Maybe the path/file boxes should collapse into one tree and use the second box for preview. + +The 'import' button behaviour will depend on the current editor state: + + - in 'normal' mode, import will import the selected flow, or the node of the appropriate type. + - if a node is being edited, the 'type' select will be restricted to the required type and clicking import will copy it over to the node edit dialog + +**Todo:** what is the `export to library` workflow. + +--- + +# External Library API + +A common request is to be able to have a shared library between a team of developers. The current model works if they are sharing a node-red instance (as the current library is local to the runtime), but doesn't help where you have assets that should be shared across instances. + +So... what's the right way to allow other libraries to be plugged in? + + + +---- + +# IGNORE STUFF BELOW HERE + +#### `/library/flows` For `flows` type, if the path is empty, it returns a complete listing of all `flow` library entries. The response object is a simple recursive structure; at the top level, two properties might exist: @@ -153,106 +287,3 @@ The previous example becomes: ] } ``` - -## Storage API - -Ideally the underlying storage api shouldn't have to change. But it needs to. - -The problem is with [`Storage.getLibraryEntry(type,name)`](http://nodered.org/docs/api/storage/methods/#storagegetlibraryentrytypename). - -In its current form, if `name` is a directory, it is expected to return a listing of the files and directories, *including any metadata about the files*. This is a problem as that metadata (such as `outputs` count on Functions) is contained inside the file; in order to return the listing, every file must be read in part to retrieve its metadata. - -We need three functions: - -1. return a listing of all items of a given type -2. return the contents of a given type -3. save a type - -That means adding a new function that returns the full listing - -#### `Storage.getLibraryEntries(type)` - -_New_: Returns the full listing of the give types in the library in the format described above. - -#### `Storage.getLibraryEntry(type,path)` - -_Changed_: Get a type-specific library entry. Unlike the current version, `path` is expected to be a specific entry - not a directory. - -It will return an object: - - { - path: "/full/path/to/the/entryName, - name: "entryName" - meta: { - a: "optional meta data about the entry" - }, - body: "the main body of the entry" - } - - -#### `Storage.saveLibraryEntry(type,name,meta,body)` - -_Unchanged_: save a type-specific library entry - - - ---- - -# Library Sidebar - -Some ascii art for the sidebar layout. - -``` -+-+-------------------------+ -| | source libraries | -+-+-------------------------+ - -+-+-------------------------+ -| | types | -+-+-------------------------+ - -+---------------------------+ -| path1 | -| path2 | -| path3 | -| path4 | -| | -+---------------------------+ -| | -| file1 | -| file2 | -| file3 | -| file4 | -| | -| | -| | -| | -| | -+---------------------------+ - -+--------+ -| import | -+--------+ -``` - -1. library select - so when there are multiple sources, one can be picked. -2. type select - the type of entity to browse. Will offer up types available for the chosen library. -3. path/file select boxes - normal file browser type behaviour -4. import button - when clicked will import the selected entry. - -**ToDo:** should there be a preview pane? Maybe the path/file boxes should collapse into one tree and use the second box for preview. - -The 'import' button behaviour will depend on the current editor state: - - - in 'normal' mode, import will import the selected flow, or the node of the appropriate type. - - if a node is being edited, the 'type' select will be restricted to the required type and clicking import will copy it over to the node edit dialog - -**Todo:** what is the `export to library` workflow. - ---- - -# External Library API - -A common request is to be able to have a shared library between a team of developers. The current model works if they are sharing a node-red instance (as the current library is local to the runtime), but doesn't help where you have assets that should be shared across instances. - -So... what's the right way to allow other libraries to be plugged in? \ No newline at end of file