mlcl 1.0.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/.eslintignore +31 -0
- package/.eslintrc.json +54 -0
- package/LICENSE +200 -0
- package/README.md +101 -0
- package/babel.config.json +10 -0
- package/build/API/authorization.js +107 -0
- package/build/API/client.js +11 -0
- package/build/API/index.js +8 -0
- package/build/API/molecule/index.js +11 -0
- package/build/API/molecule/types.js +6 -0
- package/build/API/resource/device/index.js +12 -0
- package/build/API/resource/device/types.js +6 -0
- package/build/API/resource/device/utilities/confirmSshKey.js +20 -0
- package/build/API/resource/device/utilities/index.js +7 -0
- package/build/API/resource/device/utilities/sendSshKey.js +64 -0
- package/build/API/resource/index.js +10 -0
- package/build/API/resource/molecule/index.js +12 -0
- package/build/API/resource/molecule/types.js +6 -0
- package/build/API/resource/molecule/utilities/getPlan.js +15 -0
- package/build/API/resource/molecule/utilities/index.js +6 -0
- package/build/API/resource/payment/index.js +9 -0
- package/build/API/resource/payment/plans.js +28 -0
- package/build/API/resource/payment/platform.js +7 -0
- package/build/API/resource/payment/platforms/apple/index.js +21 -0
- package/build/API/resource/payment/platforms/apple/plans/appleMonthly.js +17 -0
- package/build/API/resource/payment/platforms/apple/plans/appleYearly.js +18 -0
- package/build/API/resource/payment/platforms/apple/plans/index.js +7 -0
- package/build/API/resource/payment/platforms/google/index.js +21 -0
- package/build/API/resource/payment/platforms/google/plans/googleMonthly.js +17 -0
- package/build/API/resource/payment/platforms/google/plans/googleYearly.js +18 -0
- package/build/API/resource/payment/platforms/google/plans/index.js +7 -0
- package/build/API/resource/payment/platforms/index.js +8 -0
- package/build/API/resource/payment/platforms/stripe/index.js +25 -0
- package/build/API/resource/payment/platforms/stripe/plans/index.js +11 -0
- package/build/API/resource/payment/platforms/stripe/plans/stripeBusinessMolecule.js +21 -0
- package/build/API/resource/payment/platforms/stripe/plans/stripeMonthly.js +18 -0
- package/build/API/resource/payment/platforms/stripe/plans/stripeMonthlyMolecule.js +18 -0
- package/build/API/resource/payment/platforms/stripe/plans/stripeSingleUseMolecule.js +19 -0
- package/build/API/resource/payment/platforms/stripe/plans/stripeUnlimitedUseMolecule.js +19 -0
- package/build/API/resource/payment/platforms/stripe/plans/stripeYearly.js +19 -0
- package/build/API/resource/payment/types.js +6 -0
- package/build/API/resource/types.js +6 -0
- package/build/API/resource/user/index.js +15 -0
- package/build/API/resource/user/types.js +6 -0
- package/build/API/resource/user/utilities/getPlan.js +12 -0
- package/build/API/resource/user/utilities/index.js +7 -0
- package/build/API/resource/user/utilities/logIn.js +60 -0
- package/build/cli.js +15 -0
- package/build/commands/add-ssh-key.js +24 -0
- package/build/commands/buy.js +70 -0
- package/build/commands/clone.js +329 -0
- package/build/commands/index.js +17 -0
- package/build/commands/info.js +33 -0
- package/build/commands/login.js +20 -0
- package/build/commands/logout.js +23 -0
- package/build/commands/molecule/index.js +11 -0
- package/build/commands/molecule/types.js +6 -0
- package/build/commands/remove-ssh-key.js +36 -0
- package/build/commands/select.js +98 -0
- package/build/commands/set-api-key.js +73 -0
- package/build/commands/subscribe.js +74 -0
- package/build/commands/unsubscribe.js +59 -0
- package/build/commands/utilities/asyncExec.js +6 -0
- package/build/commands/utilities/branchExists.js +13 -0
- package/build/commands/utilities/branchExistsSync.js +12 -0
- package/build/commands/utilities/checkoutSelectionBranch.js +49 -0
- package/build/commands/utilities/cherryPick.js +20 -0
- package/build/commands/utilities/cloneRepo.js +9 -0
- package/build/commands/utilities/convertNpmToYarn.js +60 -0
- package/build/commands/utilities/convertTypeDocToJSDoc.js +51 -0
- package/build/commands/utilities/convertTypeScriptToJavaScript.js +451 -0
- package/build/commands/utilities/enableMergeDrivers.js +50 -0
- package/build/commands/utilities/getCurrentBranch.js +11 -0
- package/build/commands/utilities/getCurrentBranchSync.js +7 -0
- package/build/commands/utilities/getRepoRootPath.js +7 -0
- package/build/commands/utilities/getRepoRootPathSync.js +13 -0
- package/build/commands/utilities/index.js +16 -0
- package/build/commands/utilities/npm-to-yarn.js +41 -0
- package/build/commands/utilities/ts-to-js.js +344 -0
- package/build/commands/version.js +14 -0
- package/build/commands/x-merge-json.js +33 -0
- package/build/config.js +5 -0
- package/build/environment.js +80 -0
- package/build/index.js +23 -0
- package/build/logger.js +12 -0
- package/build/pkg.js +5 -0
- package/build/repoConfig copy.js +5 -0
- package/build/repoConfig.js +5 -0
- package/build/types/global.js +6 -0
- package/build/types/index.js +6 -0
- package/build/userConfig.js +5 -0
- package/build/utilities/__tests__/getErrorMessage.js +26 -0
- package/build/utilities/__tests__/timeAgo.js +39 -0
- package/build/utilities/checkVersion.js +29 -0
- package/build/utilities/getErrorMessage.js +15 -0
- package/build/utilities/index.js +13 -0
- package/build/utilities/readConfig.js +19 -0
- package/build/utilities/readRepoConfig copy.js +20 -0
- package/build/utilities/readRepoConfig.js +19 -0
- package/build/utilities/readUserConfig.js +20 -0
- package/build/utilities/synchronizeUserConfig.js +25 -0
- package/build/utilities/timeAgo.js +42 -0
- package/build/utilities/userLoggedIn.js +24 -0
- package/build/utilities/writeConfig.js +8 -0
- package/build/utilities/writeRepoConfig copy.js +9 -0
- package/build/utilities/writeRepoConfig.js +10 -0
- package/build/utilities/writeUserConfig.js +11 -0
- package/jest.config.json +11 -0
- package/package.json +56 -0
- package/src/API/authorization.ts +143 -0
- package/src/API/client.ts +12 -0
- package/src/API/index.ts +10 -0
- package/src/API/resource/device/index.ts +27 -0
- package/src/API/resource/device/types.ts +80 -0
- package/src/API/resource/device/utilities/confirmSshKey.ts +25 -0
- package/src/API/resource/device/utilities/index.ts +8 -0
- package/src/API/resource/device/utilities/sendSshKey.ts +80 -0
- package/src/API/resource/index.ts +12 -0
- package/src/API/resource/molecule/index.ts +30 -0
- package/src/API/resource/molecule/types.ts +332 -0
- package/src/API/resource/molecule/utilities/getPlan.ts +21 -0
- package/src/API/resource/molecule/utilities/index.ts +7 -0
- package/src/API/resource/payment/index.ts +12 -0
- package/src/API/resource/payment/plans.ts +32 -0
- package/src/API/resource/payment/platform.ts +11 -0
- package/src/API/resource/payment/platforms/apple/index.ts +25 -0
- package/src/API/resource/payment/platforms/apple/plans/appleMonthly.ts +19 -0
- package/src/API/resource/payment/platforms/apple/plans/appleYearly.ts +20 -0
- package/src/API/resource/payment/platforms/apple/plans/index.ts +9 -0
- package/src/API/resource/payment/platforms/google/index.ts +25 -0
- package/src/API/resource/payment/platforms/google/plans/googleMonthly.ts +19 -0
- package/src/API/resource/payment/platforms/google/plans/googleYearly.ts +20 -0
- package/src/API/resource/payment/platforms/google/plans/index.ts +9 -0
- package/src/API/resource/payment/platforms/index.ts +10 -0
- package/src/API/resource/payment/platforms/stripe/index.ts +29 -0
- package/src/API/resource/payment/platforms/stripe/plans/index.ts +12 -0
- package/src/API/resource/payment/platforms/stripe/plans/stripeBusinessMolecule.ts +23 -0
- package/src/API/resource/payment/platforms/stripe/plans/stripeMonthly.ts +20 -0
- package/src/API/resource/payment/platforms/stripe/plans/stripeMonthlyMolecule.ts +20 -0
- package/src/API/resource/payment/platforms/stripe/plans/stripeSingleUseMolecule.ts +21 -0
- package/src/API/resource/payment/platforms/stripe/plans/stripeUnlimitedUseMolecule.ts +21 -0
- package/src/API/resource/payment/platforms/stripe/plans/stripeYearly.ts +21 -0
- package/src/API/resource/payment/types.ts +201 -0
- package/src/API/resource/types.ts +169 -0
- package/src/API/resource/user/index.ts +29 -0
- package/src/API/resource/user/types.ts +131 -0
- package/src/API/resource/user/utilities/getPlan.ts +16 -0
- package/src/API/resource/user/utilities/index.ts +8 -0
- package/src/API/resource/user/utilities/logIn.ts +71 -0
- package/src/commands/add-ssh-key.ts +30 -0
- package/src/commands/buy.ts +83 -0
- package/src/commands/clone.ts +363 -0
- package/src/commands/index.ts +19 -0
- package/src/commands/info.ts +40 -0
- package/src/commands/login.ts +24 -0
- package/src/commands/logout.ts +27 -0
- package/src/commands/remove-ssh-key.ts +42 -0
- package/src/commands/subscribe.ts +84 -0
- package/src/commands/unsubscribe.ts +67 -0
- package/src/commands/utilities/asyncExec.ts +7 -0
- package/src/commands/utilities/branchExists.ts +15 -0
- package/src/commands/utilities/checkoutSelectionBranch.ts +62 -0
- package/src/commands/utilities/cherryPick.ts +23 -0
- package/src/commands/utilities/cloneRepo.ts +10 -0
- package/src/commands/utilities/convertNpmToYarn.ts +71 -0
- package/src/commands/utilities/convertTypeDocToJSDoc.ts +55 -0
- package/src/commands/utilities/convertTypeScriptToJavaScript.ts +526 -0
- package/src/commands/utilities/enableMergeDrivers.ts +55 -0
- package/src/commands/utilities/getCurrentBranch.ts +14 -0
- package/src/commands/utilities/getRepoRootPathSync.ts +13 -0
- package/src/commands/utilities/index.ts +17 -0
- package/src/commands/version.ts +22 -0
- package/src/commands/x-merge-json.ts +41 -0
- package/src/environment.ts +88 -0
- package/src/index.ts +30 -0
- package/src/logger.ts +29 -0
- package/src/pkg.ts +11 -0
- package/src/repoConfig.ts +6 -0
- package/src/types/global.ts +26 -0
- package/src/types/index.ts +53 -0
- package/src/types/process.env.d.ts +56 -0
- package/src/userConfig.ts +6 -0
- package/src/utilities/__tests__/getErrorMessage.ts +32 -0
- package/src/utilities/__tests__/timeAgo.ts +46 -0
- package/src/utilities/checkVersion.ts +31 -0
- package/src/utilities/getErrorMessage.ts +30 -0
- package/src/utilities/index.ts +14 -0
- package/src/utilities/readRepoConfig.ts +22 -0
- package/src/utilities/readUserConfig.ts +24 -0
- package/src/utilities/synchronizeUserConfig.ts +26 -0
- package/src/utilities/timeAgo.ts +39 -0
- package/src/utilities/userLoggedIn.ts +28 -0
- package/src/utilities/writeRepoConfig.ts +11 -0
- package/src/utilities/writeUserConfig.ts +13 -0
- package/tsconfig.json +25 -0
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import ts from 'typescript';
|
|
4
|
+
import prettier from 'prettier';
|
|
5
|
+
/**
|
|
6
|
+
* Returns the name of some node.
|
|
7
|
+
*/
|
|
8
|
+
const getName = (source, node) => {
|
|
9
|
+
const name = (node.name && node.name.escapedText)
|
|
10
|
+
|| (node.parameters && source.substring(node.parameters.pos, node.parameters.end));
|
|
11
|
+
// Change type [key: string] to {...} so it will be parsed by JSDoc.
|
|
12
|
+
if (name === 'key: string') {
|
|
13
|
+
return '{...}';
|
|
14
|
+
}
|
|
15
|
+
return name;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Returns the name of some type.
|
|
19
|
+
*/
|
|
20
|
+
const getTypeName = (source, type) => {
|
|
21
|
+
let typeName = ``;
|
|
22
|
+
if (!type) {
|
|
23
|
+
return `any`;
|
|
24
|
+
}
|
|
25
|
+
if (type.typeName && type.typeName.escapedText) {
|
|
26
|
+
typeName = type.typeName.escapedText;
|
|
27
|
+
if (type.typeArguments && type.typeArguments.length) {
|
|
28
|
+
const args = type.typeArguments.map(subType => getTypeName(source, subType)).join(', ');
|
|
29
|
+
typeName = `${typeName}<${args}>`;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else if (ts.isFunctionTypeNode(type) || ts.isFunctionLike(type)) {
|
|
33
|
+
typeName = 'function';
|
|
34
|
+
}
|
|
35
|
+
else if (ts.isArrayTypeNode(type)) {
|
|
36
|
+
typeName = 'Array';
|
|
37
|
+
}
|
|
38
|
+
else if (type.types) {
|
|
39
|
+
typeName = type.types.map(subType => getTypeName(source, subType)).join(' | ');
|
|
40
|
+
}
|
|
41
|
+
else if (type.members && type.members.length) {
|
|
42
|
+
typeName = 'object';
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
typeName = source.substring(type.pos, type.end).trim();
|
|
46
|
+
}
|
|
47
|
+
typeName = typeName.replace(/`/g, `'`);
|
|
48
|
+
typeName = typeName.replace(`['`, `#`).replace(`']`, ``);
|
|
49
|
+
typeName = typeName.replace(/keyof .+/g, `string`);
|
|
50
|
+
typeName = typeName.replace(/<.+>/gi, ``);
|
|
51
|
+
typeName = typeName.replace(/typeof /gi, ``);
|
|
52
|
+
return typeName;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Returns the JSDoc `@param` tag for some parameter.
|
|
56
|
+
*/
|
|
57
|
+
const getJSDocParamTag = (source, parameter) => {
|
|
58
|
+
let parameterName = getName(source, parameter);
|
|
59
|
+
const parameterComment = (parameter.jsDoc && parameter.jsDoc[0] && parameter.jsDoc[0].comment) || '';
|
|
60
|
+
if (parameter.questionToken) {
|
|
61
|
+
parameterName = ['[', parameterName, ']'].join('');
|
|
62
|
+
}
|
|
63
|
+
return `@param {${getTypeName(source, parameter.type)}} ${parameterName}${parameterComment ? ` ${parameterComment}` : ``}`;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Returns JSDoc `@property` tags for some type.
|
|
67
|
+
*/
|
|
68
|
+
const getJSDocPropertyTags = (source, type, tags = [], parentName = '') => {
|
|
69
|
+
// Type could be an array of types like: `{sth: 1} | string` so parse each type separately.
|
|
70
|
+
const typesToCheck = [type];
|
|
71
|
+
if (type.types && type.types.length) {
|
|
72
|
+
typesToCheck.push(...type.types);
|
|
73
|
+
}
|
|
74
|
+
typesToCheck.forEach(type => {
|
|
75
|
+
// Handling array defined like this: {element1: 'something'}[]
|
|
76
|
+
if (ts.isArrayTypeNode(type) && type.elementType) {
|
|
77
|
+
getJSDocPropertyTags(source, type.elementType, tags, parentName ? parentName + '[]' : '[]');
|
|
78
|
+
}
|
|
79
|
+
// Handling Array<{element1: 'somethin'}>
|
|
80
|
+
if (type.typeName && type.typeName.escapedText === 'Array') {
|
|
81
|
+
if (type.typeArguments && type.typeArguments.length) {
|
|
82
|
+
type.typeArguments.forEach(subType => {
|
|
83
|
+
getJSDocPropertyTags(source, subType, tags, parentName ? parentName + '[]' : '');
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Handling {property1: "value"}
|
|
88
|
+
(type.members || []).filter(m => ts.isTypeElement(m)).forEach(member => {
|
|
89
|
+
let memberName = getName(source, member);
|
|
90
|
+
const memberComment = (member.jsDoc && member.jsDoc[0] && member.jsDoc[0].comment) || '';
|
|
91
|
+
const members = member.type.members || [];
|
|
92
|
+
const memberTypeName = members.length ? 'object' : getTypeName(source, member.type);
|
|
93
|
+
if (parentName) {
|
|
94
|
+
memberName = [parentName, memberName].join('.');
|
|
95
|
+
}
|
|
96
|
+
tags.push(`@property {${memberTypeName}} ${member.questionToken ? `[${memberName}]` : memberName}${memberComment ? ` ${memberComment}` : ``}`);
|
|
97
|
+
getJSDocPropertyTags(source, member.type, tags, memberName);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
return tags;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Returns JSDoc comment lines and a method to append comment lines.
|
|
104
|
+
*/
|
|
105
|
+
const useCommentLines = (source, jsDocNode) => {
|
|
106
|
+
const commentLines = jsDocNode
|
|
107
|
+
? source.substring(jsDocNode.pos, jsDocNode.end).split(/(\n|\r|\r\n)/).filter(line => line.trim().length > 0)
|
|
108
|
+
: [`/**`, ` */`];
|
|
109
|
+
let appendedAtLeastOnce = jsDocNode ? false : true;
|
|
110
|
+
const shouldUpdate = { current: false };
|
|
111
|
+
const appendComment = line => {
|
|
112
|
+
let args = [commentLines.length - 1, 0];
|
|
113
|
+
if (!appendedAtLeastOnce) {
|
|
114
|
+
appendedAtLeastOnce = true;
|
|
115
|
+
args = args.concat(` *`);
|
|
116
|
+
}
|
|
117
|
+
args = args.concat([].concat(line).map(line => ` * ${line}`));
|
|
118
|
+
// eslint-disable-next-line prefer-spread
|
|
119
|
+
commentLines.splice.apply(commentLines, args);
|
|
120
|
+
shouldUpdate.current = true;
|
|
121
|
+
};
|
|
122
|
+
return [commentLines, appendComment, shouldUpdate];
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Updates JSDoc comments based on the type definitions.
|
|
126
|
+
*/
|
|
127
|
+
const updateJSDocComments = (source, filename, modulePath) => {
|
|
128
|
+
const sourceFile = ts.createSourceFile(filename, source, ts.ScriptTarget.Latest, true);
|
|
129
|
+
let updatedSource = source;
|
|
130
|
+
let tempConstantIndex = 1;
|
|
131
|
+
const isTest = modulePath.includes(`/__tests__/`) && !/\.(spec|test)\.tsx?$/.test(filename);
|
|
132
|
+
if (modulePath && !isTest) {
|
|
133
|
+
if (!updatedSource.includes(`* @module`)) {
|
|
134
|
+
updatedSource = `${updatedSource}\n\n/** @module ${modulePath} */`;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
for (const _statement of sourceFile.statements) {
|
|
138
|
+
const statement = _statement; // TODO fix this
|
|
139
|
+
const name = getName(source, statement);
|
|
140
|
+
const [commentLines, appendComment, shouldUpdate] = useCommentLines(source, statement.jsDoc && statement.jsDoc[0]);
|
|
141
|
+
const appendMemberOf = () => {
|
|
142
|
+
if (modulePath && !isTest) {
|
|
143
|
+
appendComment([
|
|
144
|
+
`@memberof module:${modulePath}`,
|
|
145
|
+
``
|
|
146
|
+
]);
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
let addCommentAfter = false;
|
|
150
|
+
const declaration = statement.declarationList
|
|
151
|
+
&& statement.declarationList.declarations
|
|
152
|
+
&& statement.declarationList.declarations[0];
|
|
153
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
154
|
+
const initializer = declaration && declaration.initializer; // TODO
|
|
155
|
+
const functionParameters = initializer && initializer.parameters;
|
|
156
|
+
if (ts.isTypeAliasDeclaration(statement)) {
|
|
157
|
+
addCommentAfter = true;
|
|
158
|
+
if (ts.isFunctionTypeNode(statement.type)) {
|
|
159
|
+
appendMemberOf();
|
|
160
|
+
appendComment(`@typedef {function} ${name}`);
|
|
161
|
+
statement.type.parameters.forEach(parameter => {
|
|
162
|
+
appendComment(getJSDocParamTag(source, parameter));
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
if (ts.isTypeLiteralNode(statement.type)) {
|
|
166
|
+
appendMemberOf();
|
|
167
|
+
appendComment(`@typedef {object} ${name}`);
|
|
168
|
+
getJSDocPropertyTags(source, statement.type).forEach(appendComment);
|
|
169
|
+
}
|
|
170
|
+
if (ts.isIntersectionTypeNode(statement.type)) {
|
|
171
|
+
appendMemberOf();
|
|
172
|
+
appendComment(`@typedef {object} ${name}`);
|
|
173
|
+
getJSDocPropertyTags(source, statement.type).forEach(appendComment);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
else if (ts.isInterfaceDeclaration(statement)) {
|
|
177
|
+
addCommentAfter = true;
|
|
178
|
+
appendMemberOf();
|
|
179
|
+
appendComment(`@typedef ${name}`);
|
|
180
|
+
statement.members.forEach(member => {
|
|
181
|
+
const memberName = getName(source, member);
|
|
182
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
183
|
+
const memberType = member.type; // TODO
|
|
184
|
+
appendComment(`@property {${getTypeName(source, memberType)}} ${member.questionToken ? `[${memberName}]` : memberName}`);
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
else if (ts.isClassDeclaration(statement)) {
|
|
188
|
+
const className = getName(source, statement);
|
|
189
|
+
const memberComments = [];
|
|
190
|
+
statement.members.forEach(member => {
|
|
191
|
+
if (!ts.isPropertyDeclaration(member)) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const modifiers = (member.modifiers || []).map(m => m.getText({ text: source }));
|
|
195
|
+
modifiers.forEach(m => {
|
|
196
|
+
if (['private', 'public', 'protected'].includes(m)) {
|
|
197
|
+
memberComments.push(`@${m}`);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
if (member.type) {
|
|
201
|
+
memberComments.push(`@type {${getTypeName(source, member.type)}}`);
|
|
202
|
+
}
|
|
203
|
+
if (modifiers.find((m => m === 'static'))) {
|
|
204
|
+
memberComments.push(`${className}.${getName(source, member)}`);
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
memberComments.push(`${className}.prototype.${getName(source, member)}`);
|
|
208
|
+
}
|
|
209
|
+
memberComments.forEach(appendComment);
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
else if (declaration && declaration.type) {
|
|
213
|
+
appendMemberOf();
|
|
214
|
+
appendComment(`@type {${getTypeName(source, declaration.type)}}`);
|
|
215
|
+
}
|
|
216
|
+
else if (functionParameters) {
|
|
217
|
+
appendMemberOf();
|
|
218
|
+
functionParameters.forEach(parameter => {
|
|
219
|
+
appendComment(getJSDocParamTag(source, parameter));
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
if (shouldUpdate.current) {
|
|
223
|
+
const newCommentBlock = commentLines.join(`\n`); // TODO .replace(/```ts/g, '```js')
|
|
224
|
+
const text = statement.getText().trim();
|
|
225
|
+
const fullText = statement.getFullText().trim();
|
|
226
|
+
if (filename.split(/\/|\\/).pop() === `types.ts` || !fullText || updatedSource.indexOf(fullText) < 0) {
|
|
227
|
+
updatedSource = `${updatedSource}\n\n${newCommentBlock}`;
|
|
228
|
+
}
|
|
229
|
+
else if (addCommentAfter) {
|
|
230
|
+
updatedSource = updatedSource.replace(statement.jsDoc ? fullText : text, `${text}\n\n${newCommentBlock}\nconst ___temp${tempConstantIndex++} = null`);
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
updatedSource = updatedSource.replace(statement.jsDoc ? fullText : text, `${newCommentBlock}\n${text}`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return updatedSource;
|
|
238
|
+
};
|
|
239
|
+
/**
|
|
240
|
+
* Recursively walks through the directories and converts all .ts and .tsx files
|
|
241
|
+
* to .js and .jsx files with JSDoc type annotations based on the type definitions.
|
|
242
|
+
*
|
|
243
|
+
* All other files are copied as is.
|
|
244
|
+
*/
|
|
245
|
+
const transpileRecursively = (tsPath, jsPath, modulePath = '') => {
|
|
246
|
+
const files = fs.readdirSync(tsPath);
|
|
247
|
+
for (const file of files) {
|
|
248
|
+
const tsFile = path.join(tsPath, file);
|
|
249
|
+
const jsFile = path.join(jsPath, file.replace(/\.ts$/, '.js').replace(/\.tsx$/, '.jsx'));
|
|
250
|
+
const stats = fs.statSync(tsFile);
|
|
251
|
+
if (stats.isDirectory()) {
|
|
252
|
+
transpileRecursively(tsFile, jsFile, modulePath ? `${modulePath}/${file}` : file);
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
else if (!/\.tsx?$/.test(file)) {
|
|
256
|
+
// Ensure the directory exists.
|
|
257
|
+
if (!fs.existsSync(jsPath)) {
|
|
258
|
+
fs.mkdirSync(jsPath, { recursive: true });
|
|
259
|
+
}
|
|
260
|
+
fs.copyFileSync(tsFile, jsFile);
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
else if (/\.d\.ts$/.test(file)) {
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
let source = fs.readFileSync(tsFile, 'utf8');
|
|
267
|
+
if (source.includes(`/** @ts-only */`)) {
|
|
268
|
+
// Skip copying of files with this flag.
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
// Remove lines (usually type imports) containing the `// @ts-only` comment.
|
|
272
|
+
source = source.replace(/^(.*)\/\/ @ts-only(.*)(\r|\n|\r\n)/gm, ``);
|
|
273
|
+
// Preserve double dollar signs. No idea why these are being reduced to a single one.
|
|
274
|
+
source = source.replace(/\$\$\{/g, '__DOLLAR_SIGN__${');
|
|
275
|
+
// Ensure every module is covered.
|
|
276
|
+
source = source + `\n\n\nconst ___temp = null`;
|
|
277
|
+
// Add the necessary JSDoc comments based on the type definitions.
|
|
278
|
+
source = updateJSDocComments(source, tsFile, modulePath ? `${modulePath}/${file.replace(/\.tsx?$/, ``)}` : file.replace(/\.tsx?$/, ``));
|
|
279
|
+
// Preserve line spacing.
|
|
280
|
+
source = source.replace(/(\n\n|\r\r|\r\n\r\n)/g, '\n/* __NEWLINE__ */');
|
|
281
|
+
// Get transpiled ESM code.
|
|
282
|
+
source = ts.transpileModule(source, {
|
|
283
|
+
compilerOptions: {
|
|
284
|
+
target: ts.ScriptTarget.ESNext,
|
|
285
|
+
module: ts.ModuleKind.ESNext,
|
|
286
|
+
moduleResolution: ts.ModuleResolutionKind.NodeJs,
|
|
287
|
+
esModuleInterop: true,
|
|
288
|
+
strict: false,
|
|
289
|
+
jsx: /\.tsx$/.test(file) ? ts.JsxEmit.Preserve : ts.JsxEmit.None,
|
|
290
|
+
newLine: ts.NewLineKind.LineFeed,
|
|
291
|
+
removeComments: false,
|
|
292
|
+
pretty: true
|
|
293
|
+
}
|
|
294
|
+
}).outputText;
|
|
295
|
+
// Restore line spacing.
|
|
296
|
+
source = source.replace(/\/\* __NEWLINE__ \*\//g, '\n');
|
|
297
|
+
// Remove the temporary constants.
|
|
298
|
+
source = source.replace(/const ___temp(|[0-9]+) = null/g, '');
|
|
299
|
+
// Remove @typescript-eslint lines.
|
|
300
|
+
source = source.replace(/(\s|)(\/\/|\/\*) eslint-disable(|-next-line) @typescript-eslint\/.*?(\n|\r|\r\n)/gi, `\n`);
|
|
301
|
+
try {
|
|
302
|
+
// Make the code pretty again.
|
|
303
|
+
source = prettier.format(source, {
|
|
304
|
+
filepath: jsFile,
|
|
305
|
+
printWidth: 120,
|
|
306
|
+
semi: false,
|
|
307
|
+
singleQuote: true,
|
|
308
|
+
quoteProps: 'consistent',
|
|
309
|
+
jsxSingleQuote: true,
|
|
310
|
+
trailingComma: 'none'
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
console.error(error);
|
|
315
|
+
console.log(tsFile);
|
|
316
|
+
console.log(source);
|
|
317
|
+
}
|
|
318
|
+
// Restore double dollar signs.
|
|
319
|
+
source = source.replace(/__DOLLAR_SIGN__/g, '$');
|
|
320
|
+
if (source.trim().length && source.trim() !== `export {}`) {
|
|
321
|
+
// Ensure the directory exists.
|
|
322
|
+
if (!fs.existsSync(jsPath)) {
|
|
323
|
+
fs.mkdirSync(jsPath, { recursive: true });
|
|
324
|
+
}
|
|
325
|
+
// Write the JavaScript file.
|
|
326
|
+
fs.writeFileSync(jsFile, source);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
/**
|
|
331
|
+
* A very quick and dirty hacked together script to convert a TypeScript codebase to JavaScript one.
|
|
332
|
+
*/
|
|
333
|
+
export const convertTypeScriptToJavaScript = async (cwd = `.`) => {
|
|
334
|
+
const tsPath = path.join(cwd, `src-ts`);
|
|
335
|
+
const jsPath = path.join(cwd, `src`);
|
|
336
|
+
try {
|
|
337
|
+
// Transpile all TypeScript to JavaScript.
|
|
338
|
+
fs.renameSync(jsPath, tsPath);
|
|
339
|
+
fs.mkdirSync(jsPath);
|
|
340
|
+
transpileRecursively(tsPath, jsPath);
|
|
341
|
+
fs.rmSync(tsPath, { recursive: true, force: true });
|
|
342
|
+
}
|
|
343
|
+
catch (error) {
|
|
344
|
+
}
|
|
345
|
+
try {
|
|
346
|
+
// Remove TypeScript dependencies and replace `.ts` with `.js` in `package.json`.
|
|
347
|
+
const packageJsonPath = path.join(cwd, `package.json`);
|
|
348
|
+
const packageJson = JSON.parse(await fs.promises.readFile(packageJsonPath, `utf8`));
|
|
349
|
+
delete packageJson.devDependencies[`ts-node`];
|
|
350
|
+
delete packageJson.devDependencies[`typescript`];
|
|
351
|
+
delete packageJson.devDependencies[`@babel/preset-typescript`];
|
|
352
|
+
for (const moduleName in packageJson.devDependencies) {
|
|
353
|
+
if (/^@(types\/|typescript(\/|-))/.test(moduleName)) {
|
|
354
|
+
delete packageJson.devDependencies[moduleName];
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
for (const scriptName in packageJson.scripts) {
|
|
358
|
+
const script = packageJson.scripts[scriptName];
|
|
359
|
+
if (script.includes(` --loader=ts-node/esm`)) {
|
|
360
|
+
packageJson.scripts[scriptName] = script
|
|
361
|
+
.replace(/ --loader=ts-node\/esm/g, ``)
|
|
362
|
+
.replace(/\.tsx\b/g, `.jsx`)
|
|
363
|
+
.replace(/\.ts\b/g, `.js`);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
if (packageJson.scripts.build === `tsc`) {
|
|
367
|
+
delete packageJson.scripts.build;
|
|
368
|
+
}
|
|
369
|
+
if (packageJson.scripts.start) {
|
|
370
|
+
packageJson.scripts.start = packageJson.scripts.start.replace(`node build/`, `node src/`);
|
|
371
|
+
}
|
|
372
|
+
await fs.promises.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
373
|
+
}
|
|
374
|
+
catch (error) {
|
|
375
|
+
}
|
|
376
|
+
try {
|
|
377
|
+
// Remove `tsconfig.json`.
|
|
378
|
+
await fs.promises.rm(path.join(cwd, `tsconfig.json`));
|
|
379
|
+
}
|
|
380
|
+
catch (error) {
|
|
381
|
+
}
|
|
382
|
+
try {
|
|
383
|
+
// Update `.eslintrc.json`.
|
|
384
|
+
const eslintConfigPath = path.join(cwd, `.eslintrc.json`);
|
|
385
|
+
const eslintConfig = JSON.parse(await fs.promises.readFile(eslintConfigPath, `utf8`));
|
|
386
|
+
if (eslintConfig.plugins) {
|
|
387
|
+
eslintConfig.plugins = eslintConfig.plugins.filter(plugin => plugin !== `@typescript-eslint`);
|
|
388
|
+
}
|
|
389
|
+
delete eslintConfig.parser;
|
|
390
|
+
if (eslintConfig.extends) {
|
|
391
|
+
eslintConfig.extends = eslintConfig.extends.filter(extend => extend !== `plugin:@typescript-eslint/recommended`);
|
|
392
|
+
}
|
|
393
|
+
if (eslintConfig.rules) {
|
|
394
|
+
for (const key in eslintConfig.rules) {
|
|
395
|
+
if (/^@typescript-/.test(key)) {
|
|
396
|
+
delete eslintConfig.rules[key];
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
await fs.promises.writeFile(eslintConfigPath, JSON.stringify(eslintConfig, null, 2));
|
|
401
|
+
}
|
|
402
|
+
catch (error) {
|
|
403
|
+
}
|
|
404
|
+
try {
|
|
405
|
+
// Update `jest.config.json` if it exists.
|
|
406
|
+
const jestConfigPath = path.join(cwd, `jest.config.json`);
|
|
407
|
+
await fs.promises.access(jestConfigPath, fs.constants.R_OK | fs.constants.R_OK);
|
|
408
|
+
await fs.promises.writeFile(jestConfigPath, JSON.stringify({
|
|
409
|
+
"roots": [
|
|
410
|
+
"<rootDir>/src/"
|
|
411
|
+
],
|
|
412
|
+
"setupFiles": [
|
|
413
|
+
"<rootDir>/src/environment.js"
|
|
414
|
+
],
|
|
415
|
+
"moduleNameMapper": {
|
|
416
|
+
"^(\\.{1,2}/.*)\\.jsx?$": "$1"
|
|
417
|
+
}
|
|
418
|
+
}, null, 2));
|
|
419
|
+
}
|
|
420
|
+
catch (error) {
|
|
421
|
+
}
|
|
422
|
+
try {
|
|
423
|
+
// Update `babel.config.json` if it exists.
|
|
424
|
+
const babelConfigPath = path.join(cwd, `babel.config.json`);
|
|
425
|
+
const babelConfig = JSON.parse(await fs.promises.readFile(babelConfigPath, `utf8`));
|
|
426
|
+
babelConfig.presets = babelConfig.presets.filter(preset => preset !== `@babel/preset-typescript`);
|
|
427
|
+
await fs.promises.writeFile(babelConfigPath, JSON.stringify(babelConfig, null, 2));
|
|
428
|
+
}
|
|
429
|
+
catch (error) {
|
|
430
|
+
}
|
|
431
|
+
try {
|
|
432
|
+
// Replace all TypeScript info with JavaScript.
|
|
433
|
+
const readmePath = path.join(cwd, `README.md`);
|
|
434
|
+
let README = await fs.promises.readFile(readmePath, `utf8`);
|
|
435
|
+
README = README
|
|
436
|
+
.replace(`\r\n- [\`ts-node\`](https://www.npmjs.com/package/ts-node) - Allows us to run TypeScript (.ts) files as easily as JavaScript (.js) files.\r\n`, ``)
|
|
437
|
+
.replace(`Uses the [TypeScript](typescriptlang.org) compiler to compile the \`*.ts\` files within the \`src\` directory into \`*.js\` files within the \`build\` directory. You probably don't need to use this unless you're explicitly running the production build locally, as [\`ts-node\`](https://www.npmjs.com/package/ts-node) handles everything for you in development.`, ``)
|
|
438
|
+
.replace(`### \`npm run build\`\r\n\r\n\r\n\r\n\r\n`, ``)
|
|
439
|
+
.replace(`### \`yarn run build\`\r\n\r\n\r\n\r\n\r\n`, ``)
|
|
440
|
+
.replace(`\r\n- \`@types/*\` - Type definitions for popular libraries. See [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped) for more information.\r\n`, ``)
|
|
441
|
+
.replace(`\r\n- \`@typescript-eslint/*\` - Enables linting of our TypeScript codebase.\r\n`, ``)
|
|
442
|
+
.replace(`\r\n- [\`typescript\`](https://www.npmjs.com/package/typescript) - Necessary for TypeScript support.\r\n`, ``)
|
|
443
|
+
.replace(/www\.typescriptlang\.org/g, `developer.mozilla.org/en-US/docs/Web/JavaScript`)
|
|
444
|
+
.replace(/JavaScript and TypeScript/g, `JavaScript`)
|
|
445
|
+
.replace(/TypeScript/g, `JavaScript`)
|
|
446
|
+
.replace(/\.ts\b/g, `.js`);
|
|
447
|
+
await fs.promises.writeFile(readmePath, README);
|
|
448
|
+
}
|
|
449
|
+
catch (error) {
|
|
450
|
+
}
|
|
451
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { logger } from '../../logger.js';
|
|
4
|
+
/**
|
|
5
|
+
* A bit of a hack to make it easier to merge many different commits across various branches.
|
|
6
|
+
*
|
|
7
|
+
* Creates or updates the .gitattributes file to use custom merge strategies for every file.
|
|
8
|
+
*
|
|
9
|
+
* Uses a custom JSON merge driver for `.json` files, and diff3 + union for all others.
|
|
10
|
+
*/
|
|
11
|
+
export const enableMergeDrivers = (repoPath = ``) => {
|
|
12
|
+
const gitConfigPath = repoPath ? path.join(repoPath, `.git`, `config`) : path.join(`.git`, `config`);
|
|
13
|
+
const gitConfigExisted = fs.existsSync(gitConfigPath);
|
|
14
|
+
const originalGitConfig = (gitConfigExisted && fs.readFileSync(gitConfigPath, `utf8`)) || ``;
|
|
15
|
+
const gitAttributesPath = repoPath ? path.join(repoPath, `.gitattributes`) : path.join(`.gitattributes`);
|
|
16
|
+
const gitAttributesExisted = fs.existsSync(gitAttributesPath);
|
|
17
|
+
const originalGitAttributes = (gitAttributesExisted && fs.readFileSync(gitAttributesPath, `utf8`)) || ``;
|
|
18
|
+
logger.info(`Enabling custom merge drivers...`);
|
|
19
|
+
fs.appendFileSync(gitConfigPath, [
|
|
20
|
+
``,
|
|
21
|
+
`[merge "json"]`,
|
|
22
|
+
` name = custom merge driver for json files`,
|
|
23
|
+
` driver = npx mlcl x-merge-json %O %A %B`,
|
|
24
|
+
`[merge "diff3-union"]`,
|
|
25
|
+
` name = custom merge driver for all other files`,
|
|
26
|
+
` driver = git merge-file --diff3 --union %A %O %B`,
|
|
27
|
+
``,
|
|
28
|
+
].join(`\n`));
|
|
29
|
+
fs.appendFileSync(gitAttributesPath, [
|
|
30
|
+
``,
|
|
31
|
+
`* merge=diff3-union`,
|
|
32
|
+
`*.json merge=json`,
|
|
33
|
+
``,
|
|
34
|
+
].join(`\n`));
|
|
35
|
+
return () => {
|
|
36
|
+
logger.info(`Removing custom merge drivers...`);
|
|
37
|
+
if (gitConfigExisted) {
|
|
38
|
+
fs.writeFileSync(gitConfigPath, originalGitConfig);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
fs.unlinkSync(gitConfigPath);
|
|
42
|
+
}
|
|
43
|
+
if (gitAttributesExisted) {
|
|
44
|
+
fs.writeFileSync(gitAttributesPath, originalGitAttributes);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
fs.unlinkSync(gitAttributesPath);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { asyncExec } from './asyncExec.js';
|
|
2
|
+
/**
|
|
3
|
+
* Returns the name of the current branch.
|
|
4
|
+
*/
|
|
5
|
+
export const getCurrentBranch = async (repoPath = ``) => {
|
|
6
|
+
const { stdout, stderr } = await asyncExec(`git${repoPath ? ` -C "${repoPath}"` : ``} branch --show-current`);
|
|
7
|
+
if (stderr) {
|
|
8
|
+
throw new Error(stderr);
|
|
9
|
+
}
|
|
10
|
+
return stdout.replace(/^\* /, ``).trim();
|
|
11
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { spawnSync } from 'child_process';
|
|
2
|
+
/**
|
|
3
|
+
* Returns the root path of the current git repository.
|
|
4
|
+
*/
|
|
5
|
+
export const getRepoRootPathSync = () => {
|
|
6
|
+
try {
|
|
7
|
+
const spawn = spawnSync('git', ['rev-parse', '--show-toplevel']);
|
|
8
|
+
return spawn.stdout.toString().trim() || `.`;
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
return `.`;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for common commands.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
export * from './asyncExec.js';
|
|
7
|
+
export * from './branchExists.js';
|
|
8
|
+
export * from './checkoutSelectionBranch.js';
|
|
9
|
+
export * from './cherryPick.js';
|
|
10
|
+
export * from './cloneRepo.js';
|
|
11
|
+
export * from './convertNpmToYarn.js';
|
|
12
|
+
export * from './convertTypeDocToJSDoc.js';
|
|
13
|
+
export * from './convertTypeScriptToJavaScript.js';
|
|
14
|
+
export * from './enableMergeDrivers.js';
|
|
15
|
+
export * from './getCurrentBranch.js';
|
|
16
|
+
export * from './getRepoRootPathSync.js';
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import glob from 'glob';
|
|
3
|
+
// Delete package-lock.json.
|
|
4
|
+
if (fs.existsSync(`package-lock.json`)) {
|
|
5
|
+
fs.unlinkSync(`package-lock.json`);
|
|
6
|
+
}
|
|
7
|
+
// Add Yarn to prerequisites in README.
|
|
8
|
+
let README = fs.readFileSync(`README.md`, `utf8`);
|
|
9
|
+
if (!README.includes(`[Yarn](https://yarnpkg.com/getting-started/install)`)) {
|
|
10
|
+
README = README.replace(`- [Node.js](https://nodejs.org/) (version 16.10 or greater)`, `- [Node.js](https://nodejs.org/) (version 16.10 or greater)
|
|
11
|
+
|
|
12
|
+
- [Yarn](https://yarnpkg.com/getting-started/install)
|
|
13
|
+
|
|
14
|
+
- The recommended way to install Yarn is by enabling [Corepack](https://github.com/nodejs/corepack), which is included by default with the latest Node.js version, but it is opt-in. To enable Corepack, run \`corepack enable\` in your console, which may require elevated permissions (if on Windows, run command prompt as administrator). `);
|
|
15
|
+
fs.writeFileSync(`README.md`, README);
|
|
16
|
+
}
|
|
17
|
+
glob(`{*.md,**!(node_modules)/*.md,src/**/*.{js,jsx,ts,tsx}}`, async (error, files) => {
|
|
18
|
+
const replace = file => {
|
|
19
|
+
const npmContents = fs.readFileSync(file, `utf8`);
|
|
20
|
+
const yarnContents = npmContents
|
|
21
|
+
.replace(/npm run/g, `yarn run`)
|
|
22
|
+
.replace(/npm start/g, `yarn start`)
|
|
23
|
+
.replace(/npm install/g, `yarn install`)
|
|
24
|
+
.replace(/npm version/g, `yarn version`)
|
|
25
|
+
.replace(/npm test/g, `yarn test`)
|
|
26
|
+
.replace(/npx cap/g, `yarn run cap`);
|
|
27
|
+
if (npmContents !== yarnContents) {
|
|
28
|
+
fs.writeFileSync(file, yarnContents);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
replace(`package.json`);
|
|
32
|
+
if (fs.existsSync(`electron/package.json`)) {
|
|
33
|
+
replace(`electron/package.json`);
|
|
34
|
+
}
|
|
35
|
+
for (const file of files) {
|
|
36
|
+
replace(file);
|
|
37
|
+
}
|
|
38
|
+
// yarn install
|
|
39
|
+
// git add yarn.lock
|
|
40
|
+
// git add electron/yarn.lock
|
|
41
|
+
});
|