@openwebf/webf 0.23.7 → 0.24.0
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/README.md +28 -0
- package/bin/webf.js +12 -1
- package/dist/commands.js +375 -9
- package/dist/generator.js +39 -37
- package/dist/module.js +487 -0
- package/dist/peerDeps.js +27 -0
- package/dist/react.js +10 -18
- package/dist/vue.js +138 -117
- package/package.json +2 -2
- package/src/commands.ts +441 -11
- package/src/generator.ts +41 -40
- package/src/module.ts +632 -0
- package/src/peerDeps.ts +21 -0
- package/src/react.ts +10 -18
- package/src/vue.ts +158 -128
- package/templates/module.package.json.tpl +36 -0
- package/templates/module.tsconfig.json.tpl +25 -0
- package/templates/module.tsup.config.ts.tpl +13 -0
- package/templates/react.component.tsx.tpl +2 -2
- package/templates/react.index.ts.tpl +2 -1
- package/templates/react.package.json.tpl +4 -5
- package/templates/react.tsconfig.json.tpl +8 -1
- package/templates/react.tsup.config.ts.tpl +1 -1
- package/templates/vue.component.partial.tpl +4 -4
- package/templates/vue.components.d.ts.tpl +24 -9
- package/templates/vue.package.json.tpl +4 -2
- package/test/commands.test.ts +86 -19
- package/test/generator.test.ts +33 -24
- package/test/peerDeps.test.ts +30 -0
- package/test/react-consts.test.ts +9 -3
- package/test/standard-props.test.ts +14 -14
- package/test/templates.test.ts +17 -0
- package/test/vue.test.ts +36 -11
- package/dist/constants.js +0 -242
package/dist/vue.js
CHANGED
|
@@ -8,7 +8,6 @@ const lodash_1 = __importDefault(require("lodash"));
|
|
|
8
8
|
const fs_1 = __importDefault(require("fs"));
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
10
|
const declaration_1 = require("./declaration");
|
|
11
|
-
const logger_1 = require("./logger");
|
|
12
11
|
const utils_1 = require("./utils");
|
|
13
12
|
function readTemplate(name) {
|
|
14
13
|
return fs_1.default.readFileSync(path_1.default.join(__dirname, '../templates/' + name + '.tpl'), { encoding: 'utf-8' });
|
|
@@ -50,19 +49,18 @@ function generateReturnType(type) {
|
|
|
50
49
|
return 'any';
|
|
51
50
|
if (typeof pointerType === 'string' && pointerType.startsWith('typeof ')) {
|
|
52
51
|
const ident = pointerType.substring('typeof '.length).trim();
|
|
53
|
-
return `typeof
|
|
52
|
+
return `typeof ${ident}`;
|
|
54
53
|
}
|
|
55
54
|
return pointerType;
|
|
56
55
|
}
|
|
57
56
|
if (type.isArray && typeof type.value === 'object' && !Array.isArray(type.value)) {
|
|
58
|
-
const elemType = (
|
|
59
|
-
if (elemType
|
|
57
|
+
const elemType = generateReturnType(type.value);
|
|
58
|
+
if (!elemType)
|
|
60
59
|
return 'any[]';
|
|
61
|
-
if (
|
|
62
|
-
|
|
63
|
-
return `(typeof __webfTypes.${ident})[]`;
|
|
60
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*(?:\\.[A-Za-z_][A-Za-z0-9_]*)*$/.test(elemType)) {
|
|
61
|
+
return `${elemType}[]`;
|
|
64
62
|
}
|
|
65
|
-
return
|
|
63
|
+
return `(${elemType})[]`;
|
|
66
64
|
}
|
|
67
65
|
switch (type.value) {
|
|
68
66
|
case declaration_1.FunctionArgumentType.int:
|
|
@@ -111,125 +109,111 @@ function generateMethodDeclaration(method) {
|
|
|
111
109
|
var returnType = generateReturnType(method.returnType);
|
|
112
110
|
return `${methodName}(${args}): ${returnType};`;
|
|
113
111
|
}
|
|
114
|
-
function
|
|
115
|
-
const classObjects = blob.objects;
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
112
|
+
function getVueComponentSpecs(blob) {
|
|
113
|
+
const classObjects = blob.objects.filter(obj => obj instanceof declaration_1.ClassObject);
|
|
114
|
+
if (classObjects.length === 0)
|
|
115
|
+
return [];
|
|
116
|
+
const properties = classObjects.filter(object => object.name.endsWith('Properties'));
|
|
117
|
+
const events = classObjects.filter(object => object.name.endsWith('Events'));
|
|
118
|
+
const methods = classObjects.filter(object => object.name.endsWith('Methods'));
|
|
119
|
+
const componentMap = new Map();
|
|
120
|
+
properties.forEach(prop => {
|
|
121
|
+
const className = prop.name.replace(/Properties$/, '');
|
|
122
|
+
if (!componentMap.has(className))
|
|
123
|
+
componentMap.set(className, { className });
|
|
124
|
+
componentMap.get(className).properties = prop;
|
|
125
125
|
});
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
events.forEach(ev => {
|
|
127
|
+
const className = ev.name.replace(/Events$/, '');
|
|
128
|
+
if (!componentMap.has(className))
|
|
129
|
+
componentMap.set(className, { className });
|
|
130
|
+
componentMap.get(className).events = ev;
|
|
128
131
|
});
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
+
methods.forEach(m => {
|
|
133
|
+
const className = m.name.replace(/Methods$/, '');
|
|
134
|
+
if (!componentMap.has(className))
|
|
135
|
+
componentMap.set(className, { className });
|
|
136
|
+
componentMap.get(className).methods = m;
|
|
132
137
|
});
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
138
|
+
return Array.from(componentMap.values())
|
|
139
|
+
.filter(spec => spec.className.trim().length > 0)
|
|
140
|
+
.sort((a, b) => a.className.localeCompare(b.className));
|
|
141
|
+
}
|
|
142
|
+
function renderSupportingInterface(object) {
|
|
143
|
+
const hasProps = !!object.props && object.props.length > 0;
|
|
144
|
+
const hasMethods = !!object.methods && object.methods.length > 0;
|
|
145
|
+
if (!hasProps && !hasMethods) {
|
|
146
|
+
return '';
|
|
147
|
+
}
|
|
148
|
+
const interfaceLines = [];
|
|
149
|
+
if (object.documentation && object.documentation.trim().length > 0) {
|
|
150
|
+
interfaceLines.push('/**');
|
|
151
|
+
object.documentation.split('\n').forEach(line => {
|
|
152
|
+
interfaceLines.push(` * ${line}`);
|
|
153
|
+
});
|
|
154
|
+
interfaceLines.push(' */');
|
|
155
|
+
}
|
|
156
|
+
interfaceLines.push(`export interface ${object.name} {`);
|
|
157
|
+
const propLines = (object.props || []).map(prop => {
|
|
158
|
+
const lines = [];
|
|
159
|
+
if (prop.documentation && prop.documentation.trim().length > 0) {
|
|
160
|
+
lines.push(' /**');
|
|
161
|
+
prop.documentation.split('\n').forEach(line => {
|
|
162
|
+
lines.push(` * ${line}`);
|
|
142
163
|
});
|
|
143
|
-
|
|
164
|
+
lines.push(' */');
|
|
144
165
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
lines.push(' */');
|
|
154
|
-
}
|
|
155
|
-
const optionalToken = prop.optional ? '?' : '';
|
|
156
|
-
lines.push(` ${prop.name}${optionalToken}: ${generateReturnType(prop.type)};`);
|
|
157
|
-
return lines.join('\n');
|
|
166
|
+
const optionalToken = prop.optional ? '?' : '';
|
|
167
|
+
lines.push(` ${prop.name}${optionalToken}: ${generateReturnType(prop.type)};`);
|
|
168
|
+
return lines.join('\n');
|
|
169
|
+
});
|
|
170
|
+
interfaceLines.push(propLines.join('\n'));
|
|
171
|
+
if (object.methods && object.methods.length > 0) {
|
|
172
|
+
const methodLines = object.methods.map(method => {
|
|
173
|
+
return ` ${generateMethodDeclaration(method)}`;
|
|
158
174
|
});
|
|
159
|
-
interfaceLines.push(
|
|
160
|
-
interfaceLines.push('}');
|
|
161
|
-
return interfaceLines.join('\n');
|
|
162
|
-
}).filter(dep => dep.trim() !== '').join('\n\n');
|
|
163
|
-
const componentProperties = properties.length > 0 ? properties[0] : undefined;
|
|
164
|
-
const componentEvents = events.length > 0 ? events[0] : undefined;
|
|
165
|
-
const className = (() => {
|
|
166
|
-
if (componentProperties) {
|
|
167
|
-
return componentProperties.name.replace(/Properties$/, '');
|
|
168
|
-
}
|
|
169
|
-
if (componentEvents) {
|
|
170
|
-
return componentEvents.name.replace(/Events$/, '');
|
|
171
|
-
}
|
|
172
|
-
return '';
|
|
173
|
-
})();
|
|
174
|
-
if (!className) {
|
|
175
|
-
return '';
|
|
175
|
+
interfaceLines.push(methodLines.join('\n'));
|
|
176
176
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
properties: componentProperties,
|
|
180
|
-
events: componentEvents,
|
|
181
|
-
classObjectDictionary,
|
|
182
|
-
dependencies,
|
|
183
|
-
blob,
|
|
184
|
-
generateReturnType,
|
|
185
|
-
generateMethodDeclaration,
|
|
186
|
-
generateEventHandlerType,
|
|
187
|
-
});
|
|
188
|
-
const result = content.split('\n').filter(str => {
|
|
189
|
-
return str.trim().length > 0;
|
|
190
|
-
}).join('\n');
|
|
191
|
-
return result;
|
|
177
|
+
interfaceLines.push('}');
|
|
178
|
+
return interfaceLines.join('\n');
|
|
192
179
|
}
|
|
193
|
-
function toVueTagName(
|
|
180
|
+
function toVueTagName(rawClassName) {
|
|
181
|
+
const className = rawClassName.trim();
|
|
194
182
|
if (className.startsWith('WebF')) {
|
|
195
183
|
const withoutPrefix = className.substring(4);
|
|
196
|
-
|
|
184
|
+
const suffix = lodash_1.default.kebabCase(withoutPrefix);
|
|
185
|
+
return suffix.length > 0 ? 'webf-' + suffix : 'webf';
|
|
197
186
|
}
|
|
198
|
-
|
|
187
|
+
if (className.startsWith('Flutter')) {
|
|
199
188
|
const withoutPrefix = className.substring(7);
|
|
200
|
-
|
|
189
|
+
const suffix = lodash_1.default.kebabCase(withoutPrefix);
|
|
190
|
+
return suffix.length > 0 ? 'flutter-' + suffix : 'flutter';
|
|
201
191
|
}
|
|
202
|
-
|
|
192
|
+
const kebab = lodash_1.default.kebabCase(className);
|
|
193
|
+
return kebab.replace(/^web-f-/, 'webf-');
|
|
203
194
|
}
|
|
204
195
|
function generateVueTypings(blobs) {
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
return object.name.endsWith('Events');
|
|
212
|
-
});
|
|
213
|
-
const componentProperties = properties.length > 0 ? properties[0] : undefined;
|
|
214
|
-
const componentEvents = events.length > 0 ? events[0] : undefined;
|
|
215
|
-
const className = (() => {
|
|
216
|
-
if (componentProperties) {
|
|
217
|
-
return componentProperties.name.replace(/Properties$/, '');
|
|
218
|
-
}
|
|
219
|
-
if (componentEvents) {
|
|
220
|
-
return componentEvents.name.replace(/Events$/, '');
|
|
221
|
-
}
|
|
222
|
-
return '';
|
|
223
|
-
})();
|
|
224
|
-
return className;
|
|
225
|
-
}).filter(name => {
|
|
226
|
-
return name.length > 0;
|
|
196
|
+
const componentSpecMap = new Map();
|
|
197
|
+
blobs
|
|
198
|
+
.flatMap(blob => getVueComponentSpecs(blob))
|
|
199
|
+
.forEach(spec => {
|
|
200
|
+
if (!componentSpecMap.has(spec.className))
|
|
201
|
+
componentSpecMap.set(spec.className, spec);
|
|
227
202
|
});
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
203
|
+
const componentSpecs = Array.from(componentSpecMap.values()).sort((a, b) => a.className.localeCompare(b.className));
|
|
204
|
+
const componentNames = componentSpecs.map(spec => spec.className);
|
|
205
|
+
const components = componentSpecs.map(spec => {
|
|
206
|
+
const content = lodash_1.default.template(readTemplate('vue.component.partial'))({
|
|
207
|
+
className: spec.className,
|
|
208
|
+
properties: spec.properties,
|
|
209
|
+
events: spec.events,
|
|
210
|
+
methods: spec.methods,
|
|
211
|
+
generateReturnType,
|
|
212
|
+
generateMethodDeclaration,
|
|
213
|
+
generateEventHandlerType,
|
|
214
|
+
});
|
|
215
|
+
return content.split('\n').filter(str => str.trim().length > 0).join('\n');
|
|
216
|
+
}).filter(Boolean).join('\n\n');
|
|
233
217
|
// Collect declare consts across blobs and render as exported ambient declarations
|
|
234
218
|
const consts = blobs
|
|
235
219
|
.flatMap(blob => blob.objects)
|
|
@@ -241,19 +225,55 @@ function generateVueTypings(blobs) {
|
|
|
241
225
|
uniqueConsts.set(c.name, c);
|
|
242
226
|
});
|
|
243
227
|
const constDeclarations = Array.from(uniqueConsts.values())
|
|
228
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
|
244
229
|
.map(c => `export declare const ${c.name}: ${c.type};`)
|
|
245
230
|
.join('\n');
|
|
246
231
|
// Collect declare enums across blobs
|
|
247
232
|
const enums = blobs
|
|
248
233
|
.flatMap(blob => blob.objects)
|
|
249
234
|
.filter(obj => obj instanceof declaration_1.EnumObject);
|
|
250
|
-
const
|
|
235
|
+
const uniqueEnums = new Map();
|
|
236
|
+
enums.forEach(e => {
|
|
237
|
+
if (!uniqueEnums.has(e.name))
|
|
238
|
+
uniqueEnums.set(e.name, e);
|
|
239
|
+
});
|
|
240
|
+
const enumDeclarations = Array.from(uniqueEnums.values())
|
|
241
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
|
242
|
+
.map(e => {
|
|
251
243
|
const members = e.members.map(m => m.initializer ? `${m.name} = ${m.initializer}` : `${m.name}`).join(', ');
|
|
252
244
|
return `export declare enum ${e.name} { ${members} }`;
|
|
253
|
-
})
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
245
|
+
})
|
|
246
|
+
.join('\n');
|
|
247
|
+
// Collect type aliases across blobs and render as exported declarations.
|
|
248
|
+
const typeAliases = blobs
|
|
249
|
+
.flatMap(blob => blob.objects)
|
|
250
|
+
.filter(obj => obj instanceof declaration_1.TypeAliasObject);
|
|
251
|
+
const uniqueTypeAliases = new Map();
|
|
252
|
+
typeAliases.forEach(t => {
|
|
253
|
+
if (!uniqueTypeAliases.has(t.name))
|
|
254
|
+
uniqueTypeAliases.set(t.name, t);
|
|
255
|
+
});
|
|
256
|
+
const typeAliasDeclarations = Array.from(uniqueTypeAliases.values())
|
|
257
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
|
258
|
+
.map(t => `export type ${t.name} = ${t.type};`)
|
|
259
|
+
.join('\n');
|
|
260
|
+
// Collect supporting interfaces (non-component interfaces) so referenced types exist.
|
|
261
|
+
const supportingInterfaces = blobs
|
|
262
|
+
.flatMap(blob => blob.objects)
|
|
263
|
+
.filter(obj => obj instanceof declaration_1.ClassObject);
|
|
264
|
+
const supporting = supportingInterfaces.filter(obj => {
|
|
265
|
+
return !obj.name.endsWith('Properties') && !obj.name.endsWith('Events') && !obj.name.endsWith('Methods');
|
|
266
|
+
});
|
|
267
|
+
const uniqueSupporting = new Map();
|
|
268
|
+
supporting.forEach(obj => {
|
|
269
|
+
if (!uniqueSupporting.has(obj.name))
|
|
270
|
+
uniqueSupporting.set(obj.name, obj);
|
|
271
|
+
});
|
|
272
|
+
const supportingDeclarations = Array.from(uniqueSupporting.values())
|
|
273
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
|
274
|
+
.map(obj => renderSupportingInterface(obj))
|
|
275
|
+
.filter(Boolean)
|
|
276
|
+
.join('\n\n');
|
|
257
277
|
// Build mapping of template tag names to class names for GlobalComponents
|
|
258
278
|
const componentMetas = componentNames.map(className => ({
|
|
259
279
|
className,
|
|
@@ -269,7 +289,8 @@ function generateVueTypings(blobs) {
|
|
|
269
289
|
components,
|
|
270
290
|
consts: constDeclarations,
|
|
271
291
|
enums: enumDeclarations,
|
|
272
|
-
|
|
292
|
+
typeAliases: typeAliasDeclarations,
|
|
293
|
+
dependencies: supportingDeclarations,
|
|
273
294
|
});
|
|
274
295
|
return content.split('\n').filter(str => {
|
|
275
296
|
return str.trim().length > 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openwebf/webf",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"description": "Command line tools for WebF",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"keywords": [],
|
|
26
26
|
"author": "",
|
|
27
|
-
"license": "
|
|
27
|
+
"license": "Apache-2.0",
|
|
28
28
|
"type": "commonjs",
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/inquirer": "^8.2.11",
|