Skip to content

Commit

Permalink
chore: use import type & use feathers-utils: getItemsIsArray (#72)
Browse files Browse the repository at this point in the history
  • Loading branch information
fratzinger authored Sep 15, 2022
1 parent 2ae365b commit a61c0d8
Show file tree
Hide file tree
Showing 43 changed files with 140 additions and 100 deletions.
4 changes: 2 additions & 2 deletions lib/channels/getChannelsWithReadAbility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ interface ConnectionsPerField {
}

import type { HookContext, Application } from "@feathersjs/feathers";
import type { ChannelOptions } from "../types";
import type { ChannelOptions, AnyData } from "../types";

export default (
app: Application,
data: Record<string, any>,
data: AnyData,
context: HookContext,
_options?: Partial<ChannelOptions>
): undefined | Channel | Channel[] => {
Expand Down
3 changes: 2 additions & 1 deletion lib/hooks/authorize/authorize.hook.before.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { Forbidden } from "@feathersjs/errors";
import _isEmpty from "lodash/isEmpty";
import _pick from "lodash/pick";
import _set from "lodash/set";
import { AnyAbility, subject } from "@casl/ability";
import type { AnyAbility } from "@casl/ability";
import { subject } from "@casl/ability";

import {
shouldSkip,
Expand Down
7 changes: 3 additions & 4 deletions lib/hooks/authorize/authorize.hook.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import getFieldsForConditions from "../../utils/getFieldsForConditions";
import { makeDefaultBaseOptions } from "../common";
import getAvailableFields from "../../utils/getAvailableFields";

import { getItems } from "feathers-hooks-common";
import { getItemsIsArray } from "feathers-utils";
import { HOOKNAME } from "./authorize.hook";

import {
Expand All @@ -27,7 +27,7 @@ import type {
Path,
ThrowUnlessCanOptions
} from "../../types";
import { Promisable } from "type-fest";
import type { Promisable } from "type-fest";

export const makeOptions = (
app: Application,
Expand Down Expand Up @@ -133,9 +133,8 @@ export const refetchItems = async (
params?: Params
): Promise<unknown[] | undefined> => {
if (context.type !== "after") { return; }
const itemOrItems = getItems(context);
const { items } = getItemsIsArray(context);

const items = (!itemOrItems || Array.isArray(itemOrItems)) ? itemOrItems : [itemOrItems];
if (!items) { return; }

const idField = context.service.options?.id;
Expand Down
5 changes: 2 additions & 3 deletions lib/hooks/common.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { subject } from "@casl/ability";
import { getItems } from "feathers-hooks-common";
import { getItemsIsArray } from "feathers-utils";

import { throwUnlessCan } from "./authorize/authorize.hook.utils";

Expand Down Expand Up @@ -44,8 +44,7 @@ export const checkCreatePerItem = (
if (!checkCreateForData) { return context; }

// we have all information we need (maybe we need populated data?)
let items = getItems(context);
items = (Array.isArray(items)) ? items : [items];
const { items } = getItemsIsArray(context);

for (let i = 0, n = items.length; i < n; i++) {
throwUnlessCan(
Expand Down
6 changes: 4 additions & 2 deletions lib/makeAbilityFromRules.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import {
Ability,
import type {
RawRuleFrom,
AbilityOptions,
AbilityTuple,
MongoQuery
} from "@casl/ability";
import {
Ability
} from "@casl/ability";

function makeAbilityFromRules<A extends AbilityTuple = AbilityTuple, C extends MongoQuery = MongoQuery>(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down
11 changes: 7 additions & 4 deletions lib/types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { HookContext } from "@feathersjs/feathers";
import { AnyAbility } from "@casl/ability";
import { Application } from "@feathersjs/feathers";
import type { HookContext } from "@feathersjs/feathers";
import type { AnyAbility } from "@casl/ability";
import type { Application } from "@feathersjs/feathers";
import "@feathersjs/transport-commons";
import { Channel, RealTimeConnection } from "@feathersjs/transport-commons/lib/channels/channel/base";
import type { Channel, RealTimeConnection } from "@feathersjs/transport-commons/lib/channels/channel/base";

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type AnyData = Record<string, any>


export type Adapter =
Expand Down
5 changes: 3 additions & 2 deletions test/channels/custom-actions/channels.custom-actions.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import assert from "assert";
import feathers, { Application } from "@feathersjs/feathers";
import type { Application } from "@feathersjs/feathers";
import feathers from "@feathersjs/feathers";
import socketio from "@feathersjs/socketio-client";
import { Server } from "http";
import type { Server } from "http";
import io from "socket.io-client";

import mockServer from "../.mockServer";
Expand Down
4 changes: 2 additions & 2 deletions test/channels/custom-actions/mockChannels.custom-actions.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import assert from "assert";
import "@feathersjs/transport-commons";
import { HookContext, Params } from "@feathersjs/feathers";
import type { HookContext, Params } from "@feathersjs/feathers";

import { getChannelsWithReadAbility, makeOptions } from "../../../lib/channels";
import { Application } from "@feathersjs/express";
import type { Application } from "@feathersjs/express";

export default function(app: Application): void {
if(typeof app.channel !== "function") {
Expand Down
7 changes: 4 additions & 3 deletions test/channels/custom-actions/mockServices.custom-actions.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Application, HookContext } from "@feathersjs/feathers";
import type { Application, HookContext } from "@feathersjs/feathers";
import { AuthenticationService, JWTStrategy } from "@feathersjs/authentication";
import { LocalStrategy } from "@feathersjs/authentication-local";
import { expressOauth } from "@feathersjs/authentication-oauth";

import { Ability, createAliasResolver, defineAbility } from "../../../lib";
import type { Ability } from "../../../lib";
import { createAliasResolver, defineAbility } from "../../../lib";
import { Service } from "feathers-memory";
import hashPassword from "@feathersjs/authentication-local/lib/hooks/hash-password";
import protect from "@feathersjs/authentication-local/lib/hooks/protect";
import { ServiceCaslOptions } from "../../../lib/types";
import type { ServiceCaslOptions } from "../../../lib/types";

const resolveAction = createAliasResolver({
update: "patch",
Expand Down
5 changes: 3 additions & 2 deletions test/channels/defaultSettings/channels.default.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import assert from "assert";
import feathers, { Application } from "@feathersjs/feathers";
import type { Application } from "@feathersjs/feathers";
import feathers from "@feathersjs/feathers";
import socketio from "@feathersjs/socketio-client";
import { Server } from "http";
import type { Server } from "http";
import io from "socket.io-client";

import mockServer from "../.mockServer";
Expand Down
4 changes: 2 additions & 2 deletions test/channels/defaultSettings/mockChannels.default.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import assert from "assert";
import "@feathersjs/transport-commons";
import { HookContext, Params } from "@feathersjs/feathers";
import type { HookContext, Params } from "@feathersjs/feathers";

import { getChannelsWithReadAbility, makeOptions } from "../../../lib/channels";
import { Application } from "@feathersjs/express";
import type { Application } from "@feathersjs/express";

export default function(app: Application): void {
if(typeof app.channel !== "function") {
Expand Down
5 changes: 3 additions & 2 deletions test/channels/defaultSettings/mockServices.default.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Application, HookContext } from "@feathersjs/feathers";
import type { Application, HookContext } from "@feathersjs/feathers";
import { AuthenticationService, JWTStrategy } from "@feathersjs/authentication";
import { LocalStrategy } from "@feathersjs/authentication-local";
import { expressOauth } from "@feathersjs/authentication-oauth";

import { Ability, createAliasResolver, defineAbility } from "../../../lib";
import type { Ability } from "../../../lib";
import { createAliasResolver, defineAbility } from "../../../lib";
import { Service } from "feathers-memory";
import hashPassword from "@feathersjs/authentication-local/lib/hooks/hash-password";
import protect from "@feathersjs/authentication-local/lib/hooks/protect";
Expand Down
5 changes: 3 additions & 2 deletions test/channels/receive/channels.receive.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import assert from "assert";
import feathers, { Application } from "@feathersjs/feathers";
import type { Application } from "@feathersjs/feathers";
import feathers from "@feathersjs/feathers";
import socketio from "@feathersjs/socketio-client";
import { Server } from "http";
import type { Server } from "http";
import io from "socket.io-client";

import mockServer from "../.mockServer";
Expand Down
4 changes: 2 additions & 2 deletions test/channels/receive/mockChannels.receive.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import assert from "assert";
import "@feathersjs/transport-commons";
import { HookContext, Params } from "@feathersjs/feathers";
import type { HookContext, Params } from "@feathersjs/feathers";

import { getChannelsWithReadAbility, makeOptions } from "../../../lib/channels";
import { Application } from "@feathersjs/express";
import type { Application } from "@feathersjs/express";

export default function(app: Application): void {
if(typeof app.channel !== "function") {
Expand Down
7 changes: 4 additions & 3 deletions test/channels/receive/mockServices.receive.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Application, HookContext } from "@feathersjs/feathers";
import type { Application, HookContext } from "@feathersjs/feathers";
import { AuthenticationService, JWTStrategy } from "@feathersjs/authentication";
import { LocalStrategy } from "@feathersjs/authentication-local";
import { expressOauth } from "@feathersjs/authentication-oauth";

import { Ability, createAliasResolver, defineAbility } from "../../../lib";
import type { Ability } from "../../../lib";
import { createAliasResolver, defineAbility } from "../../../lib";
import { Service } from "feathers-memory";
import hashPassword from "@feathersjs/authentication-local/lib/hooks/hash-password";
import protect from "@feathersjs/authentication-local/lib/hooks/protect";
import { ServiceCaslOptions } from "../../../lib/types";
import type { ServiceCaslOptions } from "../../../lib/types";

const resolveAction = createAliasResolver({
update: "patch",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import assert from "assert";
import feathers, { Application } from "@feathersjs/feathers";
import type { Application } from "@feathersjs/feathers";
import feathers from "@feathersjs/feathers";
import socketio from "@feathersjs/socketio-client";
import { Server } from "http";
import type { Server } from "http";
import io from "socket.io-client";

import mockServer from "../.mockServer";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import assert from "assert";
import "@feathersjs/transport-commons";
import { HookContext, Params } from "@feathersjs/feathers";
import type { HookContext, Params } from "@feathersjs/feathers";

import { getChannelsWithReadAbility, makeOptions } from "../../../lib/channels";
import { Application } from "@feathersjs/express";
import type { Application } from "@feathersjs/express";

export default function(app: Application): void {
if(typeof app.channel !== "function") {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Application, HookContext } from "@feathersjs/feathers";
import type { Application, HookContext } from "@feathersjs/feathers";
import { AuthenticationService, JWTStrategy } from "@feathersjs/authentication";
import { LocalStrategy } from "@feathersjs/authentication-local";
import { expressOauth } from "@feathersjs/authentication-oauth";

import { Ability, createAliasResolver, defineAbility } from "../../../lib";
import type { Ability } from "../../../lib";
import { createAliasResolver, defineAbility } from "../../../lib";
import { Service } from "feathers-memory";
import hashPassword from "@feathersjs/authentication-local/lib/hooks/hash-password";
import protect from "@feathersjs/authentication-local/lib/hooks/protect";
import { ServiceCaslOptions } from "../../../lib/types";
import type { ServiceCaslOptions } from "../../../lib/types";

const resolveAction = createAliasResolver({
update: "patch",
Expand Down
2 changes: 1 addition & 1 deletion test/hooks/authorize/adapters/feathers-memory.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Service } from "feathers-memory";
import { ServiceCaslOptions } from "../../../../lib/types";
import type { ServiceCaslOptions } from "../../../../lib/types";
import makeTests from "./makeTests";

declare module "@feathersjs/adapter-commons" {
Expand Down
10 changes: 4 additions & 6 deletions test/hooks/authorize/adapters/knex.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import knex from "knex";
import makeTests from "./makeTests";
import { Service } from "feathers-knex";
import { getItems } from "feathers-hooks-common";
import { getItemsIsArray } from "feathers-utils";
import path from "path";
import { ServiceCaslOptions } from "../../../../lib/types";
import { HookContext } from "@feathersjs/feathers";
import type { ServiceCaslOptions } from "../../../../lib/types";
import type { HookContext } from "@feathersjs/feathers";

const db = knex({
client: "sqlite3",
Expand Down Expand Up @@ -60,9 +60,7 @@ const boolFields = [

const afterHooks = [
(context: HookContext) => {
let items = getItems(context);
const isArray = Array.isArray(items);
items = (isArray) ? items : [items];
const { items, isArray } = getItemsIsArray(context);

const result = items;

Expand Down
4 changes: 2 additions & 2 deletions test/hooks/authorize/adapters/makeTests/create-multi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ const resolveAction = createAliasResolver({
delete: "remove",
});

import { Application } from "@feathersjs/feathers";
import type { Application } from "@feathersjs/feathers";

import authorize from "../../../../../lib/hooks/authorize/authorize.hook";
import { Adapter, AuthorizeHookOptions } from "../../../../../lib/types";
import type { Adapter, AuthorizeHookOptions } from "../../../../../lib/types";

export default (
adapterName: Adapter,
Expand Down
4 changes: 2 additions & 2 deletions test/hooks/authorize/adapters/makeTests/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ const resolveAction = createAliasResolver({
delete: "remove",
});

import { Application } from "@feathersjs/feathers";
import type { Application } from "@feathersjs/feathers";

import authorize from "../../../../../lib/hooks/authorize/authorize.hook";
import { Adapter, AuthorizeHookOptions } from "../../../../../lib/types";
import type { Adapter, AuthorizeHookOptions } from "../../../../../lib/types";

export default (
adapterName: Adapter,
Expand Down
39 changes: 36 additions & 3 deletions test/hooks/authorize/adapters/makeTests/find.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import assert from "assert";
import feathers, { Paginated } from "@feathersjs/feathers";
import type { Paginated } from "@feathersjs/feathers";
import feathers from "@feathersjs/feathers";
import { createAliasResolver, defineAbility } from "@casl/ability";
import _sortBy from "lodash/sortBy";

Expand All @@ -9,10 +10,10 @@ const resolveAction = createAliasResolver({
delete: "remove",
});

import { Application } from "@feathersjs/feathers";
import type { Application } from "@feathersjs/feathers";

import authorize from "../../../../../lib/hooks/authorize/authorize.hook";
import { Adapter, AuthorizeHookOptions } from "../../../../../lib/types";
import type { Adapter, AuthorizeHookOptions } from "../../../../../lib/types";

export default (
adapterName: Adapter,
Expand Down Expand Up @@ -489,6 +490,38 @@ export default (
"just returned one item"
);
});

it("works with nested $and/$or", async function () {
// no
await service.create({ test: true, published: false, hidden: true, userId: 1 });
await service.create({ test: true, published: false, hidden: false, userId: 2 });
await service.create({ test: true, published: true, hidden: true, userId: 3 });

// yes
await service.create({ test: true, published: false, hidden: false, userId: 1 });
await service.create({ test: true, published: true, hidden: false, userId: 2 });


const returnedItems = await service.find({
ability: defineAbility((can) => {
can("read", "tests", { userId: 1 });
can("read", "tests", { userId: { $ne: 1 }, published: true });
}, { resolveAction }),
query: {
$or: [
{ userId: 1 },
{ userId: { $ne: 1 }, published: true }
],
userId: { $in: [1, 2, 3] },
hidden: false
},
paginate: false
}) as any[];

const hallo = "";

assert.deepEqual(returnedItems.length, 2);
});
});
});
};
4 changes: 2 additions & 2 deletions test/hooks/authorize/adapters/makeTests/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ const resolveAction = createAliasResolver({
delete: "remove",
});

import { Application } from "@feathersjs/feathers";
import type { Application } from "@feathersjs/feathers";

import authorize from "../../../../../lib/hooks/authorize/authorize.hook";
import { Adapter, AuthorizeHookOptions } from "../../../../../lib/types";
import type { Adapter, AuthorizeHookOptions } from "../../../../../lib/types";

export default (
adapterName: Adapter,
Expand Down
Loading

0 comments on commit a61c0d8

Please sign in to comment.