Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Created support for event filter and permission hooks. Reorganized service hooks because of this. #75

Merged
merged 6 commits into from
Jan 5, 2017

Conversation

eddyystop
Copy link
Collaborator

@eddyystop eddyystop commented Dec 17, 2016

[Edited for simplification and clarity]

  • Eric needs some of the service hooks to work for event filters, especially the conditionals.
  • I felt the conditional hooks should work for permissions as well.
  • Duck typing would not work as service and permission hook funcs both have a signature of (hook).
  • Filter and permission hooks were therefore implemented using higher order constructs.
  • The service hooks in the repo were re-grouped into files which made sense.

hooks = require('feathers-hooks-common')

  • Runs same code as it has previously. Nothing new introduced.

filterHooks = require('feathers-hooks-common/filters')

  • Provides filterHooks.iffElse(predicate, [trueFilters], [falseFilters]);
    as well as iff, iff.else, when, unless and ifNot
  • Provides filterHooks.some(...trueFalse) and every.
  • Provides filterHooks.remove(), .pluck(), traverse() and the new setFilteredAt()
  • These hooks, the predicate and [trueFilters] have signature (data, connection, hook).
  • The [trueFilters] are dispatched one after another using the same code as
    https://github.com/feathersjs/feathers-socket-commons/blob/master/src/events.js#L41-L70
  • The hooks return 'false' or modified data.

permissionHooks = require('feathers-hooks-common/permissions')

  • Provides permissionHooks.iffElse(predicate, [truePermissions], [falsePermissions]);
    as well as iff, iff.else, when, unless and ifNot
  • Provides permissionHooks.some(...trueFalse) and every.
  • These hooks, the predicate and [truePermissions] have signature (hook).
  • some and every may be used as either the predicate or [truePermissions].
  • The [truePermissions] are dispatched in parallel. The result is true if they all returned true,
    i.e. they work file every().
  • The hooks return a boolean.

hooks = require('feathers-hooks-common/hooks')

  • All the same hooks as feathers-hooks-common but using the same same common code as filter
    and permission hooks.
  • Code for hooks and tests now sensibly organized.
  • The reorganization was cut/paste. The 350+ tests are detailed. I feel comfortable with the result.

Outstanding

Which hooks to use?

  • I suggest we change feathers-hooks-common/index.js to require feathers-hooks-common/hooks.
  • The existing hooks are packaged the way they are for historical reasons. Not logically.
  • The tests are a bag of files.
  • The hooks were repackaged to support the filer and permission higher order functions.
    The packaging is sensible and follows the layout of the docs.
  • The reganization was cut/paste. The 350+ tests are detailed. I feel comfortable with the reorganization.

…ermissions

- DO NOT MERGE
- More than a POC, this is working. Just need to expose new funcs.
- feathers-hooks-common works unchanged.
- 'Unused' code has been added to the repo for the POC.
- 'hooks' for filters were not implemented by duck typing, rather filters,
permissions, and new-hooks use common code in /src/common.
- (new-hooks are some of the existing services hooks but now using the
common code)
- It's easy to extend this design for other things.

For now:
- import filters from 'feathers-hooks-common/filters';
- import permissions from 'feathers-hooks-common/permissions';
- import newHooks from 'feathers-hooks-common/hooks';

Then:
- filters.iffElse(predicate, [trueFilters], [falseFilters]);
as well as iff, iff.else, when, unless, some, every, ifNot
- permissions.iffElse(predicate, [truePermissions], [falsePermissions])
as well as iff, iff.else, when, unless, some, every, ifNot
- [truePermissions] evals true if every func returns true i.e. like 'every'
- newHooks.iff() works like the existing hooks.iff() but using the new code

Also:
- filters.remove(), .pluck(), .traverse(), .setFilteredAt()

Pros and cons:
- duck typing might look nice but what do you do with
hooks.iff(predicate, [servicesHook, filterHook, permissionFunc]) ?
- using filters., permissions., newHooks. is unambiguous and likely
the 'right' way to implement this.
- I think it reduces the cognative load on the dev.

