diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..7cb793f --- /dev/null +++ b/.npmignore @@ -0,0 +1,2 @@ +yarn-error.log +yarn.lock \ No newline at end of file diff --git a/.woodpecker/deploy.yml b/.woodpecker/deploy.yml new file mode 100644 index 0000000..0416e64 --- /dev/null +++ b/.woodpecker/deploy.yml @@ -0,0 +1,16 @@ +pipeline: + validate: + image: node:lts-alpine + commands: + - yarn install + - yarn valid + deploy: + image: node:lts-alpine + commands: + - echo "//registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN" > .npmrc + - yarn publish --non-interactive + secrets: [ node_auth_token ] + when: + event: tag + tag: v* + diff --git a/README.md b/README.md new file mode 100644 index 0000000..76621e3 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# Flaschengeist types +![status-badge](https://ci.os-sc.org/api/badges/Flaschengeist/flaschengeist-types/status.svg) + +This package provides the TypeScript typings needed for developing with the [Flaschengeist](https://flaschengeist.dev/Flaschengeist/flaschengeist) and the [Flaschengeist-Plugin](https://flaschengeist.dev/Flaschengeist/flaschengeist-frontend) API. + +## License + +Licensed under the MIT license, see [LICENSE](./LICENSE) for more details. + +## Development + +Feel free to report bugs, issues and feature requests using the [Issues function](https://flaschengeist.dev/Flaschengeist/flaschengeist/issues). + +Please follow our [general development guide](https://flaschengeist.dev/Flaschengeist/flaschengeist/wiki/Development#general-development). diff --git a/package.json b/package.json index f857d18..1a6f939 100644 --- a/package.json +++ b/package.json @@ -1,32 +1,33 @@ { - "private": true, "license": "MIT", - "version": "0.0.1", + "version": "1.1.0", "name": "@flaschengeist/types", - "author": "Ferdinand ", - "homepage": "https://flaschengeist.dev/Flaschengeist", + "author": "Ferdinand Thiessen ", + "homepage": "https://flaschengeist.dev/", "description": "Flaschengeist TypeScript typings", "bugs": { "url": "https://flaschengeist.dev/Flaschengeist/flaschengeist/issues" }, "repository": { "type": "git", - "url": "https://flaschengeist.dev/Flaschengeist/flaschengeist-typings" + "url": "https://flaschengeist.dev/Flaschengeist/flaschengeist-types" }, - "main": "dist/index.js", - "typings": "dist/index.d.ts", + "flat": true, + "typings": "types/index.d.ts", "scripts": { - "build": "tsc", - "pretty": "prettier --config ./package.json --write '{,!(node_modules)/**/}*.ts'" - }, - "devDependencies": { - "prettier": "^2.3.0", - "typescript": "^4.2.4", - "vue": "^3.0.11", - "vue-router": "^4.0.8" + "valid": "tsc --noEmit", + "format": "prettier --config ./package.json --write '{,!(node_modules)/**/}*.ts'" }, "peerDependencies": { - "flaschengeist": "^2.0.0-alpha.1" + "vue": "^3.2.20", + "vue-router": "^4.0.11" + }, + "devDependencies": { + "@babel/types": "^7.16.0", + "prettier": "^2.5.1", + "typescript": "^4.5.2", + "vue": "^3.2.26", + "vue-router": "^4.0.12" }, "prettier": { "singleQuote": true, diff --git a/src/flaschengeist.d.ts b/src/flaschengeist.d.ts deleted file mode 100644 index 0b0a806..0000000 --- a/src/flaschengeist.d.ts +++ /dev/null @@ -1,137 +0,0 @@ -declare namespace FG { - interface Notification { - id: number; - plugin: string; - text: string; - data?: unknown; - time: Date; - } - interface User { - userid: string; - display_name: string; - firstname: string; - lastname: string; - mail: string; - birthday?: Date; - roles: Array; - permissions?: Array; - avatar_url?: string; - } - interface Session { - expires: Date; - token: string; - lifetime: number; - browser: string; - platform: string; - userid: string; - } - type Permission = string; - interface Role { - id: number; - name: string; - permissions: Array; - } - interface Transaction { - id: number; - time: Date; - amount: number; - reversal_id?: number; - author_id?: string; - sender_id?: string; - original_id?: number; - receiver_id?: string; - } - interface Event { - id: number; - start: Date; - end?: Date; - name?: string; - description?: string; - type: EventType | number; - is_template: boolean; - jobs: Array; - } - interface EventType { - id: number; - name: string; - } - interface Invite { - id: number; - job_id: number; - invitee_id: string; - sender_id: string; - } - interface Job { - id: number; - start: Date; - end?: Date; - type: JobType | number; - comment?: string; - services: Array; - required_services: number; - } - interface JobType { - id: number; - name: string; - } - interface Service { - userid: string; - is_backup: boolean; - value: number; - } - interface Drink { - id: number; - article_id?: string; - package_size?: number; - name: string; - volume?: number; - cost_per_volume?: number; - cost_per_package?: number; - tags?: Array; - type?: DrinkType; - volumes: Array; - uuid: string; - receipt?: Array; - } - interface DrinkIngredient { - id: number; - volume: number; - ingredient_id: number; - } - interface DrinkPrice { - id: number; - price: number; - public: boolean; - description?: string; - } - interface DrinkPriceVolume { - id: number; - volume: number; - min_prices: Array; - prices: Array; - ingredients: Array; - } - interface DrinkType { - id: number; - name: string; - } - interface ExtraIngredient { - id: number; - name: string; - price: number; - } - interface Ingredient { - id: number; - drink_ingredient?: DrinkIngredient; - extra_ingredient?: ExtraIngredient; - } - interface MinPrices { - percentage: number; - price: number; - } - interface Tag { - id: number; - name: string; - color: string; - } -} diff --git a/src/index.d.ts b/src/index.d.ts deleted file mode 100644 index 0f87dc5..0000000 --- a/src/index.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -/// -/// \ No newline at end of file diff --git a/src/index.ts b/src/index.ts deleted file mode 100644 index a022b03..0000000 --- a/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -/// \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 5311e73..ded90b4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,9 +4,8 @@ "target": "esnext", "module": "esnext", "declaration": true, - "outDir": "./dist", "strict": true, - "moduleResolution": "node" + "moduleResolution": "Node" }, "exclude": [ "node_modules", diff --git a/types/PEP440.d.ts b/types/PEP440.d.ts new file mode 100644 index 0000000..f55b2b9 --- /dev/null +++ b/types/PEP440.d.ts @@ -0,0 +1,14 @@ +/* This is some sort of PEP440 subset */ +type Join = T extends [] + ? '' + : T extends [string | number | boolean | bigint] + ? `${T[0]}` + : T extends [string | number | boolean | bigint, ...infer U] + ? `${T[0]}${D}${Join}` + : string; +type BaseVersion = Join<[number, number], '.'> | Join<[number, number, number], '.'>; +type PreRelease = Join<[['a' | 'b' | 'rc'], number], '.'>; +type PRVersion = BaseVersion | `${BaseVersion}${PreRelease}`; + +/** A PEP440 subset used to describe backend module versions */ +declare type PEP440Version = PRVersion | `${PRVersion}.dev${number}`; diff --git a/types/api.d.ts b/types/api.d.ts new file mode 100644 index 0000000..2d473bb --- /dev/null +++ b/types/api.d.ts @@ -0,0 +1,27 @@ +/// +/** + * Types used for communicating with the API + */ + +declare namespace FG { + interface BackendPlugin { + permissions: string[]; + version: PEP440Version; + } + interface Backend { + plugins: { [key: string]: BackendPlugin }; + version: PEP440Version; + } + interface PaginationFilter { + limit?: number; + offset?: number; + from?: Date; + to?: Date; + /** Default to ascending */ + descending?: boolean; + } + interface PaginationResponse { + result: T[]; + count: number; + } +} diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 0000000..2995593 --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,5 @@ +/// +/// +/// + +export * from './plugin'; diff --git a/types/models.d.ts b/types/models.d.ts new file mode 100644 index 0000000..3ac8bfa --- /dev/null +++ b/types/models.d.ts @@ -0,0 +1,38 @@ +/** Models exported from backend */ +declare namespace FG { + interface UserSettings { + display_name: string; + } + interface Notification { + id: number; + plugin: string; + text: string; + data?: any; + time: Date; + } + interface User { + userid: string; + deleted: boolean; + display_name: string; + firstname: string; + lastname: string; + mail: string; + birthday?: Date; + roles: Array; + permissions?: Array; + } + interface Session { + expires: Date; + token: string; + lifetime: number; + browser: string; + platform: string; + userid: string; + } + type Permission = string; + interface Role { + id: number; + name: string; + permissions: Array; + } +} diff --git a/src/plugin.d.ts b/types/plugin.d.ts similarity index 54% rename from src/plugin.d.ts rename to types/plugin.d.ts index d041af8..5d33c11 100644 --- a/src/plugin.d.ts +++ b/types/plugin.d.ts @@ -1,18 +1,29 @@ -import { RouteLocationRaw, RouteRecordRaw, RouteRecordName } from 'vue-router'; -import { Component } from 'vue'; +/// +import type { RouteLocationRaw, RouteRecordRaw, RouteRecordName } from 'vue-router'; +import type { Component } from '@vue/runtime-core'; -declare namespace FG_Plugin { +/** + * Types used for defining custom plugins and loading those plugins + * + Additional types for plugin interaction with the core + */ + +export namespace FG_Plugin { /** * Interface defining a Flaschengeist plugin */ - interface Plugin { + export interface Plugin { + /** Unique identifier for this plugin, we recommend using a FQN like com.example.my_plugin */ + id: string; + /** Arbitrary name of the plugin used inside admin view etc */ name: string; + /** Version of this plugin, used for dependencies. MUST be semver parsable */ version: string; + /** Widgets provided by this plugin */ widgets: Widget[]; - /** Pther frontend modules needed for this plugin to work correctly */ - requiredModules: string[]; + /** Widget for settings provided by this plugin **/ + settingsWidgets?: Widget[]; /** Backend modules needed for this plugin to work correctly */ - requiredBackendModules: string[]; + requiredModules: [string, PEP440Version?][]; /** Menu entries for authenticated users */ innerRoutes?: MenuRoute[]; /** Public menu entries (without authentification) */ @@ -26,7 +37,7 @@ declare namespace FG_Plugin { /** * Defines the loaded state of the Flaschengeist */ - interface Flaschengeist { + export interface Flaschengeist { /** All loaded plugins */ plugins: LoadedPlugin[]; /** All routes, combined from all plugins */ @@ -44,11 +55,13 @@ declare namespace FG_Plugin { /** * Interface for a frontend notification */ - interface Notification extends FG.Notification { - /** If set a button for accepting will be shown, this function will get called before deleting the notification */ - accept?(): Promise; - /** If set this function is called before the notification gets deleted */ - reject?(): Promise; + export interface Notification extends FG.Notification { + /** If set, a button for accepting will be shown, this function will get called before deleting the notification */ + accept?(): Promise; + /** If set, a reject button is shown and this function is called before the notification gets deleted */ + reject?(): Promise; + /** If set, this function is called before the notification gets deleted */ + dismiss?(): Promise; /** If set the notification text is interpreted as a link to this location */ link?: RouteLocationRaw; /** If set this icon is used */ @@ -59,6 +72,7 @@ declare namespace FG_Plugin { * Loaded Flaschengeist plugin */ interface LoadedPlugin { + id: string; name: string; version: string; notification(msg: FG.Notification): FG_Plugin.Notification; @@ -67,32 +81,37 @@ declare namespace FG_Plugin { /** * Defines a shortcut link */ - interface Shortcut { + export interface Shortcut { link: RouteRecordName; icon: string; permissions?: string[]; } - /** - * Defines a main menu entry along with the route - * Used when defining a plugin - */ - interface MenuRoute extends MenuEntry { - route: NamedRouteRecordRaw; - shortcut?: boolean; - children?: this[]; - } - type NamedRouteRecordRaw = RouteRecordRaw & { name: RouteRecordName; }; + /** + * Defines a main menu entry along with the route + * Used when defining a plugin + */ + export interface MenuRoute extends MenuEntry { + route: NamedRouteRecordRaw; + shortcut?: boolean; + children?: this[]; + } + /** * Defines a menu entry in the main menu */ - interface MenuLink extends MenuEntry { + export interface MenuLink extends MenuEntry { /** Name of the target route */ link: RouteRecordName; + /** + * Order inside the menu, higher numbers come ahead of lower numbers + * @todo: Promote to required with first beta + */ + order?: number; } /** @@ -108,10 +127,20 @@ declare namespace FG_Plugin { /** * Widget object for the dashboard */ - interface Widget { + export interface Widget { name: string; - priority: number; + /** + * @deprecated Deprecated in favor of order + * @todo Remove with beta 1 + */ + priority?: number; + /** + * Default order on the dashboard, higher numbers come ahead of lower numbers + * @todo Promote to required if priority is removed + */ + order?: number; permissions: FG.Permission[]; widget: Component; } } +