From 0654ef13358acb9df541ff5188719af643d10843 Mon Sep 17 00:00:00 2001 From: Adam Charron Date: Sat, 29 Oct 2016 15:52:13 -0400 Subject: [PATCH 01/19] Create nodal.d.ts --- nodal/nodal.d.ts | 1010 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1010 insertions(+) create mode 100644 nodal/nodal.d.ts diff --git a/nodal/nodal.d.ts b/nodal/nodal.d.ts new file mode 100644 index 0000000000..fe75e8e5b7 --- /dev/null +++ b/nodal/nodal.d.ts @@ -0,0 +1,1010 @@ +// Type definitions for nodal 0.12.8 +// Project: https://github.com/keithwhor/nodal +// Definitions by: Adam Charron +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +/// +/// + +import * as fxn from 'fxn'; + +export class APIConstructor { + format(obj: any, arrInterface?: string[]): { + meta: { + total: number; + count: number; + offset: number; + error: any; + summary: string | null | undefined; + resource: any; + }; + data: any; + }; + meta(total: number, count: number, offset: number, error: any, summary?: string | null, resource?: any): { + total: number; + count: number; + offset: number; + error: any; + summary: string | null | undefined; + resource: any; + }; + error(message: string, details: string): { + meta: { + total: number; + count: number; + offset: number; + error: any; + summary: string | null | undefined; + resource: any; + }; + data: never[]; + }; + spoof(obj: any, useResource?: boolean): { + meta: { + total: number; + count: number; + offset: number; + error: any; + summary: string | null | undefined; + resource: any; + }; + data: any; + }; + response(itemArray: any, arrInterface: any, useResource?: boolean): { + meta: { + total: number; + count: number; + offset: number; + error: any; + summary: string | null | undefined; + resource: any; + }; + data: any; + }; + resourceFromArray(arr: any[]): { + name: string; + fields: any[]; + }; + resourceFromModelArray(modelArray: any, arrInterface: any): any; +} + +export const API: APIConstructor; + +export const APIResource: any; + +export class Application extends fxn.Application { + constructor(); + /** + * HTTP Error + */ + error(req: any, res: any, start: any, status: number, message: string, err: any): void; +} + +export class Controller extends fxn.Controller { + /** + * Set HTTP status code for this response. If OPTIONS mode, default to 200. + * @param {Number} code + */ + status(value: number): boolean; + /** + * Using API formatting, send an http.ServerResponse indicating there was a Bad Request (400) + * @param {string} msg Error message to send + * @param {Object} details Any additional details for the error (must be serializable) + * @return {boolean} + */ + badRequest(msg: string, details: any): boolean; + /** + * Using API formatting, send an http.ServerResponse indicating there was an Unauthorized request (401) + * @param {string} msg Error message to send + * @param {Object} details Any additional details for the error (must be serializable) + * @return {boolean} + */ + unauthorized(msg: string, details: any): boolean; + /** + * Using API formatting, send an http.ServerResponse indicating the requested resource was Not Found (404) + * @param {string} msg Error message to send + * @param {Object} details Any additional details for the error (must be serializable) + * @return {boolean} + */ + notFound(msg: string, details: any): boolean; + /** + * Endpoint not implemented + * @param {string} msg Error message to send + * @param {Object} details Any additional details for the error (must be serializable) + * @return {boolean} + */ + notImplemented(msg: string, details: any): boolean; + /** + * Using API formatting, send an http.ServerResponse indicating there were Too Many Requests (429) (i.e. the client is being rate limited) + * @param {string} msg Error message to send + * @param {Object} details Any additional details for the error (must be serializable) + * @return {boolean} + */ + tooManyRequests(msg: string, details: any): boolean; + /** + * Using API formatting, send an http.ServerResponse indicating there was an Internal Server Error (500) + * @param {string} msg Error message to send + * @param {Object} details Any additional details for the error (must be serializable) + * @return {boolean} + */ + error(msg: string, details: any): boolean; + /** + * Using API formatting, generate an error or respond with model / object data. + * @param {Error|Object|Array|Nodal.Model|Nodal.ModelArray} data Object to be formatted for API response + * @param {optional Array} The interface to use for the data being returned, if not an error. + * @return {boolean} + */ + respond(data: Error | Object | any[] | Model | ModelArray, arrInterface?: string[]): boolean; +} + +export interface IComparison { + [item: string]: any; + __order?: string; + __offset?: number; + __count?: number; +} + +export class Composer { + db: Database; + Model: T; + private _parent; + private _command; + /** + * Created by Model#query, used for composing SQL queries based on Models + * @param {Nodal.Model} Model The model class the composer is querying from + * @param {Nodal.Composer} [parent=null] The composer's parent (another composer instance) + */ + constructor(modelConstructor: typeof Model, parent?: Composer); + /** + * Given rows with repeated data (due to joining in multiple children), + * return only parent models (but include references to their children) + * @param {Array} rows Rows from sql result + * @param {Boolean} grouped Are these models grouped, if so, different procedure + * @return {Nodal.ModelArray} + * @private + */ + private __parseModelsFromRows__(rows, grouped?); + /** + * Collapses linked list of queries into an array (for .reduce, .map etc) + * @return {Array} + * @private + */ + private __collapse__(); + /** + * Removes last limit command from a collapsed array of composer commands + * @param {Array} [composerArray] Array of composer commands + * @return {Array} + * @private + */ + private __removeLastLimitCommand__(composerArray); + /** + * Gets last limit command from a collapsed array of composer commands + * @param {Array} [composerArray] Array of composer commands + * @return {Array} + * @private + */ + private __getLastLimitCommand__(composerArray); + /** + * Determines whether this composer query represents a grouped query or not + * @return {Boolean} + * @private + */ + private __isGrouped__(); + /** + * Reduces an array of composer queries to a single query information object + * @param {Array} [composerArray] + * @return {Object} Looks like {commands: [], joins: []} + * @private + */ + private __reduceToQueryInformation__(composerArray); + /** + * Reduces an array of commands from query informtion to a SQL query + * @param {Array} [commandArray] + * @param {Array} [includeColumns=*] Which columns to include, includes all by default + * @return {Object} Looks like {sql: [], params: []} + * @private + */ + private __reduceCommandsToQuery__(commandArray, includeColumns?); + /** + * Retrieve all joined column data for a given join + * @param {string} joinName The name of the join relationship + * @private + */ + private __joinedColumns__(joinName); + /** + * Generate a SQL query and its associated parameters from the current composer instance + * @param {Array} [includeColumns=*] Which columns to include, includes all by default + * @param {boolean} [disableJoins=false] Disable joins if you just want a subset of data + * @return {Object} Has "params" and "sql" properties. + * @private + */ + private __generateQuery__(includeColumns?, disableJoins?); + /** + * Generate a SQL count query + * @param {boolean} [useLimit=false] Generates COUNT using limit command as well + * @return {Object} Has "params" and "sql" properties. + * @private + */ + private __generateCountQuery__(useLimit?); + /** + * Add Joins to a query from queryInfo + * @param {Object} query Must be format {sql: '', params: []} + * @param {Object} queryInfo Must be format {commands: [], joins: []} + * @param {Array} [includeColumns=*] Which columns to include, includes all by default + * @return {Object} Has "params" and "sql" properties. + * @private + */ + private __addJoinsToQuery__(query, queryInfo, includeColumns?); + /** + * When using Composer#where, format all provided comparisons + * @param {Object} comparisons Comparisons object. {age__lte: 27}, for example. + * @param {Nodal.Model} Model the model to use as the basis for comparison. Default to current model. + * @return {Array} + * @private + */ + private __parseComparisons__(comparisons, model?); + private __filterHidden__(modelConstructor, comparisonsArray); + /** + * Add comparisons to SQL WHERE clause. Does not allow filtering if Model.hides() has been called. + * @param {Object} comparisons Comparisons object. {age__lte: 27}, for example. + * @return {Nodal.Composer} new Composer instance + */ + safeWhere(...comparisonsArray: IComparison[]): this; + /** + * Join in a relationship. Filters out hidden fields from comparisons. + * @param {string} joinName The name of the joined relationship + * @param {array} comparisonsArray comparisons to perform on this join (can be overloaded) + */ + safeJoin(joinName: string, ...comparisonsArray: IComparison[]): this; + /** + * Add comparisons to SQL WHERE clause. + * @param {Object} comparisons Comparisons object. {age__lte: 27}, for example. + * @return {Nodal.Composer} new Composer instance + */ + where(...comparisonsArray: IComparison[]): this; + /** + * Order by field belonging to the current Composer instance's model. + * @param {string} field Field to order by + * @param {string} direction Must be 'ASC' or 'DESC' + * @return {Nodal.Composer} new Composer instance + */ + orderBy(field: string, direction?: 'ASC' | 'DSC' | any): this; + /** + * Limit to an offset and count + * @param {number} offset The offset at which to set the limit. If this is the only argument provided, it will be the count instead. + * @param {number} count The number of results to be returned. Can be omitted, and if omitted, first argument is used for count. + * @return {Nodal.Composer} new Composer instance + */ + limit(offset: number | string, count?: number | string): this; + /** + * Join in a relationship. + * @param {string} joinName The name of the joined relationship + * @param {array} comparisonsArray comparisons to perform on this join (can be overloaded) + */ + join(joinName: string, comparisonsArray?: IComparison[] | IComparison, orderBy?: 'ASC' | 'DESC', count?: number, offset?: number): this; + /** + * Groups by a specific field, or a transformation on a field + * @param {String} column The column to group by + */ + groupBy(column: string): this; + /** + * Aggregates a field + * @param {String} alias The alias for the new aggregate field + * @param {Function} transformation The transformation to apply to create the aggregate + */ + aggregate(alias: string, transformation?: Function): this; + /** + * Counts the results in the query + * @param {function} callback Supplied with an error and the integer value of the count + */ + count(callback: (err: Error, count: number) => void): void; + /** + * Execute the query you've been composing. + * @param {function({Error}, {Nodal.ModelArray})} callback The method to execute when the query is complete + */ + end(callback: (err: Error, modelArray: ModelArray) => void): void; + /** + * Shortcut for .limit(1).end(callback) that only returns a model object or error if not found + * @param {Function} callback Callback to execute, provides an error and model parameter + */ + first(callback: (err: Error, model: Model) => void): void; + /** + * Execute query as an update query, changed all fields specified. + * @param {Object} fields The object containing columns (keys) and associated values you'd like to update + * @param {function({Error}, {Nodal.ModelArray})} callback The callback for the update query + */ + update(fields: IAnyObject, callback: (err: Error, modelArray: ModelArray) => void): void; +} + +export const CLI: any; + +export class Daemon extends fxn.Daemon { + constructor(); + error(req: any, res: any, err: any): void; +} + +export class Database { + adapter: any; + __logColorFuncs: Function[]; + private _useLogColor; + constructor(); + connect(cfg: any): boolean; + close(callback: Function): boolean; + log(sql: string, params?: any, time?: number): boolean; + info(message: string): void; + error(message: string): boolean; + query(...args: any[]): void; + transaction(...args: any[]): void; + drop(): void; + create(): void; +} + +export class GraphQuery { + private 'constructor'; + identifier: string; + name: string; + Model: typeof Model; + structure: any; + joins: any; + /** + * Create a GraphQuery object + * @param {String} str The query to execute + * @param {Number} maxDepth The maximum depth of graph to traverse + * @param {Nodal.Model} [Model=null] The Model to base your query around (used for testing) + */ + constructor(str: string, maxDepth: number, mModel?: typeof Model); + /** + * Create and execute a GraphQuery object + * @param {String} str The query to execute + * @param {Number} maxDepth The maximum depth of graph to traverse + * @param {Function} callback The function to execute upon completion + */ + static query(str: string, maxDepth: number, callback: Function): boolean; + /** + * Parse syntax tree of a GraphQL query + */ + static parseSyntaxTree(str: string, state?: string, arr?: any[]): any; + /** + * Fully parse a GraphQL query, get necessary joins to make in SQL + */ + static parse(str: string, max: number): { + structure: any; + joins: {}; + }; + /** + * Format a parsed syntax tree in a way that the Composer expects + */ + static formatTree(tree: any[], max: number, joins: any, parents?: any): any[]; + /** + * Query the GraphQuery object from the database + * @param {Function} callback The function to execute upon completion + */ + query(callback: Function): this; +} + +export interface IArrayMetadata { + total?: number; + offset?: number; + [other: string]: any; +} + +export class ItemArray extends Array { + private _meta; + constructor(); + static from(arr: Object[]): ItemArray<{}>; + setMeta(data: IArrayMetadata): IArrayMetadata; + toObject(arrInterface: string[]): Object; +} + +export class Migration { + private db; + private id; + private schema; + constructor(db: Database); + up(): string[]; + down(): string[]; + executeUp(callback: (err: Error) => void): void; + executeDown(callback: (err: Error) => void, prevId?: string): void; + createTable(table: string, arrFieldData: Object[], modelName: string): any; + dropTable(table: string): any; + renameTable(table: string, newTableName: string, renameModel: string, newModelName: string): any; + alterColumn(table: string, column: string, type: DataType, properties: IColumnProperties): any; + addColumn(table: string, column: string, type: DataType, properties: IColumnProperties): any; + dropColumn(table: string, column: string): any; + renameColumn(table: string, column: string, newColumn: string): any; + createIndex(table: string, column: string, type: DataType): any; + dropIndex(table: string, column: string): any; + addForeignKey(table: string, referenceTable: string): any; + dropForeignKey(table: string, referenceTable: string): any; +} + +export const mime: any; + +/** + * Model Stuff + */ +export interface IErrorsObject { + _query?: any; + [field: string]: string[]; +} +export interface ICalculation { + fields: string[]; + calculate: Function; +} +export interface ICalculations { + [calculations: string]: ICalculation; +} +export class Model { + 'constructor': typeof Model; + db: Database | any; + schema: { + table: string; + columns: IColumn[]; + }; + data: any; + externalInterface: string[]; + aggregateBy: { + id: string; + created_at: string; + updated_at: string; + }; + formatters: IAnyObject; + _inStorage: boolean; + private _isSeeding; + private _changed; + private _errors; + private _joinsList; + private _joinsCache; + private _data; + _calculations: ICalculations; + private static _relationshipCache; + _validations: IAnyObject; + _validationsList: any[]; + _calculationsList: string[]; + _verificationsList: any; + _hides: IAnyObject; + _table: string; + _columnLookup: { + [key: string]: any; + }; + _columnNames: string[]; + _columns: IColumn[]; + _relationshipCache: IAnyObject; + constructor(modelData: Object, fromStorage?: boolean, fromSeed?: boolean); + /** + * Indicates whethere or not the model is currently represented in hard storage (db). + * @return {boolean} + */ + inStorage(): boolean; + /** + * Indicates whethere or not the model is being generated from a seed. + * @return {boolean} + */ + isSeeding(): boolean; + /** + * Tells us whether a model field has changed since we created it or loaded it from storage. + * @param {string} field The model field + * @return {boolean} + */ + hasChanged(field: string): boolean; + /** + * Provides an array of all changed fields since model was created / loaded from storage + * @return {Array} + */ + changedFields(): string[]; + /** + * Creates an error object for the model if any validations have failed, returns null otherwise + * @return {Error} + */ + errorObject(): IExtendedError | null; + /** + * Tells us whether or not the model has errors (failed validations) + * @return {boolean} + */ + hasErrors(): boolean; + /** + * Gives us an error object with each errored field as a key, and each value + * being an array of failure messages from the validators + * @return {Object} + */ + getErrors(): IErrorsObject; + /** + * Reads new data into the model. + * @param {Object} data Data to inject into the model + * @return {this} + */ + read(data: IAnyObject): this; + /** + * Converts a value to its intended format based on its field. Returns null if field not found. + * @param {string} field The field to use for conversion data + * @param {any} value The value to convert + */ + convert(field: string, value: any): any; + /** + * Grabs the path of the given relationship from the RelationshipGraph + * @param {string} name the name of the relationship + */ + relationship(name: string): RelationshipPath; + /** + * Sets specified field data for the model. Logs and validates the change. + * @param {string} field Field to set + * @param {any} value Value for the field + */ + set(field: string, value: any): any; + /** + * Set a joined object (Model or ModelArray) + * @param {string} field The field (name of the join relationship) + * @param {Model|ModelArray} value The joined model or array of models + */ + setJoined(field: string, value: ModelArray | Model): Model | ModelArray; + /** + * Calculate field from calculations (assumes it exists) + * @param {string} field Name of the calculated field + */ + calculate(field: string): void; + /** + * Retrieve field data for the model. + * @param {string} field Field for which you'd like to retrieve data. + */ + get(field: string, ignoreFormat?: boolean): any; + /** + * Retrieves joined Model or ModelArray + * @param {String} joinName the name of the join (list of connectors separated by __) + */ + joined(joinName: string): Model | ModelArray; + /** + * Retrieve associated models joined this model from the database. + * @param {function({Error} err, {Nodal.Model|Nodal.ModelArray} model_1, ... {Nodal.Model|Nodal.ModelArray} model_n)} + * Pass in a function with named parameters corresponding the relationships you'd like to retrieve. + * The first parameter is always an error callback. + */ + include(callback: (err: Error, ...models: (Model | ModelArray)[]) => void): void; + /** + * Creates a plain object from the Model, with properties matching an optional interface + * @param {Array} arrInterface Interface to use for object creation + */ + toObject(arrInterface?: any[]): any; + /** + * Get the table name for the model. + * @return {string} + */ + tableName(): string; + /** + * Determine if the model has a specified field. + * @param {string} field + * @return {boolean} + */ + hasField(field: string): boolean; + /** + * Retrieve the schema field data for the specified field + * @param {string} field + * @return {Object} + */ + getFieldData(field: string): any; + /** + * Retrieve the schema data type for the specified field + * @param {string} field + * @return {string} + */ + getDataTypeOf(field: string): { + convert: Function; + }; + /** + * Determine whether or not this field is an Array (PostgreSQL supports this) + * @param {string} field + * @return {boolean} + */ + isFieldArray(field: string): boolean; + /** + * Determine whether or not this field is a primary key in our schema + * @param {string} field + * @return {boolean} + */ + isFieldPrimaryKey(field: string): boolean; + /** + * Retrieve the defaultValue for this field from our schema + * @param {string} field + * @return {any} + */ + fieldDefaultValue(field: string): any; + /** + * Retrieve an array of fields for our model + * @return {Array} + */ + fieldList(): string[]; + /** + * Retrieve our field schema definitions + * @return {Array} + */ + fieldDefinitions(): IColumn[]; + /** + * Set an error for a specified field (supports multiple errors) + * @param {string} key The specified field for which to create the error (or '*' for generic) + * @param {string} message The error message + * @return {boolean} + */ + setError(key: string, message: string): boolean; + /** + * Clears all errors for a specified field + * @param {string} key The specified field for which to create the error (or '*' for generic) + * @return {boolean} + */ + clearError(key: string): boolean; + __generateSaveQuery__(): { + sql: any; + params: any; + }; + /** + * Runs all verifications before saving + * @param {function} callback Method to execute upon completion. Returns true if OK, false if failed + * @private + */ + __verify__(callback: Function): any; + /** + * Saves model to database + * @param {function} callback Method to execute upon completion, returns error if failed (including validations didn't pass) + * @private + */ + private __save__(callback); + /** + * Destroys model and cascades all deletes. + * @param {function} callback method to run upon completion + */ + destroyCascade(callback: Function): void; + /** + * Logic to execute before a model gets destroyed. Intended to be overwritten when inherited. + * @param {Function} callback Invoke with first argument as an error if failure. + */ + beforeDestroy(callback: Function): void; + /** + * Logic to execute after a model is destroyed. Intended to be overwritten when inherited. + * @param {Function} callback Invoke with first argument as an error if failure. + */ + afterDestroy(callback: Function): void; + /** + * Destroys model reference in database. + * @param {function({Error} err, {Nodal.Model} model)} callback + * Method to execute upon completion, returns error if failed + */ + destroy(callback: Function): void; + /** + * Logic to execute before a model saves. Intended to be overwritten when inherited. + * @param {Function} callback Invoke with first argument as an error if failure. + */ + beforeSave(callback: Function): void; + /** + * Logic to execute after a model saves. Intended to be overwritten when inherited. + * @param {Function} callback Invoke with first argument as an error if failure. + */ + afterSave(callback: Function): void; + /** + * Save a model (execute beforeSave and afterSave) + * @param {Function} callback Callback to execute upon completion + */ + save(callback: Function): void; + /** + * Runs an update query for this specific model instance + * @param {Object} fields Key-value pairs of fields to update + * @param {Function} callback Callback to execute upon completion + */ + update(fields: IAnyObject, callback: Function): void; + static find(id: number, callback: (err: IExtendedError, model?: Model) => void): void; + static findBy(field: string, value: any, callback: (err: IExtendedError, model?: Model) => void): void; + /** + * Creates a new model instance using the provided data. + * @param {object} data The data to load into the object. + * @param {function({Error} err, {Nodal.Model} model)} callback The callback to execute upon completion + */ + static create(data: IAnyObject, callback: (err: IExtendedError, model?: Model) => void): void; + /** + * Finds a model with a provided field, value pair. Returns the first found. + * @param {string} field Name of the field + * @param {object} data Key-value pairs of Model creation data. Will use appropriate value to query for based on "field" parametere. + * @param {function({Error} err, {Nodal.Model} model)} callback The callback to execute upon completion + */ + static findOrCreateBy(field: string, data: IAnyObject, callback: (err: IExtendedError | null, model?: Model) => void): void; + /** + * Finds and updates a model with a specified id. Return a notFound error if model does not exist. + * @param {number} id The id of the model you're looking for + * @param {object} data The data to load into the object. + * @param {function({Error} err, {Nodal.Model} model)} callback The callback to execute upon completion + */ + static update(id: number, data: IAnyObject, callback: (err: IExtendedError, model?: Model) => void): void; + /** + * Finds and destroys a model with a specified id. Return a notFound error if model does not exist. + * @param {number} id The id of the model you're looking for + * @param {function({Error} err, {Nodal.Model} model)} callback The callback to execute upon completion + */ + static destroy(id: number, callback: (err: IExtendedError, model?: Model) => void): void; + /** + * Creates a new Composer (ORM) instance to begin a new query. + * @param {optional Nodal.Database} db Deprecated - provide a database to query from. Set the model's db in its constructor file, instead. + * @return {Nodal.Composer} + */ + static query(db?: Database): Composer; + /** + * Get the model's table name + * @return {string} + */ + static table(): string; + /** + * Get the model's column data + * @return {Array} + */ + static columns(): IColumn[]; + /** + * Get the model's column names (fields) + * @return {Array} + */ + static columnNames(): string[]; + /** + * Get the model's column lookup data + * @return {Object} + */ + static columnLookup(): IAnyObject; + /** + * Check if the model has a column name in its schema + * @param {string} columnName + */ + static hasColumn(columnName: string): boolean; + /** + * Return the column schema data for a given name + * @param {string} columnName + */ + static column(columnName: string): any; + /** + * Set the database to be used for this model + * @param {Nodal.Database} db + */ + static setDatabase(db: Database): void; + /** + * Set the schema to be used for this model + * @param {Object} schema + */ + static setSchema(schema: { + table: string; + columns: IColumn[]; + }): void; + /** + * FIXME + */ + static relationships(): RelationshipNode; + /**` + * FIXME + */ + static relationship(name: string): RelationshipPath; + /** + * Sets a joins relationship for the Model. Sets joinedBy relationship for parent. + * @param {class Nodal.Model} Model The Model class which your current model belongs to + * @param {Object} [options={}] + * "name": The string name of the parent in the relationship (default to camelCase of Model name) + * "via": Which field in current model represents this relationship, defaults to `${name}_id` + * "as": What to display the name of the child as when joined to the parent (default to camelCase of child name) + * "multiple": Whether the child exists in multiples for the parent (defaults to false) + */ + static joinsTo(modelClass: typeof Model, options: { + name?: string; + via?: string; + as?: string; + multiple?: boolean; + }): RelationshipEdge | null; + /** + * Create a validator. These run synchronously and check every time a field is set / cleared. + * @param {string} field The field you'd like to validate + * @param {string} message The error message shown if a validation fails. + * @param {function({any} value)} fnAction the validation to run - first parameter is the value you're testing. + */ + static validates(field: string, message: string, fnAction: (value: any) => void): void; + /** + * Creates a verifier. These run asynchronously, support multiple fields, and check every time you try to save a Model. + * @param {string} message The error message shown if a validation fails. + * @param {function} fnAction The asynchronous verification method. The last argument passed is always a callback, + * and field names are determined by the argument names. + */ + static verifies(message: string, fnAction: Function): void; + /** + * Create a calculated field (in JavaScript). Must be synchronous. + * @param {string} calcField The name of the calculated field + * @param {function} fnCalculate The synchronous method to perform a calculation for. + * Pass the names of the (non-computed) fields you'd like to use as parameters. + */ + static calculates(calcField: string, fnCompute: Function): void; + /** + * Hides fields from being output in .toObject() (i.e. API responses), even if asked for + * @param {String} field + */ + static hides(field: string): boolean; + /** + * Tells us if a field is hidden (i.e. from API queries) + * @param {String} field + */ + static isHidden(field: string): any; + /** + * Prepare model for use + * @private + */ + private __initialize__(); + __load__(data: any, fromStorage?: boolean, fromSeed?: boolean): this; + /** + * Validates provided fieldList (or all fields if not provided) + * @private + * @param {optional Array} fieldList fields to validate + */ + private __validate__(field?); + /** + * Sets specified field data for the model, assuming data is safe and does not log changes + * @param {string} field Field to set + * @param {any} value Value for the field + */ + public __safeSet__(field, value); + /** + * Destroys model reference in database + * @param {function} callback Method to execute upon completion, returns error if failed + * @private + */ + private __destroy__(callback); +} + +export class ModelArray extends ItemArray { + Model: typeof Model; + constructor(modelConstructor: typeof Model); + static from(arr: Model[]): ModelArray; + toObject(arrInterface?: string[]): any; + has(model: Model): boolean; + readAll(data: Object): boolean; + setAll(field: string, value: string): boolean; + destroyAll(callback: Function): void; + destroyCascade(callback: Function): void; + saveAll(callback: Function): Function | undefined; + private __saveAll__(callback); +} + +export interface IModelData { + [modelName: string]: any[]; +} +/** + * Factory for creating models + * @class + */ +export class ModelFactory { + private Model; + /** + * Create the ModelFactory with a provided Model to use as a reference. + * @param {Nodal.Model} modelConstructor Must pass the constructor for the type of ModelFactory you wish to create. + */ + constructor(modelConstructor: typeof Model); + /** + * Loads all model constructors in your ./app/models directory into an array + * @return {Array} Array of model Constructors + */ + static loadModels(): any[]; + /** + * Creates new factories from a supplied array of Models, loading in data keyed by Model name + * @param {Array} Models Array of model constructors you wish to reference + * @param {Object} objModelData Keys are model names, values are arrays of model data you wish to create + * @param {Function} callback What to execute upon completion + */ + static createFromModels(Models: (typeof Model)[], objModelData: IModelData, callback: Function): void; + /** + * Populates a large amount of model data from an Object. + * @param {Array} Models Array of Model constructors + */ + static populate(objModelData: IModelData, callback: Function): void; + /** + * Creates models from an array of Objects containing the model data + * @param {Array} arrModelData Array of objects to create model data from + */ + create(arrModelData: IModelData[], callback: Function): void; +} + +export interface IOptions { + name: string; + multiple: boolean; + as: string; + via: string; +} +export class RelationshipPath { + private 'constructor'; + path: (RelationshipEdge | RelationshipNode)[]; + constructor(path: (RelationshipEdge | RelationshipNode)[]); + toString(): string; + joinName(reverse?: boolean): string; + add(node: RelationshipNode, edge: RelationshipEdge): RelationshipPath; + getModel(): typeof Model; + multiple(): boolean; + immediateMultiple(): boolean; + joins(alias?: string | null, firstTable?: string): IJoin[]; +} +export class RelationshipNode { + Graph: RelationshipGraph; + Model: typeof Model; + edges: RelationshipEdge[]; + constructor(Graph: RelationshipGraph, mModel: typeof Model); + toString(): string; + joinsTo(mModel: typeof Model, options: IOptions): RelationshipEdge | null; + childEdges(): RelationshipEdge[]; + cascade(): RelationshipPath[]; + findExplicit(pathname: string): RelationshipPath | null; + find(name: string): RelationshipPath | null; +} +export class RelationshipEdge { + id: number; + parent: RelationshipNode; + child: RelationshipNode; + options: IOptions; + constructor(parent: RelationshipNode, child: RelationshipNode, options: IOptions); + toString(): string; + hasChild(child: RelationshipNode): boolean; + hasParent(parent: RelationshipNode): boolean; + opposite(node: RelationshipNode): RelationshipNode | null; +} +export class RelationshipGraph { + nodes: RelationshipNode[]; + edges: RelationshipEdge[]; + constructor(); + of(mModel: typeof Model): RelationshipNode; +} +export class Router extends fxn.Router { +} +export class Scheduler extends fxn.Scheduler { +} + +/** + * Random types used across multiple classes. + */ +export interface IAnyObject { + [prop: string]: any; +} +export interface IExtendedError extends Error { + notFound?: boolean; + details?: Object; +} +export interface IColumn { + name: string; + type: DataType; + properties: IColumnProperties; +} +export interface ISchema { + table: string; + columns: IColumn[]; +} +export interface IJoin { + prevColumn?: string; + joinColumn?: string; + joinTable: string; + prevTable: string; + name?: string; + key?: string; + multiple?: boolean; + columns?: string[]; + columnsObject?: Object; + cachedModel?: Model; + joinAlias?: string; + multiFilter?: any; + prevAlias?: string; + orderBy?: any; + offset?: number; + count?: number; +} +export type Query = any; +export interface IColumnProperties { + length?: number | null; + nullable?: boolean; + primary_key?: 0 | 1 | boolean; + auto_increment?: boolean; + unique?: 0 | 1 | boolean; + array?: boolean; + defaultValue?: any; +} +export interface IArrInterface { + [item: string]: [string]; +} +export type InterfaceType = IArrInterface | string; +export type DataType = 'serial' | 'int' | 'currency' | 'float' | 'string' | 'text' | 'datetime' | 'boolean' | 'json'; + +export const my: { + Config?: any; + Schema?: any; + bootstrapper?: any; +}; +export const require: NodeRequire; From 01e67481eebeb5929d3b7c9277825e4ec7a7e335 Mon Sep 17 00:00:00 2001 From: Adam Charron Date: Sat, 29 Oct 2016 15:52:29 -0400 Subject: [PATCH 02/19] Create fxn.d.ts --- nodal/fxn.d.ts | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 nodal/fxn.d.ts diff --git a/nodal/fxn.d.ts b/nodal/fxn.d.ts new file mode 100644 index 0000000000..a7c5058c2a --- /dev/null +++ b/nodal/fxn.d.ts @@ -0,0 +1,65 @@ +/// + +declare module "fxn" { + namespace fxn { + type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'OPTIONS'; + + interface HttpHeaders { + [item: string]: string; + } + + abstract class Controller { + + protected _method: HttpMethod; + protected _path: string; + protected _requestHeaders: Object; + protected _headers: Object; + protected _status: number; + protected _responder: Function; + protected _securityPolicies: Object; + protected params: any; + + constructor(path: string, method: string, requestHeaders: Object, params: Object, responder: Function); + convertMethod(method: HttpMethod, id: number): string; + run(): void; + notImplemented(msg: string, details: Object): boolean; + before(): void; + after(): void; + get(): void; + put(): void; + post(): void; + del(): void; + options(): void; + index(): void; + show(): void; + update(): void; + create(): void; + destroy(): void; + status(value: number): boolean; + setHeaders(): HttpHeaders; + setHeader(key: string, value: string): string; + appendHeader(key: string, value: string): string; + getHeader(key: string, value: string): string; + code(code: number): number; + getStatus(): number; + render(data: Buffer | String | Object): void; + allowOrigin(value: string): this; + securityPolicy(directive: string, src: string): string; + redirect(location: string): void; + } + + abstract class Daemon { + constructor(string: string); + } + + abstract class Application { + constructor(string: string); + send: Function; + } + + abstract class Router {} + abstract class Scheduler {} + } + + export = fxn; +} From 9fb73ef5b33011e51d0d0f32074c051cb91f61a0 Mon Sep 17 00:00:00 2001 From: Adam Charron Date: Sat, 29 Oct 2016 15:52:48 -0400 Subject: [PATCH 03/19] Create nodal-tests.ts --- nodal/nodal-tests.ts | 154 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 nodal/nodal-tests.ts diff --git a/nodal/nodal-tests.ts b/nodal/nodal-tests.ts new file mode 100644 index 0000000000..e88a892dda --- /dev/null +++ b/nodal/nodal-tests.ts @@ -0,0 +1,154 @@ +import * as Nodal from './nodal.d'; + +let BlogPost: typeof Nodal.Model; + +class User extends Nodal.Model { + public beforeSave (callback: (err?: Error) => void) { + if (!this.hasErrors() && this.hasChanged('password')) { + callback(); + } else { + callback(new Error("Has errors")); + } + } + + public verifyPassword (unencrypted: string, callback: (model: Nodal.Model, err: Error, result: boolean) => void) { + + } +} + +User.setDatabase(Nodal.require('db/main.js')); +User.setSchema(Nodal.my.Schema.models.User); + +User.validates('username', 'must exist', v => v); +User.validates('password', 'must be at least 5 characters in length', v => v && v.length >= 5); + +class BlogPostsController extends Nodal.Controller { + index() { + BlogPost.query() + .join('user') + .join('comments') + .where(this.params.query) + .end((err, blogPosts) => { + this.respond(err || blogPosts); + }); + } + + show() { + BlogPost.find(this.params.route.id, (err, blogPost) => this.respond(err || blogPost)); + } + + create() { + BlogPost.create(this.params.body, (err, blogPost) => this.respond(err || blogPost)); + } + + update() { + BlogPost.update(this.params.route.id, this.params.body, (err, blogPost) => this.respond(err || blogPost)); + } + + destroy() { + BlogPost.destroy(this.params.route.id, (err, blogPost) => this.respond(err || blogPost)) + } +} + +type generateParam = string | number; + +class AccessToken extends Nodal.Model { + + constructor(modelData: Object) { + super(modelData); + + } + + public static generateAccessTokenString (...args: generateParam[]) { + return "thing"; + } + + public static login (params, callback: Function) { + if (params.body.grant_type !== 'password') { + return callback(new Error('Must supply grant_type')); + } + + User.query() + .where({username: params.body.username}) + .end((err, users) => { + if (err || !users || !users.length) { + return callback(new Error('User not found')); + } + + const user = users[0]; + + user.verifyPassword(params.body.password, (error, result) => { + if (error || !result) { + return callback(new Error('Invalid credentials')); + } + + new AccessToken({ + user_id: user.get('id'), + access_token: this.generateAccessTokenString(user.get('id'), user.get('email'), new Date().valueOf()), + token_type: 'bearer', + expires_at: (new Date(new Date().valueOf() + (30 * 24 * 60 * 60 * 1000))), + ip_address: params.ip_address + }).save(callback); + }); + }); + } + + public static verify (params, callback: Function) { + this.query() + .join('user') + .where({ + access_token: params.auth.access_token, + expires_at__gte: new Date() + }) + .end((err, accessTokens) => { + if (err || !accessTokens || !accessTokens.length) { + return callback(new Error('Your access token is invalid.')); + } + + const accessToken = accessTokens[0]; + + if (!accessToken.joined('user')) { + return callback(new Error('Your access token belongs to an invalid user.')); + } + + return callback(null, accessToken, accessToken.joined('user')); + }); + } + + public static logout (params, callback: Function) { + this.verify(params, (err, accessToken) => { + if (err) { + return callback(err); + } + + return accessToken.destroy(callback); + }); + } + +} + +AccessToken.setDatabase(Nodal.require('db/main.js')); +AccessToken.setSchema(Nodal.my.Schema.models.AccessToken); + +AccessToken.joinsTo(User, {multiple: true}); + +class AuthController extends Nodal.Controller { + + public authorize (callback) { + this.setHeader('Cache-Control', 'no-store'); + this.setHeader('Pragma', 'no-cache'); + + AccessToken.verify(this.params, (err: Error, accessToken: string, user) => { + if (err) { + return this.respond(err); + } + + callback(accessToken, user); + }); + } + +} + +export default AuthController; + + From 0d895d18c5aced877bd9920a9438007ac845bec7 Mon Sep 17 00:00:00 2001 From: charrondev Date: Sat, 29 Oct 2016 16:11:20 -0400 Subject: [PATCH 04/19] Fix tsc errors --- nodal/fxn.d.ts | 2 +- nodal/{nodal.d.ts => index.d.ts} | 4 ++-- nodal/nodal-tests.ts | 14 +++++++------- nodal/tsconfig.json | 20 ++++++++++++++++++++ 4 files changed, 30 insertions(+), 10 deletions(-) rename nodal/{nodal.d.ts => index.d.ts} (99%) create mode 100644 nodal/tsconfig.json diff --git a/nodal/fxn.d.ts b/nodal/fxn.d.ts index a7c5058c2a..c813552fc3 100644 --- a/nodal/fxn.d.ts +++ b/nodal/fxn.d.ts @@ -1,4 +1,4 @@ -/// +/// declare module "fxn" { namespace fxn { diff --git a/nodal/nodal.d.ts b/nodal/index.d.ts similarity index 99% rename from nodal/nodal.d.ts rename to nodal/index.d.ts index fe75e8e5b7..baad180c82 100644 --- a/nodal/nodal.d.ts +++ b/nodal/index.d.ts @@ -3,7 +3,7 @@ // Definitions by: Adam Charron // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -/// +/// /// import * as fxn from 'fxn'; @@ -836,7 +836,7 @@ export class Model { * @param {string} field Field to set * @param {any} value Value for the field */ - public __safeSet__(field, value); + public __safeSet__(field: string, value: any): void; /** * Destroys model reference in database * @param {function} callback Method to execute upon completion, returns error if failed diff --git a/nodal/nodal-tests.ts b/nodal/nodal-tests.ts index e88a892dda..de11f4e39b 100644 --- a/nodal/nodal-tests.ts +++ b/nodal/nodal-tests.ts @@ -1,4 +1,4 @@ -import * as Nodal from './nodal.d'; +import * as Nodal from './index.d'; let BlogPost: typeof Nodal.Model; @@ -63,7 +63,7 @@ class AccessToken extends Nodal.Model { return "thing"; } - public static login (params, callback: Function) { + public static login (params: any, callback: Function) { if (params.body.grant_type !== 'password') { return callback(new Error('Must supply grant_type')); } @@ -93,7 +93,7 @@ class AccessToken extends Nodal.Model { }); } - public static verify (params, callback: Function) { + public static verify (params: any, callback: Function) { this.query() .join('user') .where({ @@ -115,8 +115,8 @@ class AccessToken extends Nodal.Model { }); } - public static logout (params, callback: Function) { - this.verify(params, (err, accessToken) => { + public static logout (params: any, callback: Function) { + this.verify(params, (err: Error, accessToken: AccessToken) => { if (err) { return callback(err); } @@ -134,11 +134,11 @@ AccessToken.joinsTo(User, {multiple: true}); class AuthController extends Nodal.Controller { - public authorize (callback) { + public authorize (callback: Function) { this.setHeader('Cache-Control', 'no-store'); this.setHeader('Pragma', 'no-cache'); - AccessToken.verify(this.params, (err: Error, accessToken: string, user) => { + AccessToken.verify(this.params, (err: Error, accessToken: string, user: User) => { if (err) { return this.respond(err); } diff --git a/nodal/tsconfig.json b/nodal/tsconfig.json new file mode 100644 index 0000000000..d8e0c99bb5 --- /dev/null +++ b/nodal/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "noImplicitAny": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "nodal-tests.ts", + "fxn.d.ts" + ] +} \ No newline at end of file From 1508f1fcbafe750fe39c3b7c66cc9ac593b7c487 Mon Sep 17 00:00:00 2001 From: charrondev Date: Tue, 1 Nov 2016 14:15:34 -0400 Subject: [PATCH 05/19] Change reference path to types --- nodal/fxn.d.ts | 2 +- nodal/index.d.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/nodal/fxn.d.ts b/nodal/fxn.d.ts index c813552fc3..1344d69782 100644 --- a/nodal/fxn.d.ts +++ b/nodal/fxn.d.ts @@ -1,4 +1,4 @@ -/// +/// declare module "fxn" { namespace fxn { diff --git a/nodal/index.d.ts b/nodal/index.d.ts index baad180c82..c3bc20908c 100644 --- a/nodal/index.d.ts +++ b/nodal/index.d.ts @@ -3,8 +3,7 @@ // Definitions by: Adam Charron // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -/// -/// +/// import * as fxn from 'fxn'; From b4ed82ae4f77ac0a279c681bcf2aa3001f8b8b23 Mon Sep 17 00:00:00 2001 From: Ruben Slabbert Date: Wed, 2 Nov 2016 09:20:01 +1000 Subject: [PATCH 06/19] Updated koa context to allow dynamic fields --- koa/index.d.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/koa/index.d.ts b/koa/index.d.ts index 6cdb0cbcd1..b8ff113944 100644 --- a/koa/index.d.ts +++ b/koa/index.d.ts @@ -43,6 +43,8 @@ declare namespace Koa { toJSON(): any; inspect(): any; + + [key: string]: any; } export interface Request { From b31a80276ca9f174e48549063ae2a0061eaadc79 Mon Sep 17 00:00:00 2001 From: charrondev Date: Tue, 22 Nov 2016 12:51:15 -0500 Subject: [PATCH 07/19] Move fxn into its own module --- fxn/index.d.ts | 64 ++++++++++++++++++++++++++++++++++++++++++++ fxn/tsconfig.json | 18 +++++++++++++ nodal/fxn.d.ts | 65 --------------------------------------------- nodal/tsconfig.json | 3 +-- 4 files changed, 83 insertions(+), 67 deletions(-) create mode 100644 fxn/index.d.ts create mode 100644 fxn/tsconfig.json delete mode 100644 nodal/fxn.d.ts diff --git a/fxn/index.d.ts b/fxn/index.d.ts new file mode 100644 index 0000000000..f203ebfdda --- /dev/null +++ b/fxn/index.d.ts @@ -0,0 +1,64 @@ +// Type definitions for fxn 0.0.1 +// Project: https://fgithub.com/poly/fxn +// Definitions by: Adam Charron +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +/// + +export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'OPTIONS'; + +export interface HttpHeaders { + [item: string]: string; +} + +export abstract class Controller { + + protected _method: HttpMethod; + protected _path: string; + protected _requestHeaders: Object; + protected _headers: Object; + protected _status: number; + protected _responder: Function; + protected _securityPolicies: Object; + protected params: any; + + constructor(path: string, method: string, requestHeaders: Object, params: Object, responder: Function); + convertMethod(method: HttpMethod, id: number): string; + run(): void; + notImplemented(msg: string, details: Object): boolean; + before(): void; + after(): void; + get(): void; + put(): void; + post(): void; + del(): void; + options(): void; + index(): void; + show(): void; + update(): void; + create(): void; + destroy(): void; + status(value: number): boolean; + setHeaders(): HttpHeaders; + setHeader(key: string, value: string): string; + appendHeader(key: string, value: string): string; + getHeader(key: string, value: string): string; + code(code: number): number; + getStatus(): number; + render(data: Buffer | String | Object): void; + allowOrigin(value: string): this; + securityPolicy(directive: string, src: string): string; + redirect(location: string): void; +} + +export abstract class Daemon { + constructor(string: string); +} + +export abstract class Application { + constructor(string: string); + send: Function; +} + +export abstract class Router {} +export abstract class Scheduler {} diff --git a/fxn/tsconfig.json b/fxn/tsconfig.json new file mode 100644 index 0000000000..0f2be78cfb --- /dev/null +++ b/fxn/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "noImplicitAny": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts" + ] +} \ No newline at end of file diff --git a/nodal/fxn.d.ts b/nodal/fxn.d.ts deleted file mode 100644 index 1344d69782..0000000000 --- a/nodal/fxn.d.ts +++ /dev/null @@ -1,65 +0,0 @@ -/// - -declare module "fxn" { - namespace fxn { - type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'OPTIONS'; - - interface HttpHeaders { - [item: string]: string; - } - - abstract class Controller { - - protected _method: HttpMethod; - protected _path: string; - protected _requestHeaders: Object; - protected _headers: Object; - protected _status: number; - protected _responder: Function; - protected _securityPolicies: Object; - protected params: any; - - constructor(path: string, method: string, requestHeaders: Object, params: Object, responder: Function); - convertMethod(method: HttpMethod, id: number): string; - run(): void; - notImplemented(msg: string, details: Object): boolean; - before(): void; - after(): void; - get(): void; - put(): void; - post(): void; - del(): void; - options(): void; - index(): void; - show(): void; - update(): void; - create(): void; - destroy(): void; - status(value: number): boolean; - setHeaders(): HttpHeaders; - setHeader(key: string, value: string): string; - appendHeader(key: string, value: string): string; - getHeader(key: string, value: string): string; - code(code: number): number; - getStatus(): number; - render(data: Buffer | String | Object): void; - allowOrigin(value: string): this; - securityPolicy(directive: string, src: string): string; - redirect(location: string): void; - } - - abstract class Daemon { - constructor(string: string); - } - - abstract class Application { - constructor(string: string); - send: Function; - } - - abstract class Router {} - abstract class Scheduler {} - } - - export = fxn; -} diff --git a/nodal/tsconfig.json b/nodal/tsconfig.json index d8e0c99bb5..b9bc3ba19a 100644 --- a/nodal/tsconfig.json +++ b/nodal/tsconfig.json @@ -14,7 +14,6 @@ }, "files": [ "index.d.ts", - "nodal-tests.ts", - "fxn.d.ts" + "nodal-tests.ts" ] } \ No newline at end of file From 7143284dcdddf069da68e675d18287bc497f81f1 Mon Sep 17 00:00:00 2001 From: Adam Charron Date: Tue, 22 Nov 2016 12:54:30 -0500 Subject: [PATCH 08/19] Fix typo in fxn --- fxn/index.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fxn/index.d.ts b/fxn/index.d.ts index f203ebfdda..228a7e934a 100644 --- a/fxn/index.d.ts +++ b/fxn/index.d.ts @@ -1,5 +1,5 @@ -// Type definitions for fxn 0.0.1 -// Project: https://fgithub.com/poly/fxn +// Type definitions for fxn 0.0.4 +// Project: https://github.com/poly/fxn // Definitions by: Adam Charron // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped From 71ceb2f37d2bbb49d1c6a402d5e0ade47d6afb33 Mon Sep 17 00:00:00 2001 From: Prashant Tiwari Date: Wed, 23 Nov 2016 20:56:35 +0530 Subject: [PATCH 09/19] Add types for hoek --- hoek/hoek-tests.ts | 290 +++++++++++++++++++++++++++++++++++++++++++++ hoek/index.d.ts | 211 +++++++++++++++++++++++++++++++++ hoek/tsconfig.json | 19 +++ 3 files changed, 520 insertions(+) create mode 100644 hoek/hoek-tests.ts create mode 100644 hoek/index.d.ts create mode 100644 hoek/tsconfig.json diff --git a/hoek/hoek-tests.ts b/hoek/hoek-tests.ts new file mode 100644 index 0000000000..3568ba024b --- /dev/null +++ b/hoek/hoek-tests.ts @@ -0,0 +1,290 @@ +import * as Hoek from "hoek"; + +/** + * Import the entire module as above or use named imports: + * import { clone, merge, assert} from "hoek"; + * "Tests" taken straight from hoek API reference and adapted to TypeScript. + */ + +// clone(obj) + +let nestedObj = { + w: /^something$/ig, + x: { + a: [1, 2, 3], + b: 123456, + c: new Date() + }, + y: 'y', + z: new Date() +}; + +let copy = Hoek.clone(nestedObj); + +copy.x.b = 100; + +console.log(copy.y); // results in 'y' +console.log(nestedObj.x.b); // results in 123456 +console.log(copy.x.b); // results in 100 + +// cloneWithShallow(obj, keys) + +nestedObj = { + w: /^something$/ig, + x: { + a: [1, 2, 3], + b: 123456, + c: new Date() + }, + y: 'y', + z: new Date() +}; + +copy = Hoek.cloneWithShallow(nestedObj, ['x']); + +copy.x.b = 100; + +console.log(copy.y); // results in 'y' +console.log(nestedObj.x.b); // results in 100 +console.log(copy.x.b); // results in 100 + +// merge(target, source, isNullOverride, isMergeArrays) + +let target = { a: 1, b: 2 }; +let source = { a: 0, c: 5 }; +let source2 = { a: null, c: 5 }; + +Hoek.merge(target, source); // results in {a: 0, b: 2, c: 5} +Hoek.merge(target, source2); // results in {a: null, b: 2, c: 5} +Hoek.merge(target, source2, false); // results in {a: 1, b: 2, c: 5} + +let targetArray = [1, 2, 3]; +let sourceArray = [4, 5]; + +Hoek.merge(targetArray, sourceArray); // results in [1, 2, 3, 4, 5] +Hoek.merge(targetArray, sourceArray, true, false); // results in [4, 5] + +// applyToDefaults(defaults, options, isNullOverride) + +let defaults = { host: "localhost", port: 8000 }; +let options = { port: 8080 }; + +let config = Hoek.applyToDefaults(defaults, options); // results in { host: "localhost", port: 8080 } + +defaults = { host: "localhost", port: 8000 }; +let options1 = { host: null, port: 8080 }; + +config = Hoek.applyToDefaults(defaults, options1, true); // results in { host: null, port: 8080 } + +// applyToDefaultsWithShallow(defaults, options, keys) + +let defaults1 = { + server: { + host: "localhost", + port: 8000 + }, + name: 'example' +}; + +let options2 = { server: { port: 8080 } }; + +let config1 = Hoek.applyToDefaultsWithShallow(defaults1, options2, ['server']); // results in { server: { port: 8080 }, name: 'example' } + +// deepEqual(b, a, [options]) + +Hoek.deepEqual({ a: [1, 2], b: 'string', c: { d: true } }, { a: [1, 2], b: 'string', c: { d: true } }); //results in true +Hoek.deepEqual(Object.create(null), {}, { prototype: false }); //results in true +Hoek.deepEqual(Object.create(null), {}); //results in false + +// unique(array, key) + +let array = [1, 2, 2, 3, 3, 4, 5, 6]; + +let newArray = Hoek.unique(array); // results in [1,2,3,4,5,6] + +let array1 = [{ id: 1 }, { id: 1 }, { id: 2 }]; + +let newArray1 = Hoek.unique(array1, "id"); // results in [{id: 1}, {id: 2}] + +// mapToObject(array, key) + +array = [1, 2, 3]; +let newObject = Hoek.mapToObject(array); // results in {"1": true, "2": true, "3": true} + +array1 = [{ id: 1 }, { id: 2 }]; +newObject = Hoek.mapToObject(array1, "id"); // results in {"1": true, "2": true} + +// intersect(array1, array2) + +array = [1, 2, 3]; +let array2 = [1, 4, 5]; + +let newArray2 = Hoek.intersect(array, array2); // results in [1] + +// contain(ref, values, [options]) + +Hoek.contain('aaa', 'a', { only: true }); // true +Hoek.contain([{ a: 1 }], [{ a: 1 }], { deep: true }); // true +Hoek.contain([1, 2, 2], [1, 2], { once: true }); // false +Hoek.contain({ a: 1, b: 2, c: 3 }, { a: 1, d: 4 }, { part: true }); // true + +// flatten(array, [target]) + +let array3 = [1, [2, 3]]; + +let flattenedArray = Hoek.flatten(array); // results in [1, 2, 3] + +array3 = [1, [2, 3]]; +let target1 = [4, [5]]; + +flattenedArray = Hoek.flatten(array3, target1); // results in [4, [5], 1, 2, 3] + +// reach(obj, chain, [options]) + +let chain = 'a.b.c'; +let obj = { a: { b: { c: 1 } } }; + +Hoek.reach(obj, chain); // returns 1 + +chain = 'a.b.-1'; +let obj1 = { a: { b: [2, 3, 6] } }; + +Hoek.reach(obj1, chain); // returns 6 + +// reachTemplate(obj, template, [options]) + +chain = 'a.b.c'; +obj = { a: { b: { c: 1 } } }; + +Hoek.reachTemplate(obj, '1+{a.b.c}=2'); // returns '1+1=2' + +// transform(obj, transform, [options]) + +let source1 = { + address: { + one: '123 main street', + two: 'PO Box 1234' + }, + title: 'Warehouse', + state: 'CA' +}; + +let result = Hoek.transform(source1, { + 'person.address.lineOne': 'address.one', + 'person.address.lineTwo': 'address.two', + 'title': 'title', + 'person.address.region': 'state' +}); +// Results in +// { +// person: { +// address: { +// lineOne: '123 main street', +// lineTwo: 'PO Box 1234', +// region: 'CA' +// } +// }, +// title: 'Warehouse' +// } + +// shallow(obj) + +let shallow = Hoek.shallow({ a: { b: 1 } }); + +// stringify(obj) + +let a: any = {}; +a.b = a; +Hoek.stringify(a); // Returns '[Cannot display object: Converting circular structure to JSON]' + +// Timer + +let timerObj = new Hoek.Timer(); +console.log("Time is now: " + timerObj.ts); +console.log("Elapsed time from initialization: " + timerObj.elapsed() + 'milliseconds'); + +// Bench + +let benchObj = new Hoek.Bench(); +console.log("Elapsed time from initialization: " + benchObj.elapsed() + 'milliseconds'); + +// base64urlEncode(value) + +Hoek.base64urlEncode("hoek"); + +// base64urlDecode(value) + +Hoek.base64urlDecode("aG9law=="); + +// escapeHtml(string) + +let string = ' hey '; +let escapedString = Hoek.escapeHtml(string); // returns <html> hey </html> + +// escapeHeaderAttribute(attribute) + +a = Hoek.escapeHeaderAttribute('I said "go w\\o me"'); //returns I said \"go w\\o me\" + +// escapeRegex(string) + +a = Hoek.escapeRegex('4^f$s.4*5+-_?%=#!:@|~\\/`"(>)[<]d{}s,'); // returns 4\^f\$s\.4\*5\+\-_\?%\=#\!\:@\|~\\\/`"\(>\)\[<\]d\{\}s\, + +// assert(condition, message) + +let x = 1, y = 2; + +Hoek.assert(x === y, 'x should equal y'); // Throws 'x should equal y' + +Hoek.assert(x === y, new Error('x should equal y')); // Throws the given error object + +// abort(message) + +Hoek.abort("Error message"); + +// displayStack(slice) + +let stack = Hoek.displayStack(); +console.log(stack); + +// callStack(slice) + +let stack2 = Hoek.callStack(); +console.log(stack2); + +// nextTick(fn) + +let myFn = function () { + console.log('Do this later'); +}; + +let nextFn = Hoek.nextTick(myFn); + +nextFn(); +console.log('Do this first'); + +// Results in: +// +// Do this first +// Do this later + +// once(fn) + +myFn = function () { + console.log('Ran myFn'); +}; + +let onceFn = Hoek.once(myFn); +onceFn(); // results in "Ran myFn" +onceFn(); // results in undefined + +// ignore + +Hoek.ignore(); + +// uniqueFilename(path, extension) + +let result1 = Hoek.uniqueFilename('./test/modules', 'txt'); // results in "full/path/test/modules/{random}.txt" + +// isInteger(value) + +result = Hoek.isInteger('23'); diff --git a/hoek/index.d.ts b/hoek/index.d.ts new file mode 100644 index 0000000000..9c749d1660 --- /dev/null +++ b/hoek/index.d.ts @@ -0,0 +1,211 @@ +// Type definitions for Hoek 4.1.0 +// Project: https://github.com/hapijs/hoek +// Definitions by: Prashant Tiwari +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +interface ContainOptions { + /** Perform a deep comparison of the values? */ + deep?: boolean; + /** Allow only one occurrence of each value? */ + once?: boolean; + /** Don't allow values not explicitly listed? */ + only?: boolean; + /** Allow partial match of the values? */ + part?: boolean; +} + +interface ReachOptions { + /** String to split chain path on. Defaults to ".". */ + separator?: string; + /** Value to return if the path or value is not present. Default is undefined. */ + default?: any; + /** Throw an error on missing member? Default is false. */ + strict?: boolean; + /** Allow traversing functions for properties? */ + functions?: boolean; +} + +// Object + +/** + * Clone an object or an array. + */ +export function clone(obj: T): T; + +/** + * Clone an object or array. + * */ +export function cloneWithShallow(obj: any, keys: string[]): any; + +/** + * Merge all the properties of source into target. */ +export function merge(target: T1, source: T2, isNullOverride?: boolean, isMergeArrays?: boolean): T1 & T2; + +/** + * Apply options to a copy of the defaults. + * */ +export function applyToDefaults(defaults: T1, options: T2, isNullOverride?: boolean): T1 & T2; + +/** + * Apply options to a copy of the defaults. + */ +export function applyToDefaultsWithShallow(defaults: T1, options: T2, keys?: string[]): T1 & T2; + +/** + * Perform a deep comparison of the two values. + */ +export function deepEqual(b: T, a: T, options?: any): T; + +/** + * Remove duplicate items from Array. + */ +export function unique(array: T[], key?: string): T[]; + +/** + * Convert an Array into an Object. + */ +export function mapToObject(array: any[], key?: string): any; + +/** + * Find the common unique items in two arrays. + */ +export function intersect(array1: any[], array2: any[]): any; + +/** + * Test if the reference value contains the provided values. + */ +export function contain(ref: any, values: any, options?: ContainOptions): boolean; + +/** + * Flatten an array. + */ +export function flatten(array: any[], target?: any[]): any[]; + +/** + * Convert an object key chain string to reference. + */ +export function reach(obj: any, chain: any, options?: ReachOptions): any; + +/** + * Replace string parameters ({name}) with their corresponding object key values. + */ +export function reachTemplate(obj: any, template: string, options?: ReachOptions): any; + +/** + * Transform an existing object into a new one based on the supplied obj and transform map. + */ +export function transform(obj: any, transform: any, options?: ReachOptions): any; + +/** + * Perform a shallow copy by copying the references of all the top level children. + */ +export function shallow(obj: any): any; + +/** + * Convert an object to string. Any errors are caught and reported back in the form of the returned string. + */ +export function stringify(obj: any): string; + +// Timer + +/** + * A Timer object. + */ +export class Timer { + /** The number of milliseconds elapsed since the epoch. */ + ts: number; + /** The time (ms) elapsed since the timer was created. */ + elapsed(): number; +} + +// Bench + +/** + * Same as Timer, except ts stores the internal node clock. + */ +export class Bench { + /** The number of milliseconds on the node clock elapsed since the epoch. */ + ts: number; + /** The time (ms) elapsed since the timer was created. */ + elapsed(): number; +} + +// Binary Encoding/Decoding + +/** + * Encode value of string or buffer type in Base64 or URL encoding. + */ +export function base64urlEncode(value: string): string; + +/** + * Decode string into Base64 or URL encoding. + */ +export function base64urlDecode(value: string): string; + +// Escaping Characters + +/** + * Escape html characters. + */ +export function escapeHtml(htmlString: string): string; + +/** + * Escape attribute value for use in HTTP header. + */ +export function escapeHeaderAttribute(attribute: string): string; + +/** + * Escape string for Regex construction. + */ +export function escapeRegex(regexString: string): string; + +// Errors + +/** + * Print message or throw error if condition fails. + */ +export function assert(condition: boolean, message: string | Error): void | Error; + +/** + * Throw if process.env.NODE_ENV === 'test'. Else display most recent stack and exit process. + */ +export function abort(message: string | Error): void; + +/** + * Display the trace stack. + */ +export function displayStack(slice?: any): string[]; + +/** + * Return a trace stack array. + */ +export function callStack(slice?: any): Array[]; + +// Function + +/** + * Wrap fn in process.nextTick. + */ +export function nextTick(fn: Function): Function; + +/** + * Make sure fn is only run once. + */ +export function once(fn: Function): Function; + +/** + * A simple no-op function. + */ +export function ignore(): void; + +// Miscellaneous + +/** + * path to prepend to a randomly generated file name. + */ +export function uniqueFilename(path: string, extension?: string): string; + +/** + * Check value to see if it is an integer. + */ +export function isInteger(value: any): boolean; diff --git a/hoek/tsconfig.json b/hoek/tsconfig.json new file mode 100644 index 0000000000..ea03427572 --- /dev/null +++ b/hoek/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "noImplicitAny": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "hoek-tests.ts" + ] +} \ No newline at end of file From b733dcefe8120a1be9926e3c4126a3aa21ed1e19 Mon Sep 17 00:00:00 2001 From: Diogo Franco Date: Mon, 28 Nov 2016 13:02:33 +0900 Subject: [PATCH 10/19] Better typing for headers Lack of indexing in `AxiosXHR#headers` made it unusable without casting. Requests / Responses with more than one instance of the same header make the value be a `string[]`. Often happens with headers like `Set-Cookie`. --- axios/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/axios/index.d.ts b/axios/index.d.ts index a2c5bfbd45..d66dc3d48c 100644 --- a/axios/index.d.ts +++ b/axios/index.d.ts @@ -159,7 +159,7 @@ declare namespace Axios { /** * headers that the server responded with */ - headers: Object; + headers: {[index: string]: any}; /** * config that was provided to `axios` for the request From ae053e2298ab1f9195529cbc8c867f7e653c8e33 Mon Sep 17 00:00:00 2001 From: "Diogo Franco (Kovensky)" Date: Mon, 28 Nov 2016 13:22:35 +0900 Subject: [PATCH 11/19] Add test for headers change --- axios/axios-tests.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/axios/axios-tests.ts b/axios/axios-tests.ts index a321e97f19..eb98e2710c 100644 --- a/axios/axios-tests.ts +++ b/axios/axios-tests.ts @@ -80,7 +80,11 @@ var axiosInstance = axios.create({ timeout: 1000 }); -axiosInstance.request({url: "issues/1"}); +axiosInstance.request({url: "issues/1"}).then(res => { + if (res.headers['content-type'].startsWith('application/json')) { + throw new Error('Unexpected content-type'); + } +}); axios.all([getRepoDetails, getRepoDetails]).then(([repo1, repo2]) => { var sumIds = repo1.data.id + repo2.data.id; From f33ba1e3f4d8dbeb5c2c692bd3f984ac48461a42 Mon Sep 17 00:00:00 2001 From: Christophe Camicas Date: Tue, 29 Nov 2016 17:25:08 +0100 Subject: [PATCH 12/19] Fix dhtmlxgantt dateFromPos return type = Date --- dhtmlxgantt/dhtmlxgantt-tests.ts | 3 ++- dhtmlxgantt/index.d.ts | 32 ++++++++++++++++---------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/dhtmlxgantt/dhtmlxgantt-tests.ts b/dhtmlxgantt/dhtmlxgantt-tests.ts index f20a92506d..6ea32b509d 100644 --- a/dhtmlxgantt/dhtmlxgantt-tests.ts +++ b/dhtmlxgantt/dhtmlxgantt-tests.ts @@ -3,6 +3,7 @@ //date operations var start: Date = gantt.date.week_start(new Date()); var next: Date = gantt.date.add(new Date(), 1, "week"); +var datePos: Date = gantt.dateFromPos(0); //hotkeys gantt.keys.edit_cancel = 13; @@ -33,4 +34,4 @@ gantt.attachEvent("onBeforeLightbox", function (id?: string) { }); //gantt enterprise var gantt2 = Gantt.getGanttInstance(); -gantt2.config.api_date = "format"; \ No newline at end of file +gantt2.config.api_date = "format"; diff --git a/dhtmlxgantt/index.d.ts b/dhtmlxgantt/index.d.ts index a9542cc00f..77fa32b8e7 100644 --- a/dhtmlxgantt/index.d.ts +++ b/dhtmlxgantt/index.d.ts @@ -4,10 +4,10 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -interface GanttCallback { (...args: any[]) : any } -type GanttEventName ='onAfterAutoSchedule'|'onAfterBatchUpdate'|'onAfterLightbox'|'onAfterLinkAdd'|'onAfterLinkDelete'|'onAfterLinkUpdate'|'onAfterRedo'|'onAfterTaskAdd'|'onAfterTaskAutoSchedule'|'onAfterTaskDelete'|'onAfterTaskDrag'|'onAfterTaskMove'|'onAfterTaskUpdate'|'onAfterUndo'|'onAjaxError'|'onBeforeAutoSchedule'|'onBeforeBatchUpdate'|'onBeforeCollapse'|'onBeforeDataRender'|'onBeforeExpand'|'onBeforeGanttReady'|'onBeforeGanttRender'|'onBeforeLightbox'|'onBeforeLinkAdd'|'onBeforeLinkDelete'|'onBeforeLinkDisplay'|'onBeforeLinkUpdate'|'onBeforeParse'|'onBeforeRedo'|'onBeforeRowDragEnd'|'onBeforeTaskAdd'|'onBeforeTaskAutoSchedule'|'onBeforeTaskChanged'|'onBeforeTaskDelete'|'onBeforeTaskDisplay'|'onBeforeTaskDrag'|'onBeforeTaskMove'|'onBeforeTaskSelected'|'onBeforeTaskUpdate'|'onBeforeUndo'|'onCircularLinkError'|'onClear'|'onCollapse'|'onColumnResize'|'onColumnResizeEnd'|'onColumnResizeStart'|'onContextMenu'|'onDataRender'|'onEmptyClick'|'onError'|'onExpand'|'onGanttReady'|'onGanttRender'|'onGanttScroll'|'onGridHeaderClick'|'onGridResize'|'onGridResizeEnd'|'onGridResizeStart'|'onLightbox'|'onLightboxButton'|'onLightboxCancel'|'onLightboxChange'|'onLightboxDelete'|'onLightboxSave'|'onLinkClick'|'onLinkDblClick'|'onLinkIdChange'|'onLinkValidation'|'onLoadEnd'|'onLoadStart'|'onMouseMove'|'onOptionsLoad'|'onParse'|'onRowDragEnd'|'onRowDragStart'|'onScaleAdjusted'|'onScaleClick'|'onTaskClick'|'onTaskClosed'|'onTaskCreated'|'onTaskDblClick'|'onTaskDrag'|'onTaskIdChange'|'onTaskLoading'|'onTaskOpened'|'onTaskRowClick'|'onTaskSelected'|'onTaskUnselected'|'onTemplatesReady'; +type GanttCallback = (...args: any[]) => any; +type GanttEventName = 'onAfterAutoSchedule'|'onAfterBatchUpdate'|'onAfterLightbox'|'onAfterLinkAdd'|'onAfterLinkDelete'|'onAfterLinkUpdate'|'onAfterRedo'|'onAfterTaskAdd'|'onAfterTaskAutoSchedule'|'onAfterTaskDelete'|'onAfterTaskDrag'|'onAfterTaskMove'|'onAfterTaskUpdate'|'onAfterUndo'|'onAjaxError'|'onBeforeAutoSchedule'|'onBeforeBatchUpdate'|'onBeforeCollapse'|'onBeforeDataRender'|'onBeforeExpand'|'onBeforeGanttReady'|'onBeforeGanttRender'|'onBeforeLightbox'|'onBeforeLinkAdd'|'onBeforeLinkDelete'|'onBeforeLinkDisplay'|'onBeforeLinkUpdate'|'onBeforeParse'|'onBeforeRedo'|'onBeforeRowDragEnd'|'onBeforeTaskAdd'|'onBeforeTaskAutoSchedule'|'onBeforeTaskChanged'|'onBeforeTaskDelete'|'onBeforeTaskDisplay'|'onBeforeTaskDrag'|'onBeforeTaskMove'|'onBeforeTaskSelected'|'onBeforeTaskUpdate'|'onBeforeUndo'|'onCircularLinkError'|'onClear'|'onCollapse'|'onColumnResize'|'onColumnResizeEnd'|'onColumnResizeStart'|'onContextMenu'|'onDataRender'|'onEmptyClick'|'onError'|'onExpand'|'onGanttReady'|'onGanttRender'|'onGanttScroll'|'onGridHeaderClick'|'onGridResize'|'onGridResizeEnd'|'onGridResizeStart'|'onLightbox'|'onLightboxButton'|'onLightboxCancel'|'onLightboxChange'|'onLightboxDelete'|'onLightboxSave'|'onLinkClick'|'onLinkDblClick'|'onLinkIdChange'|'onLinkValidation'|'onLoadEnd'|'onLoadStart'|'onMouseMove'|'onOptionsLoad'|'onParse'|'onRowDragEnd'|'onRowDragStart'|'onScaleAdjusted'|'onScaleClick'|'onTaskClick'|'onTaskClosed'|'onTaskCreated'|'onTaskDblClick'|'onTaskDrag'|'onTaskIdChange'|'onTaskLoading'|'onTaskOpened'|'onTaskRowClick'|'onTaskSelected'|'onTaskUnselected'|'onTemplatesReady'; -interface GanttTemplates{ +interface GanttTemplates { /** * specifies the format of dates that are set by means of API methods. Used to parse incoming dates * @param date the date which needs formatting @@ -269,7 +269,7 @@ interface GanttTemplates{ } -interface GanttConfigOptions{ +interface GanttConfigOptions { /** * sets the date format for addTask() method to */ @@ -802,7 +802,7 @@ interface GanttConfigOptions{ } -interface GanttDateHelpers{ +interface GanttDateHelpers { add(origin: Date, count: number, unit: string): Date; copy(origin: Date): Date; @@ -823,21 +823,21 @@ interface GanttDateHelpers{ to_fixed(value: number): string; } -interface GanttHotkeys{ +interface GanttHotkeys { edit_save: number; edit_cancel: number; } -//Gantt.locale +//Gantt.locale -interface GanttLocaleDate{ +interface GanttLocaleDate { month_full: string[]; month_short: string[]; day_full: string[]; day_short: string[]; } -interface GanttLocaleLabels{ +interface GanttLocaleLabels { new_task: string; icon_save: string; icon_cancel: string; @@ -861,25 +861,25 @@ interface GanttLocaleLabels{ years: string; } -interface GanttLocale{ +interface GanttLocale { date: GanttLocaleDate; labels: GanttLocaleLabels; } -interface GanttEnterprise{ +interface GanttEnterprise { /** * Creates a new instance of Gantt */ getGanttInstance(): GanttStatic; } -interface GanttStatic{ +interface GanttStatic { templates: GanttTemplates; config: GanttConfigOptions; date: GanttDateHelpers; keys: GanttHotkeys; - skin: String; - version: String; + skin: string; + version: string; locale: GanttLocale; $click: any; @@ -1059,7 +1059,7 @@ interface GanttStatic{ * gets the date of the specified horizontal position in the chart area * @param pos the relative horizontal position you want to know the date of */ - dateFromPos(pos: number): void; + dateFromPos(pos: number): Date; /** * returns false if the provided argument is undefined, otherwise true @@ -1730,4 +1730,4 @@ interface GanttStatic{ declare var gantt: GanttStatic; -declare var Gantt: GanttEnterprise; \ No newline at end of file +declare var Gantt: GanttEnterprise; From 1c21d86677f91503afdbd55cd15a729aacbe4cb0 Mon Sep 17 00:00:00 2001 From: Christophe Camicas Date: Tue, 29 Nov 2016 17:27:22 +0100 Subject: [PATCH 13/19] add definition contribution --- dhtmlxgantt/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dhtmlxgantt/index.d.ts b/dhtmlxgantt/index.d.ts index 77fa32b8e7..c416d2a694 100644 --- a/dhtmlxgantt/index.d.ts +++ b/dhtmlxgantt/index.d.ts @@ -1,6 +1,6 @@ // Type definitions for dhtmlxGantt 4.0.0 // Project: http://dhtmlx.com/docs/products/dhtmlxGantt -// Definitions by: Maksim Kozhukh +// Definitions by: Maksim Kozhukh , Christophe Camicas // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped From da2b6c97eba247443958142e3038dd3d0773c592 Mon Sep 17 00:00:00 2001 From: Prashant Tiwari Date: Wed, 30 Nov 2016 03:08:25 +0530 Subject: [PATCH 14/19] Lint --- hoek/hoek-tests.ts | 2 +- hoek/index.d.ts | 6 +++--- hoek/tslint.json | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 hoek/tslint.json diff --git a/hoek/hoek-tests.ts b/hoek/hoek-tests.ts index 3568ba024b..09f82a7e2a 100644 --- a/hoek/hoek-tests.ts +++ b/hoek/hoek-tests.ts @@ -2,7 +2,7 @@ import * as Hoek from "hoek"; /** * Import the entire module as above or use named imports: - * import { clone, merge, assert} from "hoek"; + * import { clone, merge, assert } from "hoek"; * "Tests" taken straight from hoek API reference and adapted to TypeScript. */ diff --git a/hoek/index.d.ts b/hoek/index.d.ts index 9c749d1660..34e5ef715a 100644 --- a/hoek/index.d.ts +++ b/hoek/index.d.ts @@ -179,19 +179,19 @@ export function displayStack(slice?: any): string[]; /** * Return a trace stack array. */ -export function callStack(slice?: any): Array[]; +export function callStack(slice?: any): any[]; // Function /** * Wrap fn in process.nextTick. */ -export function nextTick(fn: Function): Function; +export function nextTick(fn: () => void): () => void; /** * Make sure fn is only run once. */ -export function once(fn: Function): Function; +export function once(fn: () => void): () => void; /** * A simple no-op function. diff --git a/hoek/tslint.json b/hoek/tslint.json new file mode 100644 index 0000000000..192203ab54 --- /dev/null +++ b/hoek/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": "../tslint.json" +} \ No newline at end of file From ba2a2dc341f5b6c6d7a0e3ac557debc441eacb49 Mon Sep 17 00:00:00 2001 From: Prashant Tiwari Date: Wed, 30 Nov 2016 03:24:10 +0530 Subject: [PATCH 15/19] Try pleasing linter for dt-header --- hoek/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hoek/index.d.ts b/hoek/index.d.ts index 34e5ef715a..98e2188fec 100644 --- a/hoek/index.d.ts +++ b/hoek/index.d.ts @@ -1,4 +1,4 @@ -// Type definitions for Hoek 4.1.0 +// Type definitions for hoek 4.1 // Project: https://github.com/hapijs/hoek // Definitions by: Prashant Tiwari // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped From 86e8ab2ca2ea3deb4d398af960a226d76f80ca35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20S=C3=A1nchez?= Date: Fri, 25 Nov 2016 22:52:45 -0600 Subject: [PATCH 16/19] Expose provided processors living in xml2js/lib/processors --- xml2js/index.d.ts | 11 +++++------ xml2js/processors.d.ts | 11 +++++++++++ xml2js/xml2js-tests.ts | 8 ++++++++ 3 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 xml2js/processors.d.ts diff --git a/xml2js/index.d.ts b/xml2js/index.d.ts index b23ebbbac2..f40aa93cb6 100644 --- a/xml2js/index.d.ts +++ b/xml2js/index.d.ts @@ -3,7 +3,7 @@ // Definitions by: Michel Salib , Jason McNeil , Christopher Currens // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped - +/// export = xml2js; @@ -29,8 +29,8 @@ declare namespace xml2js { interface Options { async?: boolean; attrkey?: string; - attrNameProcessors?: [(name: string) => string]; - attrValueProcessors?: [(name: string) => string]; + attrNameProcessors?: [(name: string) => any]; + attrValueProcessors?: [(name: string) => any]; charkey?: string; charsAsChildren?: boolean; childkey?: string; @@ -45,10 +45,10 @@ declare namespace xml2js { normalize?: boolean; normalizeTags?: boolean; strict?: boolean; - tagNameProcessors?: [(name: string) => string]; + tagNameProcessors?: [(name: string) => any]; trim?: boolean; validator?: Function; - valueProcessors?: [(name: string) => string]; + valueProcessors?: [(name: string) => any]; xmlns?: boolean; } @@ -75,4 +75,3 @@ declare namespace xml2js { toString(): string; } } - diff --git a/xml2js/processors.d.ts b/xml2js/processors.d.ts new file mode 100644 index 0000000000..008a56964f --- /dev/null +++ b/xml2js/processors.d.ts @@ -0,0 +1,11 @@ +declare module 'xml2js/lib/processors' { + export function firstCharLowerCase(name: string): string; + + export function normalize(name: string): string; + + export function parseBooleans(name: string): boolean; + + export function parseNumbers(name: string): number; + + export function stripPrefix(name: string): string; +} diff --git a/xml2js/xml2js-tests.ts b/xml2js/xml2js-tests.ts index e0bea8cf9b..62324b6908 100644 --- a/xml2js/xml2js-tests.ts +++ b/xml2js/xml2js-tests.ts @@ -1,6 +1,7 @@ /// import xml2js = require('xml2js'); +import * as processors from 'xml2js/lib/processors'; xml2js.parseString('Hello xml2js!', (err: any, result: any) => { }); @@ -32,6 +33,13 @@ xml2js.parseString('Hello xml2js!', { valueProcessors: undefined }, (err: any, result: any) => { }); +xml2js.parseString('Hello xml2js!', { + attrNameProcessors: [processors.firstCharLowerCase], + attrValueProcessors: [processors.normalize], + tagNameProcessors: [processors.stripPrefix], + valueProcessors: [processors.parseBooleans, processors.parseNumbers] +}, (err: any, result: any) => { }); + var builder = new xml2js.Builder({ renderOpts: { pretty: false From 023789d2368087837cbbf073844c4fdeebf272e6 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 29 Nov 2016 17:18:44 -0800 Subject: [PATCH 17/19] Quote glob so that it is handled by tslint and not by the shell (#12993) --- scripts/lint.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/lint.js b/scripts/lint.js index f54df63d65..6473fef6a3 100644 --- a/scripts/lint.js +++ b/scripts/lint.js @@ -7,7 +7,7 @@ const path = require("path"); // Path of tslint when `types-publisher` is symlinked const symlinkedTslintPath = "../node_modules/types-publisher/node_modules/tslint" const tslintPath = existsSync(path.join(pkg, symlinkedTslintPath)) ? symlinkedTslintPath : "../node_modules/tslint"; -const cmd = `node ${tslintPath}/lib/tslint-cli --format stylish **/*.d.ts`; +const cmd = `node ${tslintPath}/lib/tslint-cli --format stylish "**/*.d.ts"`; console.log(cmd); try { From b0a5c565969ee157b9549b35d7d5800c0d60d189 Mon Sep 17 00:00:00 2001 From: Christophe Camicas Date: Wed, 30 Nov 2016 09:11:24 +0100 Subject: [PATCH 18/19] Return type precision --- dhtmlxgantt/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dhtmlxgantt/index.d.ts b/dhtmlxgantt/index.d.ts index c416d2a694..f94ba88a33 100644 --- a/dhtmlxgantt/index.d.ts +++ b/dhtmlxgantt/index.d.ts @@ -1056,7 +1056,7 @@ interface GanttStatic { dataProcessor(url: string): void; /** - * gets the date of the specified horizontal position in the chart area + * returns the date of the specified horizontal position in the chart area * @param pos the relative horizontal position you want to know the date of */ dateFromPos(pos: number): Date; From 3c56e866d6edd234416a92c3d35c15ccd7fe6b72 Mon Sep 17 00:00:00 2001 From: Patrick Westerhoff Date: Wed, 30 Nov 2016 14:37:42 +0100 Subject: [PATCH 19/19] [core-js] Update to padStart, padEnd (stage 4) (#12440) --- core-js/core-js-tests.ts | 6 +++--- core-js/index.d.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core-js/core-js-tests.ts b/core-js/core-js-tests.ts index 6b4c03352c..08370370a0 100644 --- a/core-js/core-js-tests.ts +++ b/core-js/core-js-tests.ts @@ -334,15 +334,15 @@ b = Reflect.setPrototypeOf(a, a); // ############################################################################################# // ECMAScript 7 -// Modules: es7.array.includes, es7.string.at, es7.string.lpad, es7.string.rpad, +// Modules: es7.array.includes, es7.string.at, ees7.string.pad-start, es7.string.pad-end, // es7.object.to-array, es7.object.get-own-property-descriptors, es7.regexp.escape, // es7.map.to-json, and es7.set.to-json // ############################################################################################# b = arrayOfPoint.includes(point, i); s = s.at(i); -s = s.lpad(i, s); -s = s.rpad(i, s); +s = s.padStart(i, s); +s = s.padEnd(i, s); arrayOfAny = Object.values(a); arrayOfStringAny = Object.entries(a); pdm = Object.getOwnPropertyDescriptors(a); diff --git a/core-js/index.d.ts b/core-js/index.d.ts index 94aa14606b..7dda59aab3 100644 --- a/core-js/index.d.ts +++ b/core-js/index.d.ts @@ -890,7 +890,7 @@ declare namespace Reflect { // ############################################################################################# // ECMAScript 7 -// Modules: es7.array.includes, es7.string.at, es7.string.lpad, es7.string.rpad, +// Modules: es7.array.includes, es7.string.at, es7.string.pad-start, es7.string.pad-end, // es7.object.to-array, es7.object.get-own-property-descriptors, es7.regexp.escape, // es7.map.to-json, and es7.set.to-json // ############################################################################################# @@ -901,8 +901,8 @@ interface Array { interface String { at(index: number): string; - lpad(length: number, fillStr?: string): string; - rpad(length: number, fillStr?: string): string; + padStart(length: number, fillStr?: string): string; + padEnd(length: number, fillStr?: string): string; } interface ObjectConstructor {