Code
- src/common/conditionals.js is a factory to build conditional funcs.
- src/common/alter-data.js has the code that does updates for
non-conditional funcs. A factory wouldn't work well.
- src/filters, src/permissions, src/hooks build the funcs
- test/filters, test/permission, test/hook are tests for the new funcs.

Outstanding
- Leave these in feathers-hooks-common or bundle them with
filters and permissions?
- Do we want a filters.validateSchema?
- Those new-hooks we have will have to replace any existing hooks.
- filters.iff(some(...), ...) now passes data, connection, hook to
funcs within some(...)
- added tests to check iffElse predicate gets (hook) or
(data, connection, hook) properly
- added tests for some/every to permissions
@eddyystop
Copy link
Collaborator Author

Code Climate is complaining about 'similar' 3 line pieces of code. The code would be harder to read if I refactored. Alternatively there would be going on a dozen fingerprints to file.

I want to suppress similar code checking for this repo.

- When feathers-hooks/bundled and eddyystop/feathers-hooks-common combined,
their .js files were copied over as is. New hooks have since been added to
new.js, populate.js and so on.
- Basically the hooks are not organized in any reasonable fashion.
- The tests are also a big bag of files.
- The new-hooks have been organized in the same order of the docs. Hooks
documented in hooks .. common .. query params are in src/hooks/query-params.js
- The new-hooks test are similarly organized e.g. test/hooks/query-params
- Repetitive code has been made DRY and JSDoc comments have been removed.
The new-hook files are smaller than the regular hook ones.
- BREAKING CHANGE Some bundled hooks allowed their last param to be an
optional function that determined if the hooks was to be run. This feature
has already been deprecated. It has now been removed. (Does anyone use this?)
- validateSchema and $client, still under review for the normal hooks,
are included here.
- The babel-pollyfill has been removed from all the tests.
- src/hooks is self contained. It does not refer to any other code. It has
its own copy of legacyPopulate for example.

The point:
- We can use src/filters and src/permissions for filters and permissions.
- Devs continue to use feathers-hooks-common as they do now. They don't run
any new code that way.
- I will update src/hooks with any changes or new hooks added to the
current hooks.
- We switch over to the new-hooks for Buzzard release and
the repo's structure makes sense.
@eddyystop
Copy link
Collaborator Author

eddyystop commented Dec 18, 2016

[Removed]

@eddyystop eddyystop changed the title POC for conditional and other funcs ('hooks') for event filters and p… Reorganizing to support conditional and other funcs ('hooks') for event filters and permissions. Dec 18, 2016
@eddyystop eddyystop changed the title Reorganizing to support conditional and other funcs ('hooks') for event filters and permissions. Created support for event filter and permission hooks. Reorganized service hooks because of this. Dec 19, 2016
- Disabled checking for duplication/similar code as per talk with Eric.
- Using what Eric used in feathers-authentication
@ekryski
Copy link
Member

ekryski commented Dec 19, 2016

Do we leave the filter and permission hooks here or bundle them from elsewhere?

I think they probably should be their own repo but this is a good stop for now. Nice work!

Nice work re-organizing the files. That was a good call and was something I was going to do when I had some time.

On visual inspection it looks all good. I won't be able to pull this down and run it until this evening but if it's all good I'll merge and release (if that's cool with you @eddyystop) and then try and get feathers-permissions released as well.

@eddyystop
Copy link
Collaborator Author

There are some current hooks whose last param is an optional predicate func. That option displays a deprecated message, and the option was not documented since before I joined up here.

Full disclosure: I removed those options in feathers-hooks-common/hooks. I can make changes to remain backward compatible if that's necessary,.

@daffl
Copy link
Member

daffl commented Dec 23, 2016

I feel like I'm missing something, what was the reason for adding 8500 lines of code for supporting filters? I see there is some reorganization but it looks like all the old things are still there. Also, would it make more sense to just have each hook in their own file and not have to worry about how to organize them (that's what I was going for eventually)?

