@embracesql/shared
Advanced tools
Comparing version 0.0.9 to 0.0.10
{ | ||
"name": "@embracesql/shared", | ||
"version": "0.0.9", | ||
"version": "0.0.10", | ||
"description": "EmbraceSQL shared types between browser and node.", | ||
@@ -17,3 +17,3 @@ "type": "module", | ||
}, | ||
"gitHead": "149e4adeacf43a8b41c906a492e5ddeb4ed0114b" | ||
"gitHead": "886b89469dfe29e7613e221577f897a68323ab81" | ||
} |
172
src/ast.ts
@@ -8,4 +8,2 @@ import { | ||
import { camelCase, pascalCase } from "change-case"; | ||
import * as fs from "fs"; | ||
import * as path from "path"; | ||
@@ -69,6 +67,6 @@ /** | ||
CompositeType, | ||
AliasType, | ||
Attribute, | ||
DomainType, | ||
ArrayType, | ||
Results, | ||
} | ||
@@ -143,5 +141,5 @@ | ||
[ASTKind.Attribute]: AttributeNode; | ||
[ASTKind.AliasType]: AliasTypeNode; | ||
[ASTKind.DomainType]: DomainTypeNode; | ||
[ASTKind.ArrayType]: ArrayTypeNode; | ||
[ASTKind.Results]: ResultsNode; | ||
}; | ||
@@ -231,7 +229,7 @@ | ||
get typescriptName() { | ||
public get typescriptName() { | ||
return `${pascalCase(this.name)}`; | ||
} | ||
get typescriptNamespacedName(): string { | ||
public get typescriptNamespacedName(): string { | ||
if (this.parent) { | ||
@@ -244,7 +242,7 @@ return `${this.parent.typescriptNamespacedName}.${this.typescriptName}`; | ||
get typescriptPropertyName() { | ||
public get typescriptPropertyName() { | ||
return camelCase(cleanIdentifierForTypescript(this.name)); | ||
} | ||
get typescriptNamespacedPropertyName(): string { | ||
public get typescriptNamespacedPropertyName(): string { | ||
if (this.parent) { | ||
@@ -526,2 +524,3 @@ return `${this.parent.typescriptNamespacedName}.${this.typescriptPropertyName}`; | ||
super(name, ASTKind.Table, tables); | ||
new ResultsNode(this, type); | ||
new CreateOperationNode(this); | ||
@@ -677,19 +676,6 @@ new AllOperationNode(this); | ||
get resultsType() { | ||
return this.children | ||
.filter<AbstractTypeNode>((c): c is AbstractTypeNode => | ||
[ASTKind.CompositeType, ASTKind.AliasType].includes(c.kind), | ||
) | ||
.find((c) => c.name === RESULTS); | ||
return this.children.filter<ResultsNode>( | ||
(c): c is ResultsNode => c.kind === ASTKind.Results, | ||
)[0].type; | ||
} | ||
/** | ||
* The results type might be an alias -- resolve it to the target | ||
* final type. | ||
*/ | ||
get resultsResolvedType() { | ||
const typeNode = this.resultsType; | ||
// resolve type alias to a composite | ||
return typeNode?.kind === ASTKind.AliasType | ||
? (typeNode as AliasTypeNode).type | ||
: typeNode; | ||
} | ||
} | ||
@@ -763,21 +749,4 @@ | ||
static SCRIPTS = "Scripts"; | ||
/** | ||
* Loading up the scripts node by file system traversal. | ||
* | ||
* Once done, all scripts will be visited and loaded into the AST. | ||
*/ | ||
static async loadAST(context: GenerationContext) { | ||
if (context.sqlScriptsFrom) { | ||
const rootPath = path.parse(path.join(context.sqlScriptsFrom)); | ||
const scriptsNode = new ScriptsNode(context.database, rootPath); | ||
await ScriptFolderNode.loadAST(context, rootPath, scriptsNode); | ||
return scriptsNode; | ||
} else { | ||
return undefined; | ||
} | ||
} | ||
constructor( | ||
public database: DatabaseNode, | ||
public path: path.ParsedPath, | ||
) { | ||
constructor(public database: DatabaseNode) { | ||
super("Scripts", ASTKind.Scripts, database); | ||
@@ -796,40 +765,5 @@ } | ||
export class ScriptFolderNode extends ContainerNode { | ||
/** | ||
* Asynchronous factory builds from a folder path on disk. | ||
*/ | ||
static async loadAST( | ||
context: GenerationContext, | ||
searchPath: path.ParsedPath, | ||
addToNode: ContainerNode, | ||
) { | ||
// reading the whole directory | ||
const inPath = await fs.promises.readdir( | ||
path.join(searchPath.dir, searchPath.base), | ||
{ | ||
withFileTypes: true, | ||
}, | ||
); | ||
for (const entry of inPath) { | ||
if (entry.isDirectory()) { | ||
const folder = new ScriptFolderNode( | ||
path.parse(path.join(entry.path, entry.name)), | ||
addToNode, | ||
); | ||
await ScriptFolderNode.loadAST(context, folder.path, folder); | ||
} else if (entry.name.endsWith(".sql")) { | ||
await ScriptNode.loadAST( | ||
context, | ||
path.parse(path.join(entry.path, entry.name)), | ||
addToNode, | ||
); | ||
} | ||
} | ||
constructor(name: string, parent: ContainerNode) { | ||
super(name, ASTKind.ScriptFolder, parent); | ||
} | ||
constructor( | ||
public path: path.ParsedPath, | ||
parent: ContainerNode, | ||
) { | ||
super(path.name, ASTKind.ScriptFolder, parent); | ||
} | ||
} | ||
@@ -841,22 +775,5 @@ | ||
export class ScriptNode extends FunctionOperationNode { | ||
/** | ||
* Asynchronous factory builds from a sql file on disk. | ||
*/ | ||
static async loadAST( | ||
context: GenerationContext, | ||
scriptPath: path.ParsedPath, | ||
addToNode: ContainerNode, | ||
) { | ||
console.assert(context); | ||
new ScriptNode( | ||
scriptPath, | ||
await fs.promises.readFile(path.join(scriptPath.dir, scriptPath.base), { | ||
encoding: "utf8", | ||
}), | ||
addToNode, | ||
); | ||
} | ||
constructor( | ||
public path: path.ParsedPath, | ||
name: string, | ||
public scriptPath: string, | ||
public script: string, | ||
@@ -866,3 +783,3 @@ parent: ContainerNode, | ||
// always returnsMany | ||
super(path.name, ASTKind.Script, parent, true); | ||
super(name, ASTKind.Script, parent, true); | ||
} | ||
@@ -993,50 +910,9 @@ } | ||
public nullable: boolean, | ||
public named = true, | ||
) { | ||
super(name, ASTKind.Attribute, parent); | ||
} | ||
/** | ||
* Generate a synthetic name based on the index | ||
* when no name is provided. | ||
*/ | ||
get typescriptPropertyName(): string { | ||
if (this.name) return super.typescriptPropertyName; | ||
else return `argument_${this.index}`; | ||
} | ||
} | ||
/** | ||
* Rename a type, useful in namespaces to allow consistent | ||
* code generation. | ||
*/ | ||
export class AliasTypeNode extends AbstractTypeNode { | ||
constructor( | ||
public name: string, | ||
public type: TypeNode, | ||
parent: ContainerNode, | ||
) { | ||
super(name, ASTKind.AliasType, parent, type.id, ""); | ||
} | ||
override typescriptTypeDefinition( | ||
context: GenerationContext, | ||
): string | undefined { | ||
console.assert(context); | ||
if (this.name === RESULTS) { | ||
if (this.type.kind === ASTKind.CompositeType) { | ||
return `NullableMembers<${this.type.typescriptNamespacedName}>`; | ||
} | ||
return `Nullable<${this.type.typescriptNamespacedName}>`; | ||
} | ||
return `${this.type.typescriptNamespacedName}`; | ||
} | ||
override typescriptTypeParser(context: GenerationContext) { | ||
console.assert(context); | ||
// delegate to the actual type | ||
return `return ${this.type.typescriptNamespacedName}.parse(from)`; | ||
} | ||
} | ||
/** | ||
* A domain type is much like an alias, in that it gives a new name | ||
@@ -1086,1 +962,13 @@ * to an existing type. | ||
} | ||
/** | ||
* Results reference a type, but are not a type themselves. | ||
*/ | ||
export class ResultsNode extends ASTNode { | ||
constructor( | ||
parent: ContainerNode, | ||
public type: AbstractTypeNode, | ||
) { | ||
super(ASTKind.Results, parent); | ||
} | ||
} |
@@ -96,3 +96,3 @@ import { DatabaseNode, VisitorMap } from "./ast"; | ||
export type JsDate = Date; | ||
export class JsDate extends Date {} | ||
export type Empty = Record<string, never>; | ||
@@ -99,0 +99,0 @@ export type JSONValue = |
import { GenerationContext, NamedASTNode } from "."; | ||
/** | ||
* Simplest possible visitor just skips this level and make sure | ||
* the children are visited. | ||
*/ | ||
export const ChildrenVisitor = { | ||
before: async (context: GenerationContext, node: NamedASTNode) => { | ||
console.assert(context); | ||
console.assert(node); | ||
return ``; | ||
}, | ||
after: async (context: GenerationContext, node: NamedASTNode) => { | ||
console.assert(context); | ||
console.assert(node); | ||
return ``; | ||
}, | ||
}; | ||
/** | ||
* This is a really simple visitor that names the node into a namespace. | ||
@@ -5,0 +22,0 @@ */ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
38379
1313