Skip to content

Commit fc0264d

Browse files
authored
feat: add typescript declaration file (#594)
1 parent 6007884 commit fc0264d

File tree

5 files changed

+455
-37
lines changed

5 files changed

+455
-37
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
- [ ] Test manually the implemented changes
66
- [ ] Review my own code (indentation, syntax, style, simplicity, readability)
77
- [ ] Wonder if you can improve the existing code
8+
- [ ] If needed, Types have been updated

package.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"url": "git://github.com/ForestAdmin/forest-express-mongoose.git"
2424
},
2525
"main": "dist/index.js",
26+
"types": "./types/index.d.ts",
2627
"dependencies": {
2728
"@babel/runtime": "7.10.1",
2829
"bluebird": "2.9.25",
@@ -45,6 +46,8 @@
4546
"@semantic-release/changelog": "5.0.1",
4647
"@semantic-release/git": "9.0.0",
4748
"@types/jest": "26.0.13",
49+
"@typescript-eslint/eslint-plugin": "4.27.0",
50+
"@typescript-eslint/parser": "4.27.0",
4851
"babel-eslint": "10.0.3",
4952
"eslint": "6.7.2",
5053
"eslint-config-airbnb-base": "14.0.0",
@@ -54,17 +57,18 @@
5457
"husky": "4.2.5",
5558
"jest": "26.6.3",
5659
"jest-extended": "0.11.5",
57-
"mongoose": "5.11.20",
60+
"mongoose": "5.12.14",
5861
"mongoose-fixture-loader": "1.0.2",
5962
"semantic-release": "17.4.2",
6063
"semantic-release-npm-deprecate-old-versions": "1.1.2",
6164
"semantic-release-slack-bot": "1.6.2",
62-
"simple-git": "1.65.0"
65+
"simple-git": "1.65.0",
66+
"typescript": "4.3.3"
6367
},
6468
"scripts": {
6569
"build": "babel --out-dir dist src",
6670
"build:watch": "babel --watch --source-maps inline --out-dir dist src",
67-
"lint": "./node_modules/eslint/bin/eslint.js .eslint-bin src test",
71+
"lint": "./node_modules/eslint/bin/eslint.js .eslint-bin src test types/index.d.ts --ext '.js'",
6872
"test": "jest --runInBand",
6973
"test:coverage": "jest --runInBand --coverage --collectCoverageFrom=\"src/**/*.{ts,js}\""
7074
}

types/.eslintrc.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module.exports = {
2+
"root": true,
3+
"parser": "@typescript-eslint/parser",
4+
"plugins": [
5+
"@typescript-eslint"
6+
],
7+
"rules": {
8+
"@typescript-eslint/no-explicit-any": "off"
9+
},
10+
"extends": [
11+
"eslint:recommended",
12+
"plugin:@typescript-eslint/eslint-recommended",
13+
"plugin:@typescript-eslint/recommended"
14+
]
15+
}