@eddyystop
Copy link
Collaborator Author

eddyystop commented Dec 23, 2016

The idea is to delete the old hook files and use the new, reorganized files.

I can break the new hook files into one per hook. There will be something like 80 of them.

@daffl
Copy link
Member

daffl commented Dec 23, 2016

I think it makes sense since the test files are already mostly individual per hook and it'll be easier for everybody to know where to find what. The only other thing I was going to suggest is to use dash-separated instead of camelCased filenames. It might not be a super common problem but I had some trouble with Git, camelCased filenames and case-insensitive vs case sensitive file systems (Windows vs. Unix) before.

@ekryski
Copy link
Member

ekryski commented Dec 23, 2016

I'm down with having 1 hook per file and would prefer it but I don't think it should stop this from shipping. That's some thing that really is internal to the module and doesn't affect the public API. In fact, I'd actually love to have all hook functions exposed top level (even utils) so that we can just do:

import {checkContext} from feathers-hooks-common;

Again, not something that should happen in this PR.

@eddyystop
Copy link
Collaborator Author

I'd actually love to have all hook functions exposed top level (even utils) so that we can just do:

These changes do that.

@eddyystop
Copy link
Collaborator Author

eddyystop commented Dec 23, 2016

There is a related issue I'd like to address.

I think this is too tardy even for an approaching holiday season.

  • I'm starting to get (minor) merge conflicts with myself.
  • I have code waiting which assumes un-reviewed code will land.
  • I have to keep a list of what else to do once each PR lands.
  • I'm losing the fun factor.

Can we make go, no go decisions on the above 3 PRs?

I'll then break the hooks down to individual files. I suggest they remain under the folders as in this PR rather than a bag of 80 files. These folders tie into the structure of the docs.

- Transpiling error in arrow func with (...hooks).call(this, hook)
in iffElse() of old files
- Changed code in case same error in slightly different iffElse() in new files
@daffl
Copy link
Member

daffl commented Dec 24, 2016

I just noticed this one because it was still open and had a huge number of additions.

In general, if it's a non-breaking new feature (#63) I don't think there is anything wrong with just pushing it out and iterating.

For #65 nobody has replied to my last comment.

@eddyystop
Copy link
Collaborator Author

So I can take that as a :shipit: ?

@daffl
Copy link
Member

daffl commented Dec 30, 2016

It seems like a huge amount of additions to me which also makes it really hard to review but if it's what @ekryski needs then sure.

@ekryski
Copy link
Member

ekryski commented Dec 30, 2016

I'm looking this afternoon for real. Will come back with comments. @daffl from what I can see the majority of the changes are just restructuring.

@daffl
Copy link
Member

daffl commented Dec 30, 2016

It looks like it's mostly additions and no deletions which what I was wondering about.

@eddyystop Should we move each hook into their own files? I think it'll be the best and most straightforward way of structuring it. I can make a PR for it.

@eddyystop
Copy link
Collaborator Author

eddyystop commented Dec 31, 2016

Once this PR is approved my intent was, first, to remove the old files like new.js and common.js and have src/index.js inherit from src/hooks/index.js, thereby pointing to the new files like alter-data.js. These new files share code in src/common/ with the hooks for filters and permissions. I've already mentioned removing the old files above.

Second, to break the new files into files for individual hooks.

I've already started on this breaking out of the files but stopped part way through because this PR was going nowhere and has enough PRs added to it.

@ekryski
Copy link
Member

ekryski commented Jan 5, 2017

@eddyystop :shipit: :shipit: :shipit: :shipit: :shipit: :shipit: !!!!! 😄

Sorry it's taken me so long to review this properly but it looks good. Lemme know when you have another PR up to remove the old files and we'll get that merged ASAP. I think having the old files around and mixing new functionality with a re-structuring is what made this a harder review. Maybe in the future we can try and break those up into separate PRs.

Really nice work!

@eddyystop eddyystop merged commit dfee696 into master Jan 5, 2017
@daffl daffl deleted the filters branch January 5, 2017 22:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants