@cosmology/ast
Version:
Cosmos TypeScript AST generation
254 lines (253 loc) • 8.32 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.getOptionDeprecated = exports.getFieldOptionalityForDefaults = exports.isMapField = exports.isEnumField = exports.isArrayField = exports.isScalarField = exports.getFieldOptionalityForAmino = exports.getFieldOptionality = exports.getOneOfs = exports.getBaseCreateTypeFuncName = exports.getKeyTypeEntryName = exports.getFieldsTypeName = exports.getEnumFromJsonName = exports.getEnumToJsonName = exports.getTagNumber = exports.getPackedWireNumber = exports.getWireNumber = exports.types = exports.GOOGLE_TYPES = exports.SCALAR_TYPES = void 0;
const case_1 = require("case");
const utils_1 = require("@cosmology/utils");
exports.SCALAR_TYPES = [
'string',
'double',
'float',
'int32',
'uint32',
'sint32',
'fixed32',
'sfixed32',
'int64',
'uint64',
'sint64',
'fixed64',
'sfixed64',
'bytes',
'bool'
];
exports.GOOGLE_TYPES = [
'google.protobuf.Timestamp',
'google.protobuf.Duration',
'google.protobuf.Any'
];
// https://github.com/protobufjs/protobuf.js/blob/master/src/types.js#L38-L54
exports.types = {
basic: {
double: 1,
float: 5,
int32: 0,
uint32: 0,
sint32: 0,
fixed32: 5,
sfixed32: 5,
int64: 0,
uint64: 0,
sint64: 0,
fixed64: 1,
sfixed64: 1,
bool: 0,
string: 2,
bytes: 2
},
defaults: {
double: 0,
float: 0,
int32: 0,
uint32: 0,
sint32: 0,
fixed32: 0,
sfixed32: 0,
int64: 0,
uint64: 0,
sint64: 0,
fixed64: 0,
sfixed64: 0,
bool: false,
string: '',
bytes: [],
undefined: null
},
long: { int64: 0, uint64: 0, sint64: 0, fixed64: 1, sfixed64: 1 },
mapKey: {
int32: 0,
uint32: 0,
sint32: 0,
fixed32: 5,
sfixed32: 5,
int64: 0,
uint64: 0,
sint64: 0,
fixed64: 1,
sfixed64: 1,
bool: 0,
string: 2
},
packed: {
double: 1,
float: 5,
int32: 0,
uint32: 0,
sint32: 0,
fixed32: 5,
sfixed32: 5,
int64: 0,
uint64: 0,
sint64: 0,
fixed64: 1,
sfixed64: 1,
bool: 0
}
};
const getWireNumber = (type) => {
if (exports.types.basic.hasOwnProperty(type)) {
return exports.types.basic[type];
}
return 2;
};
exports.getWireNumber = getWireNumber;
const getPackedWireNumber = (type) => {
if (exports.types.packed.hasOwnProperty(type)) {
return exports.types.packed[type];
}
return 2;
};
exports.getPackedWireNumber = getPackedWireNumber;
const getTagNumber = (field) => {
let wire = (0, exports.getWireNumber)(field.type);
if (field.parsedType.type === 'Enum') {
wire = 0;
}
if (field.rule === 'repeated') {
wire = 2;
}
return ((field.id << 3) | wire) >>> 0;
};
exports.getTagNumber = getTagNumber;
const lowerFirst = (str) => {
return str.charAt(0).toLowerCase() + str.substring(1);
};
const upperFirst = (str) => {
return str.charAt(0).toUpperCase() + str.substring(1);
};
const getEnumToJsonName = (name) => {
return lowerFirst(name) + 'ToJSON';
};
exports.getEnumToJsonName = getEnumToJsonName;
const getEnumFromJsonName = (name) => {
return lowerFirst(name) + 'FromJSON';
};
exports.getEnumFromJsonName = getEnumFromJsonName;
const getFieldsTypeName = (field) => {
if (!field?.scope || field?.scope.length <= 1) {
if (field.parsedType) {
return field.parsedType.name;
}
else {
const temp = field.type.split(".");
return temp[temp.length - 1];
}
}
const [_pkg, ...scopes] = field.scope;
return [...scopes, field.parsedType.name].join('_');
};
exports.getFieldsTypeName = getFieldsTypeName;
const getKeyTypeEntryName = (typeName, prop) => {
return `${typeName}_${(0, case_1.pascal)(prop)}Entry`;
};
exports.getKeyTypeEntryName = getKeyTypeEntryName;
const getBaseCreateTypeFuncName = (name) => {
return `createBase${upperFirst(name)}`;
};
exports.getBaseCreateTypeFuncName = getBaseCreateTypeFuncName;
const getOneOfs = (type) => {
const keys = Object.keys(type.oneofs ?? {});
if (!keys.length)
return [];
if (keys.length !== 1)
throw new Error('getOneOfs() oneofs cardinality not known!');
return type.oneofs[keys[0]].oneof;
};
exports.getOneOfs = getOneOfs;
const getFieldOptionality = (context, field, isOneOf) => {
const isScalarDefaultToNullable = context.pluginValue('prototypes.isScalarDefaultToNullable');
if (field?.options?.['(gogoproto.moretags)'] && (0, exports.getOptionDeprecated)(field?.options?.['(gogoproto.moretags)']) === 'true') {
return true;
}
if ((0, exports.isArrayField)(field) || (0, exports.isEnumField)(field) || (!isScalarDefaultToNullable && (0, exports.isScalarField)(field))) {
// these field types are required by default!
if (isOneOf) {
return true;
}
return false;
}
return true;
};
exports.getFieldOptionality = getFieldOptionality;
const getFieldOptionalityForAmino = (context, field, isOneOf) => {
const useProtoOptionality = context.pluginValue('aminoEncoding.useProtoOptionality');
if (field?.options?.['(gogoproto.moretags)'] && (0, exports.getOptionDeprecated)(field?.options?.['(gogoproto.moretags)']) === 'true') {
return true;
}
if (useProtoOptionality) {
return (0, exports.getFieldOptionalityForDefaults)(context, field, isOneOf);
}
if (isOneOf) {
return true;
}
return (0, utils_1.shouldOmitEmpty)(context, field);
};
exports.getFieldOptionalityForAmino = getFieldOptionalityForAmino;
const isScalarField = (field) => {
return exports.SCALAR_TYPES.includes(field.type);
};
exports.isScalarField = isScalarField;
const isArrayField = (field) => {
return field.rule === 'repeated';
};
exports.isArrayField = isArrayField;
const isEnumField = (field) => {
return field.parsedType?.type === 'Enum';
};
exports.isEnumField = isEnumField;
const isMapField = (field) => {
return field.keyType;
};
exports.isMapField = isMapField;
const getFieldOptionalityForDefaults = (context, field, isOneOf) => {
const fieldDefaultIsOptional = context.pluginValue('prototypes.fieldDefaultIsOptional');
const useOptionalNullable = context.pluginValue('prototypes.useOptionalNullable');
const isScalarDefaultToNullable = !field?.options?.['(gogoproto.nullable)'] && context.pluginValue('prototypes.isScalarDefaultToNullable');
if (field?.options?.['(gogoproto.moretags)'] && (0, exports.getOptionDeprecated)(field?.options?.['(gogoproto.moretags)']) === 'true') {
return true;
}
if ((0, exports.isArrayField)(field) || (0, exports.isEnumField)(field) || !isScalarDefaultToNullable && (0, exports.isScalarField)(field) || (0, exports.isMapField)(field)) {
// these field types are required by default!
if (isOneOf || (useOptionalNullable &&
field?.options?.['(gogoproto.nullable)'])) {
return true;
}
return false;
}
const gogoprotoNullable = field?.options?.['(gogoproto.nullable)'] ?? true;
return isOneOf ||
(useOptionalNullable &&
gogoprotoNullable)
||
(
// this would only happen if previous predicate is false,
// so lets ensure not to override required properties when gogoproto.nullable=false
!useOptionalNullable &&
fieldDefaultIsOptional);
};
exports.getFieldOptionalityForDefaults = getFieldOptionalityForDefaults;
/**
* get deprecated option from string, return true/false as string
* @param input
* @returns string
*/
const getOptionDeprecated = (input) => {
// Regular expression to match deprecated value with optional spaces
const deprecatedRegex = /\s*deprecated:\s*(true|false)\s*/;
// Extract the deprecated value
const match = input.match(deprecatedRegex);
if (match && match[1]) {
return match[1];
}
return null;
};
exports.getOptionDeprecated = getOptionDeprecated;
;