<commit_before>import $path from 'path'

export class Router {
	app = null
	bindings = { }
	patterns = { }
	namedRoutes = { }

	_scopedActionStack = [ { } ]
	_scopedPrefixStack = [ '/' ]

	get _scopedAction() {
		return this._scopedActionStack[this._scopedActionStack.length - 1]
	}

	get _scopedPrefix() {
		return this._scopedPrefixStack[this._scopedPrefixStack.length - 1]
	}

	constructor(app) {
		this.app = app
	}

	group(action, callback) {
		if(!action.controller.isNil && typeof action.controller === 'function') {
			action.controller = new action.controller(this.app)
		}

		const parentAction = this._scopedAction
		const parentPrefix = this._scopedPrefix

		const scopedAction = Object.assign({ }, parentAction, action)
		let scopedPrefix = scopedAction.prefix
		delete scopedAction.prefix
		this._scopedActionStack.push(scopedAction)

		if(!scopedPrefix.isNil && scopedPrefix.length > 0) {
			if(!parentPrefix.isNil && parentPrefix.length > 0) {
				scopedPrefix = $path.join(parentPrefix, scopedPrefix)
			}

			this._scopedPrefixStack.push(this._normalizePathComponent(scopedPrefix))
		} else {
			this._scopedPrefixStack.push(parentPrefix)
		}

		callback(this, action.controller)

		this._scopedActionStack.pop()
		this._scopedPrefixStack.pop()
	}

	all(path, action) {
		console.log('Don’t use `all` routes. Offender: %s', path)
		return this.app.express.all(this._scopedPrefix + path, this._makeAction(action))
	}

	get(path, action, context) {
		return this._add('get', path, action, context)
	}

	post(path, action, context) {
		return this._add('post', path, action, context)
	}

	put(path, action, context) {
		return this._add('put', path, action, context)
	}

	patch(path, action, context) {
		return this._add('patch', path, action, context)
	}

	delete(path, action, context) {
		return this._add('delete', path, action, context)
	}

	_add(method, path, action, context) {
		const handler = this._makeAction(action)

		// WARNING: Prone to failure if ExpressJS changes this logic
		this.app.express.lazyrouter()

		const handlers = [ handler ]

		if(typeof action.use !== 'undefined') {
			if(Array.isArray(action.use)) {
				action.use = {
					before: action.use
				}
			}

			if(typeof action.use === 'object') {
				if(Array.isArray(action.use.before)) {
					handlers.unshift(...action.use.before)
				} else if(Array.isArray(action.use.before)) {
					handlers.push(...action.use.after)
				}
			}
		}

		path = this._normalizePathComponent(path)
		const compiledPath = $path.join('/', this._scopedPrefix, path).replace(/:([a-z0-0_\-\.]+)/g, (param, name) => {
			const pattern = this.patterns[name]

			if(pattern.isNil) {
				return param
			} else {
				return param + '(' + pattern + ')'
			}
		})

		let route = this.app.express._router.route(compiledPath)
		route = route[method](...handlers)
		route.context = context || {}
		route.grindRouter = this

		return route
	}

	_makeAction(action) {
		if(typeof action === 'function') {
			return action
		}

		if(typeof action === 'string') {
			action = { method: action }
		}

		action = Object.assign({ }, this._scopedAction, action)
		const method = action.controller[action.method]
		const controller = action.controller

		return (...args) => {
			const result = method.apply(controller, args)

			if(typeof result === 'object' && typeof result.catch === 'function') {
				return result.catch(args[2])
			} else {
				return result
			}
		}
	}

