contensis-cli 1.1.2-beta.1 → 1.1.2-beta.10
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/commands/copy.js +70 -0
- package/dist/commands/copy.js.map +7 -0
- package/dist/commands/create.js.map +2 -2
- package/dist/commands/dev.js +11 -4
- package/dist/commands/dev.js.map +2 -2
- package/dist/commands/get.js +1 -0
- package/dist/commands/get.js.map +2 -2
- package/dist/commands/globalOptions.js +24 -3
- package/dist/commands/globalOptions.js.map +2 -2
- package/dist/commands/import.js +1 -6
- package/dist/commands/import.js.map +2 -2
- package/dist/commands/index.js +7 -3
- package/dist/commands/index.js.map +2 -2
- package/dist/factories/RequestHandlerFactory.js +24 -13
- package/dist/factories/RequestHandlerFactory.js.map +2 -2
- package/dist/localisation/en-GB.js +3 -1
- package/dist/localisation/en-GB.js.map +2 -2
- package/dist/mappers/DevRequests-to-RequestHanderCliArgs.js +128 -88
- package/dist/mappers/DevRequests-to-RequestHanderCliArgs.js.map +3 -3
- package/dist/providers/GitHubCliModuleProvider.js +14 -4
- package/dist/providers/GitHubCliModuleProvider.js.map +2 -2
- package/dist/providers/file-provider.js +3 -0
- package/dist/providers/file-provider.js.map +2 -2
- package/dist/services/ContensisCliService.js +61 -0
- package/dist/services/ContensisCliService.js.map +2 -2
- package/dist/services/ContensisDevService.js +30 -5
- package/dist/services/ContensisDevService.js.map +3 -3
- package/dist/shell.js +1 -0
- package/dist/shell.js.map +2 -2
- package/dist/util/api-ids.js +110 -0
- package/dist/util/api-ids.js.map +7 -0
- package/dist/util/console.printer.js.map +2 -2
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +2 -3
- package/src/commands/copy.ts +79 -0
- package/src/commands/create.ts +0 -1
- package/src/commands/dev.ts +14 -6
- package/src/commands/get.ts +12 -11
- package/src/commands/globalOptions.ts +25 -2
- package/src/commands/import.ts +4 -8
- package/src/commands/index.ts +7 -3
- package/src/factories/RequestHandlerFactory.ts +38 -17
- package/src/localisation/en-GB.ts +3 -2
- package/src/mappers/DevRequests-to-RequestHanderCliArgs.ts +147 -92
- package/src/providers/GitHubCliModuleProvider.ts +19 -6
- package/src/providers/file-provider.ts +4 -0
- package/src/services/ContensisCliService.ts +82 -0
- package/src/services/ContensisDevService.ts +37 -6
- package/src/shell.ts +2 -1
- package/src/util/api-ids.ts +111 -0
- package/src/util/console.printer.ts +2 -1
- package/src/version.ts +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ContensisMigrationService } from 'migratortron';
|
|
2
|
+
import PQueue from 'p-queue';
|
|
2
3
|
import ContensisCli from '~/services/ContensisCliService';
|
|
3
4
|
|
|
4
5
|
type EndpointJson = {
|
|
@@ -32,114 +33,168 @@ type RendererRuleJson = {
|
|
|
32
33
|
interface ISiteConfigYaml {
|
|
33
34
|
alias: string;
|
|
34
35
|
projectId: string;
|
|
35
|
-
|
|
36
|
+
iisHostname: string;
|
|
37
|
+
podClusterId: string;
|
|
38
|
+
accessToken: string; // needed?
|
|
36
39
|
clientId: string;
|
|
37
40
|
sharedSecret: string;
|
|
38
41
|
blocks: BlockJson[];
|
|
39
42
|
renderers: RendererJson[];
|
|
40
43
|
}
|
|
41
44
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
class RequestHandlerArgs {
|
|
46
|
+
private cli;
|
|
47
|
+
args?: string[];
|
|
48
|
+
siteConfig?: ISiteConfigYaml;
|
|
49
|
+
|
|
50
|
+
constructor(cli: ContensisCli) {
|
|
51
|
+
this.cli = cli;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
Create = async () => {
|
|
55
|
+
this.siteConfig = await this.buildSiteConfig();
|
|
56
|
+
await this.cli.Login(this.cli.env.lastUserId, { silent: true }); // to hydrate the auth service
|
|
57
|
+
this.args = this.getArgs();
|
|
52
58
|
};
|
|
53
59
|
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
60
|
+
buildSiteConfig = async () => {
|
|
61
|
+
const { currentEnv, currentProject, env, log, messages, urls } = this.cli;
|
|
62
|
+
const contensis = await this.cli.ConnectContensis();
|
|
57
63
|
|
|
58
|
-
|
|
64
|
+
const siteConfig: ISiteConfigYaml = {
|
|
65
|
+
alias: currentEnv,
|
|
66
|
+
projectId: currentProject,
|
|
67
|
+
iisHostname: urls?.iisPreviewWeb.split('//')[1] || '',
|
|
68
|
+
podClusterId: 'hq',
|
|
69
|
+
accessToken: '',
|
|
70
|
+
clientId: '',
|
|
71
|
+
sharedSecret: '',
|
|
72
|
+
blocks: [],
|
|
73
|
+
renderers: [],
|
|
74
|
+
};
|
|
59
75
|
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
76
|
+
const getBlocks = async (contensis: ContensisMigrationService) => {
|
|
77
|
+
const [err, blocksRaw] = await contensis.blocks.GetBlocks();
|
|
78
|
+
if (err)
|
|
79
|
+
log.error(messages.blocks.noList(currentEnv, env.currentProject));
|
|
80
|
+
|
|
81
|
+
// const blocksRaw = await cli.PrintBlocks();
|
|
82
|
+
|
|
83
|
+
const blocks: BlockJson[] = [];
|
|
84
|
+
const queue = new PQueue({ concurrency: 4 });
|
|
85
|
+
for (const block of blocksRaw || []) {
|
|
86
|
+
queue.add(async () => {
|
|
87
|
+
// Retrieve block version
|
|
88
|
+
const [err, versions] = await contensis.blocks.GetBlockVersions(
|
|
71
89
|
block.id,
|
|
72
90
|
'default',
|
|
73
|
-
'latest'
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
91
|
+
'latest'
|
|
92
|
+
);
|
|
93
|
+
if (err || versions?.length === 0)
|
|
94
|
+
log.warning(
|
|
95
|
+
messages.blocks.noGet(
|
|
96
|
+
block.id,
|
|
97
|
+
'default',
|
|
98
|
+
'latest',
|
|
99
|
+
currentEnv,
|
|
100
|
+
env.currentProject
|
|
101
|
+
)
|
|
102
|
+
);
|
|
103
|
+
if (versions?.[0]) {
|
|
104
|
+
const v = versions[0];
|
|
105
|
+
blocks.push({
|
|
106
|
+
id: v.id,
|
|
107
|
+
baseUri: v.previewUrl,
|
|
108
|
+
staticPaths: v.staticPaths,
|
|
109
|
+
endpoints: v.endpoints,
|
|
110
|
+
versionNo: v.version.versionNo,
|
|
111
|
+
branch: v.source.branch,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
87
114
|
});
|
|
88
115
|
}
|
|
116
|
+
|
|
117
|
+
await queue.onIdle();
|
|
118
|
+
return blocks;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
if (contensis) {
|
|
122
|
+
const [blocks, renderers] = await Promise.all([
|
|
123
|
+
getBlocks(contensis),
|
|
124
|
+
contensis.renderers.GetRenderers(),
|
|
125
|
+
]);
|
|
126
|
+
|
|
127
|
+
siteConfig.blocks = blocks;
|
|
128
|
+
siteConfig.renderers = renderers?.[1]
|
|
129
|
+
?.filter(r => blocks.find(b => b.id === r.id))
|
|
130
|
+
.map(r => ({
|
|
131
|
+
id: r.id,
|
|
132
|
+
name: r.name,
|
|
133
|
+
assignedContentTypes: r.assignedContentTypes,
|
|
134
|
+
rules: r.rules,
|
|
135
|
+
}));
|
|
89
136
|
}
|
|
90
|
-
return
|
|
137
|
+
return siteConfig;
|
|
91
138
|
};
|
|
92
139
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
siteConfig.blocks = blocks;
|
|
101
|
-
siteConfig.renderers = renderers?.[1]?.map(r => ({
|
|
102
|
-
id: r.id,
|
|
103
|
-
name: r.name,
|
|
104
|
-
assignedContentTypes: r.assignedContentTypes,
|
|
105
|
-
rules: r.rules,
|
|
106
|
-
}));
|
|
107
|
-
}
|
|
108
|
-
return siteConfig;
|
|
109
|
-
};
|
|
140
|
+
getArgs = (overrideArgs: string[] = []) => {
|
|
141
|
+
const args = overrideArgs
|
|
142
|
+
? typeof overrideArgs?.[0] === 'string' &&
|
|
143
|
+
overrideArgs[0].includes(' ', 2)
|
|
144
|
+
? overrideArgs[0].split(' ')
|
|
145
|
+
: overrideArgs
|
|
146
|
+
: []; // args could be [ '-c .\\site_config.yaml' ] or [ '-c', '.\\site_config.yaml' ]
|
|
110
147
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
args.push('--blocks-json', JSON.stringify(siteConfig.blocks));
|
|
128
|
-
if (!args.find(a => a === '--renderers-json'))
|
|
129
|
-
args.push('--renderers-json', JSON.stringify(siteConfig.renderers));
|
|
130
|
-
|
|
131
|
-
await cli.Login(cli.env.lastUserId, { silent: true }); // to hydrate the auth service
|
|
132
|
-
const client = cli.auth?.clientDetails;
|
|
133
|
-
if (client) {
|
|
134
|
-
if (!args.find(a => a === '--client-id') && 'clientId' in client)
|
|
135
|
-
args.push('--client-id', client.clientId);
|
|
136
|
-
if (!args.find(a => a === '--client-secret') && 'clientSecret' in client)
|
|
137
|
-
args.push('--client-secret', client.clientSecret);
|
|
138
|
-
if (!args.find(a => a === '--username') && 'username' in client)
|
|
139
|
-
args.push('--username', client.username);
|
|
140
|
-
if (!args.find(a => a === '--password') && 'password' in client)
|
|
141
|
-
args.push('--password', client.password);
|
|
142
|
-
}
|
|
148
|
+
const { cli, siteConfig } = this;
|
|
149
|
+
if (siteConfig) {
|
|
150
|
+
// Add required args
|
|
151
|
+
if (!args.find(a => a === '--alias'))
|
|
152
|
+
args.push('--alias', cli.currentEnv);
|
|
153
|
+
if (!args.find(a => a === '--project-api-id'))
|
|
154
|
+
args.push('--project-api-id', cli.currentProject);
|
|
155
|
+
if (!args.find(a => a === '--iis-hostname'))
|
|
156
|
+
args.push('--iis-hostname', siteConfig.iisHostname);
|
|
157
|
+
if (!args.find(a => a === '--pod-cluster-id'))
|
|
158
|
+
args.push('--pod-cluster-id', siteConfig.podClusterId);
|
|
159
|
+
if (!args.find(a => a === '--blocks-json'))
|
|
160
|
+
args.push('--blocks-json', JSON.stringify(siteConfig.blocks));
|
|
161
|
+
if (!args.find(a => a === '--renderers-json'))
|
|
162
|
+
args.push('--renderers-json', JSON.stringify(siteConfig.renderers));
|
|
163
|
+
}
|
|
143
164
|
|
|
144
|
-
|
|
145
|
-
|
|
165
|
+
const client = cli.auth?.clientDetails;
|
|
166
|
+
if (client) {
|
|
167
|
+
if (!args.find(a => a === '--client-id') && 'clientId' in client)
|
|
168
|
+
args.push('--client-id', client.clientId);
|
|
169
|
+
if (!args.find(a => a === '--client-secret') && 'clientSecret' in client)
|
|
170
|
+
args.push('--client-secret', client.clientSecret);
|
|
171
|
+
if (!args.find(a => a === '--username') && 'username' in client)
|
|
172
|
+
args.push('--username', client.username);
|
|
173
|
+
if (!args.find(a => a === '--password') && 'password' in client)
|
|
174
|
+
args.push('--password', client.password);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return args;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
overrideBlock = (blockId: string, overrideUri: string) => {
|
|
181
|
+
if (blockId && blockId !== 'none') {
|
|
182
|
+
const blockIndex = this.siteConfig?.blocks.findIndex(
|
|
183
|
+
b => b.id.toLowerCase() === blockId.toLowerCase()
|
|
184
|
+
);
|
|
185
|
+
if (
|
|
186
|
+
typeof blockIndex === 'number' &&
|
|
187
|
+
!isNaN(blockIndex) &&
|
|
188
|
+
this.siteConfig?.blocks[blockIndex]
|
|
189
|
+
) {
|
|
190
|
+
this.siteConfig.blocks[blockIndex].baseUri = overrideUri;
|
|
191
|
+
// this.siteConfig.blocks[blockIndex].staticPaths.push(
|
|
192
|
+
// ...['/static/*', '/image-library/*']
|
|
193
|
+
// );
|
|
194
|
+
this.siteConfig.blocks[blockIndex].staticPaths.push('/*.js');
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export default RequestHandlerArgs;
|
|
@@ -3,6 +3,7 @@ import Zip from 'adm-zip';
|
|
|
3
3
|
import type { Endpoints } from '@octokit/types';
|
|
4
4
|
import HttpProvider from '~/providers/HttpProvider';
|
|
5
5
|
import {
|
|
6
|
+
addExecutePermission,
|
|
6
7
|
checkDir,
|
|
7
8
|
joinPath,
|
|
8
9
|
removeDirectory,
|
|
@@ -37,7 +38,7 @@ class GitHubCliModuleProvider {
|
|
|
37
38
|
this.repo = repo;
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
async FindLatestRelease() {
|
|
41
|
+
async FindLatestRelease(version?: string) {
|
|
41
42
|
const { http, latest_release_url, releases_url } = this;
|
|
42
43
|
// return latest tag version is:
|
|
43
44
|
|
|
@@ -55,14 +56,18 @@ class GitHubCliModuleProvider {
|
|
|
55
56
|
throw new Error(`Unable to get releases`, { cause: releasesErr });
|
|
56
57
|
} else if (!releases || releases.length === 0)
|
|
57
58
|
throw new Error(`No releases available`);
|
|
58
|
-
else if (
|
|
59
|
+
else if (version) {
|
|
60
|
+
const release = releases.find(
|
|
61
|
+
r => r.tag_name.toLowerCase() === version.toLowerCase()
|
|
62
|
+
);
|
|
63
|
+
if (release) return release;
|
|
64
|
+
else throw new Error(`No release for ${version} found`);
|
|
65
|
+
} else if (latestErr && !latest) {
|
|
59
66
|
if (latestResponse?.status === 404 && releases?.length) {
|
|
60
67
|
// No latest release, check releases for prerelease version, fallback to last release
|
|
61
68
|
const release = releases.find(r => r.prerelease) || releases[0];
|
|
62
69
|
|
|
63
|
-
if (release)
|
|
64
|
-
return release;
|
|
65
|
-
}
|
|
70
|
+
if (release) return release;
|
|
66
71
|
}
|
|
67
72
|
} else {
|
|
68
73
|
return latest;
|
|
@@ -72,10 +77,16 @@ class GitHubCliModuleProvider {
|
|
|
72
77
|
async DownloadRelease(
|
|
73
78
|
release: GitHubApiRelease,
|
|
74
79
|
{
|
|
80
|
+
cmd,
|
|
75
81
|
path,
|
|
76
82
|
platforms,
|
|
77
83
|
unzip = true,
|
|
78
|
-
}: {
|
|
84
|
+
}: {
|
|
85
|
+
cmd: string;
|
|
86
|
+
path: string;
|
|
87
|
+
unzip?: boolean;
|
|
88
|
+
platforms: [NodeJS.Platform, string][];
|
|
89
|
+
}
|
|
79
90
|
) {
|
|
80
91
|
// find os-specific asset
|
|
81
92
|
const platform = platforms.find(p => p[0] === os.platform()) || [
|
|
@@ -102,6 +113,8 @@ class GitHubCliModuleProvider {
|
|
|
102
113
|
// delete the downloaded zip file
|
|
103
114
|
removeFile(filePath);
|
|
104
115
|
}
|
|
116
|
+
|
|
117
|
+
if (os.platform() !== 'win32') addExecutePermission(joinPath(path, cmd));
|
|
105
118
|
} else
|
|
106
119
|
throw new Error(
|
|
107
120
|
`no asset found in release ${
|
|
@@ -93,6 +93,10 @@ export const cwdPath = (filePath: string) =>
|
|
|
93
93
|
|
|
94
94
|
export const joinPath = path.join;
|
|
95
95
|
|
|
96
|
+
export const addExecutePermission = (filePath: string) =>
|
|
97
|
+
// Fails in windows with `TypeError [ERR_INVALID_ARG_TYPE]: The "mode" argument must be of type number. Received undefined`
|
|
98
|
+
fs.chmodSync(filePath, fs.constants.S_IRWXU);
|
|
99
|
+
|
|
96
100
|
type DetectedFileType =
|
|
97
101
|
| { type: 'json'; contents: any }
|
|
98
102
|
| { type: 'xml' | 'csv'; contents: string };
|
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
tryStringify,
|
|
37
37
|
url,
|
|
38
38
|
} from '~/util';
|
|
39
|
+
import { sanitiseIds } from '~/util/api-ids';
|
|
39
40
|
import {
|
|
40
41
|
printBlockVersion,
|
|
41
42
|
printEntriesMigrateResult,
|
|
@@ -142,6 +143,14 @@ class ContensisCli {
|
|
|
142
143
|
this.session = new SessionCacheProvider();
|
|
143
144
|
|
|
144
145
|
this.contensisOpts = contensisOpts;
|
|
146
|
+
|
|
147
|
+
// Explicitly sanitise supplied fields to api-friendly ids
|
|
148
|
+
if (Array.isArray(this.contensisOpts.query?.fields)) {
|
|
149
|
+
this.contensisOpts.query.fields = sanitiseIds(
|
|
150
|
+
this.contensisOpts.query.fields
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
145
154
|
this.format = outputOpts?.format;
|
|
146
155
|
this.output =
|
|
147
156
|
outputOpts?.output && path.join(process.cwd(), outputOpts.output);
|
|
@@ -1788,6 +1797,79 @@ class ContensisCli {
|
|
|
1788
1797
|
}
|
|
1789
1798
|
};
|
|
1790
1799
|
|
|
1800
|
+
CopyEntryField = async ({
|
|
1801
|
+
commit,
|
|
1802
|
+
fromFile,
|
|
1803
|
+
logOutput,
|
|
1804
|
+
}: {
|
|
1805
|
+
commit: boolean;
|
|
1806
|
+
fromFile: string;
|
|
1807
|
+
logOutput: string;
|
|
1808
|
+
}) => {
|
|
1809
|
+
const { currentEnv, currentProject, log, messages } = this;
|
|
1810
|
+
|
|
1811
|
+
const contensis = await this.ConnectContensisImport({
|
|
1812
|
+
commit,
|
|
1813
|
+
fromFile,
|
|
1814
|
+
importDataType: 'entries',
|
|
1815
|
+
});
|
|
1816
|
+
|
|
1817
|
+
if (contensis) {
|
|
1818
|
+
log.line();
|
|
1819
|
+
if (contensis.isPreview) {
|
|
1820
|
+
console.log(log.successText(` -- IMPORT PREVIEW -- `));
|
|
1821
|
+
} else {
|
|
1822
|
+
console.log(log.warningText(` *** COMMITTING IMPORT *** `));
|
|
1823
|
+
}
|
|
1824
|
+
|
|
1825
|
+
const [err, result] = await to(
|
|
1826
|
+
contensis.content.copy.MigrateFieldContent()
|
|
1827
|
+
);
|
|
1828
|
+
|
|
1829
|
+
if (err) logError(err);
|
|
1830
|
+
if (result)
|
|
1831
|
+
await this.HandleFormattingAndOutput(result, () => {
|
|
1832
|
+
// print the migrateResult to console
|
|
1833
|
+
printEntriesMigrateResult(this, result, {
|
|
1834
|
+
showAll: logOutput === 'all',
|
|
1835
|
+
showDiff: logOutput === 'all' || logOutput === 'changes',
|
|
1836
|
+
showChanged: logOutput === 'changes',
|
|
1837
|
+
});
|
|
1838
|
+
});
|
|
1839
|
+
|
|
1840
|
+
if (
|
|
1841
|
+
result &&
|
|
1842
|
+
!err &&
|
|
1843
|
+
!result.errors?.length &&
|
|
1844
|
+
((!commit && result.entriesToMigrate[currentProject].totalCount) ||
|
|
1845
|
+
(commit &&
|
|
1846
|
+
(result.migrateResult?.created || result.migrateResult?.updated)))
|
|
1847
|
+
) {
|
|
1848
|
+
log.success(
|
|
1849
|
+
messages.entries.imported(
|
|
1850
|
+
currentEnv,
|
|
1851
|
+
commit,
|
|
1852
|
+
commit
|
|
1853
|
+
? (result.migrateResult?.created || 0) +
|
|
1854
|
+
(result.migrateResult?.updated || 0)
|
|
1855
|
+
: result.entriesToMigrate[currentProject].totalCount
|
|
1856
|
+
)
|
|
1857
|
+
);
|
|
1858
|
+
if (!commit) {
|
|
1859
|
+
log.raw(``);
|
|
1860
|
+
log.help(messages.entries.commitTip());
|
|
1861
|
+
}
|
|
1862
|
+
} else {
|
|
1863
|
+
log.error(messages.entries.failedImport(currentEnv), err);
|
|
1864
|
+
if (!result?.entriesToMigrate?.[currentProject]?.totalCount)
|
|
1865
|
+
log.help(messages.entries.notFound(currentEnv));
|
|
1866
|
+
}
|
|
1867
|
+
} else {
|
|
1868
|
+
log.warning(messages.models.noList(currentProject));
|
|
1869
|
+
log.help(messages.connect.tip());
|
|
1870
|
+
}
|
|
1871
|
+
};
|
|
1872
|
+
|
|
1791
1873
|
GetNodes = async (rootPath: string, depth = 0) => {
|
|
1792
1874
|
const { currentProject, log, messages } = this;
|
|
1793
1875
|
const contensis = await this.ConnectContensis();
|
|
@@ -11,7 +11,7 @@ import { createRequestHandler } from '~/factories/RequestHandlerFactory';
|
|
|
11
11
|
import { OutputOptionsConstructorArg } from '~/models/CliService';
|
|
12
12
|
import { EnvContentsToAdd } from '~/models/DevService';
|
|
13
13
|
import { mapCIWorkflowContent } from '~/mappers/DevInit-to-CIWorkflow';
|
|
14
|
-
import
|
|
14
|
+
import RequestHandlerArgs from '~/mappers/DevRequests-to-RequestHanderCliArgs';
|
|
15
15
|
import { deployKeyRole } from '~/mappers/DevInit-to-RolePermissions';
|
|
16
16
|
import { readFile, writeFile } from '~/providers/file-provider';
|
|
17
17
|
import { diffFileContent } from '~/util/diff';
|
|
@@ -412,8 +412,9 @@ class ContensisDev extends ContensisRole {
|
|
|
412
412
|
};
|
|
413
413
|
|
|
414
414
|
ExecRequestHandler = async (
|
|
415
|
-
|
|
416
|
-
overrideArgs: string[] = []
|
|
415
|
+
blockId: string[],
|
|
416
|
+
overrideArgs: string[] = [],
|
|
417
|
+
version?: string
|
|
417
418
|
) => {
|
|
418
419
|
const { debug, log, messages } = this;
|
|
419
420
|
|
|
@@ -422,15 +423,45 @@ class ContensisDev extends ContensisRole {
|
|
|
422
423
|
: log.info(messages.devrequests.launch());
|
|
423
424
|
|
|
424
425
|
// Ensure request handler is available to use
|
|
425
|
-
const requestHandler = await createRequestHandler();
|
|
426
|
+
const requestHandler = await createRequestHandler(version);
|
|
426
427
|
|
|
427
428
|
// Generate args for request handler using CLI methods
|
|
429
|
+
const args = new RequestHandlerArgs(this);
|
|
428
430
|
spinner?.start();
|
|
429
|
-
|
|
431
|
+
await args.Create();
|
|
430
432
|
spinner?.success();
|
|
431
433
|
|
|
434
|
+
// Prompt block id and dev uri to run locally (if not supplied)
|
|
435
|
+
const blockIdChoices = args.siteConfig?.blocks.map(block => block.id) || [];
|
|
436
|
+
blockIdChoices.push('none');
|
|
437
|
+
const defaultDeveloperUri = 'http://localhost:3000';
|
|
438
|
+
|
|
439
|
+
const { overrideBlockId, overrideUri } = blockId.length
|
|
440
|
+
? {
|
|
441
|
+
overrideBlockId: blockId[0],
|
|
442
|
+
overrideUri: blockId?.[1] || defaultDeveloperUri,
|
|
443
|
+
}
|
|
444
|
+
: await inquirer.prompt([
|
|
445
|
+
{
|
|
446
|
+
type: 'list',
|
|
447
|
+
prefix: '🧱',
|
|
448
|
+
message: messages.devrequests.overrideBlock(),
|
|
449
|
+
name: 'overrideBlockId',
|
|
450
|
+
choices: blockIdChoices,
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
type: 'input',
|
|
454
|
+
prefix: '🔗',
|
|
455
|
+
message: messages.devrequests.overrideUri(),
|
|
456
|
+
name: 'overrideUri',
|
|
457
|
+
default: defaultDeveloperUri,
|
|
458
|
+
},
|
|
459
|
+
]);
|
|
460
|
+
|
|
461
|
+
args.overrideBlock(overrideBlockId, overrideUri);
|
|
462
|
+
|
|
432
463
|
// Launch request handler
|
|
433
|
-
await requestHandler(args);
|
|
464
|
+
await requestHandler(args.getArgs(overrideArgs));
|
|
434
465
|
};
|
|
435
466
|
}
|
|
436
467
|
export const devCommand = (
|
package/src/shell.ts
CHANGED
|
@@ -135,6 +135,7 @@ class ContensisShell {
|
|
|
135
135
|
availableCommands.push('login', 'list projects', 'set project');
|
|
136
136
|
if (userId)
|
|
137
137
|
availableCommands.push(
|
|
138
|
+
'copy field',
|
|
138
139
|
'create key',
|
|
139
140
|
'create project',
|
|
140
141
|
'create role',
|
|
@@ -306,4 +307,4 @@ process.stdin.on('data', key => {
|
|
|
306
307
|
}
|
|
307
308
|
});
|
|
308
309
|
|
|
309
|
-
//
|
|
310
|
+
// process.env.http_proxy = 'http://127.0.0.1:8888';
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
export const sanitiseId = (id: string) =>
|
|
2
|
+
id
|
|
3
|
+
.split('.')
|
|
4
|
+
.map(part => toApiId(part, 'camelCase', true))
|
|
5
|
+
.join('.');
|
|
6
|
+
|
|
7
|
+
export const sanitiseIds = (arr: string[]) => arr.map(sanitiseId);
|
|
8
|
+
|
|
9
|
+
// borrowed from packages\contensis\components\app\src\utils.ts
|
|
10
|
+
|
|
11
|
+
export function isApiId(id: string, mode: 'camelCase' | 'snake-case'): boolean {
|
|
12
|
+
if (!id) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
const validChars = mode === 'camelCase' ? /[^a-zA-Z0-9]/g : /[^a-z0-9-]/g;
|
|
16
|
+
if (id !== id.replace(validChars, '')) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
if (!id.substr(0, 1).replace(/[^a-z]/g, '')) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function toApiId(
|
|
26
|
+
name: string,
|
|
27
|
+
mode: 'camelCase' | 'snake-case',
|
|
28
|
+
isId: boolean
|
|
29
|
+
) {
|
|
30
|
+
if (!name) {
|
|
31
|
+
return name;
|
|
32
|
+
}
|
|
33
|
+
const validChars =
|
|
34
|
+
mode === 'camelCase' ? /[^a-zA-Z0-9 ]/g : /[^a-zA-Z0-9 -]/g;
|
|
35
|
+
let id = name.replace(validChars, '');
|
|
36
|
+
id = id.replace(/-/g, ' ');
|
|
37
|
+
id = id.trim();
|
|
38
|
+
|
|
39
|
+
const noStart = '0123456789 '.split('');
|
|
40
|
+
id = id
|
|
41
|
+
.split('')
|
|
42
|
+
.reduce(
|
|
43
|
+
(prev, char) => (prev || !noStart.includes(char) ? prev + char : prev),
|
|
44
|
+
''
|
|
45
|
+
);
|
|
46
|
+
return mode === 'camelCase' ? toCamelCase(id, isId) : toSnakeCase(id);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function toSnakeCase(sentence: string): string {
|
|
50
|
+
sentence = (sentence || '').trim();
|
|
51
|
+
if (!sentence) {
|
|
52
|
+
return sentence;
|
|
53
|
+
}
|
|
54
|
+
sentence = sentence.toLowerCase();
|
|
55
|
+
return sentence
|
|
56
|
+
.split(' ')
|
|
57
|
+
.filter(w => !!w)
|
|
58
|
+
.join('-');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function toCamelCase(sentence: string, isId: boolean): string {
|
|
62
|
+
sentence = (sentence || '').trim();
|
|
63
|
+
if (!sentence) {
|
|
64
|
+
return sentence;
|
|
65
|
+
}
|
|
66
|
+
if (sentence.length < 2) {
|
|
67
|
+
return sentence.toLowerCase();
|
|
68
|
+
}
|
|
69
|
+
const words = sentence.split(' ');
|
|
70
|
+
if (isId && words.length === 1) {
|
|
71
|
+
return words[0].substr(0, 1).toLowerCase() + words[0].substr(1);
|
|
72
|
+
}
|
|
73
|
+
const result = words
|
|
74
|
+
.filter(w => !!w)
|
|
75
|
+
.map((w, index) =>
|
|
76
|
+
index === 0 ? firstWordToCamelCase(w) : wordToCamelCase(w)
|
|
77
|
+
)
|
|
78
|
+
.join('');
|
|
79
|
+
|
|
80
|
+
return result
|
|
81
|
+
.split('.')
|
|
82
|
+
.map((w, index) => (index === 0 ? w : wordToCamelCase(w)))
|
|
83
|
+
.join('.');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function firstWordToCamelCase(word: string) {
|
|
87
|
+
return isUpperCase(word)
|
|
88
|
+
? word.toLowerCase()
|
|
89
|
+
: lowerCaseInitialCapitalLettersExceptLast(word);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function wordToCamelCase(word: string) {
|
|
93
|
+
return word.substr(0, 1).toUpperCase() + word.substr(1);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function lowerCaseInitialCapitalLettersExceptLast(value: string): string {
|
|
97
|
+
return value.split('').reduce((prev, char, index) => {
|
|
98
|
+
if (index === 0) {
|
|
99
|
+
char = char.toLowerCase();
|
|
100
|
+
} else if (isUpperCase(char)) {
|
|
101
|
+
if (index + 1 < value.length && isUpperCase(value.charAt(index + 1))) {
|
|
102
|
+
char = char.toLowerCase();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return prev + char;
|
|
106
|
+
}, '');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function isUpperCase(value: string): boolean {
|
|
110
|
+
return value === value.toUpperCase();
|
|
111
|
+
}
|
|
@@ -4,6 +4,7 @@ import { deconstructApiError } from './error';
|
|
|
4
4
|
import { Logger, addNewLines } from './logger';
|
|
5
5
|
import {
|
|
6
6
|
BlockVersion,
|
|
7
|
+
CopyFieldResult,
|
|
7
8
|
EntriesResult,
|
|
8
9
|
MigrateModelsResult,
|
|
9
10
|
MigrateNodesTree,
|
|
@@ -116,7 +117,7 @@ export const printBlockVersion = (
|
|
|
116
117
|
|
|
117
118
|
export const printEntriesMigrateResult = (
|
|
118
119
|
{ log, messages, currentProject }: ContensisCli,
|
|
119
|
-
migrateResult: EntriesResult,
|
|
120
|
+
migrateResult: EntriesResult | CopyFieldResult,
|
|
120
121
|
{
|
|
121
122
|
action = 'import',
|
|
122
123
|
showDiff = false,
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const LIB_VERSION = "1.1.2-beta.
|
|
1
|
+
export const LIB_VERSION = "1.1.2-beta.10";
|