# @v-sandbox/shared-graphql-constants

> Shared constants for sandbox projects

Latest version **1.0.0** (published 2023-06-06) · UNLICENSED license · 0 weekly downloads

## Install

```sh
npm install @v-sandbox/shared-graphql-constants
pnpm add @v-sandbox/shared-graphql-constants
yarn add @v-sandbox/shared-graphql-constants
bun add @v-sandbox/shared-graphql-constants
```

## Health

**Score 20/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities.

Warnings: low downloads; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.0 |
| Published | 2023-06-06 |
| First published | 2023-06-06 |
| Weekly downloads | 0 |
| License | UNLICENSED |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 15 |
| Unpacked size | 54.6 KB |
| Known vulnerabilities | 0 (+2 in 2 direct dependencies) |
| Install scripts | no |
| Author | @zwanzigg |
| Maintainers | vshreder |

## Links

- npm: https://www.npmjs.com/package/@v-sandbox/shared-graphql-constants
- Repository: https://github.com/zwanzigg/npm-shared-graphql-constants
- Homepage: https://github.com/zwanzigg/npm-shared-graphql-constants#readme
- Issues: https://github.com/zwanzigg/npm-shared-graphql-constants/issues
- npm.io page: https://npm.io/package/@v-sandbox/shared-graphql-constants

## Dependencies (15)

