UNPKG

@appsemble/node-utils

Version:

NodeJS utilities used by Appsemble internally.

475 lines (474 loc) 16.7 kB
import { type Readable } from 'node:stream'; import { type ActionDefinition, type AppMemberGroup, type BlockDefinition, type ControllerDefinition, type CustomAppPermission, type EmailActionDefinition, type IdentifiableBlock, type ResourceDefinition, type Theme as ThemeType } from '@appsemble/lang-sdk'; import { type App, type AppConfigEntry, type AppMemberInfo, type AppMessages, type Asset, type BlockManifest, type Group, type OrganizationPermission, type Resource } from '@appsemble/types'; import { type RawAxiosRequestConfig } from 'axios'; import { type DefaultContext as DefaultContextInterface, type DefaultState, type ParameterizedContext } from 'koa'; export interface AuthSubject { id: string; } declare module 'koa' { interface Request { body: any; } interface DefaultContext { appPath: string; appHost: string; appsembleApp: App; appBlocks: BlockManifest[]; appMessages: AppMessages[]; appVariables: AppConfigEntry[]; appMembers: AppMemberInfo[]; appMemberInfo: AppMemberInfo; appGroups: ExtendedGroup[]; appAssets: AppAsset[]; appReadmes: AppReadme[]; blockConfigs: ContextBlockConfig[]; params?: Record<string, string>; } } declare module 'koas-security' { interface Clients { app: { scope: string; app: App; }; basic: {}; cli: { scope: string; }; studio: {}; webhook: {}; } interface Users { app: AuthSubject; basic: AuthSubject; cli: AuthSubject; scim: AuthSubject; studio: AuthSubject; webhook: AuthSubject; } } declare module 'koas-parameters' { interface PathParams { appId: number; appCollectionId: number; appOAuth2SecretId: number; appSamlSecretId: number; assetId: string; blockId: string; blockVersion: string; controllerName: string; controllerVersion: string; clientId: string; language: string; organizationMemberId: string; groupMemberId: string; appMemberId: string; organizationId: string; organizationSubscriptionId: number; path: string; resourceId: number; resourceType: string; resourceTypeId: string; schemaId: string; screenshotId: number; readmeId: number; snapshotId: number; groupId: number; token: string; serviceSecretId: number; appSecretId: number; appVariableId: number; userId: string; memberEmail: string; trainingId: number; container: string; webhookName: string; webhookSecretId: string; } interface QueryParams { domains: string[]; $filter?: string; filter: string; $orderby?: string; $select: string; organizationId: string; $top: number; $skip: number; code: string; count: number; period: string; subscriptionType: string; price: string; locale: string; couponCode: string; startIndex: number; view: string; resources: boolean; assets: boolean; organizationSubscriptionExpiresWithin: number; screenshots: boolean; readmes: boolean; roles?: string; includeMessages: boolean; demo: boolean; selectedGroupId: number[]; $own: boolean; delimiter?: string; email: string; width?: number; height?: number; secret: string; } } export type Operator = 'and' | 'not' | 'or'; export type Function = 'gt'; type Reserved = Function | Operator; export type NonReserved<T extends string> = T extends Reserved ? never : T; export type WhereOptions = Record<string, any>; export type OrderItem = [string, string]; export interface FindOptions { where?: WhereOptions; limit?: number; offset?: number; attributes?: string[]; order?: OrderItem[]; include?: any[]; } export interface ContextBlockConfig extends BlockManifest { OrganizationId: string; } export interface GetAppParams { context: ParameterizedContext<DefaultState, DefaultContextInterface, any>; query?: Record<string, any>; } export interface GetAppSubEntityParams { context: ParameterizedContext<DefaultState, DefaultContextInterface, any>; app: App; } export interface GetAppVariablesParams extends GetAppSubEntityParams { query?: Record<string, any>; } export interface GetAppMessagesParams extends GetAppSubEntityParams { language?: string; merge?: string[] | string; } export interface ExtendedGroup extends Group { size: number; } export interface GetAppBlockStylesParams extends GetAppSubEntityParams { name: string; } export interface GetDbUpdatedParams extends GetAppSubEntityParams { maskable: string[] | string | false; } export type BlockMessages = Pick<BlockManifest, 'messages' | 'name' | 'version'>; export type BlockQueryItem = Pick<ContextBlockConfig, 'name' | 'OrganizationId' | 'version'>; export interface GetBlockMessagesParams { context: ParameterizedContext<DefaultState, DefaultContextInterface, any>; blockQuery: BlockQueryItem[]; baseLang: string; lang: string; } export interface GetBlockAssetParams { context: ParameterizedContext<DefaultState, DefaultContextInterface, any>; name: string; filename: string; version: string; } export interface GetControllerVersionAssetParams { controllerName: string; controllerVersion: string; organizationId: string; filename: string[] | string; } export interface GetBlocksAssetsPathsParams { context: ParameterizedContext<DefaultState, DefaultContextInterface, any>; identifiableBlocks: IdentifiableBlock[]; } export type ExtendedTheme = Omit<Partial<ThemeType>, 'font'> & { bulmaVersion: string; fontFamily: string; fontSource: string; }; export interface GetHostParams { context: ParameterizedContext<DefaultState, DefaultContextInterface, any>; } export interface GetThemeParams { theme: ExtendedTheme; } export interface CreateThemeParams extends ExtendedTheme { css: string; } export interface CreateSettingsParams { context: ParameterizedContext<DefaultState, DefaultContextInterface, any>; app: App; host: string; identifiableBlocks: IdentifiableBlock[]; controllerDefinition?: ControllerDefinition; hostname: string; languages: string[]; nonce: string; } export interface GetCspParams { app: App; host: string; hostname: string; settingsHash: string; nonce: string; } export interface GetCurrentAppMemberParams { context: ParameterizedContext<DefaultState, DefaultContextInterface, any>; app: App; } export interface GetCurrentAppMemberSelectedGroupParams { context: ParameterizedContext<DefaultState, DefaultContextInterface, any>; app: App; } export interface GetCurrentAppMemberGroupsParams { context: ParameterizedContext<DefaultState, DefaultContextInterface, any>; app: App; } export type ResourceAction = 'create' | 'delete' | 'update'; export type Action = ResourceAction | 'count' | 'get' | 'patch' | 'query'; export interface ApplyAppServiceSecretsParams { context: ParameterizedContext<DefaultState, DefaultContextInterface, any>; app: App; axiosConfig: RawAxiosRequestConfig<any>; } export interface CheckAppMemberAppPermissionsParams { context: ParameterizedContext<DefaultState, DefaultContextInterface, any>; permissions: CustomAppPermission[]; app: App; } export interface CheckUserOrganizationPermissionsParams { context: ParameterizedContext<DefaultState, DefaultContextInterface, any>; permissions: OrganizationPermission[]; app: App; } export interface CheckAuthSubjectAppPermissionsParams { context: ParameterizedContext<DefaultState, DefaultContextInterface, any>; app: App; groupId?: number | number[] | null; permissions: CustomAppPermission[]; } export interface CheckAppPermissionsParams { context: ParameterizedContext<DefaultState, DefaultContextInterface, any>; app: App; groupId?: number | number[] | null; permissions: CustomAppPermission[]; } export interface ReloadUserParams { context: ParameterizedContext<DefaultState, DefaultContextInterface, any>; } export interface ParseQueryParams { tableName: string; $filter: string; $orderby: string; resourceDefinition: ResourceDefinition; } export interface GetAppResourceParams extends GetAppSubEntityParams { findOptions: FindOptions; type: string; id: number | string; } export interface GetAppAssetParams extends GetAppSubEntityParams { id: string; } export interface GetAppResourcesParams extends GetAppSubEntityParams { findOptions: FindOptions; type: string; } export interface PreparedAsset extends Pick<Asset, 'filename' | 'id' | 'mime'> { path: string; resource?: Record<string, unknown>; } export interface CreateAppResourcesWithAssetsParams extends GetAppSubEntityParams { resources: Record<string, unknown>[]; preparedAssets: PreparedAsset[]; resourceType: string; options: Options; groupId?: number | null; } export interface UpdateAppResourceParams extends GetAppSubEntityParams { id: number | string; resource: Record<string, unknown>; preparedAssets: PreparedAsset[]; resourceDefinition: ResourceDefinition; deletedAssetIds: string[]; type: string; options: Options; /** * The same where clause used by the controller's pre-lock fetch. Re-applied * inside the SELECT FOR UPDATE so the lock cannot widen the row set (e.g. * picking up an expired row or one whose GroupId or seed flag changed * between the unlocked read and the lock). */ lockWhere: WhereOptions; /** * The `If-Match` header value parsed out of the request, if any. */ ifMatch?: string; } export interface DeleteAppResourceParams extends GetAppSubEntityParams { id: number | string; type: string; whereOptions?: WhereOptions; options: Options; /** * Where-clause used by the controller's pre-lock fetch. Re-applied inside * the lock so a concurrent writer cannot widen the row set between the read * and the delete. */ lockWhere?: WhereOptions; /** * The `If-Match` header value parsed out of the request, if any. */ ifMatch?: string; } export interface CreateAppAssetParams extends GetAppSubEntityParams { payload: { filename: string; mime: string; name: string; path: string; }; seed?: boolean; } export interface DeleteAppAssetParams extends GetAppSubEntityParams { id: string; transaction?: any; } export interface EmailParams { action: EmailActionDefinition; data: any; mailer: any; options: Options; context: ParameterizedContext<DefaultState, DefaultContextInterface, any>; } export interface SendNotificationsParams { app: App; to: string; title: string; body: string; link: string; } export interface HandleActionParams { app: App; action: ActionDefinition; mailer: any; data: any; options: Options; context: ParameterizedContext<DefaultState, DefaultContextInterface, any>; } export type ServerAction = (params: HandleActionParams) => Promise<any>; export type ServerActions = Partial<Record<ActionDefinition['type'], ServerAction>>; export interface AppDetails { appPath: string; organizationId: string; } export interface AppStyles { coreStyle: string | undefined; sharedStyle: string | undefined; } export interface AppScreenshot { id: number; mime: string; screenshot: Buffer; height: number; width: number; } export interface AppReadme { id: number; file: Buffer; } export interface AppBlockStyle { style: string; } export interface AppAsset extends Asset { stream: Readable; } export interface ProjectAsset { filename: string; mime: string; content: Buffer; } export interface Block extends BlockDefinition { OrganizationId: string; } export interface Theme { css: string; } export interface ParsedQuery { order: OrderItem[]; where: WhereOptions; } export type ContentSecurityPolicy = Record<string, (string | false)[]>; export type AppServingCacheStatus = 'disabled' | 'error' | 'hit' | 'miss'; export interface AppServingCacheResult<T> { status: AppServingCacheStatus; value?: T; } export interface AppServingCache { get: <T>(key: string) => Promise<AppServingCacheResult<T>>; set: <T>(key: string, value: T) => Promise<AppServingCacheStatus>; } export interface Options { getSecurityEmail: () => string; getCurrentAppMember: (params: GetCurrentAppMemberParams) => Promise<AppMemberInfo | null>; getCurrentAppMemberSelectedGroup: (params: GetCurrentAppMemberSelectedGroupParams) => Promise<AppMemberGroup | null>; getCurrentAppMemberGroups: (params: GetCurrentAppMemberGroupsParams) => Promise<Group[] | null>; getApp: (params: GetAppParams) => Promise<App>; getAppDetails: (params: GetAppParams) => Promise<AppDetails>; getAppMessages: (params: GetAppMessagesParams) => Promise<AppMessages[]>; getAppGroups: (params: GetAppSubEntityParams) => Promise<ExtendedGroup[]>; getAppStyles: (params: GetAppParams | GetAppSubEntityParams) => Promise<AppStyles>; getAppScreenshots: (params: GetAppSubEntityParams) => Promise<AppScreenshot[]>; getAppReadmes: (params: GetAppSubEntityParams) => Promise<AppReadme[]>; getAppBlockStyles: (params: GetAppBlockStylesParams) => Promise<AppBlockStyle[]>; getAppIcon: (params: GetAppSubEntityParams) => Promise<Buffer>; getAppUrl: (params: GetAppSubEntityParams) => Promise<URL>; getDbUpdated: (params: GetDbUpdatedParams) => Promise<Date | number>; getBlockMessages: (params: GetBlockMessagesParams) => Promise<BlockMessages[]>; getBlockAsset: (params: GetBlockAssetParams) => Promise<ProjectAsset>; getBlocksAssetsPaths: (params: GetBlocksAssetsPathsParams) => Promise<string[]>; getTheme: (params: GetThemeParams) => Promise<Theme | null>; createTheme: (params: CreateThemeParams) => Promise<Theme>; getHost: (params: GetHostParams) => string; getCsp: (params: GetCspParams) => ContentSecurityPolicy; createSettings: (params: CreateSettingsParams) => Promise<[digest: string, script: string]>; appServingCache?: AppServingCache; applyAppServiceSecrets: (params: ApplyAppServiceSecretsParams) => Promise<RawAxiosRequestConfig<any>>; checkAppMemberAppPermissions: (params: CheckAppMemberAppPermissionsParams) => Promise<void>; checkUserOrganizationPermissions: (params: CheckUserOrganizationPermissionsParams) => Promise<void>; checkAuthSubjectAppPermissions: (params: CheckAuthSubjectAppPermissionsParams) => Promise<void>; checkAppPermissions: (params: CheckAppPermissionsParams) => Promise<void>; getAllowedGroups: (params: CheckAppPermissionsParams) => Promise<number[]>; reloadUser: (params: ReloadUserParams) => Promise<Record<string, any>>; parseQuery: (params: ParseQueryParams) => ParsedQuery; getAppResource: (params: GetAppResourceParams) => Promise<Resource | null>; getAppResources: (params: GetAppResourcesParams) => Promise<Resource[]>; createAppResourcesWithAssets: (params: CreateAppResourcesWithAssetsParams) => Promise<Resource[]>; updateAppResource: (params: UpdateAppResourceParams) => Promise<Resource | null>; deleteAppResource: (params: DeleteAppResourceParams) => Promise<void>; getAppAssets: (params: GetAppSubEntityParams) => Promise<Asset[]>; getAppAsset: (params: GetAppAssetParams) => Promise<AppAsset>; createAppAsset: (params: CreateAppAssetParams) => Promise<AppAsset>; deleteAppAsset: (params: DeleteAppAssetParams) => Promise<number>; email: (params: EmailParams) => Promise<void>; sendNotifications: (params: SendNotificationsParams) => Promise<void>; getAppVariables: (params: GetAppVariablesParams) => Promise<AppConfigEntry[]>; handleAction?: (serverAction: ServerAction, params: HandleActionParams) => Promise<any>; serverActions?: ServerActions; } export declare class TempFile { readonly filename: string; readonly mime: string; readonly path: string; constructor({ filename, mime, path }: { filename: string; mime: string; path: string; }); } export {};