enh: add types for project configuration files

Add types for project configuration files

Co-authored-by: Bassel Kanso <basselkanso82@gmail.com>
Co-authored-by: Christian Capeans <christiancp100@gmail.com>
Co-authored-by: Christian <christian.capeans.perez@strapi.io>
This commit is contained in:
Ben Irvin 2024-01-05 10:36:54 +01:00 committed by GitHub
parent 4cd75b2523
commit 3a87f3cd99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 222 additions and 24 deletions

View File

@ -1,4 +1,4 @@
export default ({ env }) => ({
const adminConfig = ({ env }) => ({
auth: {
secret: env('ADMIN_JWT_SECRET', 'example-token'),
},
@ -15,3 +15,5 @@ export default ({ env }) => ({
promoteEE: env.bool('FLAG_PROMOTE_EE', true),
},
});
export default adminConfig;

View File

@ -1,7 +1,9 @@
export default ({ env }) => ({
const serverConfig = ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
app: {
keys: env.array('APP_KEYS', ['toBeModified1', 'toBeModified2']),
},
});
export default serverConfig;

View File

@ -36,15 +36,7 @@ const dummyMiddleware: Common.MiddlewareHandler = (_, next) => next();
* Initialize every configured middlewares
*/
const resolveMiddlewares = (
config: Array<
| string
| {
name?: string;
resolve?: string;
config?: unknown;
}
| Common.MiddlewareHandler
>,
config: Array<Common.MiddlewareName | Common.MiddlewareConfig | Common.MiddlewareHandler>,
strapi: Strapi
) => {
const middlewares: {

View File

@ -1,7 +1,10 @@
/* eslint-disable @typescript-eslint/no-namespace */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable vars-on-top */
/* eslint-disable no-var */
// TODO v5: change all 'any' to 'unknown' or a real type
import type { Database } from '@strapi/database';
import type { Logger } from '@strapi/logger';
@ -29,6 +32,9 @@ import type { Container } from './container';
export type * from './types';
// TODO add this to ./types/core when the ts-lint (Multiple import/export error with same name) issue is fixed
export type * as Config from './types/core/config';
export {
Container,
Server,

View File

@ -1,11 +1,19 @@
import type Koa from 'koa';
import type { Strapi } from '../../..';
import type { Common, Strapi } from '../../..';
export type MiddlewareFactory<T = any> = (
config: T,
ctx: { strapi: Strapi }
) => MiddlewareHandler | void;
export type MiddlewareName = Common.UID.Middleware | string;
export type MiddlewareConfig = {
name?: MiddlewareName;
resolve?: string;
config?: unknown;
};
export type MiddlewareHandler = Koa.Middleware;
export type Middleware = MiddlewareHandler | MiddlewareFactory;

View File

@ -0,0 +1,49 @@
export interface ApiTokenProp {
salt: string;
}
export interface AuthProp {
secret: string;
}
export interface TransferTokenProp {
salt: string;
}
export interface AuditLogsProp {
retentionDays?: number;
}
export interface ForgotPasswordProp {
emailTemplate?: string;
from?: string;
replyTo?: string;
}
export interface RateLimitProp {
enabled?: boolean;
interval?: number;
max?: number;
delayAfter?: number;
timeWait?: number;
prefixKey?: number;
whitelist?: string;
store?: string;
}
export interface TransferProp {
token: TransferTokenProp;
}
export interface Admin {
// required
apiToken: ApiTokenProp;
transfer: TransferProp;
auth: AuthProp;
// optional
auditLogs?: AuditLogsProp;
url?: string;
forgotPassword?: ForgotPasswordProp;
rateLimit?: RateLimitProp;
}

View File

@ -0,0 +1,16 @@
export interface ResponsesProp {
privateAttributes: string[];
}
export interface RestProp {
prefix?: string;
port?: number;
defaultLimit?: number;
maxLimit?: number;
withCount?: boolean;
}
export interface Api {
responses?: ResponsesProp;
rest: RestProp;
}

View File

@ -0,0 +1,66 @@
import type { Utils } from '../../..';
type ClientKind = 'mysql' | 'postgres' | 'sqlite';
type IfClientIs<
TClient extends ClientKind,
TClientKind extends ClientKind,
TOnTrue,
TOnFalse
> = Utils.Expression.If<Utils.Expression.StrictEqual<TClient, TClientKind>, TOnTrue, TOnFalse>;
type SSLConfig = {
rejectUnauthorized?: boolean;
key?: string;
cert?: string;
ca?: string;
capath?: string;
cipher?: string;
};
type PoolConfig = {
min?: number;
max?: number;
acquireTimeoutMillis?: number;
createTimeoutMillis?: number;
destroyTimeoutMillis?: number;
idleTimeoutMillis?: number;
reapIntervalMillis?: number;
createRetryIntervalMillis?: number;
// Todo: add types for these callbacks
afterCreate?: (conn: unknown, done: (err?: Error, conn?: unknown) => void) => void;
};
type Connection<TClient extends ClientKind> = {
database: string;
user: string;
password: string;
port: number;
host: string;
ssl?: SSLConfig | boolean;
connectionString?: string;
timezone?: string;
} & { [key: string]: unknown } & IfClientIs<TClient, 'postgres', { schema?: string }, unknown>;
type SqliteConnection = {
filename: string;
} & { [key: string]: unknown };
export interface Database<TClient extends ClientKind> {
connection: {
client: TClient;
connection: IfClientIs<TClient, 'sqlite', SqliteConnection, Connection<TClient>>;
debug?: boolean;
pool?: PoolConfig;
acquireConnectionTimeout?: number;
} & { [key: string]: unknown } & IfClientIs<
TClient,
'sqlite',
{ useNullAsDefault?: boolean },
unknown
>;
settings?: {
forceMigration?: boolean;
runMigrations?: boolean;
};
}

View File

@ -0,0 +1,6 @@
export type { Server } from './server';
export type { Admin } from './admin';
export type { Api } from './api';
export type { Plugin } from './plugin';
export type { Database } from './database';
export type { Middlewares } from './middlewares';

View File

@ -0,0 +1,3 @@
import type { MiddlewareConfig, MiddlewareHandler, MiddlewareName } from '../common';
export type Middlewares = Array<MiddlewareName | MiddlewareConfig | MiddlewareHandler>;

View File

@ -0,0 +1,9 @@
export interface Plugin {
[key: string]:
| {
enabled: boolean;
resolve?: string;
config?: object;
}
| boolean;
}

View File

@ -0,0 +1,33 @@
export interface AppProp {
keys: string[];
}
export interface CronProp {
enabled?: boolean;
tasks?: object;
}
export interface DirsProp {
public?: string;
}
export interface WebhooksProp {
populateRelations?: boolean;
}
export interface Server {
// required
host: string;
port: number;
app: AppProp;
// optional
socket?: string | number;
emitErrors?: boolean;
url?: string;
proxy?: boolean;
globalProxy?: string;
cron?: CronProp;
dirs?: DirsProp;
webhooks?: WebhooksProp;
}

View File

@ -0,0 +1,15 @@
import { env } from '@strapi/utils';
export type ConfigParams = {
env: typeof env;
};
export type ConfigFunction<TConfigObject = UnknownConfigObject> = (
params: ConfigParams
) => TConfigObject;
export type UnknownConfigObject = Record<string, unknown>;
export type ConfigExport<TConfigObject = UnknownConfigObject> =
| ConfigFunction<TConfigObject>
| TConfigObject;

View File

@ -1,20 +1,9 @@
/**
* Note: linting will erroneously raise errors if a namespaced type has the same name as on exported by Strapi
* To work around it, use a pattern such as:
*
* import * as PluginImport from './plugins'
* export type Plugin = typeof PluginImport
*
* which causes linting to see the namespaces correctly.
*/
export * as Attribute from './attributes';
export * as Schema from './schemas';
export * as Plugin from './plugins';
export * as Entity from './entity';
export * as Permissions from './permissions';
export * from './strapi';
export * as Common from './common';
export * as Namespace from './namespace';
export * as UID from './uid';

View File

@ -1,5 +1,7 @@
import _ from 'lodash';
export type Env = typeof envFn & typeof utils;
function envFn<T>(key: string, defaultValue?: T): string | T | undefined {
return _.has(process.env, key) ? process.env[key] : defaultValue;
}
@ -94,6 +96,6 @@ const utils = {
},
};
const env = Object.assign(envFn, utils);
const env: Env = Object.assign(envFn, utils);
export default env;