@contrail/flexplm 1.7.0-alpha.71b4d30 → 1.7.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/lib/cli/commands/{config-file/create.d.ts → create.d.ts} +1 -0
- package/lib/cli/commands/{mapping-file/create.js → create.js} +20 -4
- package/lib/cli/commands/{mapping-file/create.spec.js → create.spec.js} +1 -1
- package/lib/cli/commands/upload.d.ts +19 -0
- package/lib/cli/commands/upload.js +254 -0
- package/lib/cli/commands/upload.spec.js +95 -0
- package/lib/cli/index.js +37 -18
- package/lib/cli/index.spec.js +53 -111
- package/lib/publish/base-process-publish-assortment.d.ts +2 -0
- package/lib/publish/base-process-publish-assortment.js +59 -7
- package/lib/publish/base-process-publish-assortment.spec.js +188 -0
- package/package.json +2 -2
- package/scripts/copy-template.js +5 -16
- package/lib/cli/commands/config-file/create.js +0 -61
- package/lib/cli/commands/config-file/create.spec.js +0 -74
- package/lib/cli/commands/config-file/index.d.ts +0 -2
- package/lib/cli/commands/config-file/index.js +0 -47
- package/lib/cli/commands/config-file/upload.d.ts +0 -8
- package/lib/cli/commands/config-file/upload.js +0 -84
- package/lib/cli/commands/config-file/upload.spec.js +0 -51
- package/lib/cli/commands/mapping-file/create.d.ts +0 -4
- package/lib/cli/commands/mapping-file/create.spec.d.ts +0 -1
- package/lib/cli/commands/mapping-file/index.d.ts +0 -2
- package/lib/cli/commands/mapping-file/index.js +0 -57
- package/lib/cli/commands/mapping-file/upload.d.ts +0 -3
- package/lib/cli/commands/mapping-file/upload.js +0 -70
- package/lib/cli/commands/shared/git.d.ts +0 -6
- package/lib/cli/commands/shared/git.js +0 -100
- package/lib/cli/commands/shared/prompts.d.ts +0 -2
- package/lib/cli/commands/shared/prompts.js +0 -61
- package/lib/cli/commands/shared/upload-base.d.ts +0 -24
- package/lib/cli/commands/shared/upload-base.js +0 -138
- package/lib/cli/commands/shared/upload-base.spec.d.ts +0 -1
- package/lib/cli/commands/shared/upload-base.spec.js +0 -99
- package/lib/cli/template/config-template.json.template +0 -5
- /package/lib/cli/commands/{mapping-file/compile.d.ts → compile.d.ts} +0 -0
- /package/lib/cli/commands/{mapping-file/compile.js → compile.js} +0 -0
- /package/lib/cli/commands/{mapping-file/compile.spec.d.ts → compile.spec.d.ts} +0 -0
- /package/lib/cli/commands/{mapping-file/compile.spec.js → compile.spec.js} +0 -0
- /package/lib/cli/commands/{config-file/create.spec.d.ts → create.spec.d.ts} +0 -0
- /package/lib/cli/commands/{config-file/upload.spec.d.ts → upload.spec.d.ts} +0 -0
|
@@ -26,14 +26,30 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
26
26
|
exports.CreateCommand = void 0;
|
|
27
27
|
const fs = __importStar(require("fs"));
|
|
28
28
|
const path = __importStar(require("path"));
|
|
29
|
-
const
|
|
29
|
+
const readline = __importStar(require("readline"));
|
|
30
30
|
const TEMPLATE_FILENAME = 'mapping-template.ts.template';
|
|
31
31
|
const PLACEHOLDER = '<ORG_NAME>';
|
|
32
32
|
class CreateCommand {
|
|
33
|
+
prompt(question) {
|
|
34
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
35
|
+
const onSigint = () => {
|
|
36
|
+
rl.close();
|
|
37
|
+
process.stdout.write('\n');
|
|
38
|
+
process.exit(130);
|
|
39
|
+
};
|
|
40
|
+
process.once('SIGINT', onSigint);
|
|
41
|
+
return new Promise((resolve) => {
|
|
42
|
+
rl.question(question, (answer) => {
|
|
43
|
+
process.removeListener('SIGINT', onSigint);
|
|
44
|
+
rl.close();
|
|
45
|
+
resolve(answer);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
}
|
|
33
49
|
findTemplate() {
|
|
34
50
|
const candidates = [
|
|
35
|
-
path.join(__dirname, '..', '
|
|
36
|
-
path.join(__dirname, '..', '..', '..', '
|
|
51
|
+
path.join(__dirname, '..', 'template', TEMPLATE_FILENAME),
|
|
52
|
+
path.join(__dirname, '..', '..', '..', 'src', 'cli', 'template', TEMPLATE_FILENAME),
|
|
37
53
|
];
|
|
38
54
|
for (const candidate of candidates) {
|
|
39
55
|
if (fs.existsSync(candidate)) {
|
|
@@ -43,7 +59,7 @@ class CreateCommand {
|
|
|
43
59
|
throw new Error(`Could not locate ${TEMPLATE_FILENAME}. Tried:\n ${candidates.join('\n ')}`);
|
|
44
60
|
}
|
|
45
61
|
async run() {
|
|
46
|
-
const orgName = (await
|
|
62
|
+
const orgName = (await this.prompt('orgName: ')).trim();
|
|
47
63
|
if (!orgName) {
|
|
48
64
|
throw new Error('orgName is required');
|
|
49
65
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
interface UploadOptions {
|
|
2
|
+
filePath: string;
|
|
3
|
+
message?: string;
|
|
4
|
+
branch?: string;
|
|
5
|
+
skipGit: boolean;
|
|
6
|
+
updateConfig: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare class UploadCommand {
|
|
9
|
+
static parseArgs(args: string[]): UploadOptions;
|
|
10
|
+
static buildCommitMessage(userMessage: string, fileId: string): string;
|
|
11
|
+
private prompt;
|
|
12
|
+
private promptHidden;
|
|
13
|
+
private runGit;
|
|
14
|
+
private tryRunGit;
|
|
15
|
+
private commitToGit;
|
|
16
|
+
run(args: string[]): Promise<void>;
|
|
17
|
+
private setTransformMapFileOnAppOrg;
|
|
18
|
+
}
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.UploadCommand = void 0;
|
|
27
|
+
const child_process_1 = require("child_process");
|
|
28
|
+
const fs = __importStar(require("fs"));
|
|
29
|
+
const path = __importStar(require("path"));
|
|
30
|
+
const readline = __importStar(require("readline"));
|
|
31
|
+
const sdk_1 = require("@contrail/sdk");
|
|
32
|
+
const compile_1 = require("./compile");
|
|
33
|
+
class UploadCommand {
|
|
34
|
+
static parseArgs(args) {
|
|
35
|
+
let filePath;
|
|
36
|
+
let message;
|
|
37
|
+
let branch;
|
|
38
|
+
let skipGit = false;
|
|
39
|
+
let updateConfig = false;
|
|
40
|
+
for (let i = 0; i < args.length; i++) {
|
|
41
|
+
const a = args[i];
|
|
42
|
+
if (a === '-m') {
|
|
43
|
+
message = args[++i];
|
|
44
|
+
if (message === undefined) {
|
|
45
|
+
throw new Error('-m requires a commit message argument');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else if (a === '-b') {
|
|
49
|
+
branch = args[++i];
|
|
50
|
+
if (branch === undefined) {
|
|
51
|
+
throw new Error('-b requires a branch name argument');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else if (a === '--skip-git' || a === '--skipGit') {
|
|
55
|
+
skipGit = true;
|
|
56
|
+
}
|
|
57
|
+
else if (a === '--update-config') {
|
|
58
|
+
updateConfig = true;
|
|
59
|
+
}
|
|
60
|
+
else if (a.startsWith('-')) {
|
|
61
|
+
throw new Error(`Unknown option: ${a}`);
|
|
62
|
+
}
|
|
63
|
+
else if (!filePath) {
|
|
64
|
+
filePath = a;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
throw new Error(`Unexpected argument: ${a}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (!filePath) {
|
|
71
|
+
throw new Error('upload: missing <path.ts> argument');
|
|
72
|
+
}
|
|
73
|
+
return { filePath, message, branch, skipGit, updateConfig };
|
|
74
|
+
}
|
|
75
|
+
static buildCommitMessage(userMessage, fileId) {
|
|
76
|
+
const lines = userMessage.split(/\r?\n/);
|
|
77
|
+
lines[0] = `${lines[0]} [fileId: ${fileId}]`;
|
|
78
|
+
return lines.join('\n');
|
|
79
|
+
}
|
|
80
|
+
prompt(question) {
|
|
81
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
82
|
+
return new Promise((resolve) => {
|
|
83
|
+
rl.question(question, (answer) => {
|
|
84
|
+
rl.close();
|
|
85
|
+
resolve(answer.trim());
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
promptHidden(question) {
|
|
90
|
+
return new Promise((resolve) => {
|
|
91
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout, terminal: true });
|
|
92
|
+
const rlAny = rl;
|
|
93
|
+
rlAny._writeToOutput = (str) => {
|
|
94
|
+
if (str.includes(question)) {
|
|
95
|
+
rlAny.output.write(str);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
rl.question(question, (answer) => {
|
|
99
|
+
rl.close();
|
|
100
|
+
process.stdout.write('\n');
|
|
101
|
+
resolve(answer);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
runGit(args, cwd) {
|
|
106
|
+
return (0, child_process_1.execFileSync)('git', args, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] });
|
|
107
|
+
}
|
|
108
|
+
tryRunGit(args, cwd) {
|
|
109
|
+
try {
|
|
110
|
+
const stdout = this.runGit(args, cwd);
|
|
111
|
+
return { ok: true, stdout, stderr: '' };
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
return {
|
|
115
|
+
ok: false,
|
|
116
|
+
stdout: err && err.stdout ? err.stdout.toString() : '',
|
|
117
|
+
stderr: err && err.stderr ? err.stderr.toString() : (err && err.message) || '',
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async commitToGit(absPaths, fileId, options) {
|
|
122
|
+
const repoDir = path.dirname(absPaths[0]);
|
|
123
|
+
const relPaths = absPaths.map((p) => path.basename(p));
|
|
124
|
+
const versionCheck = this.tryRunGit(['--version'], repoDir);
|
|
125
|
+
if (!versionCheck.ok) {
|
|
126
|
+
console.log('git command not available; skipping git commit.');
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const insideRepo = this.tryRunGit(['rev-parse', '--is-inside-work-tree'], repoDir);
|
|
130
|
+
if (!insideRepo.ok || insideRepo.stdout.trim() !== 'true') {
|
|
131
|
+
console.log(`Not inside a git working tree (${repoDir}); skipping git commit.`);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
for (const relPath of relPaths) {
|
|
135
|
+
const tracked = this.tryRunGit(['ls-files', '--error-unmatch', relPath], repoDir);
|
|
136
|
+
if (!tracked.ok) {
|
|
137
|
+
const answer = (await this.prompt(`File is not tracked by git: ${relPath}\nAdd it to git? (Y/n): `)).toLowerCase();
|
|
138
|
+
if (answer === 'n' || answer === 'no') {
|
|
139
|
+
console.log('Nothing was done in git.');
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (options.branch) {
|
|
145
|
+
const branchResult = this.tryRunGit(['checkout', '-b', options.branch], repoDir);
|
|
146
|
+
if (!branchResult.ok) {
|
|
147
|
+
throw new Error(`Failed to create branch "${options.branch}": ${branchResult.stderr.trim()}`);
|
|
148
|
+
}
|
|
149
|
+
console.log(`Created and switched to branch "${options.branch}"`);
|
|
150
|
+
}
|
|
151
|
+
let message = options.message;
|
|
152
|
+
if (!message) {
|
|
153
|
+
message = await this.prompt('Commit message: ');
|
|
154
|
+
if (!message) {
|
|
155
|
+
throw new Error('A commit message is required');
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const finalMessage = UploadCommand.buildCommitMessage(message, fileId);
|
|
159
|
+
const addResult = this.tryRunGit(['add', '--', ...relPaths], repoDir);
|
|
160
|
+
if (!addResult.ok) {
|
|
161
|
+
throw new Error(`git add failed: ${addResult.stderr.trim()}`);
|
|
162
|
+
}
|
|
163
|
+
const commitResult = this.tryRunGit(['commit', '-m', finalMessage, '--', ...relPaths], repoDir);
|
|
164
|
+
if (!commitResult.ok) {
|
|
165
|
+
throw new Error(`git commit failed: ${commitResult.stderr.trim() || commitResult.stdout.trim()}`);
|
|
166
|
+
}
|
|
167
|
+
console.log(commitResult.stdout.trim());
|
|
168
|
+
}
|
|
169
|
+
async run(args) {
|
|
170
|
+
const options = UploadCommand.parseArgs(args);
|
|
171
|
+
const tsAbsPath = path.resolve(process.cwd(), options.filePath);
|
|
172
|
+
if (!fs.existsSync(tsAbsPath)) {
|
|
173
|
+
throw new Error(`File not found: ${tsAbsPath}`);
|
|
174
|
+
}
|
|
175
|
+
if (!tsAbsPath.endsWith('.ts')) {
|
|
176
|
+
throw new Error(`Expected a .ts file, got: ${tsAbsPath}`);
|
|
177
|
+
}
|
|
178
|
+
await new compile_1.CompileCommand().run(tsAbsPath);
|
|
179
|
+
const absPath = tsAbsPath.replace(/\.ts$/, '.js');
|
|
180
|
+
if (!fs.existsSync(absPath)) {
|
|
181
|
+
throw new Error(`Compiled file not found: ${absPath}`);
|
|
182
|
+
}
|
|
183
|
+
let email = process.env.CONTRAIL_CLI_EMAIL;
|
|
184
|
+
let password = process.env.CONTRAIL_CLI_PASSWORD;
|
|
185
|
+
if (!email) {
|
|
186
|
+
email = await this.prompt('Email: ');
|
|
187
|
+
}
|
|
188
|
+
if (!password) {
|
|
189
|
+
password = await this.promptHidden('Password: ');
|
|
190
|
+
}
|
|
191
|
+
if (!email || !password) {
|
|
192
|
+
throw new Error('Email and password are required');
|
|
193
|
+
}
|
|
194
|
+
delete require.cache[absPath];
|
|
195
|
+
const loaded = require(absPath);
|
|
196
|
+
const mapping = loaded && loaded.mapping;
|
|
197
|
+
if (!mapping || !mapping.orgInfo) {
|
|
198
|
+
throw new Error(`Mapping file is missing "mapping.orgInfo" export: ${absPath}`);
|
|
199
|
+
}
|
|
200
|
+
const { orgName, appIdentifier } = mapping.orgInfo;
|
|
201
|
+
if (!orgName) {
|
|
202
|
+
throw new Error(`Mapping file is missing "mapping.orgInfo.orgName": ${absPath}`);
|
|
203
|
+
}
|
|
204
|
+
if (!appIdentifier) {
|
|
205
|
+
throw new Error(`Mapping file is missing "mapping.orgInfo.appIdentifier": ${absPath}`);
|
|
206
|
+
}
|
|
207
|
+
await (0, sdk_1.login)({ orgSlug: orgName, email, password });
|
|
208
|
+
console.log(`Logged in to org "${orgName}" as ${email}`);
|
|
209
|
+
const apps = await new sdk_1.Entities().get({
|
|
210
|
+
entityName: 'app',
|
|
211
|
+
criteria: { identifier: appIdentifier },
|
|
212
|
+
});
|
|
213
|
+
if (!apps || apps.length !== 1) {
|
|
214
|
+
throw new Error(`Expected exactly one app with identifier "${appIdentifier}" in org "${orgName}", found ${apps ? apps.length : 0}`);
|
|
215
|
+
}
|
|
216
|
+
const app = apps[0];
|
|
217
|
+
const buffer = fs.readFileSync(absPath);
|
|
218
|
+
const fileName = path.basename(absPath);
|
|
219
|
+
const fileOwner = `app:${app.id}`;
|
|
220
|
+
const uploadedFile = await new sdk_1.Files().createAndUploadFileFromBuffer(buffer, 'application/javascript', fileName, fileOwner);
|
|
221
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
222
|
+
const responsePath = `${absPath}.uploaded-${timestamp}.json`;
|
|
223
|
+
fs.writeFileSync(responsePath, JSON.stringify(uploadedFile, null, 2), 'utf8');
|
|
224
|
+
console.log(`Wrote response to ${responsePath}`);
|
|
225
|
+
console.log(`FILE ID: ${uploadedFile.id}`);
|
|
226
|
+
if (!options.skipGit) {
|
|
227
|
+
await this.commitToGit([tsAbsPath, absPath], uploadedFile.id, options);
|
|
228
|
+
}
|
|
229
|
+
if (options.updateConfig) {
|
|
230
|
+
await this.setTransformMapFileOnAppOrg(app.id, appIdentifier, orgName, uploadedFile.id);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
async setTransformMapFileOnAppOrg(appId, appIdentifier, orgName, fileId) {
|
|
234
|
+
const appOrgs = await new sdk_1.Entities().get({
|
|
235
|
+
entityName: 'app-org',
|
|
236
|
+
criteria: { appId },
|
|
237
|
+
});
|
|
238
|
+
if (!appOrgs || appOrgs.length === 0) {
|
|
239
|
+
throw new Error(`Failed to set the file onto the app config for "${appIdentifier}" because it is not installed in org "${orgName}". Install it via the admin console before using --update-config. You can paste the uploaded file's ID into the app config without needing to re-run this command.`);
|
|
240
|
+
}
|
|
241
|
+
if (appOrgs.length > 1) {
|
|
242
|
+
throw new Error(`Failed to set the file onto the app config for "${appIdentifier}" in org "${orgName}" because ${appOrgs.length} installations were identified. Expected one. Please contact customer support for assistance.`);
|
|
243
|
+
}
|
|
244
|
+
const appOrg = appOrgs[0];
|
|
245
|
+
const nextAppConfig = { ...(appOrg.appConfig || {}), transformMapFile: fileId };
|
|
246
|
+
await new sdk_1.Entities().update({
|
|
247
|
+
entityName: 'app-org',
|
|
248
|
+
id: appOrg.id,
|
|
249
|
+
object: { appConfig: nextAppConfig },
|
|
250
|
+
});
|
|
251
|
+
console.log(`Successfully set "appConfig.transformMapFile" for installed "${appIdentifier}" to new FILE ID: "${fileId}" on org "${orgName}"`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
exports.UploadCommand = UploadCommand;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
jest.mock('@contrail/sdk', () => ({
|
|
4
|
+
Entities: jest.fn(),
|
|
5
|
+
Files: jest.fn(),
|
|
6
|
+
login: jest.fn(),
|
|
7
|
+
}));
|
|
8
|
+
const upload_1 = require("./upload");
|
|
9
|
+
describe('UploadCommand.parseArgs', () => {
|
|
10
|
+
it('parses a bare file path', () => {
|
|
11
|
+
const opts = upload_1.UploadCommand.parseArgs(['mapping.ts']);
|
|
12
|
+
expect(opts).toEqual({
|
|
13
|
+
filePath: 'mapping.ts',
|
|
14
|
+
message: undefined,
|
|
15
|
+
branch: undefined,
|
|
16
|
+
skipGit: false,
|
|
17
|
+
updateConfig: false,
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
it('parses -m commit message option', () => {
|
|
21
|
+
const opts = upload_1.UploadCommand.parseArgs(['mapping.ts', '-m', 'my message']);
|
|
22
|
+
expect(opts.message).toEqual('my message');
|
|
23
|
+
expect(opts.skipGit).toBe(false);
|
|
24
|
+
});
|
|
25
|
+
it('parses -b branch option', () => {
|
|
26
|
+
const opts = upload_1.UploadCommand.parseArgs(['mapping.ts', '-b', 'feature/x']);
|
|
27
|
+
expect(opts.branch).toEqual('feature/x');
|
|
28
|
+
});
|
|
29
|
+
it('parses --skip-git flag', () => {
|
|
30
|
+
const opts = upload_1.UploadCommand.parseArgs(['mapping.ts', '--skip-git']);
|
|
31
|
+
expect(opts.skipGit).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
it('accepts the legacy --skipGit alias', () => {
|
|
34
|
+
const opts = upload_1.UploadCommand.parseArgs(['mapping.ts', '--skipGit']);
|
|
35
|
+
expect(opts.skipGit).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
it('parses options before the file path', () => {
|
|
38
|
+
const opts = upload_1.UploadCommand.parseArgs(['-m', 'msg', '-b', 'br', 'mapping.ts']);
|
|
39
|
+
expect(opts).toEqual({
|
|
40
|
+
filePath: 'mapping.ts',
|
|
41
|
+
message: 'msg',
|
|
42
|
+
branch: 'br',
|
|
43
|
+
skipGit: false,
|
|
44
|
+
updateConfig: false,
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
it('parses --update-config flag', () => {
|
|
48
|
+
const opts = upload_1.UploadCommand.parseArgs(['mapping.ts', '--update-config']);
|
|
49
|
+
expect(opts.updateConfig).toBe(true);
|
|
50
|
+
});
|
|
51
|
+
it('parses all options together', () => {
|
|
52
|
+
const opts = upload_1.UploadCommand.parseArgs(['mapping.ts', '-m', 'msg', '-b', 'br', '--skip-git', '--update-config']);
|
|
53
|
+
expect(opts).toEqual({
|
|
54
|
+
filePath: 'mapping.ts',
|
|
55
|
+
message: 'msg',
|
|
56
|
+
branch: 'br',
|
|
57
|
+
skipGit: true,
|
|
58
|
+
updateConfig: true,
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
it('throws when -m is missing its value', () => {
|
|
62
|
+
expect(() => upload_1.UploadCommand.parseArgs(['mapping.ts', '-m'])).toThrow(/-m requires a commit message/);
|
|
63
|
+
});
|
|
64
|
+
it('throws when -b is missing its value', () => {
|
|
65
|
+
expect(() => upload_1.UploadCommand.parseArgs(['mapping.ts', '-b'])).toThrow(/-b requires a branch name/);
|
|
66
|
+
});
|
|
67
|
+
it('throws on unknown option', () => {
|
|
68
|
+
expect(() => upload_1.UploadCommand.parseArgs(['mapping.ts', '--bogus'])).toThrow(/Unknown option: --bogus/);
|
|
69
|
+
});
|
|
70
|
+
it('throws when an extra positional argument is supplied', () => {
|
|
71
|
+
expect(() => upload_1.UploadCommand.parseArgs(['mapping.ts', 'extra.ts'])).toThrow(/Unexpected argument: extra\.ts/);
|
|
72
|
+
});
|
|
73
|
+
it('throws when no file path is provided', () => {
|
|
74
|
+
expect(() => upload_1.UploadCommand.parseArgs([])).toThrow(/missing <path\.ts>/);
|
|
75
|
+
});
|
|
76
|
+
it('throws when only options are provided', () => {
|
|
77
|
+
expect(() => upload_1.UploadCommand.parseArgs(['--skip-git'])).toThrow(/missing <path\.ts>/);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
describe('UploadCommand.buildCommitMessage', () => {
|
|
81
|
+
it('appends fileId to the first line of a single-line message', () => {
|
|
82
|
+
expect(upload_1.UploadCommand.buildCommitMessage('initial commit', 'abc123')).toEqual('initial commit [fileId: abc123]');
|
|
83
|
+
});
|
|
84
|
+
it('only appends fileId to the first line of a multi-line message', () => {
|
|
85
|
+
const result = upload_1.UploadCommand.buildCommitMessage('header line\nbody line 1\nbody line 2', 'xyz');
|
|
86
|
+
expect(result).toEqual('header line [fileId: xyz]\nbody line 1\nbody line 2');
|
|
87
|
+
});
|
|
88
|
+
it('handles CRLF line endings', () => {
|
|
89
|
+
const result = upload_1.UploadCommand.buildCommitMessage('header\r\nbody', 'fid');
|
|
90
|
+
expect(result).toEqual('header [fileId: fid]\nbody');
|
|
91
|
+
});
|
|
92
|
+
it('handles an empty message', () => {
|
|
93
|
+
expect(upload_1.UploadCommand.buildCommitMessage('', 'fid')).toEqual(' [fileId: fid]');
|
|
94
|
+
});
|
|
95
|
+
});
|
package/lib/cli/index.js
CHANGED
|
@@ -2,38 +2,57 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.main = exports.Cli = void 0;
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
5
|
+
const create_1 = require("./commands/create");
|
|
6
|
+
const compile_1 = require("./commands/compile");
|
|
7
|
+
const upload_1 = require("./commands/upload");
|
|
8
|
+
const USAGE = `Usage: flexplm-mapping <command> [args]
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
Commands:
|
|
11
|
+
create Scaffold a new mapping .ts file in the current directory
|
|
12
|
+
compile <path.ts> Transpile a mapping .ts file to .js alongside it
|
|
13
|
+
upload <path.ts> [opts] Compile a mapping .ts file and upload the resulting .js to VibeIQ
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
Upload options:
|
|
16
|
+
-m <message> Git commit message (prompted if omitted)
|
|
17
|
+
-b <branch> Create a new git branch before committing
|
|
18
|
+
--skip-git Skip the post-upload git commit (default: commit)
|
|
19
|
+
--update-config Patch the app-org appConfig.transformMapFile with the uploaded file ID without needing to paste into the admin console
|
|
20
|
+
|
|
21
|
+
Environment (upload):
|
|
22
|
+
CONTRAIL_CLI_EMAIL VibeIQ user email
|
|
23
|
+
CONTRAIL_CLI_PASSWORD VibeIQ user password
|
|
16
24
|
`;
|
|
17
25
|
class Cli {
|
|
18
26
|
async main() {
|
|
19
|
-
const [, ,
|
|
20
|
-
switch (
|
|
21
|
-
case '
|
|
22
|
-
await
|
|
27
|
+
const [, , command, ...rest] = process.argv;
|
|
28
|
+
switch (command) {
|
|
29
|
+
case 'create':
|
|
30
|
+
await new create_1.CreateCommand().run();
|
|
31
|
+
return;
|
|
32
|
+
case 'compile':
|
|
33
|
+
if (!rest[0]) {
|
|
34
|
+
console.error('compile: missing <path.ts> argument');
|
|
35
|
+
console.error(USAGE);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
await new compile_1.CompileCommand().run(rest[0]);
|
|
23
39
|
return;
|
|
24
|
-
case '
|
|
25
|
-
|
|
40
|
+
case 'upload':
|
|
41
|
+
if (!rest[0]) {
|
|
42
|
+
console.error('upload: missing <path.ts> argument');
|
|
43
|
+
console.error(USAGE);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
await new upload_1.UploadCommand().run(rest);
|
|
26
47
|
return;
|
|
27
48
|
case undefined:
|
|
28
49
|
case '-h':
|
|
29
50
|
case '--help':
|
|
30
51
|
case 'help':
|
|
31
52
|
console.log(USAGE);
|
|
32
|
-
console.log(mapping_file_1.MAPPING_FILE_USAGE);
|
|
33
|
-
console.log(config_file_1.CONFIG_FILE_USAGE);
|
|
34
53
|
return;
|
|
35
54
|
default:
|
|
36
|
-
console.error(`Unknown
|
|
55
|
+
console.error(`Unknown command: ${command}`);
|
|
37
56
|
console.error(USAGE);
|
|
38
57
|
process.exit(1);
|
|
39
58
|
}
|