- [rxjs](https://npm.io/package/rxjs.md) ^7.5.6
- [graphql](https://npm.io/package/graphql.md) ^15.5.0
- [mongodb](https://npm.io/package/mongodb.md) ^5.6.0
- [mongoose](https://npm.io/package/mongoose.md) ^7.2.2
- [@nestjs/core](https://npm.io/package/@nestjs/core.md) ^9.4.2
- [type-graphql](https://npm.io/package/type-graphql.md) ^1.1.1
- [@nestjs/common](https://npm.io/package/@nestjs/common.md) ^9.4.2
- [@nestjs/graphql](https://npm.io/package/@nestjs/graphql.md) ^7.11.0
- [class-validator](https://npm.io/package/class-validator.md) 0.14.0
- [mongoose-delete](https://npm.io/package/mongoose-delete.md) ^0.5.3
- [graphql-type-json](https://npm.io/package/graphql-type-json.md) ^0.3.2
- [@typegoose/typegoose](https://npm.io/package/@typegoose/typegoose.md) ^11.2.0
- [mongoose-autopopulate](https://npm.io/package/mongoose-autopopulate.md) ^0.12.3
- [@v-sandbox/shared-errors](https://npm.io/package/@v-sandbox/shared-errors.md) ^1.0.3
- [@v-sandbox/shared-constants](https://npm.io/package/@v-sandbox/shared-constants.md) ^1.0.1

## Recent versions

- 1.0.0 (latest) — 2023-06-06

## README

# @v-sandbox/shared-graphql-constants
 
### 1. The shared Timestamp Model:
    - TimestampModel
    - ITimestampModel

### 2. The shared User Relation Model:
    - UserRelationModel
    - IUserRelationModel
  
### 3 The shared Content Base Model:
    - ContentBaseModel
    - IContentBaseModel
  
```typescript
import { Schema } from 'mongoose';
export declare abstract class ITimestampModel {
  _id?: string;
  created_at?: Date;
  last_updated_at?: Date;
  deleted?: boolean;
  static get schema(): Schema;
  static softDelete: (_id: string, user_id?: string) => Promise<boolean>;
}
export declare abstract class TimestampModel extends ITimestampModel {
}

import { ITimestampModel } from "@blipiqlabs/edu-shared-graphql-constants";
export declare abstract class IUserRelationModel extends ITimestampModel {
  created_by?: string;
  last_updated_by?: string;
  org_id?: string;
}
export declare abstract class UserRelationModel extends IUserRelationModel {
}

import { IUserRelationModel } from "@blipiqlabs/edu-shared-graphql-constants";
import { ContentBaseModelStatus } from "@blipiqlabs/edu-shared-graphql-constants";
export declare abstract class IContentBaseModel extends IUserRelationModel {
  status: ContentBaseModelStatus;
  status_timestamp: Date;
}
export declare abstract class ContentBaseModel extends IContentBaseModel {
}

```

### 4. The shared Base Service:
    - BaseService
```typescript
import { MongoError } from 'mongodb';
import { CreateQuery, Document, FilterQuery, Model, Types, UpdateQuery } from 'mongoose';
import { UserRelationModel, TimestampModel } from "@blipiqlabs/edu-shared-graphql-constants";
import { TakePaginationInput } from "../common/take-pagination.input";
export declare abstract class BaseService<T extends TimestampModel | UserRelationModel | ContentBaseModel> {
    model: Model<T>;
    protected constructor(model: Model<T>);
    protected static throwMongoError(err: MongoError): void;
    delete(_id: string, user_id: string): Promise<boolean>;
    protected static toObjectId(id: string): Types.ObjectId;
    _findOne(filter?: {}): Promise<T>;
    findOne(filter?: {}): Promise<T>;
    _findById(id: string): Promise<T>;
    findById(id: string): Promise<T>;
    _findOneAndUpdate(query: FilterQuery<T & Document>, item: UpdateQuery<T & Document>, options?: QueryFindOneAndUpdateOptions): Promise<T>;
    findOneAndUpdate(query: FilterQuery<T & Document>, item: UpdateQuery<T & Document>, options?: QueryFindOneAndUpdateOptions): Promise<T>;
    _create(item: CreateQuery<T>): Promise<T>;
    create(item: CreateQuery<T>): Promise<T>;
    _deleteById(id: string): Promise<T>;
    deleteById(id: string): Promise<T>;
    _update(item: T, options?: QueryFindOneAndUpdateOptions): Promise<T>;
    update(item: Partial<T>, options?: QueryFindOneAndUpdateOptions): Promise<T>;
    _updateMany(filter: FilterQuery<T>, item: Partial<T>, options?: QueryFindOneAndUpdateOptions): Promise<Promise<T[]> | Query<T[]>>;
    private _count;
    count(filter?: {}): Promise<number>;
    _find(item?: {}): Promise<Array<T>>;
    find(item?: FilterQuery<T>): Promise<Array<T>>;
    private filterQuery;
    getDocuments(filter?: FilterQuery<T>, pagination?: PaginationInput, populate?: QueryPopulateOptions | QueryPopulateOptions[]): Promise<PaginatedModel<T>>;
    getDocumentsByAtlasSearch(queryString?: string, filter?: FilterQuery<T>, pagination?: PaginationInput): Promise<PaginatedModel<T>>;
    private getMatchStage;
    private static transformQueryStringToArray;
    private getTotalDocumentsByAtlasSearch;
    private getAllDocumentsByAtlasSearch;
    private getLimitedDocumentsByAtlasSearch;
    private getPageInfo;
}
```

### 5. The shared functionality:
    - Paginated

```typescript
import { Field, ObjectType, Int } from '@nestjs/graphql';
import { Type } from '@nestjs/common';

@ObjectType()
export class PageInfo {
  @Field(() => Boolean)
  hasNextPage: boolean;

  @Field(() => String, { nullable: true })
  after?: string;
}

export function Paginated<T>(classRef: Type<T>): any {
  @ObjectType({ isAbstract: true })
  abstract class PaginatedType {
    @Field(() => [classRef], { nullable: true })
    docs: T[];

    @Field(() => Int)
    total: number;

    @Field(() => PageInfo)
    pageInfo: PageInfo;
  }

  return PaginatedType;
}
```

### 6. The shared helper methods:

    -escapeRegExp


### 7. The shared types:
    - DifficultyLevel
    - AgeGroup

```typescript
@InputType('DifficultyLevelInput')
@ObjectType('DifficultyLevelType')
@modelOptions({ options: { allowMixed: Severity.ALLOW }, schemaOptions: { _id: false } })
export class DifficultyLevel {
    @Field(() => Int)
    @prop()
    public level: number;
    
    @Field(() => String)
    @prop()
    public text: string;
}


@InputType('AgeGroupInput')
@ObjectType('AgeGroupType')
@modelOptions({ options: { allowMixed: Severity.ALLOW }, schemaOptions: { _id: false } })
export class AgeGroup {
    @Field(() => Int)
    @prop()
    public id: number;

    @Field(() => String)
    @prop()
    public name: string;
}
```

### 8. The shared decorators:
    - OrgId
    - Authorization
    - User
    - ActionContext

```typescript
export const OrgId = (options?: Omit<ArgsOptions, 'type'>) => {
    const {nullable = true, ...restOptions} = options ?? {};

    return Args('org_id', {
        ...restOptions,
        nullable,
        type: () => String
    });
};


export const Authorization = createParamDecorator(
    (data: unknown, context: ExecutionContext) => {
        const ctx = GqlExecutionContext.create(context);
        return ctx.getContext().req.headers.authorization;
    }
);


export const User = createParamDecorator(
    (data: unknown, context: ExecutionContext) => {
        const ctx = GqlExecutionContext.create(context);
        return ctx.getContext().req.body.user;
    }
);


export const ActionContext = createParamDecorator(
    (data: unknown, context: ExecutionContext) => {
        const ctx = GqlExecutionContext.create(context);
        return ctx.getContext().req.actionContext;
    }
);
```


### 9. The shared interceptors:
    - OrgIdInterceptor

```typescript

@Injectable()
export class OrgIdInterceptor implements NestInterceptor {
    intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
        const gqlContext = GqlExecutionContext.create(context);

        const args = gqlContext.getArgByIndex(1);
        const req = gqlContext.getArgByIndex(2).req;
        const { user } = req.body;
        const isUserSuperAdmin = !user?.org_id;

        if (isUserSuperAdmin) {
            /* The super-admin does not belong to any organization, so they must specify org_id in the arguments. */
            if (!args?.org_id)
                throw new BadRequestException(
                    AppError.FIELD_SHOULD_BE_PROVIDED('org_id')
                );
        } else {
            /* For other users, org_id is taken from their tokens. */
            args.org_id = user.org_id;
        }

        return next.handle();
    }
}
```

---
_Source: https://npm.io/package/@v-sandbox/shared-graphql-constants · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
