@ealmansi/jagger
Advanced tools
Comparing version 0.1.27 to 0.1.28
#!/usr/bin/env -S node --no-warnings | ||
import { Command } from "commander"; | ||
import assert from "node:assert/strict"; | ||
import ts from "typescript"; | ||
import packageJson from "../../package.json" assert { type: "json" }; | ||
import { generateComponentImplementations } from "../lib/generateComponentImplementations.js"; | ||
import ts from "typescript"; | ||
function main() { | ||
const options = new Command() | ||
const system = ts.sys; | ||
const { project: tsConfigFilePath } = parseCommandLineArguments(); | ||
generateComponentImplementations(system, tsConfigFilePath); | ||
} | ||
function parseCommandLineArguments() { | ||
const values = new Command() | ||
.name("jagger-generate") | ||
@@ -13,6 +19,7 @@ .version(packageJson.version) | ||
.opts(); | ||
const tsConfigFileName = typeof options["project"] === "string" ? options["project"] : undefined; | ||
generateComponentImplementations(ts.sys, tsConfigFileName); | ||
const project = values["project"]; | ||
assert.ok(project === undefined || typeof project === "string"); | ||
return { project }; | ||
} | ||
main(); | ||
//# sourceMappingURL=generate.js.map |
import ts from "typescript"; | ||
export interface Graph { | ||
components: ts.ClassDeclaration[]; | ||
componentModule: WeakMap<ts.ClassDeclaration, ts.ClassDeclaration>; | ||
componentResolvers: WeakMap<ts.ClassDeclaration, ts.MethodDeclaration[]>; | ||
resolverReturnType: WeakMap<ts.MethodDeclaration, ts.Type>; | ||
componentModule: Map<ts.ClassDeclaration, ts.ClassDeclaration>; | ||
componentResolvers: Map<ts.ClassDeclaration, ts.MethodDeclaration[]>; | ||
resolverReturnType: Map<ts.MethodDeclaration, ts.Type>; | ||
modules: ts.ClassDeclaration[]; | ||
moduleImports: WeakMap<ts.ClassDeclaration, ts.ClassDeclaration[]>; | ||
moduleProviders: WeakMap<ts.ClassDeclaration, (ts.PropertyDeclaration | ts.MethodDeclaration)[]>; | ||
providerModule: WeakMap<ts.PropertyDeclaration | ts.MethodDeclaration, ts.ClassDeclaration>; | ||
providerParameterTypes: WeakMap<ts.PropertyDeclaration | ts.MethodDeclaration, ts.Type[]>; | ||
providerReturnType: WeakMap<ts.PropertyDeclaration | ts.MethodDeclaration, ts.Type>; | ||
moduleImports: Map<ts.ClassDeclaration, ts.ClassDeclaration[]>; | ||
moduleProviders: Map<ts.ClassDeclaration, (ts.PropertyDeclaration | ts.MethodDeclaration)[]>; | ||
providerModule: Map<ts.PropertyDeclaration | ts.MethodDeclaration, ts.ClassDeclaration>; | ||
providerParameterTypes: Map<ts.PropertyDeclaration | ts.MethodDeclaration, ts.Type[]>; | ||
providerReturnType: Map<ts.PropertyDeclaration | ts.MethodDeclaration, ts.Type>; | ||
} | ||
export declare function buildGraph(program: ts.Program): Graph; | ||
//# sourceMappingURL=buildGraph.d.ts.map |
@@ -0,9 +1,9 @@ | ||
import assert from "node:assert/strict"; | ||
import ts from "typescript"; | ||
import assert from "node:assert/strict"; | ||
import { ok } from "./ok.js"; | ||
import { orThrow } from "./orThrow.js"; | ||
export function buildGraph(program) { | ||
const components = getComponents(program); | ||
const modules = getModules(program); | ||
const componentModule = new WeakMap(); | ||
const componentResolvers = new WeakMap(); | ||
const componentModule = new Map(); | ||
const componentResolvers = new Map(); | ||
for (const component of components) { | ||
@@ -13,3 +13,3 @@ componentModule.set(component, getComponentModule(program, component)); | ||
} | ||
const resolverReturnType = new WeakMap(); | ||
const resolverReturnType = new Map(); | ||
for (const component of components) { | ||
@@ -22,4 +22,4 @@ const resolvers = componentResolvers.get(component); | ||
} | ||
const moduleImports = new WeakMap(); | ||
const moduleProviders = new WeakMap(); | ||
const moduleImports = new Map(); | ||
const moduleProviders = new Map(); | ||
for (const module of modules) { | ||
@@ -29,5 +29,5 @@ moduleImports.set(module, getModuleImports(program, module)); | ||
} | ||
const providerModule = new WeakMap(); | ||
const providerParameterTypes = new WeakMap(); | ||
const providerReturnType = new WeakMap(); | ||
const providerModule = new Map(); | ||
const providerParameterTypes = new Map(); | ||
const providerReturnType = new Map(); | ||
for (const module of modules) { | ||
@@ -76,3 +76,3 @@ const providers = moduleProviders.get(module); | ||
heritageClause.types.length === 1) { | ||
const expressionWithTypeArguments = ok(heritageClause.types.at(0)); | ||
const expressionWithTypeArguments = orThrow(heritageClause.types.at(0)); | ||
return (ts.isPropertyAccessExpression(expressionWithTypeArguments.expression) && | ||
@@ -105,3 +105,3 @@ ts.isIdentifier(expressionWithTypeArguments.expression.expression) && | ||
heritageClause.types.length === 1) { | ||
const expressionWithTypeArguments = ok(heritageClause.types.at(0)); | ||
const expressionWithTypeArguments = orThrow(heritageClause.types.at(0)); | ||
return (ts.isPropertyAccessExpression(expressionWithTypeArguments.expression) && | ||
@@ -183,3 +183,3 @@ ts.isIdentifier(expressionWithTypeArguments.expression.expression) && | ||
assert.ok(signatures.length === 1, "signatures.length === 1"); | ||
const signature = ok(signatures.at(0)); | ||
const signature = orThrow(signatures.at(0)); | ||
const parameterSymbols = signature.getParameters(); | ||
@@ -190,3 +190,3 @@ const parameterDeclarations = signature.getDeclaration().parameters; | ||
const type = typeChecker.getTypeOfSymbol(parameterSymbol); | ||
const parameterDeclaration = ok(parameterDeclarations[index]); | ||
const parameterDeclaration = orThrow(parameterDeclarations[index]); | ||
if (parameterDeclaration.dotDotDotToken !== undefined) { | ||
@@ -225,3 +225,3 @@ if (type.getFlags() & ts.TypeFlags.Object) { | ||
assert.ok(signatures.length === 1, "signatures.length === 1"); | ||
const signature = ok(signatures.at(0)); | ||
const signature = orThrow(signatures.at(0)); | ||
return signature.getReturnType(); | ||
@@ -228,0 +228,0 @@ } |
@@ -0,16 +1,17 @@ | ||
import assert from "node:assert/strict"; | ||
import path from "node:path"; | ||
import ts from "typescript"; | ||
import path from "node:path"; | ||
import assert from "node:assert/strict"; | ||
import { buildGraph } from "./buildGraph.js"; | ||
import { buildGraphResolution, } from "./buildGraphResolution.js"; | ||
import { ok } from "./ok.js"; | ||
import { buildResolution, } from "./computeResolution.js"; | ||
import { orThrow } from "./orThrow.js"; | ||
export function createComponentImplementationsBundle(program) { | ||
const factory = ts.factory; | ||
const typeChecker = program.getTypeChecker(); | ||
const graph = buildGraph(program); | ||
const graphResolution = buildGraphResolution(program, graph); | ||
const resolution = buildResolution(typeChecker, graph); | ||
return factory.createBundle(graph.components.map((component) => { | ||
return createComponentImplementationSourceFile(program, graph, graphResolution, component); | ||
return createComponentImplementationSourceFile(graph, resolution, component); | ||
})); | ||
} | ||
function createComponentImplementationSourceFile(program, graph, graphResolution, component) { | ||
function createComponentImplementationSourceFile(graph, resolution, component) { | ||
const factory = ts.factory; | ||
@@ -21,4 +22,4 @@ const inputSourceFile = component.getSourceFile(); | ||
const outputSourceFile = factory.createSourceFile([ | ||
...createComponentImportDeclarations(program, graph, graphResolution, component, outputFileName), | ||
createComponentClassDeclaration(program, graph, graphResolution, component), | ||
...createComponentImportDeclarations(resolution, component, outputFileName), | ||
createComponentClassDeclaration(graph, resolution, component), | ||
], factory.createToken(ts.SyntaxKind.EndOfFileToken), ts.NodeFlags.None); | ||
@@ -28,5 +29,5 @@ outputSourceFile.fileName = outputFileName; | ||
} | ||
function createComponentImportDeclarations(_program, _graph, graphResolution, component, outputFileName) { | ||
function createComponentImportDeclarations(resolution, component, outputFileName) { | ||
const factory = ts.factory; | ||
const moduleInstances = ok(graphResolution.componentModuleInstances.get(component)); | ||
const moduleInstances = orThrow(resolution.componentModuleInstances.get(component)); | ||
return [component, ...moduleInstances].map((componentOrModule) => { | ||
@@ -46,3 +47,3 @@ const sourceFile = componentOrModule.getSourceFile(); | ||
} | ||
function createComponentClassDeclaration(_program, graph, graphResolution, component) { | ||
function createComponentClassDeclaration(graph, resolution, component) { | ||
const factory = ts.factory; | ||
@@ -52,4 +53,4 @@ assert.ok(component.name, "component.name"); | ||
assert.ok(resolvers, "resolvers"); | ||
const moduleInstances = ok(graphResolution.componentModuleInstances.get(component)); | ||
const typeResolutions = ok(graphResolution.componentTypeResolutions.get(component)); | ||
const moduleInstances = orThrow(resolution.componentModuleInstances.get(component)); | ||
const typeResolutions = orThrow(resolution.componentTypeResolutions.get(component)); | ||
const typeResolutionNames = new Set(); | ||
@@ -68,3 +69,3 @@ const syntheticTypeResolutionName = new Map(); | ||
assert.ok(module, "module"); | ||
const typeResolution = ok(graphResolution.resolverTypeResolution.get(resolver)); | ||
const typeResolution = orThrow(resolution.resolverTypeResolution.get(resolver)); | ||
return factory.createMethodDeclaration(undefined, undefined, factory.createIdentifier(resolver.name.text), undefined, undefined, [], undefined, factory.createBlock([ | ||
@@ -75,4 +76,3 @@ factory.createReturnStatement(factory.createCallExpression(factory.createPropertyAccessExpression(factory.createThis(), factory.createIdentifier(buildTypeResolutionName(typeResolution, syntheticTypeResolutionName))), undefined, [])), | ||
...moduleInstances.map((moduleInstance) => { | ||
assert.ok(moduleInstance.name, "module.name"); | ||
return factory.createPropertyDeclaration([factory.createToken(ts.SyntaxKind.PrivateKeyword)], factory.createIdentifier("_" + moduleInstance.name.text), undefined, undefined, undefined); | ||
return factory.createPropertyDeclaration([factory.createToken(ts.SyntaxKind.PrivateKeyword)], factory.createIdentifier(buildModuleInstanceName(moduleInstance)), undefined, undefined, undefined); | ||
}), | ||
@@ -82,4 +82,3 @@ factory.createConstructorDeclaration(undefined, [], factory.createBlock([ | ||
...moduleInstances.map((moduleInstance) => { | ||
assert.ok(moduleInstance.name, "module.name"); | ||
return factory.createExpressionStatement(factory.createBinaryExpression(factory.createPropertyAccessExpression(factory.createThis(), factory.createIdentifier("_" + moduleInstance.name.text)), factory.createToken(ts.SyntaxKind.EqualsToken), factory.createNewExpression(factory.createIdentifier(moduleInstance.name.text), undefined, []))); | ||
return factory.createExpressionStatement(factory.createBinaryExpression(factory.createPropertyAccessExpression(factory.createThis(), factory.createIdentifier(buildModuleInstanceName(moduleInstance))), factory.createToken(ts.SyntaxKind.EqualsToken), factory.createNewExpression(factory.createIdentifier(orThrow(moduleInstance.name).text), undefined, []))); | ||
}), | ||
@@ -97,3 +96,3 @@ ], true)), | ||
factory.createMethodDeclaration([factory.createToken(ts.SyntaxKind.PrivateKeyword)], undefined, factory.createIdentifier(typeResolutionName), undefined, undefined, [], undefined, factory.createBlock([ | ||
factory.createReturnStatement(factory.createCallExpression(factory.createPropertyAccessExpression(factory.createPropertyAccessExpression(factory.createThis(), factory.createIdentifier("_" + ok(typeResolution.module.name).text)), factory.createIdentifier(typeResolution.provider.name.getText())), undefined, [ | ||
factory.createReturnStatement(factory.createCallExpression(factory.createPropertyAccessExpression(factory.createPropertyAccessExpression(factory.createThis(), factory.createIdentifier("_" + orThrow(typeResolution.module.name).text)), factory.createIdentifier(typeResolution.provider.name.getText())), undefined, [ | ||
...typeResolution.parameterTypeResolutions.map((parameterTypeResolution) => { | ||
@@ -124,4 +123,3 @@ return factory.createCallExpression(factory.createPropertyAccessExpression(factory.createThis(), factory.createIdentifier(buildTypeResolutionName(parameterTypeResolution, syntheticTypeResolutionName))), undefined, []); | ||
case "ProviderTypeResolution": | ||
return ("_" + | ||
ok(typeResolution.module.name).text + | ||
return (buildModuleInstanceName(typeResolution.module) + | ||
"_" + | ||
@@ -133,8 +131,10 @@ typeResolution.provider.name.getText()); | ||
} | ||
return ("_" + | ||
ok(typeResolution.module.name).text + | ||
return (buildModuleInstanceName(typeResolution.module) + | ||
"_" + | ||
ok(syntheticTypeResolutionName.get(typeResolution))); | ||
orThrow(syntheticTypeResolutionName.get(typeResolution))); | ||
} | ||
} | ||
function buildModuleInstanceName(module) { | ||
return "_" + orThrow(module.name).text; | ||
} | ||
//# sourceMappingURL=createComponentImplementationsBundle.js.map |
import ts from "typescript"; | ||
export declare function generateComponentImplementations(system: ts.System, tsConfigFileName: string | undefined): void; | ||
export declare function generateComponentImplementations(system: ts.System, tsConfigFilePath: string | undefined): void; | ||
//# sourceMappingURL=generateComponentImplementations.d.ts.map |
import { createComponentImplementationsBundle } from "./createComponentImplementationsBundle.js"; | ||
import { loadProgramFromTsConfigFile } from "./loadProgramFromTsConfig.js"; | ||
import { writeBundle } from "./writeBundle.js"; | ||
export function generateComponentImplementations(system, tsConfigFileName) { | ||
const program = loadProgramFromTsConfigFile(system, tsConfigFileName); | ||
export function generateComponentImplementations(system, tsConfigFilePath) { | ||
const program = loadProgramFromTsConfigFile(system, tsConfigFilePath); | ||
const componentImplementationsBundle = createComponentImplementationsBundle(program); | ||
@@ -7,0 +7,0 @@ writeBundle(system, componentImplementationsBundle); |
import ts from "typescript"; | ||
export declare function loadProgramFromTsConfigFile(system: ts.System, tsConfigFileName: string | undefined): ts.Program; | ||
export declare function loadProgramFromTsConfigFile(system: ts.System, tsConfigFilePath: string | undefined): ts.Program; | ||
//# sourceMappingURL=loadProgramFromTsConfig.d.ts.map |
import ts from "typescript"; | ||
import path from "node:path"; | ||
import assert from "node:assert/strict"; | ||
export function loadProgramFromTsConfigFile(system, tsConfigFileName) { | ||
if (tsConfigFileName === undefined) { | ||
const searchPath = path.resolve("."); | ||
const tsConfigBaseName = "tsconfig.json"; | ||
tsConfigFileName = ts.findConfigFile(searchPath, system.fileExists, tsConfigBaseName); | ||
assert.ok(tsConfigFileName, "fileName"); | ||
export function loadProgramFromTsConfigFile(system, tsConfigFilePath) { | ||
if (tsConfigFilePath === undefined) { | ||
const searchPath = system.resolvePath(system.getCurrentDirectory()); | ||
tsConfigFilePath = ts.findConfigFile(searchPath, system.fileExists); | ||
assert.ok(tsConfigFilePath, "Could not find tsconfig.json file"); | ||
} | ||
const readConfigFileResult = ts.readConfigFile(tsConfigFileName, system.readFile); | ||
const readConfigFileResult = ts.readConfigFile(tsConfigFilePath, system.readFile); | ||
if (readConfigFileResult.error !== undefined) { | ||
@@ -20,3 +19,3 @@ if (typeof readConfigFileResult.error.messageText === "string") { | ||
} | ||
const parsedCommandLine = ts.parseJsonConfigFileContent(readConfigFileResult.config, system, path.dirname(tsConfigFileName)); | ||
const parsedCommandLine = ts.parseJsonConfigFileContent(readConfigFileResult.config, system, path.dirname(tsConfigFilePath)); | ||
const createProgramOptions = { | ||
@@ -23,0 +22,0 @@ options: parsedCommandLine.options, |
{ | ||
"name": "@ealmansi/jagger", | ||
"version": "0.1.27", | ||
"version": "0.1.28", | ||
"description": "WIP", | ||
@@ -5,0 +5,0 @@ "files": [ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
68275
699