Skip to content

Commit 5a070ee

Browse files
author
naman-contentstack
committed
created a utils file and addressed comments
1 parent 6e38b2f commit 5a070ee

3 files changed

Lines changed: 108 additions & 56 deletions

File tree

.talismanrc

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,4 @@ fileignoreconfig:
66
checksum: 863e4c99d7da6be90dc7af0a2744a470092019418ab1ff6f2c8e87b40a25eb59
77
- filename: .husky/pre-commit
88
checksum: 5baabd7d2c391648163f9371f0e5e9484f8fb90fa2284cfc378732ec3192c193
9-
- filename: src/generateTS/factory.ts
10-
checksum: c00585856029a635ba2f1d6f7405bac68a4b05f7a83bee83f5374244df0d3b10
11-
- filename: tests/integration/generateTS/generateTS.test.ts
12-
checksum: 328090da57e8cb2dd616091f3336b6da77a253f97ddfd47e3e1dd683260e58eb
13-
- filename: src/generateTS/shared/cslp-helpers.ts
14-
checksum: 55aa5c0c9ec0cd6c6139d4e9e4f1666abc7bc083313ccc2bf410c56935f35ef2
15-
- filename: tests/unit/tsgen/numeric-keys.test.ts
16-
checksum: 8871e816eef01a03439dc090c213cb75353705efc417a8fbdf905c6f9774192c
17-
- filename: src/graphqlTS/index.ts
18-
checksum: 24b1e285d463d0cf1f82a2f46b7e6de9ae66e3318221241a742ce813b65ae7cb
19-
- filename: src/generateTS/index.ts
20-
checksum: 0f4d4bc5ef7373e7749ef6ea71e8a5edece8816ff6cf44cf42aea58e26c30524
219
version: "1.0"

src/generateTS/factory.ts

Lines changed: 49 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ import * as ContentstackTypes from "../types/schema";
44
import * as _ from "lodash";
55
import { CSLP_HELPERS } from "./shared/cslp-helpers";
66
import { cliux } from "@contentstack/cli-utilities";
7+
import {
8+
isNumericIdentifier,
9+
NUMERIC_IDENTIFIER_EXCLUSION_REASON,
10+
checkNumericIdentifierExclusion,
11+
} from "./shared/utils";
712

