Skip to content

Commit

Permalink
simple wrapped types
Browse files Browse the repository at this point in the history
  • Loading branch information
pyramation committed May 29, 2024
1 parent 64412b9 commit 326f9f2
Show file tree
Hide file tree
Showing 8 changed files with 4,718 additions and 10 deletions.
2,326 changes: 2,326 additions & 0 deletions __fixtures__/output/types/node-wrapped/types.ts

Large diffs are not rendered by default.

2,334 changes: 2,334 additions & 0 deletions packages/parser/__tests__/__snapshots__/types.test.ts.snap

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions packages/parser/__tests__/types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,14 @@ describe('types', () => {
}
});
});
it('wrappedNodeTypeExport', () => {
parseAndSnap('types/node-wrapped', {
types: {
enabled: true,
enumsSource: 'my-enums.ts',
filename: 'types.ts',
wrappedNodeTypeExport: true
}
});
});
});
38 changes: 35 additions & 3 deletions packages/parser/src/ast/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Type, Field } from '@launchql/protobufjs';
import * as t from '@babel/types';
import { createNamedImport, createNamedImportAsSuffix, getFieldName, toSpecialCamelCase } from '../../utils';
import { PgProtoParserOptions } from '../../options';
import { SPECIAL_TYPES } from '../../constants';
import { NODE_TYPE, SPECIAL_TYPES } from '../../constants';
import { resolveTypeName } from './utils';

export const generateTypeImports = (types: Type[], source: string, suffix?: string) => {
Expand Down Expand Up @@ -89,18 +89,50 @@ export const generateAstHelperMethods = (types: Type[]): t.ExportDefaultDeclarat
}

// special for Node
export const generateNodeUnionType = (types: Type[]) => {
export const generateNodeUnionType = (
options: PgProtoParserOptions,
types: Type[]
) => {
if (options.types.wrappedNodeTypeExport) {
return generateNodeUnionTypeObjectKeys(types);
}
const unionTypeNames = types.map(type => t.tsTypeReference(t.identifier(type.name)));

const unionTypeAlias = t.tsTypeAliasDeclaration(
t.identifier('Node'),
t.identifier(NODE_TYPE),
null,
t.tsUnionType(unionTypeNames)
);

return t.exportNamedDeclaration(unionTypeAlias, []);
};


export const generateNodeUnionTypeObjectKeys = (types: Type[]) => {
// Mapping types to TypeScript object type annotations
const unionTypeNames = types.map(type =>
t.tsTypeLiteral([
t.tsPropertySignature(
t.identifier(type.name),
t.tsTypeAnnotation(t.tsTypeReference(t.identifier(type.name)))
)
])
);

// Creating the TypeScript union type
const unionTypeAlias = t.tsTypeAliasDeclaration(
t.identifier(NODE_TYPE),
null,
t.tsUnionType(unionTypeNames)
);

// Exporting the union type declaration
return t.exportNamedDeclaration(unionTypeAlias, []);
};




// TODO: why is the Field.rule missing in types, but there in the JSON?
interface FieldType extends Field {
rule: string;
Expand Down
1 change: 1 addition & 0 deletions packages/parser/src/options/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const defaultPgProtoParserOptions: PgProtoParserOptions = {
filename: 'types.ts',
optionalFields: true,
enumsSource: './enums',
wrappedNodeTypeExport: false,
wrapped: {
enabled: false,
enumsSource: './enums',
Expand Down
3 changes: 3 additions & 0 deletions packages/parser/src/options/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ export interface PgProtoStoreOptions {
optionalFields?: boolean;
// Enums source specifier
enumsSource?: string;
// Node Object Keys, e.g. { ParseResult: ParseResult, ... }
// meant for simpler user cases where wrapped is advanced
wrappedNodeTypeExport?: boolean;
// wrapped types, for building AST
wrapped?: {
// Enabled wrapped types, to match AST
Expand Down
9 changes: 5 additions & 4 deletions packages/parser/src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getOptionsWithDefaults, PgProtoStoreOptions } from './options';
import { cloneAndNameNode, convertAstToCode, createDefaultImport, getUndefinedKey, hasUndefinedInitialValue, stripExtension, writeFileToDisk } from './utils';
import { nestedObjCode } from './inline-helpers';
import * as t from '@babel/types';
import { NODE_TYPE } from './constants';

interface IProtoStore {
options: PgProtoStoreOptions;
Expand Down Expand Up @@ -107,12 +108,12 @@ export class ProtoStore implements IProtoStore {
}

allTypesExceptNode () {
return this.types.filter(type => type.name !== 'Node');
return this.types.filter(type => type.name !== NODE_TYPE);
}

typesToProcess () {
return this.types
.filter(type => type.name !== 'Node')
.filter(type => type.name !== NODE_TYPE)
.filter(type => !this.options.exclude.includes(type.name));
}

Expand All @@ -125,7 +126,7 @@ export class ProtoStore implements IProtoStore {
if (this.options.types.enabled) {
const typesToProcess = this.typesToProcess();
const enumsToProcess = this.enumsToProcess();
const node = generateNodeUnionType(typesToProcess);
const node = generateNodeUnionType(this.options, typesToProcess);
const enumImports = generateEnumImports(enumsToProcess, this.options.types.enumsSource);
const types = typesToProcess.reduce((m, type) => {
return [...m, convertTypeToTsInterface(type, this.options)]
Expand All @@ -145,7 +146,7 @@ export class ProtoStore implements IProtoStore {
this.enumsToProcess(),
this.options.types.wrapped.enumsSource
);
const node = generateNodeUnionType(typesToProcess);
const node = generateNodeUnionType(this.options, typesToProcess);
const types = typesToProcess.reduce((m, type) => {
return [...m, convertTypeToWrappedTsInterface(type, this.options)]
}, []);
Expand Down
7 changes: 4 additions & 3 deletions packages/parser/src/utils/deps.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Type, Enum, Field, ReflectionObject } from '@launchql/protobufjs';
import { Type, Enum, Field } from '@launchql/protobufjs';
import { isPrimitiveType } from './types';
import { NODE_TYPE } from '../constants';

const dependenciesResolve = (types: Type[], enums: Enum[], symbolName: string, resolved: string[], unresolved: string[]) => {
if (symbolName === 'Node') return;
if (symbolName === NODE_TYPE) return;

unresolved.push(symbolName);

Expand Down Expand Up @@ -41,7 +42,7 @@ export const getDependencies = (name: string, types: Type[], enums: Enum[]) => {
}

const dependentsResolve = (types, enums, symbolName, resolved, unresolved) => {
if (symbolName === 'Node') return;
if (symbolName === NODE_TYPE) return;

unresolved.push(symbolName);

Expand Down

0 comments on commit 326f9f2

Please sign in to comment.