@travetto/transformer 3.0.0-rc.16 → 3.0.0-rc.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/transformer",
3
- "version": "3.0.0-rc.16",
3
+ "version": "3.0.0-rc.17",
4
4
  "description": "Functionality for AST transformations, with transformer registration, and general utils",
5
5
  "keywords": [
6
6
  "typescript",
package/src/importer.ts CHANGED
@@ -26,7 +26,7 @@ export class ImportManager {
26
26
  constructor(public source: ts.SourceFile, public factory: ts.NodeFactory, resolver: TransformResolver) {
27
27
  this.#imports = ImportUtil.collectImports(source);
28
28
  this.#resolver = resolver;
29
- this.#importName = this.#resolver.getImportName(source.fileName);
29
+ this.#importName = this.#resolver.getFileImportName(source.fileName);
30
30
  }
31
31
 
32
32
  #getImportFile(spec?: ts.Expression): string | undefined {
@@ -101,7 +101,7 @@ export class ImportManager {
101
101
  * Import a file if needed, and record it's identifier
102
102
  */
103
103
  importFile(file: string, name?: string): Import {
104
- file = this.#resolver.getImportName(file);
104
+ file = this.#resolver.getFileImportName(file);
105
105
 
106
106
  // Allow for node classes to be imported directly
107
107
  if (/@types\/node/.test(file)) {
@@ -145,7 +145,7 @@ export const TypeBuilder: {
145
145
  external: {
146
146
  build: (resolver, type) => {
147
147
  const name = CoreUtil.getSymbol(type)?.getName();
148
- const importName = resolver.getImportName(type);
148
+ const importName = resolver.getTypeImportName(type)!;
149
149
  const tsTypeArguments = resolver.getAllTypeArguments(type);
150
150
  return { key: 'external', name, importName, tsTypeArguments };
151
151
  }
@@ -180,9 +180,14 @@ export const TypeBuilder: {
180
180
  build: (resolver, type, alias?) => {
181
181
  const tsFieldTypes: Record<string, ts.Type> = {};
182
182
  const name = CoreUtil.getSymbol(alias ?? type)?.getName();
183
- const importName = resolver.getImportName(type);
183
+ const importName = resolver.getTypeImportName(type) ?? '<unknown>';
184
184
  const tsTypeArguments = resolver.getAllTypeArguments(type);
185
- for (const member of resolver.getPropertiesOfType(type)) {
185
+ const props = resolver.getPropertiesOfType(type);
186
+ if (props.length === 0) {
187
+ return { key: 'unknown', name, importName };
188
+ }
189
+
190
+ for (const member of props) {
186
191
  const dec = DeclarationUtil.getPrimaryDeclarationNode(member);
187
192
  if (DeclarationUtil.isPublic(dec)) { // If public
188
193
  const memberType = resolver.getType(dec);
@@ -215,10 +220,10 @@ export const TypeBuilder: {
215
220
  ?.getSourceFile().fileName ?? '';
216
221
 
217
222
  if (importName === '.') {
218
- importName = resolver.getImportName(rawSourceFile);
223
+ importName = resolver.getFileImportName(rawSourceFile);
219
224
  } else {
220
225
  const base = path.dirname(rawSourceFile);
221
- importName = resolver.getImportName(path.resolve(base, importName));
226
+ importName = resolver.getFileImportName(path.resolve(base, importName));
222
227
  }
223
228
  }
224
229
  return { key: 'external', name, importName };
@@ -29,11 +29,10 @@ export class SimpleResolver implements TransformResolver {
29
29
  }
30
30
 
31
31
  /**
32
- * Resolve an import name (e.g. @module/path/file) for a given input or type
32
+ * Resolve an import name (e.g. @module/path/file) for a file
33
33
  */
34
- getImportName(fileOrType: string | ts.Type, removeExt?: boolean): string {
35
- const ogSource = typeof fileOrType === 'string' ? fileOrType : DeclarationUtil.getPrimaryDeclarationNode(fileOrType).getSourceFile().fileName;
36
- let sourceFile = path.toPosix(ogSource);
34
+ getFileImportName(file: string, removeExt?: boolean): string {
35
+ let sourceFile = path.toPosix(file);
37
36
 
38
37
  if (!sourceFile.endsWith('.js') && !sourceFile.endsWith('.ts')) {
39
38
  sourceFile = `${sourceFile}.ts`;
@@ -42,11 +41,19 @@ export class SimpleResolver implements TransformResolver {
42
41
  const imp =
43
42
  this.#manifestIndex.getEntry(/[.]ts$/.test(sourceFile) ? sourceFile : `${sourceFile}.js`)?.import ??
44
43
  this.#manifestIndex.getFromImport(sourceFile.replace(/^.*node_modules\//, '').replace(/[.]ts$/, ''))?.import ??
45
- ogSource;
44
+ file;
46
45
 
47
46
  return removeExt ? imp.replace(/[.]js$/, '') : imp;
48
47
  }
49
48
 
49
+ /**
50
+ * Resolve an import name (e.g. @module/path/file) for a type
51
+ */
52
+ getTypeImportName(type: ts.Type, removeExt?: boolean): string | undefined {
53
+ const ogSource = DeclarationUtil.getPrimaryDeclarationNode(type)?.getSourceFile()?.fileName;
54
+ return ogSource ? this.getFileImportName(ogSource, removeExt) : undefined;
55
+ }
56
+
50
57
  /**
51
58
  * Is the file/import known to the index, helpful for determine ownership
52
59
  */
@@ -97,7 +104,7 @@ export class SimpleResolver implements TransformResolver {
97
104
  /**
98
105
  * Resolve an `AnyType` from a `ts.Type` or a `ts.Node`
99
106
  */
100
- resolveType(node: ts.Type | ts.Node): AnyType {
107
+ resolveType(node: ts.Type | ts.Node, importName: string): AnyType {
101
108
  const visited = new VisitCache();
102
109
  const resolve = (resType: ts.Type, alias?: ts.Symbol, depth = 0): AnyType => {
103
110
 
@@ -149,7 +156,7 @@ export class SimpleResolver implements TransformResolver {
149
156
  if (!(err instanceof Error)) {
150
157
  throw err;
151
158
  }
152
- console.error('Unable to resolve type', err.stack);
159
+ console.error(`Unable to resolve type in ${importName}`, err.stack);
153
160
  return { key: 'literal', ctor: Object, name: 'object' };
154
161
  }
155
162
  }
@@ -153,7 +153,8 @@ export type AnyType = TupleType | ShapeType | UnionType | LiteralType | External
153
153
  */
154
154
  export interface TransformResolver {
155
155
  isKnownFile(file: string): boolean;
156
- getImportName(fileOrType: string | ts.Type, removeExt?: boolean): string;
156
+ getFileImportName(file: string, removeExt?: boolean): string;
157
+ getTypeImportName(type: ts.Type, removeExt?: boolean): string | undefined;
157
158
  getAllTypeArguments(type: ts.Type): ts.Type[];
158
159
  getPropertiesOfType(type: ts.Type): ts.Symbol[];
159
160
  getTypeAsString(type: ts.Type): string | undefined;
package/src/state.ts CHANGED
@@ -47,7 +47,7 @@ export class TransformerState implements State {
47
47
  this.#imports = new ImportManager(source, factory, this.#resolver);
48
48
  this.file = path.toPosix(this.source.fileName);
49
49
 
50
- this.importName = this.#resolver.getImportName(this.file, true);
50
+ this.importName = this.#resolver.getFileImportName(this.file, true);
51
51
  }
52
52
 
53
53
  /**
@@ -68,7 +68,7 @@ export class TransformerState implements State {
68
68
  * Resolve an `AnyType` from a `ts.Type` or `ts.Node`
69
69
  */
70
70
  resolveType(node: ts.Type | ts.Node): AnyType {
71
- const resolved = this.#resolver.resolveType(node);
71
+ const resolved = this.#resolver.resolveType(node, this.importName);
72
72
  this.#imports.importFromResolved(resolved);
73
73
  return resolved;
74
74
  }
@@ -80,7 +80,7 @@ export class TransformerState implements State {
80
80
  const resolved = this.resolveType(node);
81
81
  if (resolved.key !== 'external') {
82
82
  const file = node.getSourceFile().fileName;
83
- const src = this.#resolver.getImportName(file);
83
+ const src = this.#resolver.getFileImportName(file);
84
84
  throw new Error(`Unable to import non-external type: ${node.getText()} ${resolved.key}: ${src}`);
85
85
  }
86
86
  return resolved;
@@ -147,7 +147,7 @@ export class TransformerState implements State {
147
147
  this.#resolver.getType(ident)
148
148
  );
149
149
  const src = decl?.getSourceFile().fileName;
150
- const mod = src ? this.#resolver.getImportName(src, true) : undefined;
150
+ const mod = src ? this.#resolver.getFileImportName(src, true) : undefined;
151
151
  const file = this.#manifestIndex.getFromImport(mod ?? '')?.outputFile;
152
152
  const targets = DocUtil.readAugments(this.#resolver.getType(ident));
153
153
  const module = file ? mod : undefined;
@@ -266,7 +266,7 @@ export class TransformerState implements State {
266
266
  if (this.#fileIdent === undefined) {
267
267
  this.#fileIdent = this.createIdentifier('ᚕf');
268
268
  const decl = this.factory.createVariableDeclaration(this.#fileIdent, undefined, undefined,
269
- this.fromLiteral(this.#resolver.getImportName(this.source.fileName) ?? this.source.fileName)
269
+ this.fromLiteral(this.#resolver.getFileImportName(this.source.fileName) ?? this.source.fileName)
270
270
  );
271
271
  this.addStatements([
272
272
  this.factory.createVariableStatement([], this.factory.createVariableDeclarationList([decl]))