@twin.org/nameof-transformer 0.0.2-next.16 → 0.0.2-next.18
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.
- package/dist/cjs/index.cjs +85 -3
- package/dist/esm/index.mjs +85 -3
- package/dist/types/index.d.ts +1 -1
- package/dist/types/stringHelper.d.ts +18 -0
- package/docs/changelog.md +14 -0
- package/docs/reference/variables/version.md +1 -1
- package/package.json +1 -1
package/dist/cjs/index.cjs
CHANGED
|
@@ -23,6 +23,52 @@ function _interopNamespaceDefault(e) {
|
|
|
23
23
|
|
|
24
24
|
var ts__namespace = /*#__PURE__*/_interopNamespaceDefault(ts);
|
|
25
25
|
|
|
26
|
+
// Copyright 2024 IOTA Stiftung.
|
|
27
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
28
|
+
/**
|
|
29
|
+
* Camel case all the words.
|
|
30
|
+
* @param input The input to convert.
|
|
31
|
+
* @returns The camel case version of the input.
|
|
32
|
+
*/
|
|
33
|
+
function camelCase(input) {
|
|
34
|
+
let output = input;
|
|
35
|
+
// Strip interface prefix if there is one.
|
|
36
|
+
if (/I[A-Z]/.test(output)) {
|
|
37
|
+
output = output.slice(1);
|
|
38
|
+
}
|
|
39
|
+
const words = wordsSplit(output);
|
|
40
|
+
return words.length === 0
|
|
41
|
+
? ""
|
|
42
|
+
: `${words[0].toLowerCase()}${words
|
|
43
|
+
.slice(1)
|
|
44
|
+
.map(w => `${w[0].toUpperCase()}${w.slice(1).toLowerCase()}`)
|
|
45
|
+
.join("")}`;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Convert the input string to kebab case.
|
|
49
|
+
* @param input The input to convert.
|
|
50
|
+
* @returns The kebab case version of the input.
|
|
51
|
+
*/
|
|
52
|
+
function kebabCase(input) {
|
|
53
|
+
let output = input;
|
|
54
|
+
// Strip interface prefix if there is one.
|
|
55
|
+
if (/I[A-Z]/.test(output)) {
|
|
56
|
+
output = output.slice(1);
|
|
57
|
+
}
|
|
58
|
+
return wordsSplit(output).join("-").toLowerCase();
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Split a string into words.
|
|
62
|
+
* @param input The input to split.
|
|
63
|
+
* @returns The string split into words.
|
|
64
|
+
*/
|
|
65
|
+
function wordsSplit(input) {
|
|
66
|
+
return (input
|
|
67
|
+
.replace(/([A-Z])/g, " $1")
|
|
68
|
+
.trim()
|
|
69
|
+
.match(/[^\u0000-\u002F\u003A-\u0040\u005B-\u0060\u007B-\u007F]+/g) ?? []);
|
|
70
|
+
}
|
|
71
|
+
|
|
26
72
|
// Copyright 2024 IOTA Stiftung.
|
|
27
73
|
// SPDX-License-Identifier: Apache-2.0.
|
|
28
74
|
/**
|
|
@@ -70,7 +116,11 @@ function visitNode(node) {
|
|
|
70
116
|
}
|
|
71
117
|
catch { }
|
|
72
118
|
// Is this a call to nameof<Type>(), if so just replace with a string e.g. "Type"
|
|
73
|
-
if (expressionText === "nameof"
|
|
119
|
+
if ((expressionText === "nameof" ||
|
|
120
|
+
expressionText === "nameofKebabCase" ||
|
|
121
|
+
expressionText === "nameofCamelCase") &&
|
|
122
|
+
node.typeArguments &&
|
|
123
|
+
node.typeArguments.length === 1) {
|
|
74
124
|
let typeName;
|
|
75
125
|
if (ts__namespace.isTypeReferenceNode(node.typeArguments[0])) {
|
|
76
126
|
typeName = node.typeArguments[0].typeName.getText();
|
|
@@ -79,10 +129,20 @@ function visitNode(node) {
|
|
|
79
129
|
typeName = `${node.typeArguments[0].elementType.getText()}[]`;
|
|
80
130
|
}
|
|
81
131
|
if (typeName) {
|
|
132
|
+
if (expressionText.endsWith("KebabCase")) {
|
|
133
|
+
return ts__namespace.factory.createStringLiteral(kebabCase(typeName));
|
|
134
|
+
}
|
|
135
|
+
else if (expressionText.endsWith("CamelCase")) {
|
|
136
|
+
return ts__namespace.factory.createStringLiteral(camelCase(typeName));
|
|
137
|
+
}
|
|
82
138
|
return ts__namespace.factory.createStringLiteral(typeName);
|
|
83
139
|
}
|
|
84
140
|
}
|
|
85
|
-
else if (expressionText === "nameof"
|
|
141
|
+
else if ((expressionText === "nameof" ||
|
|
142
|
+
expressionText === "nameofKebabCase" ||
|
|
143
|
+
expressionText === "nameofCamelCase") &&
|
|
144
|
+
node.arguments &&
|
|
145
|
+
node.arguments.length >= 1) {
|
|
86
146
|
// This is an nameof(propName, ?optionalParent) call.
|
|
87
147
|
// Return the whole property path as the string, but remove any chaining operators
|
|
88
148
|
// The second parameter is an optional string, if set change the top level owner
|
|
@@ -95,6 +155,12 @@ function visitNode(node) {
|
|
|
95
155
|
return ts__namespace.factory.createBinaryExpression(ts__namespace.factory.createIdentifier(node.arguments[1].getText()), ts__namespace.factory.createToken(ts__namespace.SyntaxKind.PlusToken), ts__namespace.factory.createStringLiteral(parts.join(".")));
|
|
96
156
|
}
|
|
97
157
|
}
|
|
158
|
+
if (expressionText.endsWith("KebabCase")) {
|
|
159
|
+
return ts__namespace.factory.createStringLiteral(kebabCase(propertyPath));
|
|
160
|
+
}
|
|
161
|
+
else if (expressionText.endsWith("CamelCase")) {
|
|
162
|
+
return ts__namespace.factory.createStringLiteral(camelCase(propertyPath));
|
|
163
|
+
}
|
|
98
164
|
return ts__namespace.factory.createStringLiteral(propertyPath);
|
|
99
165
|
}
|
|
100
166
|
}
|
|
@@ -123,9 +189,25 @@ function manual(content) {
|
|
|
123
189
|
// or the nameof<IMyObject<IType2>>() with "IMyObject"
|
|
124
190
|
const nameRegEx = /nameof<(.*?)(?:<.*>)?>\(\)/g;
|
|
125
191
|
content = content.replace(nameRegEx, '"$1"');
|
|
192
|
+
// Replace the nameofCamelCase<IMyObject>() with the camelCase version of the type name
|
|
193
|
+
// e.g. nameofCamelCase<IMyObject>() => "myObject"
|
|
194
|
+
// and nameofCamelCase<IMyObject<IType2>>() => "myObject"
|
|
195
|
+
const nameRegExCamelCase = /nameofCamelCase<(.*?)(?:<.*?>)?>\(\)/g;
|
|
196
|
+
content = content.replace(nameRegExCamelCase, (_match, typeName) => `"${camelCase(typeName)}"`);
|
|
197
|
+
// Replace the nameofKebabCase<IMyObject>() with the kebabCase version of the type name
|
|
198
|
+
// e.g. nameofKebabCase<IMyObject>() => "my-object"
|
|
199
|
+
// and nameofKebabCase<IMyObject<IType2>>() => "my-object"
|
|
200
|
+
const nameRegExKebabCase = /nameofKebabCase<(.*?)(?:<.*?>)?>\(\)/g;
|
|
201
|
+
content = content.replace(nameRegExKebabCase, (_match, typeName) => `"${kebabCase(typeName)}"`);
|
|
126
202
|
// Replace the nameof(object?.prop) with "object.prop"
|
|
127
203
|
const propRegEx = /nameof\((.*?)\)/g;
|
|
128
204
|
content = content.replace(propRegEx, '"$1"');
|
|
205
|
+
// Replace the nameofCamelCase(object?.prop) with "object.prop"
|
|
206
|
+
const propRegExCamelCase = /nameofCamelCase\((.*?)\)/g;
|
|
207
|
+
content = content.replace(propRegExCamelCase, (_match, typeName) => `"${camelCase(typeName)}"`);
|
|
208
|
+
// Replace the nameofKebabCase(object?.prop) with "object.prop"
|
|
209
|
+
const propRegExKebabCase = /nameofKebabCase\((.*?)\)/g;
|
|
210
|
+
content = content.replace(propRegExKebabCase, (_match, typeName) => `"${kebabCase(typeName)}"`);
|
|
129
211
|
}
|
|
130
212
|
return content;
|
|
131
213
|
}
|
|
@@ -162,7 +244,7 @@ const factory = () => transformerFactory;
|
|
|
162
244
|
* Exports the factory version.
|
|
163
245
|
* @returns The factory.
|
|
164
246
|
*/
|
|
165
|
-
const version = "0.0.2-next.
|
|
247
|
+
const version = "0.0.2-next.18"; // x-release-please-version
|
|
166
248
|
/**
|
|
167
249
|
* Exports the factory name.
|
|
168
250
|
* @returns The factory.
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1,5 +1,51 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
2
|
|
|
3
|
+
// Copyright 2024 IOTA Stiftung.
|
|
4
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
5
|
+
/**
|
|
6
|
+
* Camel case all the words.
|
|
7
|
+
* @param input The input to convert.
|
|
8
|
+
* @returns The camel case version of the input.
|
|
9
|
+
*/
|
|
10
|
+
function camelCase(input) {
|
|
11
|
+
let output = input;
|
|
12
|
+
// Strip interface prefix if there is one.
|
|
13
|
+
if (/I[A-Z]/.test(output)) {
|
|
14
|
+
output = output.slice(1);
|
|
15
|
+
}
|
|
16
|
+
const words = wordsSplit(output);
|
|
17
|
+
return words.length === 0
|
|
18
|
+
? ""
|
|
19
|
+
: `${words[0].toLowerCase()}${words
|
|
20
|
+
.slice(1)
|
|
21
|
+
.map(w => `${w[0].toUpperCase()}${w.slice(1).toLowerCase()}`)
|
|
22
|
+
.join("")}`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Convert the input string to kebab case.
|
|
26
|
+
* @param input The input to convert.
|
|
27
|
+
* @returns The kebab case version of the input.
|
|
28
|
+
*/
|
|
29
|
+
function kebabCase(input) {
|
|
30
|
+
let output = input;
|
|
31
|
+
// Strip interface prefix if there is one.
|
|
32
|
+
if (/I[A-Z]/.test(output)) {
|
|
33
|
+
output = output.slice(1);
|
|
34
|
+
}
|
|
35
|
+
return wordsSplit(output).join("-").toLowerCase();
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Split a string into words.
|
|
39
|
+
* @param input The input to split.
|
|
40
|
+
* @returns The string split into words.
|
|
41
|
+
*/
|
|
42
|
+
function wordsSplit(input) {
|
|
43
|
+
return (input
|
|
44
|
+
.replace(/([A-Z])/g, " $1")
|
|
45
|
+
.trim()
|
|
46
|
+
.match(/[^\u0000-\u002F\u003A-\u0040\u005B-\u0060\u007B-\u007F]+/g) ?? []);
|
|
47
|
+
}
|
|
48
|
+
|
|
3
49
|
// Copyright 2024 IOTA Stiftung.
|
|
4
50
|
// SPDX-License-Identifier: Apache-2.0.
|
|
5
51
|
/**
|
|
@@ -47,7 +93,11 @@ function visitNode(node) {
|
|
|
47
93
|
}
|
|
48
94
|
catch { }
|
|
49
95
|
// Is this a call to nameof<Type>(), if so just replace with a string e.g. "Type"
|
|
50
|
-
if (expressionText === "nameof"
|
|
96
|
+
if ((expressionText === "nameof" ||
|
|
97
|
+
expressionText === "nameofKebabCase" ||
|
|
98
|
+
expressionText === "nameofCamelCase") &&
|
|
99
|
+
node.typeArguments &&
|
|
100
|
+
node.typeArguments.length === 1) {
|
|
51
101
|
let typeName;
|
|
52
102
|
if (ts.isTypeReferenceNode(node.typeArguments[0])) {
|
|
53
103
|
typeName = node.typeArguments[0].typeName.getText();
|
|
@@ -56,10 +106,20 @@ function visitNode(node) {
|
|
|
56
106
|
typeName = `${node.typeArguments[0].elementType.getText()}[]`;
|
|
57
107
|
}
|
|
58
108
|
if (typeName) {
|
|
109
|
+
if (expressionText.endsWith("KebabCase")) {
|
|
110
|
+
return ts.factory.createStringLiteral(kebabCase(typeName));
|
|
111
|
+
}
|
|
112
|
+
else if (expressionText.endsWith("CamelCase")) {
|
|
113
|
+
return ts.factory.createStringLiteral(camelCase(typeName));
|
|
114
|
+
}
|
|
59
115
|
return ts.factory.createStringLiteral(typeName);
|
|
60
116
|
}
|
|
61
117
|
}
|
|
62
|
-
else if (expressionText === "nameof"
|
|
118
|
+
else if ((expressionText === "nameof" ||
|
|
119
|
+
expressionText === "nameofKebabCase" ||
|
|
120
|
+
expressionText === "nameofCamelCase") &&
|
|
121
|
+
node.arguments &&
|
|
122
|
+
node.arguments.length >= 1) {
|
|
63
123
|
// This is an nameof(propName, ?optionalParent) call.
|
|
64
124
|
// Return the whole property path as the string, but remove any chaining operators
|
|
65
125
|
// The second parameter is an optional string, if set change the top level owner
|
|
@@ -72,6 +132,12 @@ function visitNode(node) {
|
|
|
72
132
|
return ts.factory.createBinaryExpression(ts.factory.createIdentifier(node.arguments[1].getText()), ts.factory.createToken(ts.SyntaxKind.PlusToken), ts.factory.createStringLiteral(parts.join(".")));
|
|
73
133
|
}
|
|
74
134
|
}
|
|
135
|
+
if (expressionText.endsWith("KebabCase")) {
|
|
136
|
+
return ts.factory.createStringLiteral(kebabCase(propertyPath));
|
|
137
|
+
}
|
|
138
|
+
else if (expressionText.endsWith("CamelCase")) {
|
|
139
|
+
return ts.factory.createStringLiteral(camelCase(propertyPath));
|
|
140
|
+
}
|
|
75
141
|
return ts.factory.createStringLiteral(propertyPath);
|
|
76
142
|
}
|
|
77
143
|
}
|
|
@@ -100,9 +166,25 @@ function manual(content) {
|
|
|
100
166
|
// or the nameof<IMyObject<IType2>>() with "IMyObject"
|
|
101
167
|
const nameRegEx = /nameof<(.*?)(?:<.*>)?>\(\)/g;
|
|
102
168
|
content = content.replace(nameRegEx, '"$1"');
|
|
169
|
+
// Replace the nameofCamelCase<IMyObject>() with the camelCase version of the type name
|
|
170
|
+
// e.g. nameofCamelCase<IMyObject>() => "myObject"
|
|
171
|
+
// and nameofCamelCase<IMyObject<IType2>>() => "myObject"
|
|
172
|
+
const nameRegExCamelCase = /nameofCamelCase<(.*?)(?:<.*?>)?>\(\)/g;
|
|
173
|
+
content = content.replace(nameRegExCamelCase, (_match, typeName) => `"${camelCase(typeName)}"`);
|
|
174
|
+
// Replace the nameofKebabCase<IMyObject>() with the kebabCase version of the type name
|
|
175
|
+
// e.g. nameofKebabCase<IMyObject>() => "my-object"
|
|
176
|
+
// and nameofKebabCase<IMyObject<IType2>>() => "my-object"
|
|
177
|
+
const nameRegExKebabCase = /nameofKebabCase<(.*?)(?:<.*?>)?>\(\)/g;
|
|
178
|
+
content = content.replace(nameRegExKebabCase, (_match, typeName) => `"${kebabCase(typeName)}"`);
|
|
103
179
|
// Replace the nameof(object?.prop) with "object.prop"
|
|
104
180
|
const propRegEx = /nameof\((.*?)\)/g;
|
|
105
181
|
content = content.replace(propRegEx, '"$1"');
|
|
182
|
+
// Replace the nameofCamelCase(object?.prop) with "object.prop"
|
|
183
|
+
const propRegExCamelCase = /nameofCamelCase\((.*?)\)/g;
|
|
184
|
+
content = content.replace(propRegExCamelCase, (_match, typeName) => `"${camelCase(typeName)}"`);
|
|
185
|
+
// Replace the nameofKebabCase(object?.prop) with "object.prop"
|
|
186
|
+
const propRegExKebabCase = /nameofKebabCase\((.*?)\)/g;
|
|
187
|
+
content = content.replace(propRegExKebabCase, (_match, typeName) => `"${kebabCase(typeName)}"`);
|
|
106
188
|
}
|
|
107
189
|
return content;
|
|
108
190
|
}
|
|
@@ -139,7 +221,7 @@ const factory = () => transformerFactory;
|
|
|
139
221
|
* Exports the factory version.
|
|
140
222
|
* @returns The factory.
|
|
141
223
|
*/
|
|
142
|
-
const version = "0.0.2-next.
|
|
224
|
+
const version = "0.0.2-next.18"; // x-release-please-version
|
|
143
225
|
/**
|
|
144
226
|
* Exports the factory name.
|
|
145
227
|
* @returns The factory.
|
package/dist/types/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export declare const factory: () => ts.TransformerFactory<ts.Node>;
|
|
|
8
8
|
* Exports the factory version.
|
|
9
9
|
* @returns The factory.
|
|
10
10
|
*/
|
|
11
|
-
export declare const version = "0.0.2-next.
|
|
11
|
+
export declare const version = "0.0.2-next.18";
|
|
12
12
|
/**
|
|
13
13
|
* Exports the factory name.
|
|
14
14
|
* @returns The factory.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Camel case all the words.
|
|
3
|
+
* @param input The input to convert.
|
|
4
|
+
* @returns The camel case version of the input.
|
|
5
|
+
*/
|
|
6
|
+
export declare function camelCase(input: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Convert the input string to kebab case.
|
|
9
|
+
* @param input The input to convert.
|
|
10
|
+
* @returns The kebab case version of the input.
|
|
11
|
+
*/
|
|
12
|
+
export declare function kebabCase(input: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Split a string into words.
|
|
15
|
+
* @param input The input to split.
|
|
16
|
+
* @returns The string split into words.
|
|
17
|
+
*/
|
|
18
|
+
export declare function wordsSplit(input: string): string[];
|
package/docs/changelog.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @twin.org/nameof-transformer - Changelog
|
|
2
2
|
|
|
3
|
+
## [0.0.2-next.18](https://github.com/twinfoundation/framework/compare/nameof-transformer-v0.0.2-next.17...nameof-transformer-v0.0.2-next.18) (2025-09-29)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Miscellaneous Chores
|
|
7
|
+
|
|
8
|
+
* **nameof-transformer:** Synchronize repo versions
|
|
9
|
+
|
|
10
|
+
## [0.0.2-next.17](https://github.com/twinfoundation/framework/compare/nameof-transformer-v0.0.2-next.16...nameof-transformer-v0.0.2-next.17) (2025-09-29)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* additional nameof operators ([a5aab60](https://github.com/twinfoundation/framework/commit/a5aab60bf66a86f1b7ff8af7c4f044cb03706d50))
|
|
16
|
+
|
|
3
17
|
## [0.0.2-next.16](https://github.com/twinfoundation/framework/compare/nameof-transformer-v0.0.2-next.15...nameof-transformer-v0.0.2-next.16) (2025-09-28)
|
|
4
18
|
|
|
5
19
|
|
package/package.json
CHANGED