813
export type TSGenOptions = {
914
docgen: DocumentationGenerator;
@@ -87,11 +92,6 @@ export default function (userOptions: TSGenOptions) {
8792
const skippedBlocks: Array<{ uid: string; path: string; reason: string }> =
8893
[];
8994

90-
// Helper function to check if a key starts with a number
91-
function isNumericKey(key: string): boolean {
92-
return /^\d/.test(key);
93-
}
94-
9595
const typeMap: TypeMap = {
9696
text: { func: type_text, track: true, flag: TypeFlags.BuiltinJS },
9797
number: { func: type_number, track: true, flag: TypeFlags.BuiltinJS },
@@ -234,7 +234,7 @@ export default function (userOptions: TSGenOptions) {
234234
`Skipped field "${field.uid}" with unknown type "${field.data_type}": ${reason}`,
235235
{ color: "yellow" }
236236
);
237-
type = "unknown"; // Use unknown as fallback for better type safety
237+
type = "Record<string, unknown>"; // Use Record<string, unknown> for balanced type safety
238238
}
239239
}
240240

@@ -243,12 +243,14 @@ export default function (userOptions: TSGenOptions) {
243243

244244
const handleGlobalField = (field: ContentstackTypes.Field): string => {
245245
// Skip global field references with numeric UIDs
246-
if (isNumericKey(field.reference_to)) {
247-
const reason =
248-
"TypeScript constraint: object keys cannot start with numbers";
249-
skippedFields.push({ uid: field.uid, path: field.uid, reason });
246+
const exclusionCheck = checkNumericIdentifierExclusion(
247+
field.reference_to,
248+
field.uid
249+
);
250+
if (exclusionCheck.shouldExclude) {
251+
skippedFields.push(exclusionCheck.record!);
250252
cliux.print(
251-
`Skipped global field reference "${field.uid}" to "${field.reference_to}": ${reason}`,
253+
`Skipped global field reference "${field.uid}" to "${field.reference_to}": ${NUMERIC_IDENTIFIER_EXCLUSION_REASON}`,
252254
{ color: "yellow" }
253255
);
254256
return "string"; // Use string as fallback for global field references
@@ -295,17 +297,15 @@ export default function (userOptions: TSGenOptions) {
295297

296298
for (const field of schema) {
297299
// Skip fields with numeric UIDs
298-
if (isNumericKey(field.uid)) {
299-
const fieldPath = path ? `${path}.${field.uid}` : field.uid;
300-
const reason =
301-
"TypeScript constraint: object keys cannot start with numbers";
302-
skippedFields.push({
303-
uid: field.uid,
304-
path: fieldPath,
305-
reason,
306-
});
300+
const fieldPath = path ? `${path}.${field.uid}` : field.uid;
301+
const exclusionCheck = checkNumericIdentifierExclusion(
302+
field.uid,
303+
fieldPath
304+
);
305+
if (exclusionCheck.shouldExclude) {
306+
skippedFields.push(exclusionCheck.record!);
307307
cliux.print(
308-
` Skipped field "${field.uid}" at path "${fieldPath}": ${reason}`,
308+
`Skipped field "${field.uid}" at path "${fieldPath}": ${NUMERIC_IDENTIFIER_EXCLUSION_REASON}`,
309309
{ color: "yellow" }
310310
);
311311
continue;
@@ -361,17 +361,15 @@ export default function (userOptions: TSGenOptions) {
361361
const modularBlockDefinitions = field.blocks
362362
.map((block) => {
363363
// Skip blocks with numeric UIDs
364-
if (isNumericKey(block.uid)) {
365-
const blockPath = `${field.uid}.blocks.${block.uid}`;
366-
const reason =
367-
"TypeScript constraint: object keys cannot start with numbers";
368-
skippedBlocks.push({
369-
uid: block.uid,
370-
path: blockPath,
371-
reason,
372-
});
364+
const blockPath = `${field.uid}.blocks.${block.uid}`;
365+
const exclusionCheck = checkNumericIdentifierExclusion(
366+
block.uid,
367+
blockPath
368+
);
369+
if (exclusionCheck.shouldExclude) {
370+
skippedBlocks.push(exclusionCheck.record!);
373371
cliux.print(
374-
`Skipped block "${block.uid}" at path "${blockPath}": ${reason}`,
372+
`Skipped block "${block.uid}" at path "${blockPath}": ${NUMERIC_IDENTIFIER_EXCLUSION_REASON}`,
375373
{ color: "yellow" }
376374
);
377375
return null; // Return null to filter out later
@@ -467,13 +465,18 @@ export default function (userOptions: TSGenOptions) {
467465

468466
function type_global_field(field: ContentstackTypes.GlobalField) {
469467
// Skip global fields with numeric UIDs
470-
if (isNumericKey(field.uid)) {
471-
const reason =
472-
"TypeScript constraint: object keys cannot start with numbers";
473-
skippedFields.push({ uid: field.uid, path: field.uid, reason });
474-
cliux.print(`Skipped global field "${field.uid}": ${reason}`, {
475-
color: "yellow",
476-
});
468+
const exclusionCheck = checkNumericIdentifierExclusion(
469+
field.uid,
470+
field.uid
471+
);
472+
if (exclusionCheck.shouldExclude) {
473+
skippedFields.push(exclusionCheck.record!);
474+
cliux.print(
475+
`Skipped global field "${field.uid}": ${NUMERIC_IDENTIFIER_EXCLUSION_REASON}`,
476+
{
477+
color: "yellow",
478+
}
479+
);
477480
return "string"; // Use string as fallback for global fields
478481
}
479482

@@ -496,22 +499,22 @@ export default function (userOptions: TSGenOptions) {
496499
if (Array.isArray(field.reference_to)) {
497500
field.reference_to.forEach((v) => {
498501
// Skip references to content types with numeric names
499-
if (!isNumericKey(v)) {
502+
if (!isNumericIdentifier(v)) {
500503
references.push(name_type(v));
501504
} else {
502505
cliux.print(
503-
`Skipped reference to content type "${v}": TypeScript constraint: object keys cannot start with numbers`,
506+
`Skipped reference to content type "${v}": ${NUMERIC_IDENTIFIER_EXCLUSION_REASON}`,
504507
{ color: "yellow" }
505508
);
506509
}
507510
});
508511
} else {
509512
// Skip references to content types with numeric names
510-
if (!isNumericKey(field.reference_to)) {
513+
if (!isNumericIdentifier(field.reference_to)) {
511514
references.push(name_type(field.reference_to));
512515
} else {
513516
cliux.print(
514-
`Skipped reference to content type "${field.reference_to}": TypeScript constraint: object keys cannot start with numbers`,
517+
`Skipped reference to content type "${field.reference_to}": ${NUMERIC_IDENTIFIER_EXCLUSION_REASON}`,
515518
{ color: "yellow" }
516519
);
517520
}
@@ -558,7 +561,8 @@ export default function (userOptions: TSGenOptions) {
558561

559562
// Log summary table of skipped fields and blocks
560563
if (skippedFields.length > 0 || skippedBlocks.length > 0) {
561-
cliux.print("\n Summary of Skipped Items:", {
564+
cliux.print("");
565+
cliux.print("Summary of Skipped Items:", {
562566
color: "cyan",
563567
bold: true,
564568
});
@@ -591,7 +595,8 @@ export default function (userOptions: TSGenOptions) {
591595
);
592596

593597
const totalSkipped = skippedFields.length + skippedBlocks.length;
594-
cliux.print(`\n Total skipped items: ${totalSkipped}`, {
598+
cliux.print("", {});
599+
cliux.print(`Total skipped items: ${totalSkipped}`, {
595600
color: "yellow",
596601
});
597602
cliux.success(" Generation completed successfully with partial schema.");

src/generateTS/shared/utils.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* General utility functions for the types-generator library
3+
*/
4+
5+
/**
6+
* Checks if a string identifier starts with a number
7+
* @param identifier - The string to check
8+
* @returns true if the identifier starts with a number, false otherwise
9+
*/
10+
export function isNumericIdentifier(identifier: string): boolean {
11+
return /^\d/.test(identifier);
12+
}
13+
14+
/**
15+
* Creates a skipped item record for tracking
16+
* @param uid - The UID of the skipped item
17+
* @param path - The path where the item was found
18+
* @param reason - The reason for skipping
19+
* @returns A skipped item record
20+
*/
21+
export function createSkippedItemRecord(
22+
uid: string,
23+
path: string,
24+
reason: string
25+
): { uid: string; path: string; reason: string } {
26+
return { uid, path, reason };
27+
}
28+
29+
/**
30+
* The standard reason for excluding items with numeric identifiers
31+
*/
32+
export const NUMERIC_IDENTIFIER_EXCLUSION_REASON =
33+
"TypeScript constraint: object keys cannot start with numbers";
34+
35+
/**
36+
* Checks if an item should be excluded due to numeric identifier and creates the appropriate record
37+
* @param uid - The UID to check
38+
* @param path - The path where the item was found
39+
* @returns Object with shouldExclude boolean and record if applicable
40+
*/
41+
export function checkNumericIdentifierExclusion(
42+
uid: string,
43+
path: string
44+
): {
45+
shouldExclude: boolean;
46+
record?: { uid: string; path: string; reason: string };
47+
} {
48+
if (isNumericIdentifier(uid)) {
49+
return {
50+
shouldExclude: true,
51+
record: createSkippedItemRecord(
52+
uid,
53+
path,
54+
NUMERIC_IDENTIFIER_EXCLUSION_REASON
55+
),
56+
};
57+
}
58+
return { shouldExclude: false };
59+
}

0 commit comments

Comments
 (0)