From 7d6c59eb2cadda0fc328b00e6072e328455bda4d Mon Sep 17 00:00:00 2001 From: uasan Date: Mon, 26 Feb 2024 00:29:23 +0100 Subject: [PATCH] WIP --- .eslintrc.json | 3 ++- src/compiler/entities/migrations/table.js | 10 ++++++- src/compiler/entities/models/table.js | 2 +- src/compiler/helpers/checker.js | 17 +++++++++--- src/compiler/helpers/function.js | 23 ++++++++++++---- src/compiler/helpers/types.js | 26 ++++++++++++------- src/compiler/helpers/validator.js | 15 ++++++----- src/compiler/makers/types/validator.js | 1 + src/compiler/makers/types/validators/Blob.js | 1 + .../makers/types/validators/DateLike.js | 4 +-- src/compiler/makers/types/validators/File.js | 2 ++ src/compiler/makers/types/validators/Int16.js | 3 ++- src/compiler/makers/types/validators/Int32.js | 3 ++- src/compiler/makers/types/validators/Int8.js | 3 ++- .../makers/types/validators/TypedArray.js | 4 ++- .../makers/types/validators/Uint16.js | 3 ++- .../makers/types/validators/Uint32.js | 3 ++- src/compiler/makers/types/validators/Uint8.js | 3 ++- .../makers/types/validators/Uint8Array.js | 1 + src/compiler/makers/types/validators/int.js | 5 ++-- src/compiler/makers/types/validators/tuple.js | 2 +- src/interfaces/types/validators.ts | 2 +- src/runtime/types/File.js | 4 +++ 23 files changed, 100 insertions(+), 40 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 7b3db8a..0596347 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -15,7 +15,8 @@ "prettier" ], "rules": { - "prettier/prettier": 2 // Means error + "prettier/prettier": 2, + "@typescript-eslint/no-explicit-any": 1 }, "env": { "browser": true, diff --git a/src/compiler/entities/migrations/table.js b/src/compiler/entities/migrations/table.js index 58932a7..d19ea1f 100644 --- a/src/compiler/entities/migrations/table.js +++ b/src/compiler/entities/migrations/table.js @@ -42,7 +42,15 @@ export function createTableMigration(model) { if (table.unique) { for (const key of Object.keys(table.unique)) { - fields.push(' CONSTRAINT "' + key + '" UNIQUE ("' + key + '")'); + const { columns } = table.unique[key]; + + if (columns) { + fields.push( + ' CONSTRAINT "' + key + '" UNIQUE ("' + columns.join('", "') + '")' + ); + } else { + fields.push(' CONSTRAINT "' + key + '" UNIQUE ("' + key + '")'); + } } } diff --git a/src/compiler/entities/models/table.js b/src/compiler/entities/models/table.js index fddbf39..6880ae8 100644 --- a/src/compiler/entities/models/table.js +++ b/src/compiler/entities/models/table.js @@ -75,8 +75,8 @@ export function TableModel(node) { name: meta.name, type: getSqlType(meta), default: meta.defaultValue, - isNotNull: !meta.isNullable, references: getTableReferences(meta.links), + isNotNull: !meta.isNullable && !meta.isUndefined, }); model.fields.set(meta.name, [ diff --git a/src/compiler/helpers/checker.js b/src/compiler/helpers/checker.js index 9f0097b..6d2361b 100644 --- a/src/compiler/helpers/checker.js +++ b/src/compiler/helpers/checker.js @@ -23,6 +23,14 @@ export const { ObjectFlagsType, } = ts.TypeFlags; +const { + Interface, + TypeAlias, + Alias, + ExportValue, + Value: ValueSymbol, +} = ts.SymbolFlags; + export const { Decorator, TrueKeyword, @@ -40,7 +48,6 @@ const { Readonly: CheckFlagReadonly } = ts.CheckFlags; const { Readonly: ModifierFlagReadonly } = ts.ModifierFlags; const { Const } = ts.NodeFlags; const { SignatureConstruct } = ts.SignatureKind; -const { Interface, TypeAlias, Alias, ExportValue } = ts.SymbolFlags; const { every, some, getCheckFlags, getDeclarationModifierFlagsFromSymbol } = ts; @@ -132,6 +139,7 @@ export const getSymbolOfNode = node => host.checker.getSymbolAtLocation(node); export const isTypeSymbol = ({ flags }) => (flags & TypeAlias) !== 0 || (flags & Interface) !== 0; +export const isValueSymbol = ({ flags }) => (flags & ValueSymbol) !== 0; export const isAliasSymbol = symbol => (symbol.flags & Alias) !== 0; export const isExportSymbol = symbol => (symbol.flags & ExportValue) !== 0; export const isExportKeyword = ({ kind }) => kind === ExportKeyword; @@ -204,10 +212,11 @@ export const getSignaturesConstructOfType = type => export const getSignaturesConstructOfSymbol = symbol => getSignaturesConstructOfType(getTypeOfSymbol(symbol)); -export const hasSignatureConstruct = node => - getSignaturesConstructOfSymbol(getSymbolOfNode(node)).length > 0; +export const hasSignatureConstruct = symbol => + getSignaturesConstructOfSymbol(symbol).length > 0; export const getConstructIdentifier = node => - node.kind === TypeReference && hasSignatureConstruct(node.typeName) + node.kind === TypeReference && + hasSignatureConstruct(getSymbolOfNode(node.typeName)) ? node.typeName : null; diff --git a/src/compiler/helpers/function.js b/src/compiler/helpers/function.js index 32b1821..062a53c 100644 --- a/src/compiler/helpers/function.js +++ b/src/compiler/helpers/function.js @@ -56,6 +56,19 @@ export const factoryRouteFunction = statements => host.factory.createBlock(statements, false) ); +export const updateMethodParameters = (node, parameters) => + host.factory.updateMethodDeclaration( + node, + node.modifiers, + undefined, + node.name, + undefined, + undefined, + parameters, + undefined, + node.body + ); + export const updateMethodStatements = (node, statements) => host.factory.updateMethodDeclaration( node, @@ -70,9 +83,9 @@ export const updateMethodStatements = (node, statements) => ); export function ensureArgument(node, index = 0) { - const { name } = node.parameters[index]; + const parameter = node.parameters[index]; - if (name.kind === Identifier) { + if (parameter.name.kind === Identifier) { return node; } @@ -80,7 +93,7 @@ export function ensureArgument(node, index = 0) { const arg = host.module.createIdentifier('_'); parameters[index] = host.factory.updateParameterDeclaration( - node.parameters[index], + parameter, undefined, undefined, arg, @@ -89,8 +102,8 @@ export function ensureArgument(node, index = 0) { undefined ); - return updateMethodStatements(node, [ - factoryLet(name, arg), + return updateMethodStatements(updateMethodParameters(node, parameters), [ + factoryLet(parameter.name, arg), ...node.body.statements, ]); } diff --git a/src/compiler/helpers/types.js b/src/compiler/helpers/types.js index d912221..5747a37 100644 --- a/src/compiler/helpers/types.js +++ b/src/compiler/helpers/types.js @@ -7,6 +7,7 @@ import { getTypeOfNode, getTypeOfTypeNode, hasNullType, + hasSignatureConstruct, hasUndefinedType, } from './checker.js'; @@ -46,7 +47,9 @@ function makeMetaType(meta, node) { if (types.has(symbol)) { types.get(symbol).make(meta, node.typeArguments); - } else if (meta.isBinary === false) { + } else if (hasSignatureConstruct(symbol)) { + meta.isConstruct = true; + } else { const typeNode = symbol.declarations?.[0]?.type; if (typeNode) { @@ -95,6 +98,8 @@ export class MetaType { isNullable = false; isOptional = false; + isUndefined = false; + isTypeTrusted = false; isBlob = false; isFile = false; @@ -102,6 +107,7 @@ export class MetaType { isBinary = false; isStream = false; isDateLike = false; + isConstruct = false; isBufferStream = false; isRefType = false; @@ -118,14 +124,7 @@ export class MetaType { this.node = node; this.type = type; - if (DateLike.isAssignable(type)) { - this.isDateLike = true; - this.sqlType = DateLike.sqlType; - } else if (BinaryData.isAssignable(type)) { - this.isBinary = true; - this.sqlType = BinaryData.sqlType; - } - + //console.log(host.checker.typeToString(type), DateLike.isAssignable(type)); makeMetaType(this, node); } @@ -145,6 +144,7 @@ export class MetaType { if (hasUndefinedType(self.type)) { self.isOptional = true; + self.isUndefined = true; self.type = getNonUndefinedType(self.type); } @@ -153,6 +153,14 @@ export class MetaType { self.defaultValue = node.initializer; } + if (DateLike.isAssignable(self.type)) { + self.isDateLike = true; + self.sqlType = DateLike.sqlType; + } else if (BinaryData.isAssignable(self.type)) { + self.isBinary = true; + self.sqlType = BinaryData.sqlType; + } + return self; } } diff --git a/src/compiler/helpers/validator.js b/src/compiler/helpers/validator.js index 6c18258..9d2dcd7 100644 --- a/src/compiler/helpers/validator.js +++ b/src/compiler/helpers/validator.js @@ -114,7 +114,7 @@ function makeValidatorsByType(ast, meta, type = meta.type) { } function makeValidatorsByMeta(ast, meta) { - if (meta.isBinary) { + if (meta.isConstruct) { return ast; } @@ -167,17 +167,20 @@ export function makePayloadValidator(node, type) { let initAst = host.factory.createIdentifier('_'); let ast = makeValidatorsBySymbols(initAst, metaType.props); - if (initAst !== ast) { - addTransformer(node, node => { - node = ensureArgument(node); + addTransformer(node, node => { + node = ensureArgument(node); + + if (initAst !== ast) { Object.assign(initAst, internals.newValidator(node.parameters[0].name)); return updateMethodStatements(node, [ factoryStatement(factoryCallMethod(ast, 'validate')), ...node.body.statements, ]); - }); - } + } else { + return node; + } + }); } return metaType; diff --git a/src/compiler/makers/types/validator.js b/src/compiler/makers/types/validator.js index ea657c2..6f9b932 100644 --- a/src/compiler/makers/types/validator.js +++ b/src/compiler/makers/types/validator.js @@ -57,6 +57,7 @@ export class Validator { static make(meta, args) { meta.sqlType ||= this.sqlType; + meta.validators.add(new this().setProps(meta, args?.[0])); } diff --git a/src/compiler/makers/types/validators/Blob.js b/src/compiler/makers/types/validators/Blob.js index 9132b98..7eef95d 100644 --- a/src/compiler/makers/types/validators/Blob.js +++ b/src/compiler/makers/types/validators/Blob.js @@ -5,6 +5,7 @@ export class Blob extends Validator { static make(meta) { meta.isBlob = true; + meta.isConstruct = true; meta.isBufferStream = true; } } diff --git a/src/compiler/makers/types/validators/DateLike.js b/src/compiler/makers/types/validators/DateLike.js index a0e8f9b..39b4d44 100644 --- a/src/compiler/makers/types/validators/DateLike.js +++ b/src/compiler/makers/types/validators/DateLike.js @@ -3,7 +3,7 @@ import { Validator } from '../Validator.js'; export class DateLike extends Validator { static sqlType = 'timestamptz'; - static make() { - // + static make(meta) { + meta.isConstruct = true; } } diff --git a/src/compiler/makers/types/validators/File.js b/src/compiler/makers/types/validators/File.js index 18d6381..09fa3c8 100644 --- a/src/compiler/makers/types/validators/File.js +++ b/src/compiler/makers/types/validators/File.js @@ -5,6 +5,8 @@ export class File extends Validator { static make(meta) { meta.isFile = true; + meta.isConstruct = true; + meta.isTypeTrusted = true; meta.isBufferStream = true; } } diff --git a/src/compiler/makers/types/validators/Int16.js b/src/compiler/makers/types/validators/Int16.js index 87899e4..f3ecb47 100644 --- a/src/compiler/makers/types/validators/Int16.js +++ b/src/compiler/makers/types/validators/Int16.js @@ -1,7 +1,8 @@ import { Int } from './Int.js'; export class Int16 extends Int { + static sqlType = 'smallint'; + byteLength = 2; - sqlType = 'smallint'; numberType = 'Int16'; } diff --git a/src/compiler/makers/types/validators/Int32.js b/src/compiler/makers/types/validators/Int32.js index 6357c03..69f336c 100644 --- a/src/compiler/makers/types/validators/Int32.js +++ b/src/compiler/makers/types/validators/Int32.js @@ -1,7 +1,8 @@ import { Int } from './Int.js'; export class Int32 extends Int { + static sqlType = 'int'; + byteLength = 4; - sqlType = 'int'; numberType = 'Int32'; } diff --git a/src/compiler/makers/types/validators/Int8.js b/src/compiler/makers/types/validators/Int8.js index b867b54..9894909 100644 --- a/src/compiler/makers/types/validators/Int8.js +++ b/src/compiler/makers/types/validators/Int8.js @@ -1,7 +1,8 @@ import { Int } from './Int.js'; export class Int8 extends Int { + static sqlType = 'smallint'; + byteLength = 1; - sqlType = 'smallint'; numberType = 'Int8'; } diff --git a/src/compiler/makers/types/validators/TypedArray.js b/src/compiler/makers/types/validators/TypedArray.js index 0d7141b..bcedca5 100644 --- a/src/compiler/makers/types/validators/TypedArray.js +++ b/src/compiler/makers/types/validators/TypedArray.js @@ -1,5 +1,7 @@ import { Validator } from '../Validator.js'; export class TypedArray extends Validator { - static make(meta) { } + static make(meta) { + meta.isConstruct = true; + } } diff --git a/src/compiler/makers/types/validators/Uint16.js b/src/compiler/makers/types/validators/Uint16.js index 839adb8..41e0d36 100644 --- a/src/compiler/makers/types/validators/Uint16.js +++ b/src/compiler/makers/types/validators/Uint16.js @@ -1,7 +1,8 @@ import { Int } from './Int.js'; export class Uint16 extends Int { + static sqlType = 'smallint'; + byteLength = 2; - sqlType = 'smallint'; numberType = 'Uint16'; } diff --git a/src/compiler/makers/types/validators/Uint32.js b/src/compiler/makers/types/validators/Uint32.js index f3e0663..5c18992 100644 --- a/src/compiler/makers/types/validators/Uint32.js +++ b/src/compiler/makers/types/validators/Uint32.js @@ -1,7 +1,8 @@ import { Int } from './Int.js'; export class Uint32 extends Int { + static sqlType = 'int'; + byteLength = 4; - sqlType = 'int'; numberType = 'Uint32'; } diff --git a/src/compiler/makers/types/validators/Uint8.js b/src/compiler/makers/types/validators/Uint8.js index e14ef43..103918e 100644 --- a/src/compiler/makers/types/validators/Uint8.js +++ b/src/compiler/makers/types/validators/Uint8.js @@ -1,7 +1,8 @@ import { Int } from './Int.js'; export class Uint8 extends Int { + static sqlType = 'smallint'; + byteLength = 1; - sqlType = 'smallint'; numberType = 'Uint8'; } diff --git a/src/compiler/makers/types/validators/Uint8Array.js b/src/compiler/makers/types/validators/Uint8Array.js index bb84781..65b5405 100644 --- a/src/compiler/makers/types/validators/Uint8Array.js +++ b/src/compiler/makers/types/validators/Uint8Array.js @@ -7,6 +7,7 @@ export class Uint8Array extends Validator { static make(meta, args) { const self = new this().setProps(meta, args?.[0]); + meta.isConstruct = true; meta.sqlType = self.sqlType; if (self.props.has('length')) { diff --git a/src/compiler/makers/types/validators/int.js b/src/compiler/makers/types/validators/int.js index 2134e54..4f9fb52 100644 --- a/src/compiler/makers/types/validators/int.js +++ b/src/compiler/makers/types/validators/int.js @@ -1,14 +1,15 @@ import { Validator } from '../Validator.js'; export class Int extends Validator { + static sqlType = 'int'; + byteLength = 4; - sqlType = 'int'; numberType = 'Int32'; make(ast, method = 'isInt') { super.make(ast, method); - this.meta.sqlType = this.sqlType; + //this.meta.sqlType = this.sqlType; this.meta.bytelength = this.bytelength; this.meta.numberType = this.numberType; diff --git a/src/compiler/makers/types/validators/tuple.js b/src/compiler/makers/types/validators/tuple.js index bfb6de2..8bca4a1 100644 --- a/src/compiler/makers/types/validators/tuple.js +++ b/src/compiler/makers/types/validators/tuple.js @@ -1,4 +1,4 @@ -import { Validator } from '../validator.js'; +import { Validator } from '../Validator.js'; export class Tuple extends Validator { make(ast) { diff --git a/src/interfaces/types/validators.ts b/src/interfaces/types/validators.ts index e3c0597..53324f2 100644 --- a/src/interfaces/types/validators.ts +++ b/src/interfaces/types/validators.ts @@ -48,7 +48,7 @@ export type BigIntSerial = bigint; export type Int = number; export type Int8 = number; -export type Int15 = number; +export type Int16 = number; export type Int32 = number; export type Uint = number; export type Uint8 = number; diff --git a/src/runtime/types/File.js b/src/runtime/types/File.js index 321ef4a..e1f6fb3 100644 --- a/src/runtime/types/File.js +++ b/src/runtime/types/File.js @@ -83,4 +83,8 @@ export class File { return path; } + + [Symbol.dispose]() { + console.log('File dispose'); + } }