diff --git a/package.json b/package.json index 1f3df5673..10cd3d0c1 100644 --- a/package.json +++ b/package.json @@ -97,6 +97,7 @@ "style-loader": "^1.2.1", "svg-url-loader": "^6.0.0", "terser-webpack-plugin": "^3.0.6", + "ts-essentials": "^9.1.2", "twin.macro": "^2.0.7", "typescript": "^4.2.4", "webpack": "^4.43.0", diff --git a/resources/scripts/api/definitions/index.d.ts b/resources/scripts/api/definitions/index.d.ts new file mode 100644 index 000000000..68925c863 --- /dev/null +++ b/resources/scripts/api/definitions/index.d.ts @@ -0,0 +1,32 @@ +import { MarkRequired } from 'ts-essentials'; + +export type UUID = string; + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface Model {} + +interface ModelWithRelationships extends Model { + relationships: Record; +} + +/** + * Allows a model to have optional relationships that are marked as being + * present in a given pathway. This allows different API calls to specify the + * "completeness" of a response object without having to make every API return + * the same information, or every piece of logic do explicit null checking. + * + * Example: + * >> const user: WithLoaded = {}; + * >> // "user.servers" is no longer potentially undefined. + */ +type WithLoaded = M & { + relationships: MarkRequired; +} + +/** + * Helper type that allows you to infer the type of an object by giving + * it the specific API request function with a return type. For example: + * + * type Egg = InferModel; + */ +export type InferModel any> = ReturnType extends Promise ? U : T; diff --git a/resources/scripts/api/definitions/user/index.ts b/resources/scripts/api/definitions/user/index.ts new file mode 100644 index 000000000..7d8db7094 --- /dev/null +++ b/resources/scripts/api/definitions/user/index.ts @@ -0,0 +1,2 @@ +export * from './models.d'; +export { default as Transformers, MetaTransformers } from './transformers'; diff --git a/resources/scripts/api/definitions/user/models.d.ts b/resources/scripts/api/definitions/user/models.d.ts new file mode 100644 index 000000000..d462cadf8 --- /dev/null +++ b/resources/scripts/api/definitions/user/models.d.ts @@ -0,0 +1,2 @@ +// empty export +export type _T = string; diff --git a/resources/scripts/api/definitions/user/transformers.ts b/resources/scripts/api/definitions/user/transformers.ts new file mode 100644 index 000000000..a69ad708d --- /dev/null +++ b/resources/scripts/api/definitions/user/transformers.ts @@ -0,0 +1,5 @@ +export default class Transformers { +} + +export class MetaTransformers { +} diff --git a/tsconfig.json b/tsconfig.json index 26423ecd6..578a73e31 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,6 +22,9 @@ "@/*": [ "./resources/scripts/*" ], + "@definitions/*": [ + "./resources/scripts/api/definitions/*" + ], "@feature/*": [ "./resources/scripts/components/server/features/*" ] diff --git a/webpack.config.js b/webpack.config.js index 777b0be1b..8a9b76609 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -60,6 +60,7 @@ module.exports = { extensions: ['.ts', '.tsx', '.js', '.json'], alias: { '@': path.join(__dirname, '/resources/scripts'), + '@definitions': path.join(__dirname, '/resources/scripts/api/definitions'), '@feature': path.join(__dirname, '/resources/scripts/components/server/features'), }, symlinks: false, diff --git a/yarn.lock b/yarn.lock index 9c67ff246..4b67c3662 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7481,6 +7481,11 @@ tryer@^1.0.1: resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== +ts-essentials@^9.1.2: + version "9.1.2" + resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-9.1.2.tgz#46db6944b73b4cd603f3d959ef1123c16ba56f59" + integrity sha512-EaSmXsAhEiirrTY1Oaa7TSpei9dzuCuFPmjKRJRPamERYtfaGS8/KpOSbjergLz/Y76/aZlV9i/krgzsuWEBbg== + ts-toolbelt@^8.0.7: version "8.0.7" resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-8.0.7.tgz#4dad2928831a811ee17dbdab6eb1919fc0a295bf"