From efa0bcd86ca8ef01d777794cad28e97928faf57b Mon Sep 17 00:00:00 2001 From: antoniopresto Date: Tue, 24 Oct 2023 15:31:28 -0300 Subject: [PATCH] remove method package --- packages/method/.babelrc.js | 1 - packages/method/.eslintrc.js | 1 - packages/method/.gitignore | 77 ------ packages/method/.nvmrc | 1 - packages/method/.prettierrc | 4 - packages/method/README.md | 203 ---------------- packages/method/jest.config.js | 16 -- packages/method/package.json | 97 -------- packages/method/setupTests.js | 1 - packages/method/src/App.ts | 108 --------- packages/method/src/Method.ts | 196 --------------- packages/method/src/__tests__/Method.spec.ts | 134 ----------- packages/method/src/index.ts | 2 - packages/method/src/types.ts | 238 ------------------- packages/method/tsconfig.declarations.json | 9 - packages/method/tsconfig.json | 27 --- packages/method/tsconfig.lint.json | 8 - packages/method/tsconfig.module.json | 14 -- packages/method/tsconfig.prod.json | 11 - 19 files changed, 1148 deletions(-) delete mode 100644 packages/method/.babelrc.js delete mode 100644 packages/method/.eslintrc.js delete mode 100644 packages/method/.gitignore delete mode 100644 packages/method/.nvmrc delete mode 100644 packages/method/.prettierrc delete mode 100644 packages/method/README.md delete mode 100644 packages/method/jest.config.js delete mode 100644 packages/method/package.json delete mode 100644 packages/method/setupTests.js delete mode 100644 packages/method/src/App.ts delete mode 100644 packages/method/src/Method.ts delete mode 100644 packages/method/src/__tests__/Method.spec.ts delete mode 100644 packages/method/src/index.ts delete mode 100644 packages/method/src/types.ts delete mode 100644 packages/method/tsconfig.declarations.json delete mode 100644 packages/method/tsconfig.json delete mode 100644 packages/method/tsconfig.lint.json delete mode 100644 packages/method/tsconfig.module.json delete mode 100644 packages/method/tsconfig.prod.json diff --git a/packages/method/.babelrc.js b/packages/method/.babelrc.js deleted file mode 100644 index 3dc068f7..00000000 --- a/packages/method/.babelrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@powership/boilerplate/babel-config') diff --git a/packages/method/.eslintrc.js b/packages/method/.eslintrc.js deleted file mode 100644 index 1c0e5c18..00000000 --- a/packages/method/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@powership/boilerplate/eslintrc') diff --git a/packages/method/.gitignore b/packages/method/.gitignore deleted file mode 100644 index befde3c1..00000000 --- a/packages/method/.gitignore +++ /dev/null @@ -1,77 +0,0 @@ -# See https://help.github.com/ignore-files/ for more about ignoring files. - -.idea -/lib - -# VisualStudioCode.gitignore -# See https://github.com/github/gitignore/blob/master/Global/VisualStudioCode.gitignore -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json -/src/generated - -# dependencies -/node_modules - -# testing -/coverage - -# production -/build - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Xcode -# -build/ -*.pbxuser -!default.pbxuser -*.mode1v3 -!default.mode1v3 -*.mode2v3 -!default.mode2v3 -*.perspectivev3 -!default.perspectivev3 -xcuserdata -*.xccheckout -*.moved-aside -DerivedData -*.hmap -*.ipa -*.xcuserstate -project.xcworkspace - -# Android/IJ -# -.gradle -local.properties - -# node.js -# -npm-debug.log -yarn-error.log - -# BUCK -buck-out/ -\.buckd/ -android/app/libs -android/keystores/debug.keystore - -lib/ -webpack-assets.json -webpack-stats.json -*.swp - -# Modern Relay -__generated__ diff --git a/packages/method/.nvmrc b/packages/method/.nvmrc deleted file mode 100644 index 3c032078..00000000 --- a/packages/method/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -18 diff --git a/packages/method/.prettierrc b/packages/method/.prettierrc deleted file mode 100644 index 2ddc9656..00000000 --- a/packages/method/.prettierrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "singleQuote": true, - "printWidth": 80 -} diff --git a/packages/method/README.md b/packages/method/README.md deleted file mode 100644 index d505e16d..00000000 --- a/packages/method/README.md +++ /dev/null @@ -1,203 +0,0 @@ -# @powership/schema -Typescript schema validation with static type inference. - -Schemas are a crucial part of a microservices architecture or a detachable application architecture (powership). -They can serve as contracts between different pieces of an application (frontend, backend, forms) and different services. -So schemas should be **easily portable, written and read**, and that's the goal of this package. - -![image](https://user-images.githubusercontent.com/6221799/151898179-2774489b-8905-4fdb-9575-023de9f3e19a.png) - -# Installation - -To install: - -```sh -npm install @powership/schema -``` - -⚠️ IMPORTANT: You must enable `strict` mode in your `tsconfig.json`. This is a best practice for all TypeScript projects. - -```ts -// tsconfig.json -{ - // ... - "compilerOptions": { - // ... - "strict": true - } -} -``` - -# Usage - -### Schema -```ts - const addressSchema = createSchema({ - street: 'string', - number: 'int?', - }); - - const schemaDefinition = { - name: 'string', // any string - email: 'email?', // email type - will validate against email regex - age: 'int?', // optional integer - notes: '[int]?', - - // declaring an union - unionField: [['string?', '[int]?']], - - // represents an enum - letter: ['a', 'b', 'c'], - - // more detailed way to define enums - letterOptionalList: { - enum: ['x', 'y', 'z'], - optional: true, - list: true, - }, - - // using a previous schema as field type - optionalAddress: { - type: addressSchema, - optional: true, - }, - - // another way to define schema fields - deliveryAddress: { - schema: { - street: 'string', - number: 'int?', - }, - }, - } as const; // "as const" is needed to TS to infer types correctly - - const userSchema = createSchema(schemaDefinition); - - expect(() => userSchema.parse({ name: 'Antonio', letter: 'x' })).toThrow( - `field "letter": accepted: 'a' or 'b' or 'c', found x.` - ); - - expect(() => userSchema.parse({ name: 'antonio', letter: 'a', deliveryAddress: {} })).toThrow( - 'field "deliveryAddress": ➤ field "street": expected type string, found undefined.' - ); - - const parsed = userSchema.parse({ name: 'antonio', letter: 'a', deliveryAddress: { street: 'alameda' } }); - - type InferType = typeof parsed; - - assert< - IsExact< - InferType, - { - name: string; - email?: string | undefined; - age?: number | undefined; - notes?: number[] | undefined; - unionField?: string | number[] | undefined; - letter: 'a' | 'b' | 'c'; - letterOptionalList?: ('x' | 'y' | 'z')[] | undefined; - optionalAddress?: - | { - street: string; - number?: number | undefined; - } - | undefined; - - deliveryAddress: { - street: string; - number?: number | undefined; - }; - } - > - >(true); -``` - -### schemaToTypescript -Returns a string of an interface representing a PowershipSchema; -``` ts -import { schemaToTypescript } from '@powership/schema/lib/schemaToTypescript'; - -const interfaceTxt = await schemaToTypescript('User', userSchema); - -const interfaceTxt = await schemaToTypescript('User', userSchema); -expect(interfaceTxt).toBe(` -export interface User { - name: string; - email?: Email; - age?: number; - notes?: number[]; - unionField?: string | number[]; - letter: "a" | "b" | "c"; - letterOptionalList?: ("x" | "y" | "z")[]; - optionalAddress?: { - street: string; - number?: number; - }; - deliveryAddress: { - street: string; - number?: number; - }; -}`); -``` - -### schemaToJSON -Receives a PowershipSchema and returns a [json-schema](https://json-schema.org/) - -``` ts - import { schemaToJSON } from '@powership/schema/lib/schemaToJSON'; - - const jsonSchema = schemaToJSON('User', userSchema); - - expect(jsonSchema).toEqual({ - properties: { - address: { - properties: { - number: { - type: 'integer', - }, - street: { - type: 'string', - }, - }, - required: ['street'], - title: '', - type: 'object', - }, - age: { - type: 'integer', - }, - email: { - tsType: 'Email', - type: 'string', - }, - letter: { - enum: ['a', 'b', 'c'], - title: 'EnumLetterUser', - type: 'string', - }, - letterOptionalList: { - items: { - enum: ['x', 'y', 'z'], - title: 'Enum__subLetterOptionalList', - type: 'string', - }, - type: 'array', - }, - name: { - type: 'string', - }, - notes: { - items: { - type: 'integer', - }, - type: 'array', - }, - }, - required: ['name', 'letter'], - title: 'User', - type: 'object', - }); -``` - -# TODO -- [ ] improve documentation diff --git a/packages/method/jest.config.js b/packages/method/jest.config.js deleted file mode 100644 index 2412a3e0..00000000 --- a/packages/method/jest.config.js +++ /dev/null @@ -1,16 +0,0 @@ -const { pathsToModuleNameMapper } = require('ts-jest'); - -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testTimeout: +(process.env.TEST_TIMEOUT || 30000), - testRegex: '(spec|test)\\.tsx?$', - modulePathIgnorePatterns: ['node_modules', 'testing.d.ts'], - setupFilesAfterEnv: ['/setupTests.js'], - moduleNameMapper: pathsToModuleNameMapper( - {}, - { - prefix: '/src/', - } - ), -}; diff --git a/packages/method/package.json b/packages/method/package.json deleted file mode 100644 index f434f428..00000000 --- a/packages/method/package.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "name": "@powership/method", - "version": "2.3.1-beta.3", - "main": "out/index.js", - "module": "out/module/index.js", - "sideEffects": false, - "browser": { - "out/module/index.js": "./out/browser/module/index.js", - "out/index.js": "./out/browser/index.js" - }, - "author": "antoniopresto ", - "license": "MIT", - "scripts": { - "test": "jest --runInBand", - "ts": "tsc --noEmit", - "build": "run-s clear && run-p declarations build:*", - "clear": "rimraf out", - "fix": "run-s fix:* ", - "fix:prettier": "prettier \"src/**/*.ts\" --write", - "fix:lint": "eslint src --ext .ts --fix", - "prepublishOnly": "run-p build fix && run-p test", - "build-targets": "run-p build:*", - "build:browser": "TARGET=browser npm run babild -- --out-dir out/browser", - "build:module-browser": "TARGET=module-browser npm run babild -- --out-dir out/browser/module", - "build:node": "TARGET=node npm run babild -- --out-dir out", - "build:module-node": "TARGET=module-node npm run babild -- --out-dir out/module", - "declarations": "tsc -p tsconfig.declarations.json", - "babild": "babel 'src' --extensions '.ts,.tsx' --source-maps=true --ignore '**/__tests__'" - }, - "description": "Powership method", - "repository": { - "type": "git", - "url": "https://github.com/antoniopresto/powership/tree/master/packages/schema" - }, - "keywords": [ - "typescript", - "schema", - "graphql", - "validation", - "type", - "inference" - ], - "dependencies": { - "@powership/schema": "workspace:*", - "@powership/utils": "workspace:*" - }, - "devDependencies": { - "@powership/boilerplate": "workspace:*", - "@types/json-schema": "7.0.11", - "@babel/cli": "7.19.3", - "@babel/core": "7.19.3", - "@babel/plugin-transform-typescript": "7.19.3", - "@babel/preset-env": "7.19.3", - "@babel/preset-typescript": "7.18.6", - "@powership/babel-plugins": "workspace:*", - "@types/babel__core": "7.1.19", - "@types/babel__helper-plugin-utils": "7.10.0", - "@types/express": "4.17.14", - "@types/jest": "29.5.3", - "@types/lodash": "4.14.191", - "@types/node": "16.18.3", - "@types/supertest": "2.0.12", - "@typescript-eslint/eslint-plugin": "5.39.0", - "@typescript-eslint/parser": "5.39.0", - "babel-preset-minify": "0.5.2", - "conditional-type-checks": "1.0.6", - "esbuild": "0.15.10", - "eslint": "8.25.0", - "eslint-config-prettier": "8.5.0", - "eslint-plugin-eslint-comments": "3.2.0", - "eslint-plugin-import": "2.26.0", - "eslint-plugin-sort-keys-fix": "1.1.2", - "eslint-plugin-typescript-sort-keys": "2.1.0", - "express": "4.18.2", - "graphql": "16.6.0", - "jest": "29.6.2", - "npm-run-all": "4.1.5", - "prettier": "2.8.8", - "prettier-plugin-multiline-arrays": "1.1.3", - "rimraf": "3.0.2", - "supertest": "6.3.0", - "ts-jest": "29.1.0", - "typedoc": "0.23.24", - "typescript": "4.9.3" - }, - "files": [ - "package.json", - "out/*", - "README.md" - ], - "typedoc": { - "entryPoint": "./src/index.ts", - "readmeFile": "./README.md", - "displayName": "Powership Method", - "tsconfig": "./tsconfig.module.json" - } -} diff --git a/packages/method/setupTests.js b/packages/method/setupTests.js deleted file mode 100644 index 960eeced..00000000 --- a/packages/method/setupTests.js +++ /dev/null @@ -1 +0,0 @@ -require('@powership/utils').formatWithPrettier.prettier = require('prettier'); diff --git a/packages/method/src/App.ts b/packages/method/src/App.ts deleted file mode 100644 index 94e2d8ff..00000000 --- a/packages/method/src/App.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { - AppOptions, - AppRequestContext, - InferMethodTypes, - MethodLike, - MethodPayload, - MethodRequest, - MethodRequestOptions, - ObjectOfMethods, -} from './types'; - -export class App< - M extends Readonly<[MethodLike, ...MethodLike[]]>, - Info extends InferMethodTypes = InferMethodTypes, - Context extends AppRequestContext = AppRequestContext -> { - static defaultOptions: Required> = { - name: 'unknown', - batchRequests: true, - batchTimeoutMS: 50, - maxBatchCallsCount: 30, - buildRequestContext() { - throw new Error('buildRequestContext was not provided.'); - }, - onResult() {}, - beforeCall() {}, - }; - - private options: Required>; - private methods: ObjectOfMethods; - - constructor(methods: M, options: AppOptions) { - let errors: string[] = []; - - // @ts-ignore - this.methods = {}; - - methods.forEach((m) => { - if (this.methods[m.methodName]) { - errors.push( - ` ☂︎ found repeated item with methodName "${m.methodName}".` - ); - } - // @ts-ignore - this.methods[m.methodName] = m; - }); - - this.options = { ...App.defaultOptions, ...options }; - - if (errors.length) { - throw new Error('RootMethod: \n' + errors.join(`\n`)); - } - } - - private queue: MethodRequest[] = []; - private timeout: any = null; - private dispatch = async () => { - const requests = [...this.queue]; - this.queue = []; - - const context = await this.options.buildRequestContext(requests); - - const payload: MethodPayload = { - args, - context, - requestInfo: { - app: this, - appOptions: this.options, - requests, - }, - }; - - await this.options.beforeCall([payload]); - - return method.call(args, payload); - }; - - call = ( - name: Name - ): { - with( - args: Info[Name]['args'], - options?: MethodRequestOptions - ): Promise; - } => { - const method: MethodLike = this.methods[name]; - - return { - with: async (args, options) => { - const request: Omit, 'context'> = { - args, - options: { ...options }, - method: name, - }; - }, - }; - }; - - static create = < - Methods extends Readonly<[MethodLike, ...MethodLike[]]>, - Ctx extends AppRequestContext - >( - methods: Methods, - options: AppOptions - ): App => { - return new App(methods, options); - }; -} diff --git a/packages/method/src/Method.ts b/packages/method/src/Method.ts deleted file mode 100644 index 52b93600..00000000 --- a/packages/method/src/Method.ts +++ /dev/null @@ -1,196 +0,0 @@ -import { - assertType, - createType, - FieldInput, - GraphType, - Infer, - ObjectDefinitionInput, - ObjectType, -} from '@powership/schema'; -import { Compute, MaybePromise } from '@powership/utils'; - -import { - AppRequestContext, - Fetcher, - Handler, - MethodDefinition, - MethodKind, - MethodLike, - MethodPayload, -} from './types'; - -// Regular expression for validating method names. -const NAME_RX = /^[_a-zA-Z][_a-zA-Z0-9]*$/; - -/** - * Function to validate method names. - * Throws an error if the name is invalid. - * @param name - The name to validate. - */ -function validateIdentifier(name: string) { - assertType( - name, - 'string', - `Method definition: invalid name type "${typeof name}" found.` - ); - if (!NAME_RX.test(name)) { - throw new Error(`Method definition: invalid name "${name}" found.`); - } -} - -/** - * Class representing a Method. - * @template RequestDefinition - The type definition for the request fields. - * @template ResponseDefinition - The type definition for the response fields. - * @template Context - The type definition for the method context. - */ -export class Method< - ArgsDefinition extends ObjectDefinitionInput, - ResponseDefinition extends FieldInput, - Name extends Readonly, - Context extends AppRequestContext = AppRequestContext -> implements MethodLike -{ - __isPSMethod: true; // Internal flag to mark this as a PSMethod. - readonly methodName: Name; // The name of the method. - kind: MethodKind; // The kind of method, either 'query' or 'mutation'. - argsType: GraphType<{ object: ArgsDefinition }>; // GraphType for args validation. - outputType: GraphType; // GraphType for output validation. - private __definition: MethodDefinition; // Private storage for method definition. - - /** - * The handler function for this method. - */ - call: Handler; - - /** - * The fetch function for this method. - */ - fetch: Fetcher; - - /** - * Constructs a new Method instance. - * @param definition - The method definition. - */ - constructor( - definition: MethodDefinition - ) { - this.__definition = definition; - - const { name, args, output, kind } = definition; - - // Validate the method name. - validateIdentifier(name); - - // Validate the kind of method. - assertType(kind, { enum: ['query', 'mutation'] } as const); - this.kind = kind; - - // Set the method name. - this.methodName = name as Name; - - // Initialize the output type. - this.outputType = GraphType.is(output) - ? (output as any) - : createType(`${name}Output`, output); - - // Initialize the args type. - this.argsType = ((): any => { - if (GraphType.is(args)) { - if (!args.__lazyGetter.objectType) { - throw new Error( - 'Invalid definition: args value should respect one of the following types: ' + - 'ObjectType, GraphType or ObjectTypeDefinition.\n' - ); - } - if (args.optionalId) return args; - // @ts-ignore - return args.clone((el) => el.graphType(`${name}Args`)); - } - - if (ObjectType.is(args)) { - // @ts-ignore - if (args.id) return createType(args); - return createType(`${name}Args`, args); - } - - // @ts-ignore - return createType(`${name}Args`, { object: args } as any); - })(); - - // Initialize the fetch function with a placeholder. - this.fetch = function call() { - throw new Error('Method has no fetch handler defined.'); - }; - - // Initialize the handle function with a placeholder. - this.call = async function receive() { - throw new Error( - 'Method has no handler defined. Register one using `method.defineHandler(handler)`.' - ); - } as any; - } - - /** - * Sets the fetch function for this method. - * For example, on the client side, it can be a `fetch` call to the backend. - * @param fetcher - The fetch function. - */ - setFetcher = (fetcher: Fetcher) => { - this.fetch = async ( - args: Infer<{ object: ArgsDefinition }> - ): Promise> => { - args = this.argsType.parse(args); - const response = await fetcher(args); - return this.outputType.parse(response); - }; - }; - - /** - * Sets the handle function for this method. - * For example, on the server side, it can be a function that queries a database. - * @param handle - The handle function. - */ - defineHandler = ( - handle: ( - args: Compute>, - payload: Compute> - ) => MaybePromise> - ): Method => { - const { - argsType, - outputType, - methodName, - __definition: { throwOnInvalidResultingListItems }, - } = this; - - this.call = async function handleMethod( - args: any, - payload: MethodPayload - ) { - let { parent, context, requestInfo } = payload; - - args = argsType.parse(args, { - customMessage: (_, error) => { - return `Invalid args provided to method "${methodName}":\n ${error.message}`; - }, - }); - - const resulting = await handle(args, { - parent, - args, - context, - requestInfo, - }); - - return outputType.parse(resulting, { - customMessage: (_, error) => { - return `Invalid output from method "${methodName}": ${error.message}`; - }, - excludeInvalidListItems: !throwOnInvalidResultingListItems, - }); - } as Handler; - - return this as any; - }; -} diff --git a/packages/method/src/__tests__/Method.spec.ts b/packages/method/src/__tests__/Method.spec.ts deleted file mode 100644 index 65df0f94..00000000 --- a/packages/method/src/__tests__/Method.spec.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { createType } from '@powership/schema'; -import { assert, IsExact } from 'conditional-type-checks'; -import { App } from '../App'; -import { Method } from '../Method'; -import { AppRequestContext, AppRequestInfo } from '../types'; - -describe('Method', () => { - // afterEach(); - - test('basic test', async () => { - const sut = new Method({ - name: 'findOne', - kind: 'query', - output: 'string', - args: { username: 'string' }, - }).defineHandler<{ parent: 'yes' }>( - (args, { args: { username }, parent }) => { - const x = { - args, - username, - parent, - }; - - assert< - IsExact< - typeof x, - { - args: { username: string }; - username: typeof username; - parent: { parent: 'yes' }; - } - > - >(true); - - return `hi, ${username}!`; - } - ); - - type Param = Parameters; - - assert< - IsExact< - Param, - [ - { username: string }, - { - parent: any; - args: { username: string }; - context: AppRequestContext; - requestInfo: AppRequestInfo; - } - ] - > - >(true); - - const parent = { parent: 'yes' } as const; - const context = { t: 'context' }; - const requestInfo = { t: 'requestInfo', requests: [] }; - - const spy = jest.spyOn(sut, 'call'); - - const promise = sut.call( - { username: 'Antonio' }, - { - parent, - args: { username: 'Antonio' }, - context, - requestInfo, - } - ); - - assert>>(true); - - const res = await promise; - - expect(res).toEqual('hi, Antonio!'); - - expect(spy).toBeCalledWith( - { username: 'Antonio' }, - { - parent, - args: { username: 'Antonio' }, - context, - requestInfo, - } - ); - - spy.mockRestore(); - }); - - describe('App', () => { - const User = createType('User', { object: { id: 'ID', email: 'email' } }); - - const createOne = new Method({ - name: 'createOne', - kind: 'mutation', - output: User, - args: User.definition.object, - }).defineHandler(({ email }) => { - return { id: '123', email }; - }); - - const findOne = new Method({ - name: 'findOne', - kind: 'query', - output: '[string]', - args: { username: 'string' }, - }).defineHandler<{ parent: 'yes' }>(({ username }) => { - return [`hi, ${username}!`]; - }); - - test('combine methods', async () => { - const root = App.create([createOne, findOne], { - name: 'myApp', - buildRequestContext(request) { - console.log(request); - return {}; - }, - }); - - type M = Parameters; - assert>(true); - - const execute = root.call('findOne'); - - type P = Parameters<(typeof execute)['with']>; - assert>(true); - - const result = await execute.with({ username: 'antonio' }); - - expect(result).toEqual(['hi, antonio!']); - }); - }); -}); diff --git a/packages/method/src/index.ts b/packages/method/src/index.ts deleted file mode 100644 index 93369f82..00000000 --- a/packages/method/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './Method'; -export * from './types'; diff --git a/packages/method/src/types.ts b/packages/method/src/types.ts deleted file mode 100644 index a4474dfe..00000000 --- a/packages/method/src/types.ts +++ /dev/null @@ -1,238 +0,0 @@ -import { FieldInput, Infer, ObjectDefinitionInput } from '@powership/schema'; -import { - AnyFunction, - Compute, - IsKnown, - List, - MaybePromise, - StringValue, -} from '@powership/utils'; - -import type { App } from './App'; - -/** - * Enum representing the types of method requests. - * - 'query': For read-only fetch operations - may be cached. - * - 'mutation': For write operations that change data - can't be cached. - */ -export type MethodKind = 'query' | 'mutation'; - -/** - * Interface for additional context that methods might require. - */ -export interface AppRequestContext {} - -/** - * Interface for additional information that methods might use. - */ -export interface AppRequestInfo { - app?: App; - appOptions?: AppOptions; - requests?: Omit, 'context'>[]; -} - -export interface MethodRequestOptions { - /** - * Max cache age. - * Applied to requests for methods with kind "query", ignored by mutations. - * Can be any value accepted by `ms` (https://github.com/vercel/ms) - */ - maxAge?: number | StringValue; - context?: AppRequestContext; -} - -/** - * Type definition for a method. - * @template Args - The type definition for the args fields. - * @template Output - The type definition for the output fields. - */ -export type MethodDefinition< - Args extends ObjectDefinitionInput, - Output extends FieldInput, - Name extends Readonly -> = { - kind: MethodKind; // The kind of method, either 'query' or 'mutation'. - name: Name; // The name of the method. - output: Output; // The output type definition. - args: Args; // The args type definition. - throwOnInvalidResultingListItems?: boolean; // Optional flag to throw on invalid list items. -}; - -/** - * Type definition for the payload of a method. - * @template Args - The type definition for the args fields. - * @template Context - The type definition for the method context. - * @template Parent - The type definition for the parent object. - */ -export type MethodPayload< - Args extends ObjectDefinitionInput, - Context extends AppRequestContext = AppRequestContext, - Parent extends any = any -> = { - parent?: Parent; // The parent object. - args: Infer<{ object: Args }>; // The actual args data. - context: Context; // The root context. - requestInfo: AppRequestInfo; // Additional method information. -}; - -/** - * Type definition for fetch operations. - * @template Args - The type definition for the args fields. - * @template Output - The type definition for the output fields. - */ -export type Fetcher< - Args extends ObjectDefinitionInput, - Output extends FieldInput -> = (args: Infer<{ object: Args }>) => Promise>; - -/** - * Type definition for handling method operations. - * @template Args - The type definition for the args fields. - * @template Output - The type definition for the output fields. - * @template Context - The type definition for the method context. - * @template Parent - The type definition for the parent object. - */ -export type Handler< - Args extends ObjectDefinitionInput, - Output extends FieldInput, - Context extends AppRequestContext = AppRequestContext, - Parent extends any = any -> = [IsKnown] extends [1] - ? [IsKnown] extends [1] - ? ( - args: Infer<{ object: Args }>, - payload: Compute> - ) => Promise> - : never - : never; - -export interface MethodLike { - methodName: string; - __isPSMethod: true; - call: AnyFunction; -} - -export interface AppRequestError { - message: string; - method: string; -} - -export interface MethodRequest { - method: Extract; - args: Args; - options: MethodRequestOptions; - context: AppRequestContext; - result?: - | { data: Result; error: null } - | { data: null; error: AppRequestError }; -} - -export interface MethodRequestResult - extends MethodRequest { - result: - | { data: Result; error: null } - | { data: null; error: AppRequestError }; -} - -export type MethodRequestResultUnion< - Methods extends Readonly<[MethodLike, ...MethodLike[]]> -> = { - [Method in keyof InferMethodTypes]: MethodRequestResult< - Method, - InferMethodTypes['args'], - InferMethodTypes['result'] - >; -}[keyof InferMethodTypes]; - -export type MethodRequestUnion< - Methods extends Readonly<[MethodLike, ...MethodLike[]]> -> = { - [Method in keyof InferMethodTypes]: MethodRequest< - Method, - InferMethodTypes['args'], - InferMethodTypes['result'] - >; -}[keyof InferMethodTypes]; - -export type AppOptions< - Methods extends Readonly<[MethodLike, ...MethodLike[]]>, - Context extends AppRequestContext -> = { - name: string; - - batchRequests?: boolean; - - /** - * Time to wait for new requests before dispatch calls - */ - batchTimeoutMS?: number; - - maxBatchCallsCount?: number; - - buildRequestContext( - request: Omit, 'context'>[] - ): MaybePromise; - - /** - * Runs before returning the value - * to the caller - * @param requests - */ - beforeCall?(requests: MethodPayload[]): MaybePromise; - - /** - * Runs before returning the value - * to the caller - * @param requests - */ - onResult?(requests: MethodRequestResultUnion[]): MaybePromise; -}; - -export type ObjectOfMethods> = - ( - List.ObjectOf extends infer R - ? { - [K in keyof R as R[K] extends { methodName: infer NM } - ? NM extends string - ? NM - : never - : never]: R[K]; - } & {} - : never - ) extends infer R - ? R extends unknown - ? R extends { [K: string]: MethodLike } - ? { [K in keyof R]: R[K] extends MethodLike ? R[K] : never } & {} - : never - : never - : never; - -export type InferMethodTypes< - M extends Readonly<[MethodLike, ...MethodLike[]]> -> = ( - List.ObjectOf extends infer R - ? { - [K in keyof R as R[K] extends { methodName: infer NM } - ? NM extends string - ? NM - : never - : never]: R[K] extends {} - ? R[K] extends { - argsType: infer Input; - outputType: infer Output; - } - ? { - args: Infer; - output: Infer; - } - : never - : never; - } & {} - : never -) extends infer R - ? R extends unknown - ? R extends { [K: string]: { args: unknown; output: unknown } } - ? { [K in keyof R]: R[K] } & {} - : never - : never - : never; diff --git a/packages/method/tsconfig.declarations.json b/packages/method/tsconfig.declarations.json deleted file mode 100644 index fc516d2f..00000000 --- a/packages/method/tsconfig.declarations.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "./tsconfig.prod.json", - "compilerOptions": { - "emitDeclarationOnly": true - }, - "exclude": [ - "node_modules/**" - ] -} diff --git a/packages/method/tsconfig.json b/packages/method/tsconfig.json deleted file mode 100644 index 654dcfea..00000000 --- a/packages/method/tsconfig.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "compilerOptions": { - "outDir": "out", - "rootDir": "src", - "paths": {}, - "lib": ["es5", "es6", "es7", "esnext", "dom"], - "declaration": true, - "target": "es5", - "removeComments": false, - "esModuleInterop": true, - "moduleResolution": "node", - "resolveJsonModule": true, - "strict": true, - "skipLibCheck": true, - "strictPropertyInitialization": false, - "forceConsistentCasingInFileNames": true, - "noUnusedLocals": false, - "noUnusedParameters": false, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - "downlevelIteration": true, - "isolatedModules": true, - "noImplicitAny": false, - "typeRoots": ["node_modules/@types", "src/generated"] - }, - "include": ["./src/**/*"] -} diff --git a/packages/method/tsconfig.lint.json b/packages/method/tsconfig.lint.json deleted file mode 100644 index c16309be..00000000 --- a/packages/method/tsconfig.lint.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "./tsconfig", - "compilerOptions": { - "noUnusedLocals": true, - "noUnusedParameters": true - }, - "exclude": ["node_modules/**"] -} diff --git a/packages/method/tsconfig.module.json b/packages/method/tsconfig.module.json deleted file mode 100644 index 45e474ab..00000000 --- a/packages/method/tsconfig.module.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "extends": "./tsconfig.prod.json", - "compilerOptions": { - "target": "esnext", - "outDir": "out/module", - "module": "esnext", - "noUnusedLocals": true, - "noUnusedParameters": true - }, - "exclude": [ - "node_modules/**", // - "**/*/__tests__/*" - ] -} diff --git a/packages/method/tsconfig.prod.json b/packages/method/tsconfig.prod.json deleted file mode 100644 index 1e7d536c..00000000 --- a/packages/method/tsconfig.prod.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "./tsconfig", - "compilerOptions": { - "noUnusedLocals": true, - "noUnusedParameters": true - }, - "exclude": [ - "node_modules/**", - "**/*/__tests__/*" - ] -}