@saltcorn/cli 1.6.0-alpha.1 → 1.6.0-alpha.2
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 +67 -58
- package/npm-shrinkwrap.json +562 -602
- package/oclif.manifest.json +27 -1
- package/package.json +8 -8
- package/src/commands/build-app.js +46 -22
- package/src/commands/dev/plugin-test.js +61 -10
package/oclif.manifest.json
CHANGED
|
@@ -264,6 +264,12 @@
|
|
|
264
264
|
"allowNo": false,
|
|
265
265
|
"type": "boolean"
|
|
266
266
|
},
|
|
267
|
+
"syncOnAppResume": {
|
|
268
|
+
"description": "When offline mode is enabled, synchronize the synchedTables tables when the app is resumed.",
|
|
269
|
+
"name": "syncOnAppResume",
|
|
270
|
+
"allowNo": false,
|
|
271
|
+
"type": "boolean"
|
|
272
|
+
},
|
|
267
273
|
"pushSync": {
|
|
268
274
|
"description": "When offline mode is enabled, synchronize the synchedTables tables when a push notification is received.",
|
|
269
275
|
"name": "pushSync",
|
|
@@ -277,6 +283,12 @@
|
|
|
277
283
|
"multiple": false,
|
|
278
284
|
"type": "option"
|
|
279
285
|
},
|
|
286
|
+
"noProvisioningProfile": {
|
|
287
|
+
"description": "Do not use a provisioning profile, only for simulator builds (iOS only)",
|
|
288
|
+
"name": "noProvisioningProfile",
|
|
289
|
+
"allowNo": false,
|
|
290
|
+
"type": "boolean"
|
|
291
|
+
},
|
|
280
292
|
"provisioningProfile": {
|
|
281
293
|
"description": "This profile will be used to sign your app",
|
|
282
294
|
"name": "provisioningProfile",
|
|
@@ -298,6 +310,12 @@
|
|
|
298
310
|
"multiple": false,
|
|
299
311
|
"type": "option"
|
|
300
312
|
},
|
|
313
|
+
"allowClearTextTraffic": {
|
|
314
|
+
"description": "Enable this to allow unsecure HTTP connections. Useful for local testing.",
|
|
315
|
+
"name": "allowClearTextTraffic",
|
|
316
|
+
"allowNo": false,
|
|
317
|
+
"type": "boolean"
|
|
318
|
+
},
|
|
301
319
|
"androidKeystore": {
|
|
302
320
|
"description": "A self-signed certificate that includes the private key used to sign your app.",
|
|
303
321
|
"name": "androidKeystore",
|
|
@@ -2127,6 +2145,14 @@
|
|
|
2127
2145
|
"hasDynamicHelp": false,
|
|
2128
2146
|
"multiple": false,
|
|
2129
2147
|
"type": "option"
|
|
2148
|
+
},
|
|
2149
|
+
"overwriteDependency": {
|
|
2150
|
+
"char": "o",
|
|
2151
|
+
"description": "Dependency to overwrite with a local plugin (can be used multiple times). Please specify the path to the local plugin, the module name will be taken from there.",
|
|
2152
|
+
"name": "overwriteDependency",
|
|
2153
|
+
"hasDynamicHelp": false,
|
|
2154
|
+
"multiple": true,
|
|
2155
|
+
"type": "option"
|
|
2130
2156
|
}
|
|
2131
2157
|
},
|
|
2132
2158
|
"hasDynamicHelp": false,
|
|
@@ -2315,5 +2341,5 @@
|
|
|
2315
2341
|
]
|
|
2316
2342
|
}
|
|
2317
2343
|
},
|
|
2318
|
-
"version": "1.6.0-alpha.
|
|
2344
|
+
"version": "1.6.0-alpha.2"
|
|
2319
2345
|
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@saltcorn/cli",
|
|
3
3
|
"description": "Command-line interface for Saltcorn, open-source no-code platform",
|
|
4
4
|
"homepage": "https://saltcorn.com",
|
|
5
|
-
"version": "1.6.0-alpha.
|
|
5
|
+
"version": "1.6.0-alpha.2",
|
|
6
6
|
"author": "Tom Nielsen @glutamate",
|
|
7
7
|
"bin": {
|
|
8
8
|
"saltcorn": "./bin/saltcorn"
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@oclif/core": "4.4.0",
|
|
13
13
|
"@oclif/plugin-plugins": "^5.4.26",
|
|
14
|
-
"@saltcorn/admin-models": "1.6.0-alpha.
|
|
15
|
-
"@saltcorn/common-code": "1.6.0-alpha.
|
|
16
|
-
"@saltcorn/data": "1.6.0-alpha.
|
|
17
|
-
"@saltcorn/mobile-app": "1.6.0-alpha.
|
|
18
|
-
"@saltcorn/mobile-builder": "1.6.0-alpha.
|
|
19
|
-
"@saltcorn/plugins-loader": "1.6.0-alpha.
|
|
20
|
-
"@saltcorn/server": "1.6.0-alpha.
|
|
14
|
+
"@saltcorn/admin-models": "1.6.0-alpha.2",
|
|
15
|
+
"@saltcorn/common-code": "1.6.0-alpha.2",
|
|
16
|
+
"@saltcorn/data": "1.6.0-alpha.2",
|
|
17
|
+
"@saltcorn/mobile-app": "1.6.0-alpha.2",
|
|
18
|
+
"@saltcorn/mobile-builder": "1.6.0-alpha.2",
|
|
19
|
+
"@saltcorn/plugins-loader": "1.6.0-alpha.2",
|
|
20
|
+
"@saltcorn/server": "1.6.0-alpha.2",
|
|
21
21
|
"contractis": "^0.1.0",
|
|
22
22
|
"dateformat": "^4.6.3",
|
|
23
23
|
"inquirer": "^12.3.3",
|
|
@@ -2,9 +2,7 @@ const { Command, Flags } = require("@oclif/core");
|
|
|
2
2
|
const path = require("path");
|
|
3
3
|
const Plugin = require("@saltcorn/data/models/plugin");
|
|
4
4
|
const { MobileBuilder } = require("@saltcorn/mobile-builder/mobile-builder");
|
|
5
|
-
const {
|
|
6
|
-
decodeProvisioningProfile,
|
|
7
|
-
} = require("@saltcorn/mobile-builder/utils/common-build-utils");
|
|
5
|
+
const { decodeProvisioningProfile } = require("@saltcorn/data/utils");
|
|
8
6
|
const { init_multi_tenant, getState } = require("@saltcorn/data/db/state");
|
|
9
7
|
const { loadAllPlugins } = require("@saltcorn/server/load_plugins");
|
|
10
8
|
const User = require("@saltcorn/data/models/user");
|
|
@@ -44,7 +42,7 @@ class BuildAppCommand extends Command {
|
|
|
44
42
|
);
|
|
45
43
|
}
|
|
46
44
|
|
|
47
|
-
if (flags.platforms.includes("ios")) {
|
|
45
|
+
if (flags.platforms.includes("ios") && !flags.noProvisioningProfile) {
|
|
48
46
|
if (!flags.provisioningProfile)
|
|
49
47
|
throw new Error("Please specify a provisioning profile");
|
|
50
48
|
if (flags.allowShareTo && !flags.shareExtensionProvisioningProfile)
|
|
@@ -73,26 +71,30 @@ class BuildAppCommand extends Command {
|
|
|
73
71
|
async buildIosParams(flags) {
|
|
74
72
|
let result = undefined;
|
|
75
73
|
if (flags.platforms.includes("ios")) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
guuid: mainProfileVals.guuid,
|
|
84
|
-
},
|
|
85
|
-
};
|
|
86
|
-
if (flags.allowShareTo) {
|
|
87
|
-
const shareExtProfileVals = await decodeProvisioningProfile(
|
|
88
|
-
flags.buildDirectory,
|
|
89
|
-
flags.shareExtensionProvisioningProfile
|
|
74
|
+
if (flags.noProvisioningProfile)
|
|
75
|
+
result = {
|
|
76
|
+
noProvisioningProfile: true,
|
|
77
|
+
};
|
|
78
|
+
else {
|
|
79
|
+
const mainProfileVals = await decodeProvisioningProfile(
|
|
80
|
+
flags.provisioningProfile
|
|
90
81
|
);
|
|
91
|
-
result
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
82
|
+
result = {
|
|
83
|
+
appleTeamId: mainProfileVals.teamId,
|
|
84
|
+
mainProvisioningProfile: {
|
|
85
|
+
guuid: mainProfileVals.guuid,
|
|
86
|
+
},
|
|
95
87
|
};
|
|
88
|
+
if (flags.allowShareTo) {
|
|
89
|
+
const shareExtProfileVals = await decodeProvisioningProfile(
|
|
90
|
+
flags.shareExtensionProvisioningProfile
|
|
91
|
+
);
|
|
92
|
+
result.shareExtensionProvisioningProfile = {
|
|
93
|
+
guuid: shareExtProfileVals.guuid,
|
|
94
|
+
specifier: shareExtProfileVals.specifier,
|
|
95
|
+
identifier: shareExtProfileVals.identifier,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
96
98
|
}
|
|
97
99
|
}
|
|
98
100
|
return result;
|
|
@@ -138,6 +140,7 @@ class BuildAppCommand extends Command {
|
|
|
138
140
|
showContinueAsPublicUser: flags.showContinueAsPublicUser,
|
|
139
141
|
allowOfflineMode: flags.allowOfflineMode,
|
|
140
142
|
syncOnReconnect: flags.syncOnReconnect,
|
|
143
|
+
syncOnAppResume: flags.syncOnAppResume,
|
|
141
144
|
pushSync: flags.pushSync,
|
|
142
145
|
syncInterval: flags.syncInterval,
|
|
143
146
|
allowShareTo: flags.allowShareTo,
|
|
@@ -147,6 +150,7 @@ class BuildAppCommand extends Command {
|
|
|
147
150
|
iosParams: iosParams,
|
|
148
151
|
tenantAppName: flags.tenantAppName,
|
|
149
152
|
buildType: flags.buildType,
|
|
153
|
+
allowClearTextTraffic: flags.allowClearTextTraffic,
|
|
150
154
|
keyStorePath: flags.androidKeystore,
|
|
151
155
|
keyStoreAlias: flags.androidKeyStoreAlias,
|
|
152
156
|
keyStorePassword: flags.androidKeystorePassword,
|
|
@@ -324,6 +328,12 @@ BuildAppCommand.flags = {
|
|
|
324
328
|
"Run Synchronizations and return into online mode when the network connection is restored. " +
|
|
325
329
|
"When disabled, you still can do this manually.",
|
|
326
330
|
}),
|
|
331
|
+
syncOnAppResume: Flags.boolean({
|
|
332
|
+
name: "Sync on app resume",
|
|
333
|
+
string: "syncOnAppResume",
|
|
334
|
+
description:
|
|
335
|
+
"When offline mode is enabled, synchronize the synchedTables tables when the app is resumed.",
|
|
336
|
+
}),
|
|
327
337
|
pushSync: Flags.boolean({
|
|
328
338
|
name: "Push sync",
|
|
329
339
|
string: "pushSync",
|
|
@@ -337,6 +347,13 @@ BuildAppCommand.flags = {
|
|
|
337
347
|
"Perdiodic interval (in minutes) to run synchronizations in the background. " +
|
|
338
348
|
"This is just a min interval, depending on system conditions, the actual time may be longer.",
|
|
339
349
|
}),
|
|
350
|
+
noProvisioningProfile: Flags.boolean({
|
|
351
|
+
name: "no provisioning profile",
|
|
352
|
+
string: "noProvisioningProfile",
|
|
353
|
+
description:
|
|
354
|
+
"Do not use a provisioning profile, only for simulator builds (iOS only)",
|
|
355
|
+
default: false,
|
|
356
|
+
}),
|
|
340
357
|
provisioningProfile: Flags.string({
|
|
341
358
|
name: "provisioning profile",
|
|
342
359
|
string: "provisioningProfile",
|
|
@@ -353,6 +370,13 @@ BuildAppCommand.flags = {
|
|
|
353
370
|
string: "buildType",
|
|
354
371
|
description: "debug or release build",
|
|
355
372
|
}),
|
|
373
|
+
allowClearTextTraffic: Flags.boolean({
|
|
374
|
+
name: "allow clear text traffic",
|
|
375
|
+
string: "allowClearTextTraffic",
|
|
376
|
+
description:
|
|
377
|
+
"Enable this to allow unsecure HTTP connections. Useful for local testing.",
|
|
378
|
+
default: false,
|
|
379
|
+
}),
|
|
356
380
|
androidKeystore: Flags.string({
|
|
357
381
|
name: "android key store",
|
|
358
382
|
string: "androidKeyStore",
|
|
@@ -15,7 +15,9 @@ const removePluginsDir = () => {
|
|
|
15
15
|
fs.rmSync(pluginsPath, { force: true, recursive: true });
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
const writeJestConfigIntoPluginDir = (location) => {
|
|
18
|
+
const writeJestConfigIntoPluginDir = (location, plugin) => {
|
|
19
|
+
const state = getState();
|
|
20
|
+
const module = state.plugins[plugin.name];
|
|
19
21
|
fs.writeFileSync(
|
|
20
22
|
path.join(location, "jest.config.js"),
|
|
21
23
|
`const sqliteDir = process.env.JEST_SC_SQLITE_DIR;
|
|
@@ -35,6 +37,17 @@ const config = {
|
|
|
35
37
|
"@saltcorn/markup$": markupDir,
|
|
36
38
|
"@saltcorn/markup/(.*)": markupDir + "/$1",
|
|
37
39
|
"@saltcorn/admin-models/(.*)": adminModelsDir + "/$1",
|
|
40
|
+
${(module?.dependencies || [])
|
|
41
|
+
.map((dep) => {
|
|
42
|
+
let pluginLocation = state.plugin_locations[dep];
|
|
43
|
+
if (!pluginLocation) {
|
|
44
|
+
// try without org
|
|
45
|
+
const orgRemoved = dep.replace(/^@[^/]+\//, "");
|
|
46
|
+
pluginLocation = state.plugin_locations[orgRemoved];
|
|
47
|
+
}
|
|
48
|
+
return pluginLocation ? `"${dep}": "${pluginLocation}",` : "";
|
|
49
|
+
})
|
|
50
|
+
.join("\n ")}
|
|
38
51
|
},
|
|
39
52
|
modulePaths: [modulePath],
|
|
40
53
|
};
|
|
@@ -77,13 +90,20 @@ const spawnTest = async (installDir, env) => {
|
|
|
77
90
|
return ret.status;
|
|
78
91
|
};
|
|
79
92
|
|
|
80
|
-
const
|
|
93
|
+
const preparePlugin = async (plugin, overwrites) => {
|
|
81
94
|
await removeOldPlugin(plugin);
|
|
82
95
|
removePluginsDir();
|
|
83
|
-
await loadAndSaveNewPlugin(
|
|
96
|
+
await loadAndSaveNewPlugin(
|
|
97
|
+
plugin,
|
|
98
|
+
false,
|
|
99
|
+
false,
|
|
100
|
+
(str) => str,
|
|
101
|
+
false,
|
|
102
|
+
overwrites
|
|
103
|
+
);
|
|
84
104
|
const location = getPluginLocation(plugin.name);
|
|
85
105
|
writeMockFilesIntoPluginDir(location);
|
|
86
|
-
writeJestConfigIntoPluginDir(location);
|
|
106
|
+
writeJestConfigIntoPluginDir(location, plugin);
|
|
87
107
|
return location;
|
|
88
108
|
};
|
|
89
109
|
|
|
@@ -122,7 +142,7 @@ const getPluginLocation = (pluginName) => {
|
|
|
122
142
|
);
|
|
123
143
|
};
|
|
124
144
|
|
|
125
|
-
const testLocalPlugin = async (dir, env, backupFile) => {
|
|
145
|
+
const testLocalPlugin = async (dir, env, backupFile, overwrites) => {
|
|
126
146
|
if (backupFile) {
|
|
127
147
|
await prep_test_db(path.join(dir, "tests", backupFile));
|
|
128
148
|
} else await require("@saltcorn/data/db/reset_schema")();
|
|
@@ -134,27 +154,49 @@ const testLocalPlugin = async (dir, env, backupFile) => {
|
|
|
134
154
|
source: "local",
|
|
135
155
|
location: path.resolve(dir),
|
|
136
156
|
});
|
|
137
|
-
const installDir = await
|
|
157
|
+
const installDir = await preparePlugin(plugin, overwrites);
|
|
138
158
|
return await spawnTest(installDir, env);
|
|
139
159
|
};
|
|
140
160
|
|
|
141
|
-
const testReleasedPlugin = async (pluginName, env, backupFile) => {
|
|
161
|
+
const testReleasedPlugin = async (pluginName, env, backupFile, overwrites) => {
|
|
142
162
|
await require("@saltcorn/data/db/reset_schema")();
|
|
143
163
|
const plugin = await Plugin.store_by_name(pluginName);
|
|
144
164
|
delete plugin.id;
|
|
145
|
-
const installDir = await
|
|
165
|
+
const installDir = await preparePlugin(plugin, overwrites);
|
|
146
166
|
if (backupFile) {
|
|
147
167
|
await prep_test_db(path.join(installDir, "tests", backupFile));
|
|
148
168
|
}
|
|
149
169
|
return await spawnTest(installDir, env);
|
|
150
170
|
};
|
|
151
171
|
|
|
172
|
+
/**
|
|
173
|
+
*
|
|
174
|
+
* @param {string[]} overwrites paths to local plugins
|
|
175
|
+
* @returns an object mapping module names to paths
|
|
176
|
+
*/
|
|
177
|
+
const prepOverwritesCfg = (overwrites) => {
|
|
178
|
+
const result = {};
|
|
179
|
+
if (overwrites) {
|
|
180
|
+
for (const flag of overwrites) {
|
|
181
|
+
const pkgpath = path.join(flag, "package.json");
|
|
182
|
+
if (!fs.existsSync(pkgpath))
|
|
183
|
+
throw new Error(
|
|
184
|
+
`Overwrite dependency package.json not found in ${flag}`
|
|
185
|
+
);
|
|
186
|
+
const pkg = require(pkgpath);
|
|
187
|
+
result[pkg.name] = flag;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return result;
|
|
191
|
+
};
|
|
192
|
+
|
|
152
193
|
/**
|
|
153
194
|
* Install a plugin, spawn 'npm run test' in the install dir and check the return code
|
|
154
195
|
*/
|
|
155
196
|
class PluginTestCommand extends Command {
|
|
156
197
|
async run() {
|
|
157
198
|
const { flags } = await this.parse(PluginTestCommand);
|
|
199
|
+
const overwrites = prepOverwritesCfg(flags.overwriteDependency);
|
|
158
200
|
const dbname = flags.database ? flags.database : "saltcorn_test";
|
|
159
201
|
let env = null;
|
|
160
202
|
const db = require("@saltcorn/data/db");
|
|
@@ -173,14 +215,16 @@ class PluginTestCommand extends Command {
|
|
|
173
215
|
jestStatus = await testLocalPlugin(
|
|
174
216
|
flags.directory,
|
|
175
217
|
env,
|
|
176
|
-
flags.backupFile
|
|
218
|
+
flags.backupFile,
|
|
219
|
+
overwrites
|
|
177
220
|
);
|
|
178
221
|
} else if (flags.name) {
|
|
179
222
|
console.log(`Testing released plugin '${flags.name}'`);
|
|
180
223
|
jestStatus = await testReleasedPlugin(
|
|
181
224
|
flags.name,
|
|
182
225
|
env,
|
|
183
|
-
flags.backupFile
|
|
226
|
+
flags.backupFile,
|
|
227
|
+
overwrites
|
|
184
228
|
);
|
|
185
229
|
}
|
|
186
230
|
} catch (error) {
|
|
@@ -217,6 +261,13 @@ PluginTestCommand.flags = {
|
|
|
217
261
|
string: "database",
|
|
218
262
|
description: "Run on specified database. Default is 'saltcorn_test''",
|
|
219
263
|
}),
|
|
264
|
+
overwriteDependency: Flags.string({
|
|
265
|
+
char: "o",
|
|
266
|
+
description:
|
|
267
|
+
"Dependency to overwrite with a local plugin (can be used multiple times). " +
|
|
268
|
+
"Please specify the path to the local plugin, the module name will be taken from there.",
|
|
269
|
+
multiple: true,
|
|
270
|
+
}),
|
|
220
271
|
};
|
|
221
272
|
|
|
222
273
|
PluginTestCommand.description =
|