	_normalizePathComponent(component) {
		return $path.normalize(component.trim()).replace(/^\//, '')
	}

	bind(name, resolver, context) {
		this.bindings[name] = { resolver }<commit_msg>Renamed all `path` vars in `Router` to `pathname` This allows for `path to be imported as `path` instead of `$path`<commit_after>import path from 'path'

export class Router {
	app = null
	bindings = { }
	patterns = { }
	namedRoutes = { }

	_scopedActionStack = [ { } ]
	_scopedPrefixStack = [ '/' ]

	get _scopedAction() {
		return this._scopedActionStack[this._scopedActionStack.length - 1]
	}

	get _scopedPrefix() {
		return this._scopedPrefixStack[this._scopedPrefixStack.length - 1]
	}

	constructor(app) {
		this.app = app
	}

	group(action, callback) {
		if(!action.controller.isNil && typeof action.controller === 'function') {
			action.controller = new action.controller(this.app)
		}

		const parentAction = this._scopedAction
		const parentPrefix = this._scopedPrefix

		const scopedAction = Object.assign({ }, parentAction, action)
		let scopedPrefix = scopedAction.prefix
		delete scopedAction.prefix
		this._scopedActionStack.push(scopedAction)

		if(!scopedPrefix.isNil && scopedPrefix.length > 0) {
			if(!parentPrefix.isNil && parentPrefix.length > 0) {
				scopedPrefix = path.join(parentPrefix, scopedPrefix)
			}

			this._scopedPrefixStack.push(this._normalizePathComponent(scopedPrefix))
		} else {
			this._scopedPrefixStack.push(parentPrefix)
		}

		callback(this, action.controller)

		this._scopedActionStack.pop()
		this._scopedPrefixStack.pop()
	}

	all(pathname, action) {
		console.log('Don’t use `all` routes. Offender: %s', pathname)
		return this.app.express.all(this._scopedPrefix + pathname, this._makeAction(action))
	}

	get(pathname, action, context) {
		return this._add('get', pathname, action, context)
	}

	post(pathname, action, context) {
		return this._add('post', pathname, action, context)
	}

	put(pathname, action, context) {
		return this._add('put', pathname, action, context)
	}

	patch(pathname, action, context) {
		return this._add('patch', pathname, action, context)
	}

	delete(pathname, action, context) {
		return this._add('delete', pathname, action, context)
	}

	_add(method, pathname, action, context) {
		const handler = this._makeAction(action)

		// WARNING: Prone to failure if ExpressJS changes this logic
		this.app.express.lazyrouter()

		const handlers = [ handler ]

		if(typeof action.use !== 'undefined') {
			if(Array.isArray(action.use)) {
				action.use = {
					before: action.use
				}
			}

			if(typeof action.use === 'object') {
				if(Array.isArray(action.use.before)) {
					handlers.unshift(...action.use.before)
				} else if(Array.isArray(action.use.before)) {
					handlers.push(...action.use.after)
				}
			}
		}

		pathname = this._normalizePathComponent(pathname)
		const compiledPath = path.join('/', this._scopedPrefix, pathname).replace(/:([a-z0-0_\-\.]+)/g, (param, name) => {
			const pattern = this.patterns[name]

			if(pattern.isNil) {
				return param
			} else {
				return param + '(' + pattern + ')'
			}
		})

		let route = this.app.express._router.route(compiledPath)
		route = route[method](...handlers)
		route.context = context || {}
		route.grindRouter = this

		return route
	}

	_makeAction(action) {
		if(typeof action === 'function') {
			return action
		}

		if(typeof action === 'string') {
			action = { method: action }
		}

		action = Object.assign({ }, this._scopedAction, action)
		const method = action.controller[action.method]
		const controller = action.controller

		return (...args) => {
			const result = method.apply(controller, args)

			if(typeof result === 'object' && typeof result.catch === 'function') {
				return result.catch(args[2])
			} else {
				return result
			}
		}
	}

	_normalizePathComponent(component) {
		return path.normalize(component.trim()).replace(/^\//, '')
	}

	bind(name, resolver, context) {
		this.bindings[name] = { resolver }
{'fraction_non_alphanumeric': 0.14516999460334593, 'fraction_numerical': 0.0018888289260658392, 'mean_word_length': 3.7276785714285716, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4687699', 'n_tokens_mistral': 2766, 'n_tokens_neox': 2436, 'n_words': 487}