From 621b438ae82f4b63a07278ffc4ac81d0a03b1456 Mon Sep 17 00:00:00 2001 From: naman-contentstack Date: Tue, 12 May 2026 15:21:28 +0530 Subject: [PATCH] fix: issue with interface names starting with numbers --- .talismanrc | 2 +- package-lock.json | 310 +++++++++--------- package.json | 6 +- src/generateTS/factory.ts | 167 +++++----- .../numeric-uid-prefix.test.ts | 165 ++++++++++ 5 files changed, 410 insertions(+), 240 deletions(-) create mode 100644 tests/unit/generateTSFromContentTypes/numeric-uid-prefix.test.ts diff --git a/.talismanrc b/.talismanrc index 7ee7f82..7fc9f85 100644 --- a/.talismanrc +++ b/.talismanrc @@ -3,5 +3,5 @@ fileignoreconfig: ignore_detectors: - filecontent - filename: package-lock.json - checksum: 8d6d64bf4285ff8042f14af5951c6147a9cf56967b07ad21186bd9d129e3c291 + checksum: 3b78b6e76e2556306c4878601299bcecae5c5a73da5d1482a6d99a171c902aa7 version: "1.0" diff --git a/package-lock.json b/package-lock.json index 2051a58..e966d21 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,18 @@ { "name": "@contentstack/types-generator", - "version": "3.9.5", + "version": "3.10.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@contentstack/types-generator", - "version": "3.9.5", + "version": "3.10.0", "license": "MIT", "dependencies": { "@contentstack/delivery-sdk": "^5.2.0", "@gql2ts/from-schema": "^2.0.0-4", "async": "^3.2.6", - "axios": "1.15.2", + "axios": "1.16.0", "lodash": "^4.18.1", "prettier": "^3.8.3" }, @@ -28,7 +28,7 @@ "jest": "^29.7.0", "jest-json-reporter": "^1.2.2", "nock": "^13.5.6", - "rollup": "^4.60.1", + "rollup": "^4.60.3", "ts-jest": "^29.4.9", "tsup": "^8.5.1", "typescript": "^5.9.3" @@ -50,9 +50,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", - "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", + "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", "dev": true, "license": "MIT", "engines": { @@ -221,9 +221,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", - "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", + "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", "dev": true, "license": "MIT", "dependencies": { @@ -531,12 +531,12 @@ "license": "MIT" }, "node_modules/@contentstack/core": { - "version": "1.3.13", - "resolved": "https://registry.npmjs.org/@contentstack/core/-/core-1.3.13.tgz", - "integrity": "sha512-bsCwB7nPr7Ti3vaz3B6AAHUwxC7f16kiwIdzNqbMrtamvbwTCOJpPUXuXFpkWWHmGuBqWZz6WyJzr6ucOf4MDQ==", + "version": "1.3.14", + "resolved": "https://registry.npmjs.org/@contentstack/core/-/core-1.3.14.tgz", + "integrity": "sha512-wQsBcVF94448UKX2Simfnkx8nC+OMMNEhBoXIBeB51CXxIStP44I3HMk/d/m2PvrGqMKdcbGjVBBI/trK1qANQ==", "license": "MIT", "dependencies": { - "axios": "^1.15.0", + "axios": "^1.15.2", "axios-mock-adapter": "^2.1.0", "lodash": "^4.18.1", "qs": "6.15.1", @@ -1423,9 +1423,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.2.tgz", - "integrity": "sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.3.tgz", + "integrity": "sha512-x35CNW/ANXG3hE/EZpRU8MXX1JDN86hBb2wMGAtltkz7pc6cxgjpy1OMMfDosOQ+2hWqIkag/fGok1Yady9nGw==", "cpu": [ "arm" ], @@ -1437,9 +1437,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.2.tgz", - "integrity": "sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.3.tgz", + "integrity": "sha512-xw3xtkDApIOGayehp2+Rz4zimfkaX65r4t47iy+ymQB2G4iJCBBfj0ogVg5jpvjpn8UWn/+q9tprxleYeNp3Hw==", "cpu": [ "arm64" ], @@ -1451,9 +1451,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.2.tgz", - "integrity": "sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.3.tgz", + "integrity": "sha512-vo6Y5Qfpx7/5EaamIwi0WqW2+zfiusVihKatLvtN1VFVy3D13uERk/6gZLU1UiHRL6fDXqj/ELIeVRGnvcTE1g==", "cpu": [ "arm64" ], @@ -1465,9 +1465,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.2.tgz", - "integrity": "sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.3.tgz", + "integrity": "sha512-D+0QGcZhBzTN82weOnsSlY7V7+RMmPuF1CkbxyMAGE8+ZHeUjyb76ZiWmBlCu//AQQONvxcqRbwZTajZKqjuOw==", "cpu": [ "x64" ], @@ -1479,9 +1479,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.2.tgz", - "integrity": "sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.3.tgz", + "integrity": "sha512-6HnvHCT7fDyj6R0Ph7A6x8dQS/S38MClRWeDLqc0MdfWkxjiu1HSDYrdPhqSILzjTIC/pnXbbJbo+ft+gy/9hQ==", "cpu": [ "arm64" ], @@ -1493,9 +1493,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.2.tgz", - "integrity": "sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.3.tgz", + "integrity": "sha512-KHLgC3WKlUYW3ShFKnnosZDOJ0xjg9zp7au3sIm2bs/tGBeC2ipmvRh/N7JKi0t9Ue20C0dpEshi8WUubg+cnA==", "cpu": [ "x64" ], @@ -1507,9 +1507,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.2.tgz", - "integrity": "sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.3.tgz", + "integrity": "sha512-DV6fJoxEYWJOvaZIsok7KrYl0tPvga5OZ2yvKHNNYyk/2roMLqQAbGhr78EQ5YhHpnhLKJD3S1WFusAkmUuV5g==", "cpu": [ "arm" ], @@ -1521,9 +1521,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.2.tgz", - "integrity": "sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.3.tgz", + "integrity": "sha512-mQKoJAzvuOs6F+TZybQO4GOTSMUu7v0WdxEk24krQ/uUxXoPTtHjuaUuPmFhtBcM4K0ons8nrE3JyhTuCFtT/w==", "cpu": [ "arm" ], @@ -1535,9 +1535,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.2.tgz", - "integrity": "sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.3.tgz", + "integrity": "sha512-Whjj2qoiJ6+OOJMGptTYazaJvjOJm+iKHpXQM1P3LzGjt7Ff++Tp7nH4N8J/BUA7R9IHfDyx4DJIflifwnbmIA==", "cpu": [ "arm64" ], @@ -1549,9 +1549,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.2.tgz", - "integrity": "sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.3.tgz", + "integrity": "sha512-4YTNHKqGng5+yiZt3mg77nmyuCfmNfX4fPmyUapBcIk+BdwSwmCWGXOUxhXbBEkFHtoN5boLj/5NON+u5QC9tg==", "cpu": [ "arm64" ], @@ -1563,9 +1563,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.2.tgz", - "integrity": "sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.3.tgz", + "integrity": "sha512-SU3kNlhkpI4UqlUc2VXPGK9o886ZsSeGfMAX2ba2b8DKmMXq4AL7KUrkSWVbb7koVqx41Yczx6dx5PNargIrEA==", "cpu": [ "loong64" ], @@ -1577,9 +1577,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.2.tgz", - "integrity": "sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.3.tgz", + "integrity": "sha512-6lDLl5h4TXpB1mTf2rQWnAk/LcXrx9vBfu/DT5TIPhvMhRWaZ5MxkIc8u4lJAmBo6klTe1ywXIUHFjylW505sg==", "cpu": [ "loong64" ], @@ -1591,9 +1591,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.2.tgz", - "integrity": "sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.3.tgz", + "integrity": "sha512-BMo8bOw8evlup/8G+cj5xWtPyp93xPdyoSN16Zy90Q2QZ0ZYRhCt6ZJSwbrRzG9HApFabjwj2p25TUPDWrhzqQ==", "cpu": [ "ppc64" ], @@ -1605,9 +1605,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.2.tgz", - "integrity": "sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.3.tgz", + "integrity": "sha512-E0L8X1dZN1/Rph+5VPF6Xj2G7JJvMACVXtamTJIDrVI44Y3K+G8gQaMEAavbqCGTa16InptiVrX6eM6pmJ+7qA==", "cpu": [ "ppc64" ], @@ -1619,9 +1619,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.2.tgz", - "integrity": "sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.3.tgz", + "integrity": "sha512-oZJ/WHaVfHUiRAtmTAeo3DcevNsVvH8mbvodjZy7D5QKvCefO371SiKRpxoDcCxB3PTRTLayWBkvmDQKTcX/sw==", "cpu": [ "riscv64" ], @@ -1633,9 +1633,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.2.tgz", - "integrity": "sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.3.tgz", + "integrity": "sha512-Dhbyh7j9FybM3YaTgaHmVALwA8AkUwTPccyCQ79TG9AJUsMQqgN1DDEZNr4+QUfwiWvLDumW5vdwzoeUF+TNxQ==", "cpu": [ "riscv64" ], @@ -1647,9 +1647,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.2.tgz", - "integrity": "sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.3.tgz", + "integrity": "sha512-cJd1X5XhHHlltkaypz1UcWLA8AcoIi1aWhsvaWDskD1oz2eKCypnqvTQ8ykMNI0RSmm7NkTdSqSSD7zM0xa6Ig==", "cpu": [ "s390x" ], @@ -1661,9 +1661,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.2.tgz", - "integrity": "sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.3.tgz", + "integrity": "sha512-DAZDBHQfG2oQuhY7mc6I3/qB4LU2fQCjRvxbDwd/Jdvb9fypP4IJ4qmtu6lNjes6B531AI8cg1aKC2di97bUxA==", "cpu": [ "x64" ], @@ -1675,9 +1675,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.2.tgz", - "integrity": "sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.3.tgz", + "integrity": "sha512-cRxsE8c13mZOh3vP+wLDxpQBRrOHDIGOWyDL93Sy0Ga8y515fBcC2pjUfFwUe5T7tqvTvWbCpg1URM/AXdWIXA==", "cpu": [ "x64" ], @@ -1689,9 +1689,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.2.tgz", - "integrity": "sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.3.tgz", + "integrity": "sha512-QaWcIgRxqEdQdhJqW4DJctsH6HCmo5vHxY0krHSX4jMtOqfzC+dqDGuHM87bu4H8JBeibWx7jFz+h6/4C8wA5Q==", "cpu": [ "x64" ], @@ -1703,9 +1703,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.2.tgz", - "integrity": "sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.3.tgz", + "integrity": "sha512-AaXwSvUi3QIPtroAUw1t5yHGIyqKEXwH54WUocFolZhpGDruJcs8c+xPNDRn4XiQsS7MEwnYsHW2l0MBLDMkWg==", "cpu": [ "arm64" ], @@ -1717,9 +1717,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.2.tgz", - "integrity": "sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.3.tgz", + "integrity": "sha512-65LAKM/bAWDqKNEelHlcHvm2V+Vfb8C6INFxQXRHCvaVN1rJfwr4NvdP4FyzUaLqWfaCGaadf6UbTm8xJeYfEg==", "cpu": [ "arm64" ], @@ -1731,9 +1731,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.2.tgz", - "integrity": "sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.3.tgz", + "integrity": "sha512-EEM2gyhBF5MFnI6vMKdX1LAosE627RGBzIoGMdLloPZkXrUN0Ckqgr2Qi8+J3zip/8NVVro3/FjB+tjhZUgUHA==", "cpu": [ "ia32" ], @@ -1745,9 +1745,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.2.tgz", - "integrity": "sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.3.tgz", + "integrity": "sha512-E5Eb5H/DpxaoXH++Qkv28RcUJboMopmdDUALBczvHMf7hNIxaDZqwY5lK12UK1BHacSmvupoEWGu+n993Z0y1A==", "cpu": [ "x64" ], @@ -1759,9 +1759,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.2.tgz", - "integrity": "sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.3.tgz", + "integrity": "sha512-hPt/bgL5cE+Qp+/TPHBqptcAgPzgj46mPcg/16zNUmbQk0j+mOEQV/+Lqu8QRtDV3Ek95Q6FeFITpuhl6OTsAA==", "cpu": [ "x64" ], @@ -1914,9 +1914,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.19.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.39.tgz", - "integrity": "sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw==", + "version": "20.19.41", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.41.tgz", + "integrity": "sha512-ECymXOukMnOoVkC2bb1Vc/w/836DXncOg5m8Xj1RH7xSHZJWNYY6Zh7EH477vcnD5egKNNfy2RpNOmuChhFPgQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2046,12 +2046,12 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.2.tgz", - "integrity": "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz", + "integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.11", + "follow-redirects": "^1.16.0", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } @@ -2194,9 +2194,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.10.23", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.23.tgz", - "integrity": "sha512-xwVXGqevyKPsiuQdLj+dZMVjidjJV508TBqexND5HrF89cGdCYCJFB3qhcxRHSeMctdCfbR1jrxBajhDy7o29g==", + "version": "2.10.29", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.29.tgz", + "integrity": "sha512-Asa2krT+XTPZINCS+2QcyS8WTkObE77RwkydwF7h6DmnKqbvlalz93m/dnphUyCa6SWSP51VgtEUf2FN+gelFQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2370,9 +2370,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001791", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001791.tgz", - "integrity": "sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ==", + "version": "1.0.30001792", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001792.tgz", + "integrity": "sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==", "dev": true, "funding": [ { @@ -2709,9 +2709,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.344", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.344.tgz", - "integrity": "sha512-4MxfbmNDm+KPh066EZy+eUnkcDPcZ35wNmOWzFuh/ijvHsve6kbLTLURy88uCNK5FbpN+yk2nQY6BYh1GEt+wg==", + "version": "1.5.353", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.353.tgz", + "integrity": "sha512-kOrWphBi8TOZyiJZqsgqIle0lw+tzmnQK83pV9dZUd01Nm2POECSyFQMAuarzZdYqQW7FH9RaYOuaRo3h+bQ3w==", "dev": true, "license": "ISC" }, @@ -3377,13 +3377,13 @@ } }, "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", "dev": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.2" + "hasown": "^2.0.3" }, "engines": { "node": ">= 0.4" @@ -3470,9 +3470,9 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", "dev": true, "license": "ISC", "bin": { @@ -4041,9 +4041,9 @@ } }, "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", "dev": true, "license": "ISC", "bin": { @@ -4377,9 +4377,9 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", "dev": true, "license": "ISC", "bin": { @@ -4559,9 +4559,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.38", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.38.tgz", - "integrity": "sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==", + "version": "2.0.44", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.44.tgz", + "integrity": "sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==", "dev": true, "license": "MIT" }, @@ -5108,9 +5108,9 @@ } }, "node_modules/rollup": { - "version": "4.60.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.2.tgz", - "integrity": "sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==", + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.3.tgz", + "integrity": "sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A==", "dev": true, "license": "MIT", "dependencies": { @@ -5124,31 +5124,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.60.2", - "@rollup/rollup-android-arm64": "4.60.2", - "@rollup/rollup-darwin-arm64": "4.60.2", - "@rollup/rollup-darwin-x64": "4.60.2", - "@rollup/rollup-freebsd-arm64": "4.60.2", - "@rollup/rollup-freebsd-x64": "4.60.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.60.2", - "@rollup/rollup-linux-arm-musleabihf": "4.60.2", - "@rollup/rollup-linux-arm64-gnu": "4.60.2", - "@rollup/rollup-linux-arm64-musl": "4.60.2", - "@rollup/rollup-linux-loong64-gnu": "4.60.2", - "@rollup/rollup-linux-loong64-musl": "4.60.2", - "@rollup/rollup-linux-ppc64-gnu": "4.60.2", - "@rollup/rollup-linux-ppc64-musl": "4.60.2", - "@rollup/rollup-linux-riscv64-gnu": "4.60.2", - "@rollup/rollup-linux-riscv64-musl": "4.60.2", - "@rollup/rollup-linux-s390x-gnu": "4.60.2", - "@rollup/rollup-linux-x64-gnu": "4.60.2", - "@rollup/rollup-linux-x64-musl": "4.60.2", - "@rollup/rollup-openbsd-x64": "4.60.2", - "@rollup/rollup-openharmony-arm64": "4.60.2", - "@rollup/rollup-win32-arm64-msvc": "4.60.2", - "@rollup/rollup-win32-ia32-msvc": "4.60.2", - "@rollup/rollup-win32-x64-gnu": "4.60.2", - "@rollup/rollup-win32-x64-msvc": "4.60.2", + "@rollup/rollup-android-arm-eabi": "4.60.3", + "@rollup/rollup-android-arm64": "4.60.3", + "@rollup/rollup-darwin-arm64": "4.60.3", + "@rollup/rollup-darwin-x64": "4.60.3", + "@rollup/rollup-freebsd-arm64": "4.60.3", + "@rollup/rollup-freebsd-x64": "4.60.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.3", + "@rollup/rollup-linux-arm-musleabihf": "4.60.3", + "@rollup/rollup-linux-arm64-gnu": "4.60.3", + "@rollup/rollup-linux-arm64-musl": "4.60.3", + "@rollup/rollup-linux-loong64-gnu": "4.60.3", + "@rollup/rollup-linux-loong64-musl": "4.60.3", + "@rollup/rollup-linux-ppc64-gnu": "4.60.3", + "@rollup/rollup-linux-ppc64-musl": "4.60.3", + "@rollup/rollup-linux-riscv64-gnu": "4.60.3", + "@rollup/rollup-linux-riscv64-musl": "4.60.3", + "@rollup/rollup-linux-s390x-gnu": "4.60.3", + "@rollup/rollup-linux-x64-gnu": "4.60.3", + "@rollup/rollup-linux-x64-musl": "4.60.3", + "@rollup/rollup-openbsd-x64": "4.60.3", + "@rollup/rollup-openharmony-arm64": "4.60.3", + "@rollup/rollup-win32-arm64-msvc": "4.60.3", + "@rollup/rollup-win32-ia32-msvc": "4.60.3", + "@rollup/rollup-win32-x64-gnu": "4.60.3", + "@rollup/rollup-win32-x64-msvc": "4.60.3", "fsevents": "~2.3.2" } }, @@ -5666,9 +5666,9 @@ } }, "node_modules/ts-jest/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", "dev": true, "license": "ISC", "bin": { @@ -5798,9 +5798,9 @@ } }, "node_modules/ufo": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz", - "integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==", + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz", + "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==", "dev": true, "license": "MIT" }, diff --git a/package.json b/package.json index 172d21e..e04281a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/types-generator", - "version": "3.9.5", + "version": "3.10.0", "description": "Contentstack type definition generation library", "private": false, "author": "Contentstack", @@ -42,7 +42,7 @@ "jest": "^29.7.0", "jest-json-reporter": "^1.2.2", "nock": "^13.5.6", - "rollup": "^4.60.1", + "rollup": "^4.60.3", "ts-jest": "^29.4.9", "tsup": "^8.5.1", "typescript": "^5.9.3" @@ -51,7 +51,7 @@ "@contentstack/delivery-sdk": "^5.2.0", "@gql2ts/from-schema": "^2.0.0-4", "async": "^3.2.6", - "axios": "1.15.2", + "axios": "1.16.0", "lodash": "^4.18.1", "prettier": "^3.8.3" }, diff --git a/src/generateTS/factory.ts b/src/generateTS/factory.ts index 15eb828..d76f942 100644 --- a/src/generateTS/factory.ts +++ b/src/generateTS/factory.ts @@ -12,6 +12,18 @@ import { } from "./shared/utils"; import { ERROR_MESSAGES } from "../constants"; +export function hasPrefixedNaming(prefix: string | undefined): boolean { + return typeof prefix === "string" && prefix.trim().length > 0; +} + +export function composePrefixedInterfaceName( + uid: string, + prefix: string, +): string { + const trimmed = prefix.trim(); + return trimmed + _.upperFirst(_.camelCase(uid)); +} + export type TSGenOptions = { docgen: DocumentationGenerator; naming?: { @@ -98,6 +110,11 @@ export default function (userOptions: TSGenOptions) { const skippedBlocks: Array<{ uid: string; path: string; reason: string }> = []; + const trimmedNamingPrefix = + typeof options.naming?.prefix === "string" + ? options.naming.prefix.trim() + : ""; + // Collect numeric identifier errors instead of throwing immediately const numericIdentifierErrors: Array<{ uid: string; @@ -138,7 +155,7 @@ export default function (userOptions: TSGenOptions) { function track_dependency( field: ContentstackTypes.Field, type: string, - flag: TypeFlags + flag: TypeFlags, ) { if (flag === TypeFlags.BuiltinJS) { visitedJSTypes.add(type); @@ -163,53 +180,43 @@ export default function (userOptions: TSGenOptions) { } function name_type(uid: string) { - // Check if the UID starts with a number, which would create invalid TypeScript + if (trimmedNamingPrefix) { + return composePrefixedInterfaceName(uid, trimmedNamingPrefix); + } if (isNumericIdentifier(uid)) { - // Return a fallback name to continue processing return `InvalidInterface_${uid}`; } - - return [options?.naming?.prefix, _.upperFirst(_.camelCase(uid))] - .filter((v) => v) - .join(""); + return composePrefixedInterfaceName(uid, ""); } function define_interface( contentType: ContentstackTypes.ContentType | ContentstackTypes.GlobalField, - systemFields = false + systemFields = false, ) { - // Validate the interface name before creating it - let interfaceName: string; - const isGlobalField = contentType.data_type === "global_field"; + const nameSourceUid = + isGlobalField && contentType.reference_to + ? (contentType.reference_to as string) + : contentType.uid; - // Check if the content type's own UID starts with a number - if (isNumericIdentifier(contentType.uid)) { - numericIdentifierErrors.push({ - uid: contentType.uid, - type: "content_type", - }); - // Return a fallback interface declaration to continue processing - interfaceName = `InvalidInterface_${contentType.uid}`; - } else if ( - isGlobalField && - contentType.reference_to && - isNumericIdentifier(contentType.reference_to as string) - ) { - // For global fields, check if the referenced content type has a numeric identifier - // This is a global field error because it references an invalid content type - numericIdentifierErrors.push({ - uid: contentType.uid, // The global field's UID - type: "global_field", - referenceTo: contentType.reference_to as string, // The referenced content type's UID - }); - // Return a fallback interface declaration to continue processing - interfaceName = `InvalidInterface_${contentType.reference_to}`; + let interfaceName: string; + + if (!trimmedNamingPrefix && isNumericIdentifier(nameSourceUid)) { + if (isGlobalField && contentType.reference_to) { + numericIdentifierErrors.push({ + uid: contentType.uid, + type: "global_field", + referenceTo: contentType.reference_to as string, + }); + } else { + numericIdentifierErrors.push({ + uid: contentType.uid, + type: "content_type", + }); + } + interfaceName = `InvalidInterface_${nameSourceUid}`; } else { - // No numeric identifier issues, generate normal interface name - interfaceName = name_type( - isGlobalField ? (contentType.reference_to as string) : contentType.uid - ); + interfaceName = name_type(nameSourceUid); } const interface_declaration = ["export interface", interfaceName]; @@ -280,8 +287,8 @@ export default function (userOptions: TSGenOptions) { ERROR_MESSAGES.SKIPPED_FIELD_UNKNOWN_TYPE( field.uid, field.data_type, - reason - ) + reason, + ), ); type = "Record"; // Use Record for balanced type safety } @@ -291,21 +298,20 @@ export default function (userOptions: TSGenOptions) { } const handleGlobalField = (field: ContentstackTypes.Field): string => { - // Skip global field references with numeric UIDs - const exclusionCheck = checkNumericIdentifierExclusion( - field.reference_to, - field.uid - ); - if (exclusionCheck.shouldExclude) { + if (!trimmedNamingPrefix && isNumericIdentifier(field.reference_to)) { + const exclusionCheck = checkNumericIdentifierExclusion( + field.reference_to, + field.uid, + ); skippedFields.push(exclusionCheck.record!); logger?.warn( ERROR_MESSAGES.SKIPPED_GLOBAL_FIELD_REFERENCE( field.uid, field.reference_to, - NUMERIC_IDENTIFIER_EXCLUSION_REASON - ) + NUMERIC_IDENTIFIER_EXCLUSION_REASON, + ), ); - return "string"; // Use string as fallback for global field references + return "string"; } const referenceName = name_type(field.reference_to); @@ -352,7 +358,7 @@ export default function (userOptions: TSGenOptions) { const fieldPath = path ? `${path}.${field.uid}` : field.uid; const exclusionCheck = checkNumericIdentifierExclusion( field.uid, - fieldPath + fieldPath, ); if (exclusionCheck.shouldExclude) { skippedFields.push(exclusionCheck.record!); @@ -360,8 +366,8 @@ export default function (userOptions: TSGenOptions) { ERROR_MESSAGES.SKIPPED_FIELD_AT_PATH( field.uid, fieldPath, - NUMERIC_IDENTIFIER_EXCLUSION_REASON - ) + NUMERIC_IDENTIFIER_EXCLUSION_REASON, + ), ); continue; } @@ -380,7 +386,7 @@ export default function (userOptions: TSGenOptions) { // If editableTags is enabled, add the $ field if (options.isEditableTags) { const fieldComment = options.docgen.field( - "CSLP mapping for editable fields" + "CSLP mapping for editable fields", ); const lines = fieldComment ? [fieldComment, CSLP_HELPERS.createMappingBlock(dollarKeys)] @@ -392,7 +398,7 @@ export default function (userOptions: TSGenOptions) { } function visit_content_type( - contentType: ContentstackTypes.ContentType | ContentstackTypes.GlobalField + contentType: ContentstackTypes.ContentType | ContentstackTypes.GlobalField, ) { modularBlockInterfaces.clear(); const contentTypeInterface = [ @@ -419,7 +425,7 @@ export default function (userOptions: TSGenOptions) { const blockPath = `${field.uid}.blocks.${block.uid}`; const exclusionCheck = checkNumericIdentifierExclusion( block.uid, - blockPath + blockPath, ); if (exclusionCheck.shouldExclude) { skippedBlocks.push(exclusionCheck.record!); @@ -427,8 +433,8 @@ export default function (userOptions: TSGenOptions) { ERROR_MESSAGES.SKIPPED_BLOCK_AT_PATH( block.uid, blockPath, - NUMERIC_IDENTIFIER_EXCLUSION_REASON - ) + NUMERIC_IDENTIFIER_EXCLUSION_REASON, + ), ); return null; // Return null to filter out later } @@ -437,7 +443,7 @@ export default function (userOptions: TSGenOptions) { ? name_type(block.reference_to) : visit_fields( block.schema || [], - `${field.uid}.blocks.${block.uid}` + `${field.uid}.blocks.${block.uid}`, ); const blockSchemaDefinition = block.reference_to @@ -450,7 +456,7 @@ export default function (userOptions: TSGenOptions) { // If all blocks were skipped, return a more specific fallback type if (modularBlockDefinitions.length === 0) { if (options.systemFields) { - const modularBlocksType = `${options.naming?.prefix || ""}ModularBlocksExtension`; + const modularBlocksType = `${trimmedNamingPrefix}ModularBlocksExtension`; return field.multiple ? `${modularBlocksType}>[]` : `${modularBlocksType}>`; @@ -469,7 +475,7 @@ export default function (userOptions: TSGenOptions) { if (existingInterfaceName) { // Wrap with ModularBlocks type to add _metadata support only when systemFields is enabled if (options.systemFields) { - const modularBlocksType = `${options.naming?.prefix || ""}ModularBlocksExtension`; + const modularBlocksType = `${trimmedNamingPrefix}ModularBlocksExtension`; return field.multiple ? `${modularBlocksType}<${existingInterfaceName}>[]` : `${modularBlocksType}<${existingInterfaceName}>`; @@ -488,7 +494,7 @@ export default function (userOptions: TSGenOptions) { } const modularBlockInterfaceDefinition = [ - `export interface ${modularBlockInterfaceName}${options.systemFields ? ` extends ${options.naming?.prefix || ""}SystemFields` : ""} {`, + `export interface ${modularBlockInterfaceName}${options.systemFields ? ` extends ${trimmedNamingPrefix}SystemFields` : ""} {`, modularBlockDefinitions.join("\n"), "}", ].join("\n"); @@ -500,7 +506,7 @@ export default function (userOptions: TSGenOptions) { // Wrap with ModularBlocks type to add _metadata support only when systemFields is enabled if (options.systemFields) { - const modularBlocksType = `${options.naming?.prefix || ""}ModularBlocksExtension`; + const modularBlocksType = `${trimmedNamingPrefix}ModularBlocksExtension`; return field.multiple ? `${modularBlocksType}<${modularBlockInterfaceName}>[]` : `${modularBlocksType}<${modularBlockInterfaceName}>`; @@ -529,7 +535,7 @@ export default function (userOptions: TSGenOptions) { } function type_link() { - return `${options.naming?.prefix}Link`; + return `${trimmedNamingPrefix}Link`; } function type_file(field: ContentstackTypes.Field): string { @@ -539,22 +545,22 @@ export default function (userOptions: TSGenOptions) { } // Default behavior with prefix support for other file-related fields - return `${options.naming?.prefix}File`; + return `${trimmedNamingPrefix}File`; } function type_global_field(field: ContentstackTypes.GlobalField) { // Skip global fields with numeric UIDs const exclusionCheck = checkNumericIdentifierExclusion( field.uid, - field.uid + field.uid, ); if (exclusionCheck.shouldExclude) { skippedFields.push(exclusionCheck.record!); logger?.warn( ERROR_MESSAGES.SKIPPED_GLOBAL_FIELD( field.uid, - NUMERIC_IDENTIFIER_EXCLUSION_REASON - ) + NUMERIC_IDENTIFIER_EXCLUSION_REASON, + ), ); return "string"; // Use string as fallback for global fields } @@ -563,7 +569,7 @@ export default function (userOptions: TSGenOptions) { const reason = "Schema not found for global field"; skippedFields.push({ uid: field.uid, path: field.uid, reason }); logger?.warn( - ERROR_MESSAGES.SKIPPED_GLOBAL_FIELD_NO_SCHEMA(field.uid, reason) + ERROR_MESSAGES.SKIPPED_GLOBAL_FIELD_NO_SCHEMA(field.uid, reason), ); return "string"; // Use string as fallback } @@ -579,7 +585,7 @@ export default function (userOptions: TSGenOptions) { // Handle reference types with or without ReferencedEntry interface if (options.includeReferencedEntry) { - const referencedEntryType = `${options.naming?.prefix || ""}ReferencedEntry`; + const referencedEntryType = `${trimmedNamingPrefix}ReferencedEntry`; const baseUnion = references.join(" | "); const types = `(${baseUnion} | ${referencedEntryType})`; @@ -595,28 +601,27 @@ export default function (userOptions: TSGenOptions) { if (Array.isArray(field.reference_to)) { field.reference_to.forEach((v) => { - // Skip references to content types with numeric names - if (!isNumericIdentifier(v)) { + if (trimmedNamingPrefix || !isNumericIdentifier(v)) { references.push(name_type(v)); } else { logger?.warn( ERROR_MESSAGES.SKIPPED_REFERENCE( v, - NUMERIC_IDENTIFIER_EXCLUSION_REASON - ) + NUMERIC_IDENTIFIER_EXCLUSION_REASON, + ), ); } }); } else { - // Skip references to content types with numeric names - if (!isNumericIdentifier(field.reference_to)) { - references.push(name_type(field.reference_to)); + const v = field.reference_to; + if (trimmedNamingPrefix || !isNumericIdentifier(v)) { + references.push(name_type(v)); } else { logger?.warn( ERROR_MESSAGES.SKIPPED_REFERENCE( - field.reference_to, - NUMERIC_IDENTIFIER_EXCLUSION_REASON - ) + v, + NUMERIC_IDENTIFIER_EXCLUSION_REASON, + ), ); } } @@ -625,7 +630,7 @@ export default function (userOptions: TSGenOptions) { } return function ( - contentType: ContentstackTypes.ContentType + contentType: ContentstackTypes.ContentType, ): TSGenResult | any { if (contentType.schema_type === "global_field") { const name = name_type(contentType.uid); @@ -677,7 +682,7 @@ export default function (userOptions: TSGenOptions) { { value: "Schema Path" }, { value: "Reason" }, ], - allSkippedItems + allSkippedItems, ); } @@ -709,7 +714,7 @@ export default function (userOptions: TSGenOptions) { }; function type_taxonomy() { - return `${options?.naming?.prefix}Taxonomy | ${options?.naming?.prefix}TaxonomyEntry`; + return `${trimmedNamingPrefix}Taxonomy | ${trimmedNamingPrefix}TaxonomyEntry`; } function type_json_rte(field: ContentstackTypes.Field) { diff --git a/tests/unit/generateTSFromContentTypes/numeric-uid-prefix.test.ts b/tests/unit/generateTSFromContentTypes/numeric-uid-prefix.test.ts new file mode 100644 index 0000000..5cd0277 --- /dev/null +++ b/tests/unit/generateTSFromContentTypes/numeric-uid-prefix.test.ts @@ -0,0 +1,165 @@ +import { + composePrefixedInterfaceName, + hasPrefixedNaming, +} from "../../../src/generateTS/factory"; +import { generateTSFromContentTypes } from "../../../src/generateTS/index"; +import { ContentType } from "../../../src/types/schema"; + +const minimalTextField = { + data_type: "text", + display_name: "Title", + field_metadata: {}, + mandatory: true, + uid: "title", + unique: true, + multiple: false, + non_localizable: false, +}; + +const numericUidContentType: ContentType = { + uid: "404", + description: "", + schema: [minimalTextField] as ContentType["schema"], + _version: 1, +}; + +describe("hasPrefixedNaming / composePrefixedInterfaceName", () => { + it("treats only whitespace prefix as absent", () => { + expect(hasPrefixedNaming(undefined)).toBe(false); + expect(hasPrefixedNaming("")).toBe(false); + expect(hasPrefixedNaming(" ")).toBe(false); + expect(hasPrefixedNaming("cs_")).toBe(true); + }); + + it("composePrefixedInterfaceName joins trimmed prefix with camel/Pascal UID", () => { + expect(composePrefixedInterfaceName("404", "cs_")).toBe("cs_404"); + expect(composePrefixedInterfaceName("blog_post", "")).toBe("BlogPost"); + }); +}); + +describe("generateTSFromContentTypes — numeric content-type UID and prefix", () => { + it("accepts numeric CT uid when prefix is set", async () => { + const out = await generateTSFromContentTypes({ + contentTypes: [numericUidContentType], + prefix: "cs_", + includeDocumentation: false, + systemFields: false, + includeReferencedEntry: false, + }); + + expect(out).toContain("export interface cs_404"); + expect(out).toMatch(/\bcs_404\b[\s\S]*\btitle:\s*string/); + }); + + it("rejects numeric CT uid without prefix", async () => { + await expect( + generateTSFromContentTypes({ + contentTypes: [numericUidContentType], + prefix: "", + includeDocumentation: false, + }) + ).rejects.toMatchObject({ + type: "validation", + error_code: "VALIDATION_ERROR", + }); + }); + + it("whitespace-only prefix rejects numeric CT uid like absent prefix", async () => { + await expect( + generateTSFromContentTypes({ + contentTypes: [numericUidContentType], + prefix: " ", + includeDocumentation: false, + }) + ).rejects.toMatchObject({ + type: "validation", + error_code: "VALIDATION_ERROR", + }); + }); + + const numericRefGlobalField: ContentType & { data_type: string } = { + title: "wrap", + uid: "wrapper_gf", + description: "", + schema_type: "global_field", + data_type: "global_field", + reference_to: "404", + schema: [{ ...minimalTextField, uid: "gtitle" }] as ContentType["schema"], + _version: 1, + }; + + it("GF with numeric reference_to succeeds with prefix", async () => { + const out = await generateTSFromContentTypes({ + contentTypes: [numericRefGlobalField, numericUidContentType], + prefix: "I", + includeDocumentation: false, + systemFields: false, + }); + + expect(out).toContain("export interface I404"); + }); + + it("GF with numeric reference_to fails without prefix", async () => { + await expect( + generateTSFromContentTypes({ + contentTypes: [numericRefGlobalField, numericUidContentType], + prefix: "", + includeDocumentation: false, + }) + ).rejects.toMatchObject({ + type: "validation", + error_code: "VALIDATION_ERROR", + }); + }); + + const gfStartsWithDigitRefsBlog: ContentType & { data_type: string } = { + title: "broken uid gf", + uid: "404_gf_own_uid", + description: "", + schema_type: "global_field", + data_type: "global_field", + reference_to: "blog", + schema: [{ ...minimalTextField, uid: "x" }] as ContentType["schema"], + _version: 1, + }; + + it("does not error when GF uid starts with digit but reference_to is valid (no prefix)", async () => { + const out = await generateTSFromContentTypes({ + contentTypes: [gfStartsWithDigitRefsBlog], + prefix: "", + includeDocumentation: false, + systemFields: false, + }); + + expect(out).toContain("export interface Blog"); + }); + + const pageWithRef404: ContentType = { + uid: "page", + description: "", + schema: [ + { + ...minimalTextField, + uid: "ref_field", + data_type: "reference", + display_name: "Ref", + reference_to: "404", + mandatory: false, + } as unknown as ContentType["schema"][0], + ], + _version: 1, + }; + + it("reference to numeric CT includes type when prefix is set", async () => { + const out = await generateTSFromContentTypes({ + contentTypes: [pageWithRef404, numericUidContentType], + prefix: "P", + includeDocumentation: false, + includeReferencedEntry: false, + systemFields: false, + }); + + expect(out).toContain("P404"); + expect(out).toMatch(/ref_field\?\s*:\s*P404\[\]/); + }); +});