cds-typer icon indicating copy to clipboard operation
cds-typer copied to clipboard

feat/refactor: use only one CSN flavor + other improvements

Open stockbal opened this issue 4 months ago • 0 comments

Hi @daogrady,

proposal to get rid of one of the CSN flavors. I chose to remove the xtended flavor. All in all the required fixes/changes were not many and had some nice side effects.

  • working dedicated classes for inline compositions
  • working dedicated classes for localized elements

Tasks

  • [ ] add test cases

Here is short sample to show the changes to the generated classes (only the important parts are included)

Sample cds schema

namespace bookshop;

entity Books : cuid {
  title      : localized String;
  publishers : Composition of many {
                 key ID      : UUID;
                     name    : String;
                     type    : String enum {
                       self;
                       independent;
                     };
                     offices : Composition of many {
                                 key ID      : UUID;
                                     city    : String;
                                     zipCode : String;
                               }
               }
}

Generated index.ts for namespace bookshop

// enum
const publisher_type = {
  self: "self",
  independent: "independent",
} as const;
type publisher_type = "self" | "independent"

export function _BookAspect<TBase extends new (...args: any[]) => object>(Base: TBase) {
  return class Book extends _._cuidAspect(Base) {
    declare title?: string | null;
    declare publishers?: __.Composition.of.many<Books.publishers>;
    // properties to access composition and association to generated table for 'localized' elements
    // #################################
    declare texts?: __.Composition.of.many<Books.texts>;
    declare localized?: __.Association.to<Books.text> | null;
    // #################################
  };
}
export class Book extends _BookAspect(__.Entity) {}
export class Books extends Array<Book> {$count?: number}

export namespace Books {
  // classes for inline composition inside namespace of parent entity
  export function _publisherAspect<TBase extends new (...args: any[]) => object>(Base: TBase) {
    return class publisher extends Base {
      declare up_?: __.Key<__.Association.to<Book>>;
      declare up__ID?: __.Key<string>;
      declare ID?: __.Key<string>;
      declare name?: string | null;
      declare type?: publisher_type | null;
      declare offices?: __.Composition.of.many<Books.publishers.offices>;
      
      static type = publisher_type
    };
  }
  export class publisher extends _publisherAspect(__.Entity) {}
  export class publishers extends Array<publisher> {$count?: number}
  
  // generated text entity inside namespace of parent entity
  export function _textAspect<TBase extends new (...args: any[]) => object>(Base: TBase) {
    return class text extends _sap_common._TextsAspectAspect(Base) {
      declare ID?: __.Key<string>;
      declare title?: string | null;
    };
  }
  export class text extends _textAspect(__.Entity) {}
  export class texts extends Array<text> {$count?: number}
  
}

export namespace Books.publishers {
  // classes for nested inline composition 'offices'
  export function _officeAspect<TBase extends new (...args: any[]) => object>(Base: TBase) {
    return class office extends Base {
      declare up_?: __.Key<__.Association.to<Books.publisher>>;
      declare up__ID?: __.Key<string>;
      declare up__up__ID?: __.Key<string>;
      declare ID?: __.Key<string>;
      declare city?: string | null;
      declare zipCode?: string | null;
    };
  }
  export class office extends _officeAspect(__.Entity) {}
  export class offices extends Array<office> {$count?: number}
}

Generated index.js for namespace bookshop

// Books
module.exports.Book = { is_singular: true, __proto__: csn.Books }
module.exports.Books = csn.Books
// Books.publishers
module.exports.Books.publisher = { is_singular: true, __proto__: csn.Books.publishers }
module.exports.Books.publishers = csn.Books.publishers
// Books.texts
module.exports.Books.text = { is_singular: true, __proto__: csn.Books.texts }
module.exports.Books.texts = csn.Books.texts
// Books.publishers.offices
module.exports.Books.publishers.office = { is_singular: true, __proto__: csn.Books.publishers.offices }
module.exports.Books.publishers.offices = csn.Books.publishers.offices
// events
// actions
// enums
module.exports.publisher.type ??= { self: "self", independent: "independent" }

This branch is again based on the fix for the draftable state (see #348)

Fixes #116 Closes #77 Closes #128

Let me know if you want to go forward with this branch/approach.

Regards, Ludwig

stockbal avatar Oct 12 '24 13:10 stockbal