Skip to content

Commit

Permalink
feat(types): declare types, noissue
Browse files Browse the repository at this point in the history
  • Loading branch information
MrSwitch committed Dec 4, 2023
1 parent d79a7b5 commit c2a69be
Show file tree
Hide file tree
Showing 80 changed files with 930 additions and 27 deletions.
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
"type": "module",
"main": "./src/index.js",
"exports": {
".": "./src/index.js",
".": {
"import": "./src/index.js",
"types": "./types/src/index.d.ts"
},
"./utils/*": "./src/utils/*.js"
},
"types": "./types/src/index.d.ts",
"engines": {
"node": ">=16.9"
},
Expand Down Expand Up @@ -40,7 +44,8 @@
},
"homepage": "https://github.com/5app/dare#readme",
"files": [
"src/"
"src/",
"types/"
],
"devDependencies": {
"@5app/prettier-config": "^1.0.4",
Expand Down
71 changes: 49 additions & 22 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,35 @@ import response_handler, {responseRowHandler} from './response_handler.js';
/**
* @typedef {import('sql-template-tag').Sql} Sql
*
* @typedef {object} Model
* @property {Object<string, object | Function | Array<string> | string | null | false>} [schema] - Model Schema
* @property {string} [table] - Alias for the table
* @property {Object<string, string>} [shortcut_map] - Shortcut map
* @property {Function} [get] - Get handler
* @property {Function} [post] - Post handler
* @property {Function} [patch] - Patch handler
* @property {Function} [del] - Delete handler
*
* @typedef {object} RequestObject
* @property {string} [table] - Name of the table to query
* @property {Array} [fields] - Fields array to return
* @property {object} [filter] - Filter Object to query
* @property {object} [join] - Place filters on the joining tables
* @property {object} [body] - Body containing new data
* @property {object} [query] - Query attached to a post request to create INSERT...SELECT operations
* @property {number} [limit] - Number of items to return
* @property {number} [start] - Number of items to skip
* @property {Array} [orderby] - Array of fields to order by
* @property {string | string[]} [orderby] - Array of fields to order by
* @property {string} [groupby] - Field to group by
* @property {string} [duplicate_keys] - 'ignore' to prevent throwing Duplicate key errors
* @property {Array<string>} [duplicate_keys_update] - An array of fields to update on presence of duplicate key constraints
* @property {string[]} [duplicate_keys_update] - An array of fields to update on presence of duplicate key constraints
* @property {*} [notfound] - If not undefined will be returned in case of a single entry not found
* @property {object} [models] - Models with schema defintitions
* @property {Object<string, Model>} [models] - Models with schema defintitions
* @property {Function} [validateInput] - Validate input
* @property {boolean} [infer_intermediate_models] - Infer intermediate models
* @property {Function} [rowHandler] - Override default Function to handle each row
* @property {Function} [getFieldKey] - Override default Function to interpret the field key
* @property {string} [conditional_operators_in_value] - Allowable conditional operators in value
* @property {object} [scope] - Arbitary data to carry through to the model/response handlers
*
* @typedef {object} InternalProps
Expand All @@ -47,6 +58,11 @@ import response_handler, {responseRowHandler} from './response_handler.js';
* @property {boolean} [skip] - Skip the request
* @property {string} [alias] - Alias for the table
* @property {boolean} [countRows] - Count all rows
* @property {string} [sql_table] - SQL Table
* @property {string} [sql_alias] - SQL Alias
* @property {Array} [sql_joins] - SQL Join
* @property {string} [ignore] - SQL Fields
* @property {Array} [sql_where_conditions] - SQL Where conditions
*
* @typedef {RequestObject & InternalProps} QueryOptions
*/
Expand All @@ -62,7 +78,7 @@ export {DareError};
* Sets up a new instance of Dare
*
* @param {QueryOptions} options - Initial options defining the instance
* @returns {object} instance of dare
* @returns {Dare} instance of dare
*/
function Dare(options = {}) {
// Overwrite default properties
Expand Down Expand Up @@ -99,7 +115,11 @@ Dare.prototype.rowid = '_rowid';
// Set the Max Limit for SELECT statements
Dare.prototype.MAX_LIMIT = null;

// Capture the generated field functions to run after the request
Dare.prototype.generated_fields = [];

// Default options
/** @type {QueryOptions} */
Dare.prototype.options = {
// Infer intermediate tables when two models are not directly linked
infer_intermediate_models: true,
Expand All @@ -125,6 +145,8 @@ Dare.prototype.get_unique_alias = function (iterate = 1) {
return `\`${str}\``;
};

// eslint-disable-next-line jsdoc/valid-types
/** @type {(options: QueryOptions) => Promise<QueryOptions>} */
Dare.prototype.format_request = format_request;

Dare.prototype.response_handler = response_handler;
Expand All @@ -133,20 +155,24 @@ Dare.prototype.response_handler = response_handler;
* GetFieldKey
* @param {string} field - Field
* @param {object} schema - Model Schema
* @returns {object | undefined} Field Key
* @returns {string | void} Field Key
*/
// eslint-disable-next-line no-unused-vars
Dare.prototype.getFieldKey = function getFieldKey(field, schema) {
// Do nothing, default is to set it to same as field
};

/* eslint-disable jsdoc/valid-types */
/* eslint-disable jsdoc/check-tag-names */
/**
* Dare.after
* Defines where the instance goes looking to apply post execution handlers and potentially mutate the response
*
* @param {object|Array} resp - Response object
* @returns {object} response data formatted or not
* @template {object|Array} T
* @param {T} resp - Response object
* @returns {T} response data formatted or not
*/
/* eslint-enable jsdoc/valid-types */
/* eslint-enable jsdoc/check-tag-names */
Dare.prototype.after = function (resp) {
// Define the after handler
const handler = `after${this.options.method.replace(/^[a-z]/, m =>
Expand All @@ -167,7 +193,7 @@ Dare.prototype.after = function (resp) {
* Use
* Creates a new instance of Dare and merges new options with the base options
* @param {QueryOptions} options - set of instance options
* @returns {object} Instance of Dare
* @returns {Dare} Instance of Dare
*/
Dare.prototype.use = function (options = {}) {
const inst = Object.create(this);
Expand Down Expand Up @@ -203,6 +229,7 @@ Dare.prototype.resultset = undefined;
/**
* Add a row to the resultset
* @param {object} row - Row record to add to the rows resultset
* @returns {void}
*/
Dare.prototype.addRow = function (row) {
// Format the SQL Row
Expand All @@ -219,9 +246,9 @@ Dare.prototype.addRow = function (row) {
* Dare.sql
* Prepares and processes SQL statements
*
* @param {string | Sql} sql - SQL string containing the query
* @param {string | Sql | {sql: string, values: Array}} sql - SQL string containing the query
* @param {Array<Array, string, number, boolean>} [values] - List of prepared statement values
* @returns {Promise<object|Array>} Returns response object or array of values
* @returns {Promise} Returns response object or array of values
*/
Dare.prototype.sql = async function sql(sql, values) {
let req;
Expand All @@ -244,7 +271,7 @@ Dare.prototype.sql = async function sql(sql, values) {
* @param {Array} [fields] - Fields array to return
* @param {object} [filter] - Filter Object to query
* @param {RequestObject} [options] - An Options object containing all other request options
* @returns {Promise<object|Array>} Results
* @returns {Promise<any>} Results
*/
Dare.prototype.get = async function get(table, fields, filter, options = {}) {
/**
Expand Down Expand Up @@ -304,8 +331,8 @@ Dare.prototype.get = async function get(table, fields, filter, options = {}) {
* Returns the total number of results which match the conditions
*
* @param {string | RequestObject} table - Name of the table to query
* @param {object} filter - Filter Object to query
* @param {RequestObject} options - An Options object containing all other request options
* @param {object} [filter] - Filter Object to query
* @param {RequestObject} [options] - An Options object containing all other request options
* @returns {Promise<number>} Number of matched items
*/
Dare.prototype.getCount = async function getCount(table, filter, options = {}) {
Expand Down Expand Up @@ -353,10 +380,10 @@ Dare.prototype.getCount = async function getCount(table, filter, options = {}) {
* Updates records matching the conditions
*
* @param {string | RequestObject} table - Name of the table to query
* @param {object} filter - Filter Object to query
* @param {object} body - Body containing new data
* @param {object} [filter] - Filter Object to query
* @param {object} [body] - Body containing new data
* @param {RequestObject} [options] - An Options object containing all other request options
* @returns {Promise<object>} Affected Rows statement
* @returns {Promise<any>} Affected Rows statement
*/
Dare.prototype.patch = async function patch(table, filter, body, options = {}) {
/**
Expand Down Expand Up @@ -434,9 +461,9 @@ Dare.prototype.patch = async function patch(table, filter, body, options = {}) {
* Insert new data into database
*
* @param {string | RequestObject} table - Name of the table to query
* @param {object | Array<object>} body - Body containing new data
* @param {object | Array<object>} [body] - Body containing new data
* @param {RequestObject} [options] - An Options object containing all other request options
* @returns {Promise<object>} Affected Rows statement
* @returns {Promise<any>} Affected Rows statement
*/
Dare.prototype.post = async function post(table, body, options = {}) {
/**
Expand Down Expand Up @@ -667,9 +694,9 @@ Dare.prototype.post = async function post(table, body, options = {}) {
* Delete a record matching condition
*
* @param {string | RequestObject} table - Name of the table to query
* @param {object} filter - Filter Object to query
* @param {RequestObject} options - An Options object containing all other request options
* @returns {Promise<object>} Affected Rows statement
* @param {object} [filter] - Filter Object to query
* @param {RequestObject} [options] - An Options object containing all other request options
* @returns {Promise<any>} Affected Rows statement
*/
Dare.prototype.del = async function del(table, filter, options = {}) {
/**
Expand Down
4 changes: 3 additions & 1 deletion test/specs/init.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ describe('Dare', () => {
});

it('should define default options', () => {
const models = {};
const models = {
mytable: {},
};
const dare = new Dare({
models,
});
Expand Down
14 changes: 12 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"noEmit": true,
"esModuleInterop": true,
"moduleResolution": "nodenext",
"target": "ES2022",
"typeRoots": ["node_modules/@types"],
"module": "NodeNext",
"checkJs": true,
"strict": false, // true for making types mandatory
// Tells TypeScript to read JS files, as
// normally they are ignored as source files
"allowJs": true,
"strict": false // true for making types mandatory
// Generate d.ts files
"declaration": true,
// This compiler run should
// only output d.ts files
"emitDeclarationOnly": true,
// Types should go into this directory.
// Removing this would place the .d.ts files
// next to the .js file
"outDir": "types"
},
"include": ["./**/*.js"]
}
38 changes: 38 additions & 0 deletions types/src/format/field_reducer.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Return a reducer function deriving local props and nested props
* @param {object} opts - Options
* @param {string} opts.field_alias_path - Current address path of the resource
* @param {Function} opts.extract - Function for handling the extraction of content
* @param {object} opts.table_schema - Table schema/Data model
* @param {object} opts.dareInstance - Instance of Dare which is calling this
* @returns {(fieldsArray: array, field: string | object, index: number, originalArray: array) => array} Fields Reducer function
*/
export default function fieldReducer({
field_alias_path,
extract,
table_schema,
dareInstance,
}: {
field_alias_path: string;
extract: Function;
table_schema: object;
dareInstance: object;
}): (
fieldsArray: any[],
field: string | object,
index: number,
originalArray: any[]
) => any[];
/**
* Get target path
* Given a model path, such as `picture`, reduce it of the parent path in the request path like `picture.url`
* So the result would be empty path because the target is on the base.
* If model path is `picture` and the request path is `url`, then the target path is just `picture`
* @param {string} modelPath - Model Path
* @param {string} requestPath - Request Path (incl. field)
* @returns {Array<string>} Target path
*/
export function getTargetPath(
modelPath: string,
requestPath: string
): Array<string>;
7 changes: 7 additions & 0 deletions types/src/format/groupby_reducer.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function groupbyReducer({
current_path,
extract,
}: {
current_path: any;
extract: any;
}): (list: any, item: any, index: any) => any;
13 changes: 13 additions & 0 deletions types/src/format/join_handler.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Join Handler
* Obtain the table join conditions which says how two tables reference one another
* @param {object} join_object - The object being joined
* @param {object} root_object - The root object, for which we want the join_object too attach
* @param {object} dareInstance - Dare Instance
* @returns {object} An updated join_object with new join_conditions attached
*/
export default function joinHandler(
join_object: object,
root_object: object,
dareInstance: object
): object;
39 changes: 39 additions & 0 deletions types/src/format/limit_clause.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* @typedef {object} LimitClause
* @property {number} limit - Limit defintion
* @property {number} [start] - Start defintion
* @property {boolean} [single] - Whether this is a single limit
*/
/**
* Limit Clause
* Set/Check limit and start positions
* @param {object} opts - Options object
* @param {number} opts.limit - Limit defintion
* @param {number} opts.start - Start defintion
* @param {number} MAX_LIMIT - Max limit on instance
* @returns {LimitClause} - Limit Clause
*/
export default function limitClause(
{
limit,
start,
}: {
limit: number;
start: number;
},
MAX_LIMIT: number
): LimitClause;
export type LimitClause = {
/**
* - Limit defintion
*/
limit: number;
/**
* - Start defintion
*/
start?: number;
/**
* - Whether this is a single limit
*/
single?: boolean;
};
12 changes: 12 additions & 0 deletions types/src/format/orderby_reducer.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
declare function _default({
current_path,
extract,
table_schema,
dareInstance,
}: {
current_path: any;
extract: any;
table_schema: any;
dareInstance: any;
}): (list: any, item: any, index: any) => any;
export default _default;

0 comments on commit c2a69be

Please sign in to comment.