@journeyapps/cloudcode-build
Advanced tools
Comparing version 1.9.6 to 1.9.7-beta1
@@ -1,2 +0,49 @@ | ||
import { Schema } from '@journeyapps/parser-schema'; | ||
import { Type, Schema } from '@journeyapps/parser-schema'; | ||
/** | ||
* Given a Journey type, return a TypeScript type name. | ||
* | ||
* If the type is unknown, we return 'any'. | ||
*/ | ||
export declare function mapType(type: Type | null): any; | ||
export declare function schemaToDefinitions(schema: Schema): string; | ||
/** | ||
* Get a reference to a model type/interface. | ||
* | ||
* "user" => "DB.user". | ||
* "class" => DB._class". | ||
* | ||
* @param modelName Name of the model. | ||
*/ | ||
export declare function typeRef(modelName: string): string; | ||
/** | ||
* Given a model name, return a safe identifier for the model interface. | ||
* | ||
* Generally the interface name should equal the model name. However, in some cases the model name is a reserved | ||
* keyword, in which case we prepend an underscore. | ||
* | ||
* "user" => "user" | ||
* "class" => "_class". | ||
* | ||
* @param name Name of the model. | ||
*/ | ||
export declare function modelInterfaceName(name: string): string; | ||
/** | ||
* Returns true if an identifier is valid as a property name in JavaScript / TypeScript. | ||
* In other words, it can be directly used as obj.prop_name_here, versus the workaround of obj["prop name here"]. | ||
* | ||
* General restrictions are that it cannot start with a number, and cannot contain spaces or special characters. | ||
* @param name - The identifier | ||
*/ | ||
export declare function isValidProperty(name: string): boolean; | ||
/** | ||
* Return a property name safe to embed in a TS definition file. | ||
* | ||
* Where feasible, we return the property directly. If it's not a valid name directly, we wrap it in quotes. | ||
* | ||
* my_prop123 => my_prop123 | ||
* 1time => "1time" | ||
* multiple words => "multiple words" | ||
* | ||
* @param name - The property name. | ||
*/ | ||
export declare function safeProperty(name: string): string; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const reservedKeywords_1 = require("./reservedKeywords"); | ||
const TYPE_MAP = { | ||
@@ -18,6 +19,30 @@ text: 'string', | ||
}; | ||
function isArrayType(type) { | ||
return type.name == 'array'; | ||
} | ||
function isQueryType(type) { | ||
return type.name == 'query'; | ||
} | ||
/** | ||
* Given a Journey type, return a TypeScript type name. | ||
* | ||
* If the type is unknown, we return 'any'. | ||
*/ | ||
function mapType(type) { | ||
if (type.name in TYPE_MAP) { | ||
if (type == null) { | ||
// Safety fallback. | ||
return 'any'; | ||
} | ||
else if (type.name in TYPE_MAP) { | ||
return TYPE_MAP[type.name]; | ||
} | ||
else if (type.isObject) { | ||
return typeRef(type.name); | ||
} | ||
else if (isArrayType(type) && type.objectType) { | ||
return `${typeRef(type.objectType.name)}[]`; | ||
} | ||
else if (isQueryType(type) && type.objectType) { | ||
return `Query<${typeRef(type.objectType.name)}>`; | ||
} | ||
else { | ||
@@ -27,2 +52,3 @@ return 'any'; | ||
} | ||
exports.mapType = mapType; | ||
function indentation(levels) { | ||
@@ -60,6 +86,6 @@ let r = ''; | ||
let attrs = []; | ||
for (let attributeName in model.attributes) { | ||
for (let attributeName of Object.keys(model.attributes)) { | ||
let attribute = model.attributes[attributeName]; | ||
attrs.push(`/** ${attribute.label} (${attribute.sourceTypeName}) */`, `${attributeName}: ${mapType(attribute.type)};`); | ||
if (attribute.type.name == 'attachment') { | ||
attrs.push(`/** ${attribute.label} (${attribute.sourceTypeName}) */`, `${safeProperty(attributeName)}: ${mapType(attribute.type)};`); | ||
if (attribute.type && attribute.type.name == 'attachment') { | ||
attrs.push(`/** ID of ${attribute.label}. */`, `readonly ${attributeName}_id: string;`); | ||
@@ -70,10 +96,16 @@ } | ||
let rel = model.belongsTo[relName]; | ||
attrs.push(`/** Lookup related ${rel.foreignType.label}. */`, `${relName}(): Promise<DB.${rel.foreignType.name}>;`, `/** Set related ${rel.foreignType.label}. */`, `${relName}(value: DB.${rel.foreignType.name}): void;`, `/** ID of related ${rel.foreignType.label}. */`, `${relName}_id: string;`); | ||
if (!rel.foreignType) { | ||
continue; | ||
} | ||
attrs.push(`/** Lookup related ${rel.foreignType.label}. */`, `${safeProperty(relName)}(): Promise<${typeRef(rel.foreignType.name)}>;`, `/** Set related ${rel.foreignType.label}. */`, `${safeProperty(relName)}(value: ${typeRef(rel.foreignType.name)}): void;`, `/** ID of related ${rel.foreignType.label}. */`, `${safeProperty(relName + '_id')}: string;`); | ||
} | ||
for (let relName in model.hasMany) { | ||
let rel = model.hasMany[relName]; | ||
attrs.push(`/** Query for related ${rel.objectType.label}. */`, `readonly ${relName}: Query<DB.${rel.objectType.name}>;`); | ||
if (!rel.objectType) { | ||
continue; | ||
} | ||
attrs.push(`/** Query for related ${rel.objectType.label}. */`, `readonly ${safeProperty(relName)}: Query<${typeRef(rel.objectType.name)}>;`); | ||
} | ||
const modelTs = ` | ||
interface ${modelName} extends DatabaseObject { | ||
interface ${modelInterfaceName(modelName)} extends DatabaseObject { | ||
${indent(attrs)} | ||
@@ -92,3 +124,3 @@ } | ||
interface DB extends Database { | ||
${indent(modelNames.map(name => `${name}: Collection<DB.${name}>;`))} | ||
${indent(modelNames.map(name => `${JSON.stringify(name)}: Collection<${typeRef(name)}>;`))} | ||
} | ||
@@ -109,2 +141,69 @@ | ||
exports.schemaToDefinitions = schemaToDefinitions; | ||
/** | ||
* Get a reference to a model type/interface. | ||
* | ||
* "user" => "DB.user". | ||
* "class" => DB._class". | ||
* | ||
* @param modelName Name of the model. | ||
*/ | ||
function typeRef(modelName) { | ||
return `DB.${modelInterfaceName(modelName)}`; | ||
} | ||
exports.typeRef = typeRef; | ||
/** | ||
* Given a model name, return a safe identifier for the model interface. | ||
* | ||
* Generally the interface name should equal the model name. However, in some cases the model name is a reserved | ||
* keyword, in which case we prepend an underscore. | ||
* | ||
* "user" => "user" | ||
* "class" => "_class". | ||
* | ||
* @param name Name of the model. | ||
*/ | ||
function modelInterfaceName(name) { | ||
// If the name is a reserved word, we prepend an underscore to the type name. | ||
// This only applies to the type, not the model. | ||
// Effectively we'd get `var c: DB._class = DB.class.create()` | ||
if (reservedKeywords_1.isReservedTypeName(name)) { | ||
return `_${name}`; | ||
} | ||
return name; | ||
} | ||
exports.modelInterfaceName = modelInterfaceName; | ||
const PROPERTY_REGEXP = /^(?![0-9])[a-zA-Z0-9$_]+$/; | ||
/** | ||
* Returns true if an identifier is valid as a property name in JavaScript / TypeScript. | ||
* In other words, it can be directly used as obj.prop_name_here, versus the workaround of obj["prop name here"]. | ||
* | ||
* General restrictions are that it cannot start with a number, and cannot contain spaces or special characters. | ||
* @param name - The identifier | ||
*/ | ||
function isValidProperty(name) { | ||
return PROPERTY_REGEXP.test(name); | ||
} | ||
exports.isValidProperty = isValidProperty; | ||
/** | ||
* Return a property name safe to embed in a TS definition file. | ||
* | ||
* Where feasible, we return the property directly. If it's not a valid name directly, we wrap it in quotes. | ||
* | ||
* my_prop123 => my_prop123 | ||
* 1time => "1time" | ||
* multiple words => "multiple words" | ||
* | ||
* @param name - The property name. | ||
*/ | ||
function safeProperty(name) { | ||
// We may get invalid property names. In that case the datamodel should have validation errors, but we still | ||
// attempt to handle them gracefully here, by wrapping them in quotes. | ||
if (isValidProperty(name)) { | ||
return name; | ||
} | ||
else { | ||
return JSON.stringify(name); | ||
} | ||
} | ||
exports.safeProperty = safeProperty; | ||
//# sourceMappingURL=datamodel.js.map |
@@ -1,5 +0,6 @@ | ||
import { schemaToDefinitions } from './datamodel'; | ||
import { schemaToDefinitions, mapType, typeRef, safeProperty } from './datamodel'; | ||
import { buildTypescript } from './build'; | ||
import { ProcessError } from './ProcessError'; | ||
export { buildTypescript, ProcessError, schemaToDefinitions }; | ||
export { buildTypescript, ProcessError, schemaToDefinitions, mapType, typeRef, safeProperty }; | ||
export { isReservedTypeName } from './reservedKeywords'; | ||
export interface BuildOptions { | ||
@@ -6,0 +7,0 @@ datamodel: string; |
@@ -5,2 +5,5 @@ "use strict"; | ||
exports.schemaToDefinitions = datamodel_1.schemaToDefinitions; | ||
exports.mapType = datamodel_1.mapType; | ||
exports.typeRef = datamodel_1.typeRef; | ||
exports.safeProperty = datamodel_1.safeProperty; | ||
const build_1 = require("./build"); | ||
@@ -10,2 +13,4 @@ exports.buildTypescript = build_1.buildTypescript; | ||
exports.ProcessError = ProcessError_1.ProcessError; | ||
var reservedKeywords_1 = require("./reservedKeywords"); | ||
exports.isReservedTypeName = reservedKeywords_1.isReservedTypeName; | ||
const path = require("path"); | ||
@@ -12,0 +17,0 @@ const fs = require("fs"); |
{ | ||
"name": "@journeyapps/cloudcode-build", | ||
"version": "1.9.6", | ||
"version": "1.9.7-beta1", | ||
"main": "./lib/index.js", | ||
@@ -32,3 +32,3 @@ "license": "MIT", | ||
], | ||
"gitHead": "53b2dae1865d28acf340ec097768c5eb19980464" | ||
"gitHead": "825341c721aa9d77eb92c777bb26939b3517417b" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
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
26349
21
495
2