ad-on-is / adonis-autoswagger

Auto-Generate swagger docs for AdonisJS
MIT License
129 stars 41 forks source link

Unable to see updates when adding comments #110

Closed m2jobe closed 4 months ago

m2jobe commented 4 months ago

As an example the following doesn't overwrite and update the docs.

import type { HttpContext } from '@adonisjs/core/http';
import { inject } from '@adonisjs/core';
import User from '../models/user.js';
import createUserValidator from '../validators/user.js';
import UserCreated from '#events/user_created';
import RoleService from '#services/role_service';
import Role from '#models/role';
import InternalServerErrorException from '#exceptions/internal_server_error_exception';

@inject()
export default class UsersController {
  constructor(private roleService: RoleService) {}

  /**
   * @post
   * @responseBody 200
   * @requestBody <User>
   */
  async create({ request }: HttpContext) {
    // 1- extract data / throw error if any is not there
    const { role, ...userAttributes } = await request.validateUsing(createUserValidator);

    // 2- set claim

    try {
      await this.roleService.setCustomClaim(userAttributes.external_auth_user_id, role);
    } catch (error) {
      throw new InternalServerErrorException(error.message);
    }

    // 3- create user
    const user = await User.create(userAttributes);
    UserCreated.dispatch(user);

    // 4- Retrieve role id
    const { id } = (await Role.findBy('role', role)) as Role;

    // 5- create role for user
    await this.roleService.assignUserRole(user, id);

    return user;
  }
}
ad-on-is commented 4 months ago

🤷🏻

m2jobe commented 4 months ago

🤷🏻

Sorry ive updated this with a description, the config ive setup is the following:

// for AdonisJS v6
import path from 'node:path';
import url from 'node:url';
// ---

export default {
  // path: __dirname + "/../", for AdonisJS v5
  // eslint-disable-next-line prefer-template
  path: path.dirname(url.fileURLToPath(import.meta.url)) + '/../', // for AdonisJS v6
  title: 'Foo', // use info instead
  version: '1.0.0', // use info instead
  description: '', // use info instead
  tagIndex: 1,
  info: {
    title: 'title',
    version: '1.0.0',
    description: '',
  },
  snakeCase: true,

  debug: true, // set to true, to get some useful debug output
  ignore: ['/swagger', '/docs'],
  preferredPutPatch: 'PUT', // if PUT/PATCH are provided for the same route, prefer PUT
  common: {
    parameters: {}, // OpenAPI conform parameters that are commonly used
    headers: {}, // OpenAPI conform headers that are commonly used
  },
  securitySchemes: {}, // optional
  authMiddlewares: ['auth', 'auth:api'], // optional
  defaultSecurityScheme: 'BearerAuth', // optional
  persistAuthorization: true, // persist authorization between reloads on the swagger page
  showFullPath: false, // the path displayed after endpoint summary
};

Routes folder

/*
|--------------------------------------------------------------------------
| Routes file
|--------------------------------------------------------------------------
|
| The routes file is used for defining the HTTP routes.
|
*/

import router from '@adonisjs/core/services/router';
import AutoSwagger from 'adonis-autoswagger';
import swagger from '#config/swagger';
import { middleware } from './kernel.js';

const UsersController = () => import('#controllers/users_controller');
const InvoiceController = () => import('#controllers/stripe/webhooks/invoices_controller');
const AccountsController = () => import('#controllers/stripe/webhooks/accounts_controller');
const VeriffDecisionsController = () => import('#controllers/veriff/webhooks/decisions_controller');

router
  .group(() => {
    router.post('users', [UsersController, 'create']);
  })
  .prefix('/api');

/**
 * Stripe Webhook route group
 */
router
  .group(() => {
    router.post('invoice-voided', [InvoiceController, 'voided']);
    router.post('account-updated', [AccountsController, 'updated']);
    router.post('invoice-payment-failed', [InvoiceController, 'paymentDeclined']);
    router.post('invoice-paid', [InvoiceController, 'paid']);
  })
  .prefix('/api/stripe-webhooks')
  .use(middleware.stripeWebhook());

/**
 * Veriff Webhook route group
 */
router
  .group(() => {
    router.post('decision', [VeriffDecisionsController, 'decision']);
  })
  .prefix('/api/veriff-webhooks')
  .use(middleware.veriffWebhook());

// returns swagger in YAML
router.get('/swagger', async () => {
  console.log('router.toJSON()', router.toJSON());
  return AutoSwagger.default.docs(router.toJSON(), swagger);
});

// Renders Swagger-UI and passes YAML-output of /swagger
router.get('/docs', async () => {
  return AutoSwagger.default.ui('/swagger', swagger);
  // return AutoSwagger.default.scalar("/swagger", swagger); to use Scalar instead
  // return AutoSwagger.default.rapidoc("/swagger", swagger); to use RapiDoc instead
});

Please let me know if I am missing any configs

m2jobe commented 4 months ago
Screenshot 2024-07-15 at 4 03 12 PM

Updating models seems to work except for email attribute which doesnt get overwritten:

import {
  BaseModel,
  column,
  hasOne,
  hasMany,
  manyToMany,
  hasManyThrough,
} from '@adonisjs/lucid/orm';
import type { HasOne, HasMany, ManyToMany, HasManyThrough } from '@adonisjs/lucid/types/relations';
import { DateTime } from 'luxon';
import GuestPaymentAccount from '#models/guest_payment_account';
import Role from '#models/role';
import HostPaymentAccount from '#models/host_payment_account';
import Listing from '#models/listing';
import ListingSpace from '#models/listing_space';
import UserVerification from '#models/user_verification';

export default class User extends BaseModel {
  @column({ isPrimary: true })
  declare id: number;

  @column()
  // @example(Jim)
  declare first_name: string;

  @column()
  declare last_name: string;

  @column()
  // @example(test_id)
  declare external_auth_user_id: string;

  @column()
  // @example(newemail@gmail.com)
  declare email: string;

  @column.dateTime({ autoCreate: true })
  declare created_at: DateTime;

  @column.dateTime({ autoCreate: true, autoUpdate: true })
  declare updated_at: DateTime;

  @manyToMany(() => Role, {
    pivotTable: 'user_roles',
    pivotForeignKey: 'user_id',
    pivotRelatedForeignKey: 'role_id',
    pivotTimestamps: true,
  })
  declare roles: ManyToMany<typeof Role>;

  @hasOne(() => GuestPaymentAccount, {
    foreignKey: 'guest_id',
  })
  declare guestPaymentAccount: HasOne<typeof GuestPaymentAccount>;

  @hasOne(() => HostPaymentAccount, {
    foreignKey: 'host_id',
  })
  declare hostPaymentAccount: HasOne<typeof HostPaymentAccount>;

  @hasMany(() => Listing, {
    foreignKey: 'host_id',
  })
  declare listings: HasMany<typeof Listing>;

  @hasManyThrough([() => ListingSpace, () => Listing])
  declare listingSpaces: HasManyThrough<typeof ListingSpace>;

  @hasMany(() => UserVerification, {
    foreignKey: 'user_id',
  })
  declare userVerifications: HasMany<typeof UserVerification>;
}
ad-on-is commented 4 months ago

Ooh ok... seems like a minor issue somewhere parsing the provided example for a field... will have a look into it.

Thx for the info.

ad-on-is commented 4 months ago

Fixed in 3.58.0