airtable-ts-codegen 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Reset the internal state - useful for testing
3
+ */
4
+ export declare function resetIdentifierState(): void;
1
5
  /**
2
6
  * Used for identifiers:
3
7
  * - If the name is already a valid JS identifier, return it unmodified.
@@ -5,6 +9,7 @@
5
9
  * - Remove invalid characters.
6
10
  * - Convert to PascalCase.
7
11
  * - If the result starts with a digit, prefix with `_`.
12
+ * - If duplicate, add a number suffix.
8
13
  * - Returns a default identifier if the identifier cannot be salvaged.
9
14
  */
10
15
  export declare function escapeIdentifier(name: string): string;
@@ -1,9 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resetIdentifierState = resetIdentifierState;
3
4
  exports.escapeIdentifier = escapeIdentifier;
4
5
  const diacritics_1 = require("diacritics");
5
6
  let invalidIdentifierCount = 0;
6
7
  const DEFAULT_IDENTIFIER = 'invalidIdentifier';
8
+ // Track used identifiers to avoid duplicates
9
+ const usedIdentifiers = new Set();
10
+ /**
11
+ * Reset the internal state - useful for testing
12
+ */
13
+ function resetIdentifierState() {
14
+ usedIdentifiers.clear();
15
+ invalidIdentifierCount = 0;
16
+ }
7
17
  /**
8
18
  * Checks if 'str' is already a valid JavaScript identifier.
9
19
  * If yes, returns true. Otherwise false.
@@ -46,6 +56,7 @@ function toPascalCase(str) {
46
56
  * - Remove invalid characters.
47
57
  * - Convert to PascalCase.
48
58
  * - If the result starts with a digit, prefix with `_`.
59
+ * - If duplicate, add a number suffix.
49
60
  * - Returns a default identifier if the identifier cannot be salvaged.
50
61
  */
51
62
  function escapeIdentifier(name) {
@@ -92,5 +103,13 @@ function escapeIdentifier(name) {
92
103
  return `${DEFAULT_IDENTIFIER}${invalidIdentifierCount}`;
93
104
  }
94
105
  }
95
- return pascal;
106
+ // Handle duplicates by adding numbers
107
+ let finalIdentifier = pascal;
108
+ let counter = 2;
109
+ while (usedIdentifiers.has(finalIdentifier)) {
110
+ finalIdentifier = `${pascal}${counter}`;
111
+ counter += 1;
112
+ }
113
+ usedIdentifiers.add(finalIdentifier);
114
+ return finalIdentifier;
96
115
  }
package/dist/index.js CHANGED
@@ -18,17 +18,19 @@ const main = async (config) => {
18
18
  ].join('\n');
19
19
  };
20
20
  exports.main = main;
21
- const generateInterfaceEntry = ({ jsName, jsType, name, type }) => {
21
+ const generateInterfaceEntry = ({ jsName, jsType, name, type, originalName }) => {
22
22
  if (jsType === null) {
23
- return `\n // Unsupported field ${name} of type ${type}`;
23
+ return `\n // Unsupported field "${name}" of type ${type}`;
24
24
  }
25
- return `\n ${jsName}: ${jsType},`;
25
+ const comment = originalName !== jsName ? ` // Original field: "${originalName}"` : '';
26
+ return `\n ${jsName}: ${jsType},${comment}`;
26
27
  };
27
- const generateMappingEntry = ({ jsName, id, jsType, name }) => {
28
+ const generateMappingEntry = ({ jsName, id, jsType, name, originalName }) => {
28
29
  if (jsType === null) {
29
- return `\n // Unsupported field ${name}: ${(0, escapeString_1.escapeString)(id)}`;
30
+ return `\n // Unsupported field "${name}": ${(0, escapeString_1.escapeString)(id)}`;
30
31
  }
31
- return `\n ${jsName}: '${(0, escapeString_1.escapeString)(id)}',`;
32
+ const comment = originalName !== jsName ? ` // Original field: "${originalName}"` : '';
33
+ return `\n ${jsName}: '${(0, escapeString_1.escapeString)(id)}',${comment}`;
32
34
  };
33
35
  const generateSchemaEntry = ({ jsName, jsType }) => {
34
36
  if (jsType === null) {
@@ -37,11 +39,13 @@ const generateSchemaEntry = ({ jsName, jsType }) => {
37
39
  return `\n ${jsName}: '${(0, escapeString_1.escapeString)(jsType)}',`;
38
40
  };
39
41
  const generateCode = (config, tableSchema) => {
42
+ (0, escapeIdentifier_1.resetIdentifierState)();
40
43
  const itemNameRaw = (0, escapeIdentifier_1.escapeIdentifier)((0, recase_1.recase)(null, 'pascal', tableSchema.name));
41
44
  const itemName = /.s$/.test(itemNameRaw) ? itemNameRaw.slice(0, itemNameRaw.length - 1) : itemNameRaw;
42
45
  const tableName = (0, escapeIdentifier_1.escapeIdentifier)(`${(0, recase_1.recase)(null, 'camel', tableSchema.name)}Table`);
43
46
  const fields = tableSchema.fields.map((f) => ({
44
47
  ...f,
48
+ originalName: f.name,
45
49
  jsName: (0, escapeIdentifier_1.escapeIdentifier)((0, recase_1.recase)(null, 'camel', (0, escapeIdentifier_1.escapeIdentifier)(f.name))),
46
50
  jsType: (0, jsTypeForAirtableType_1.jsTypeForAirtableType)(f),
47
51
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "airtable-ts-codegen",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Autogenerate TypeScript definitions for your Airtable base",
5
5
  "license": "MIT",
6
6
  "author": "Adam Jones (domdomegg)",