types/index.d.ts

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
import { RequestHandler, Response, Request, NextFunction, Application } from 'express';
2+
import {
3+
ConnectionOptions,
4+
Mongoose,
5+
Connection,
6+
Model,
7+
Types,
8+
Document,
9+
FilterQuery,
10+
} from "mongoose";
11+
12+
// Everything related to Forest initialization
13+
14+
export interface LianaOptions {
15+
objectMapping: Mongoose;
16+
envSecret: string;
17+
authSecret: string;
18+
connections: Record<string, Connection>;
19+
includedModels?: string[];
20+
excludedModels?: string[];
21+
configDir?: string;
22+
}
23+
24+
export function init(options: LianaOptions): Promise<Application>;
25+
26+
export interface DatabaseConfiguration {
27+
name: string,
28+
modelsDir: string,
29+
connection: {
30+
url: string,
31+
options: ConnectionOptions,
32+
}
33+
}
34+
35+
// Everything related to Forest Authentication
36+
37+
export function ensureAuthenticated(request: Request, response: Response, next: NextFunction): void;
38+
39+
// Everything related to Forest constants
40+
41+
export const PUBLIC_ROUTES: string[];
42+
43+
// Everything related to record manipulation
44+
45+
type RecordId = Types.ObjectId | string | number;
46+
47+
interface RecordsSerialized {
48+
data: Record<string, unknown>[],
49+
included: Record<string, unknown>[],
50+
}
51+
52+
export class AbstractRecordTool<T> {
53+
constructor(model: Model<T>)
54+
serialize(records: Document<T> | Document<T>[]): Promise<RecordsSerialized>;
55+
}
56+
57+
export class RecordGetter<T> extends AbstractRecordTool<T> {
58+
get(recordId: RecordId): Promise<T & Document>;
59+
}
60+
61+
export class RecordsGetter<T> extends AbstractRecordTool<T> {
62+
getAll(query: Query): Promise<(T & Document)[]>;
63+
getIdsFromRequest(request: Request): Promise<string[]>;
64+
}
65+
66+
export class RecordsCounter<M extends Model<any>> extends AbstractRecordTool<M> {
67+
count(query: Query): Promise<number>;
68+
}
69+
70+
export class RecordsExporter<M extends Model<any>> extends AbstractRecordTool<M> {
71+
streamExport(response: Response, query: Query): Promise<void>;
72+
}
73+
74+
export class RecordUpdater<M extends Model<any>> extends AbstractRecordTool<M> {
75+
deserialize(body: Record<string, unknown>): Promise<Record<string, unknown>>;
76+
update(record: Record<string, unknown>, recordId: RecordId): Promise<M>;
77+
}
78+
79+
export class RecordCreator<M extends Model<any>> extends AbstractRecordTool<M> {
80+
deserialize(body: Record<string, unknown>): Promise<Record<string, unknown>>;
81+
create(record: Record<string, unknown>): Promise<M>;
82+
}
83+
84+
export class RecordRemover<M extends Model<any>> extends AbstractRecordTool<M> {
85+
remove(recordId: RecordId): Promise<void>;
86+
}
87+
88+
export class RecordsRemover<M extends Model<any>> extends AbstractRecordTool<M> {
89+
remove(recordIds: RecordId[]): Promise<void>;
90+
}
91+
92+
// Everything related to Forest permissions
93+
94+
export class PermissionMiddlewareCreator {
95+
constructor(collectionName: string)
96+
list(): RequestHandler;
97+
export(): RequestHandler;
98+
details(): RequestHandler;
99+
create(): RequestHandler;
100+
update(): RequestHandler;
101+
delete(): RequestHandler;
102+
smartAction(): RequestHandler;
103+
}
104+
105+
// Everything related to Forest Charts
106+
107+
export interface StatSerialized {
108+
data: {
109+
type: string,
110+
id: string,
111+
attributes: {
112+
value: any[]
113+
}
114+
};
115+
}
116+
117+
export class StatSerializer {
118+
constructor(stats: { value: any[] })
119+
perform(): StatSerialized;
120+
}
121+
122+
// Everything related to Forest request params
123+
124+
export interface Page {
125+
number: number;
126+
size: number;
127+
}
128+
129+
export interface Filter {
130+
field: string;
131+
operator: string;
132+
value: string;
133+
}
134+
135+
export enum Aggregator {
136+
AND = 'and',
137+
OR = 'or'
138+
}
139+
140+
export interface AggregatedFilters {
141+
aggregator: Aggregator;
142+
conditions: Filter[];
143+
}
144+
145+
export interface Query {
146+
timezone?: string;
147+
search?: string;
148+
fields?: {[key: string]: string};
149+
sort?: string;
150+
filters?: Filter|AggregatedFilters;
151+
page?: Page;
152+
searchExtended?: string;
153+
}
154+
155+
// Everything related to Forest collection configuration
156+
157+
export interface SmartFieldValueGetter<T = any> {
158+
(record: T & Document): any;
159+
}
160+
161+
export interface SmartFieldValueSetter<T = any> {
162+
(record: T & Document, fieldValue: any): any;
163+
}
164+
165+
export interface SmartFieldSearcher {
166+
(search: string): FilterQuery<any>;
167+
}
168+
169+
export interface SmartFieldFiltererFilter {
170+
condition: FilterQuery<any>,
171+
where: Record<symbol, Record<symbol, any> | any>,
172+
}
173+
174+
export interface SmartFieldFilterer {
175+
(filter: SmartFieldFiltererFilter): FilterQuery<any>;
176+
}
177+
178+
export interface SegmentAggregationCreator<T = any> {
179+
(model: Model<T>): FilterQuery<any>;
180+
}
181+
182+
type FieldType = 'Boolean' | 'Date' | 'Dateonly' | 'Enum' | 'File' | 'Number' | 'String' | ['Enum'] | ['Number'] | ['String'];
183+
184+
type FieldEnumsType = string[] | number[] | Date[] | boolean[];
185+
186+
export interface SmartFieldOptions {
187+
field: string;
188+
description?: string;
189+
type: FieldType;
190+
isFilterable?: boolean;
191+
isReadOnly?: boolean;
192+
isRequired?: boolean;
193+
reference?: string;
194+
enums?: FieldEnumsType;
195+
defaultValue?: any;
196+
get?: SmartFieldValueGetter;
197+
set?: SmartFieldValueSetter;
198+
search?: SmartFieldSearcher;
199+
filter?: SmartFieldFilterer;
200+
}
201+
202+
export interface SmartActionField {
203+
field: string,
204+
description?: string,
205+
type: FieldType,
206+
isRequired?: boolean,
207+
isReadOnly?: boolean,
208+
enums?: FieldEnumsType,
209+
defaultValue?: any,
210+
reference?: string,
211+
}
212+
213+
export interface SmartActionHookField extends SmartActionField {
214+
value: any,
215+
}
216+
217+
export interface SmartActionLoadHookField extends SmartActionHookField {
218+
position: number,
219+
}
220+
221+
export interface SmartActionLoadHook<T = any> {
222+
(context: { fields: Record<string, SmartActionLoadHookField>, record: T & Document }): Record<string, SmartActionLoadHookField>
223+
}
224+
225+
export interface SmartActionChangeHookField extends SmartActionHookField {
226+
previousValue: any,
227+
}
228+
229+
export interface SmartActionChangeHook<T = any> {
230+
(context: { fields: Record<string, SmartActionChangeHookField>, record: T }): Record<string, SmartActionChangeHookField>
231+
}
232+
233+
export interface SmartActionHooks {
234+
load: SmartActionLoadHook;
235+
change: Record<string, SmartActionChangeHook>;
236+
}
237+
238+
export interface SmartActionOptions {
239+
name: string;
240+
type?: 'global' | 'bulk' | 'single';
241+
fields?: SmartActionField[];
242+
download?: boolean;
243+
endpoint?: string;
244+
httpMethod?: string;
245+
hooks?: SmartActionHooks;
246+
}
247+
248+
export interface SmartSegmentOptions {
249+
name: string;
250+
where: SegmentAggregationCreator;
251+
}
252+
253+
export interface CollectionOptions {
254+
fields?: SmartFieldOptions[];
255+
actions?: SmartActionOptions[];
256+
segments?: SmartSegmentOptions[];
257+
}
258+
259+
export function collection(name: string, options: CollectionOptions): void;
260+
261+
export function errorHandler(): RequestHandler;

0 commit comments

Comments
 (0)