Skip to content

[BUG] Invalid class when referencing a cds element named like a reserved word #469

@MarvinWeitz

Description

@MarvinWeitz

Is there an existing issue for this?

  • I have searched the existing issues

Nature of Your Project

JavaScript, TypeScript

Current Behavior

When naming a cds element like a reserved word, like its done in the SAP Document Management Service API GetChildren, cds-typer creates classes that violate naming restrictions.

The cds file generated from the API specification looks like this:

...
type Get.Children_types.object {
  objects                         : many {
    object                        : {
      properties                  : {
...

which results in

...
  return class object extends Base {
...

This is an invalid name for a class.

Expected Behavior

An expected behavior would be to "escape" the class name. I'd suggest preceeding it with an _, resulting in _object.

The issue (at least in my specific case for generated classes as singular) occurs in four lines of /lib/visitor.js:

  1. method #aspectify: buffer.addIndentedBlock(`return class ${clean} extends... - clean is evaluated to object
  2. method #aspectify: buffer.add(`export class ${identSingular(clean)} extends ... - clean is evaluated to object
  3. method #printEntity: buffer.add(overrideNameProperty(singular, entity.name)) - singular is evaluated to object
  4. method #printEntity: buffer.add(`Object.defineProperty(${singular}, 'is_singular', { value: true })`) - singular is evaluated to object

Steps To Reproduce

  1. cds init
  2. cds add typescript
  3. npm i
  4. cds import <path/to/GetChildrenAPI.json> --as cds
  5. Look at @cds-models/Get/Children_types/index.ts

Environment

- **OS**: Debian GNU/Linux 12 (bookworm)
- **Node**: v20.18.1
- **npm**: 10.8.2
- **cds-typer**: 0.31.0
- **cds**: 8.6.1

Repository Containing a Minimal Reproducible Example

https://github.com/MarvinWeitz/cds-typer-reserved-names-bug

Anything else?

A bandaid-fix in my case is calleing this script in the postinstall script of the package.json

const fs = require("fs")
const path = require("path")

// Path to the file
const filePath = path.join(
    process.cwd(),
    "node_modules/@cap-js/cds-typer/lib/visitor.js"
)

// Read the file
fs.readFile(filePath, "utf8", (err, data) => {
    if (err) {
        console.error("Error reading file:", err)
        return
    }

    // Replace the specific line
    const modifiedContent = data
        .replace(
            /buffer\.addIndentedBlock\(`return class \${clean} extends/,
            'buffer.addIndentedBlock(`return class ${clean === "object" ? "_" + clean : clean} extends'
        )
        .replace(
            /buffer\.add\(`export class \${identSingular\(clean\)} extends/,
            'buffer.add(`export class ${identSingular(clean === "object" ? "_" + clean : clean)} extends'
        )
        .replace(
            /buffer\.add\(`Object\.defineProperty\(\${singular}/,
            'buffer.add(`Object.defineProperty(${singular === "object" ? "_" + singular : singular}'
        )
        .replace(
            /buffer\.add\(overrideNameProperty\(singular/,
            'buffer.add(overrideNameProperty(singular === "object" ? "_" + singular : singular'
        )

    // Write the modified content back to the file
    fs.writeFile(filePath, modifiedContent, "utf8", (err) => {
        if (err) {
            console.error("Error writing file:", err)
            return
        }
        console.log("File has been modified successfully")
    })
})

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingkeepaliveWill not be closed by Stale botnew

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions