pinstripe 0.32.0 → 0.33.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/cli.js +23 -33
- package/lib/command.js +40 -3
- package/lib/command.test.js +32 -0
- package/lib/commands/generate_app.js +5 -3
- package/lib/commands/generate_background_job.js +2 -2
- package/lib/commands/generate_command.js +2 -2
- package/lib/commands/generate_component.js +2 -3
- package/lib/commands/generate_migration.js +13 -13
- package/lib/commands/generate_model.js +6 -9
- package/lib/commands/generate_project.js +13 -8
- package/lib/commands/generate_service.js +2 -2
- package/lib/commands/generate_static_site.js +1 -3
- package/lib/commands/generate_view.js +2 -2
- package/lib/commands/list_commands.js +6 -0
- package/lib/commands/list_views.js +1 -3
- package/lib/commands/run_background_job.js +2 -2
- package/lib/commands/start_server.js +4 -7
- package/lib/project.js +0 -2
- package/lib/registry.js +1 -0
- package/lib/services/cli_utils.js +19 -71
- package/lib/services/server.js +1 -1
- package/lib/views/shared/_button.js +1 -0
- package/package.json +8 -7
- package/lib/services/args.js +0 -9
package/cli.js
CHANGED
|
@@ -1,46 +1,36 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { spawn } from 'child_process';
|
|
4
|
-
|
|
5
3
|
import { Project } from './lib/project.js';
|
|
6
4
|
import { Command } from './lib/command.js';
|
|
7
5
|
import { importAll } from './lib/import_all.js';
|
|
8
6
|
import { Workspace } from './lib/workspace.js';
|
|
9
7
|
|
|
10
8
|
(async () => {
|
|
11
|
-
const { entryPath,
|
|
12
|
-
const { argv
|
|
13
|
-
const args = argv.slice(2);
|
|
9
|
+
const { entryPath, exists } = await Project.instance;
|
|
10
|
+
const { argv } = process;
|
|
11
|
+
const [name, ...args ] = argv.slice(2);
|
|
14
12
|
|
|
15
|
-
if
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
stdio: 'inherit'
|
|
19
|
-
});
|
|
20
|
-
} else {
|
|
21
|
-
if(entryPath){
|
|
22
|
-
import(entryPath);
|
|
23
|
-
}
|
|
13
|
+
if(entryPath){
|
|
14
|
+
import(entryPath);
|
|
15
|
+
}
|
|
24
16
|
|
|
25
|
-
|
|
17
|
+
await importAll();
|
|
26
18
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
await
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
console.error(e);
|
|
44
|
-
}
|
|
19
|
+
if(exists){
|
|
20
|
+
Command.names.forEach(commandName => {
|
|
21
|
+
if(!Command.for(commandName).internal) Command.unregister(commandName);
|
|
22
|
+
});
|
|
23
|
+
} else {
|
|
24
|
+
Command.names.forEach(commandName => {
|
|
25
|
+
if(!Command.for(commandName).external) Command.unregister(commandName);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
await Workspace.run(async function(){
|
|
31
|
+
await this.runCommand(name, args);
|
|
32
|
+
});
|
|
33
|
+
} catch(e) {
|
|
34
|
+
console.error(e);
|
|
45
35
|
}
|
|
46
36
|
})();
|
package/lib/command.js
CHANGED
|
@@ -4,9 +4,15 @@ import { inflector } from './inflector.js';
|
|
|
4
4
|
import { Registry } from './registry.js';
|
|
5
5
|
import { ServiceConsumer } from './service_consumer.js';
|
|
6
6
|
|
|
7
|
+
const optionPattern = /^-([a-z]|-[a-z\-]+)$/;
|
|
8
|
+
|
|
7
9
|
export const Command = Class.extend().include({
|
|
8
10
|
meta(){
|
|
9
|
-
this.assignProps({
|
|
11
|
+
this.assignProps({
|
|
12
|
+
name: 'Command',
|
|
13
|
+
internal: true,
|
|
14
|
+
external: false
|
|
15
|
+
});
|
|
10
16
|
|
|
11
17
|
this.include(Registry);
|
|
12
18
|
this.include(ServiceConsumer);
|
|
@@ -16,12 +22,43 @@ export const Command = Class.extend().include({
|
|
|
16
22
|
return inflector.dasherize(name);
|
|
17
23
|
},
|
|
18
24
|
|
|
19
|
-
async run(context, name = 'list-commands',
|
|
25
|
+
async run(context, name = 'list-commands', params = {}){
|
|
20
26
|
await context.fork().run(async context => {
|
|
21
|
-
context.
|
|
27
|
+
context.params = Array.isArray(params) ? this.extractParams(params) : params;
|
|
22
28
|
await this.create(name, context).run();
|
|
23
29
|
});
|
|
24
30
|
},
|
|
31
|
+
|
|
32
|
+
extractParams(_args = []){
|
|
33
|
+
const args = [ ..._args ];
|
|
34
|
+
const out = {};
|
|
35
|
+
let currentName;
|
|
36
|
+
while(args.length){
|
|
37
|
+
const arg = args.shift();
|
|
38
|
+
const matches = arg.match(optionPattern);
|
|
39
|
+
if(matches){
|
|
40
|
+
currentName = inflector.camelize(matches[1]);
|
|
41
|
+
if(out[currentName] === undefined){
|
|
42
|
+
out[currentName] = [];
|
|
43
|
+
}
|
|
44
|
+
} else {
|
|
45
|
+
if(currentName === undefined){
|
|
46
|
+
currentName = 'args';
|
|
47
|
+
out[currentName] = [];
|
|
48
|
+
}
|
|
49
|
+
out[currentName].push(arg);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
Object.keys(out).forEach(name => {
|
|
53
|
+
const value = out[name];
|
|
54
|
+
if(!value.length){
|
|
55
|
+
out[name] = true;
|
|
56
|
+
} else {
|
|
57
|
+
out[name] = value.join(' ');
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
25
62
|
});
|
|
26
63
|
},
|
|
27
64
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Command } from "./command.js";
|
|
2
|
+
|
|
3
|
+
[
|
|
4
|
+
{ args: [], expectedParams: {} },
|
|
5
|
+
{ args: ["-a"], expectedParams: { a: true } },
|
|
6
|
+
{ args: ["--apple"], expectedParams: { apple: true } },
|
|
7
|
+
{ args: ["--apple", "--pear"], expectedParams: { apple: true, pear: true } },
|
|
8
|
+
{ args: ["Hello world!"], expectedParams: { args: "Hello world!" } },
|
|
9
|
+
{ args: ["Hello", "world!"], expectedParams: { args: "Hello world!" } },
|
|
10
|
+
{
|
|
11
|
+
args: [
|
|
12
|
+
"Hello", "world!",
|
|
13
|
+
"--apple",
|
|
14
|
+
"--pear",
|
|
15
|
+
"--plum-color", "purple",
|
|
16
|
+
"--other-fruit", "peach", "orange",
|
|
17
|
+
],
|
|
18
|
+
expectedParams: {
|
|
19
|
+
args: "Hello world!",
|
|
20
|
+
apple: true,
|
|
21
|
+
pear: true,
|
|
22
|
+
plumColor: "purple",
|
|
23
|
+
otherFruit: "peach orange",
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
].forEach(({ args, expectedParams }, i) => {
|
|
27
|
+
test(`Command.extractParams (${i}})`, () => {
|
|
28
|
+
expect(Command.extractParams(args)).toStrictEqual(expectedParams);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
export default {
|
|
4
4
|
async run(){
|
|
5
|
-
const
|
|
5
|
+
const { name = '' } = this.params;
|
|
6
6
|
const normalizedName = this.inflector.snakeify(name);
|
|
7
7
|
if(normalizedName == ''){
|
|
8
|
-
console.error('An app name must be given.');
|
|
8
|
+
console.error('An app --name must be given.');
|
|
9
9
|
process.exit();
|
|
10
10
|
}
|
|
11
11
|
|
|
@@ -35,7 +35,9 @@ export default {
|
|
|
35
35
|
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
-
await this.runCommand('generate-view',
|
|
38
|
+
await this.runCommand('generate-view', {
|
|
39
|
+
name: `${normalizedName}/index`
|
|
40
|
+
});
|
|
39
41
|
}
|
|
40
42
|
}
|
|
41
43
|
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
export default {
|
|
4
4
|
async run(){
|
|
5
|
-
const
|
|
5
|
+
const { name = '' } = this.params;
|
|
6
6
|
const normalizedName = this.inflector.snakeify(name);
|
|
7
7
|
if(normalizedName == ''){
|
|
8
|
-
console.error('A
|
|
8
|
+
console.error('A background job --name must be given.');
|
|
9
9
|
process.exit();
|
|
10
10
|
}
|
|
11
11
|
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
export default {
|
|
4
4
|
async run(){
|
|
5
|
-
const
|
|
5
|
+
const { name = '' } = this.params;
|
|
6
6
|
const normalizedName = this.inflector.snakeify(name);
|
|
7
7
|
if(normalizedName == ''){
|
|
8
|
-
console.error('A command name must be given.');
|
|
8
|
+
console.error('A command --name must be given.');
|
|
9
9
|
process.exit();
|
|
10
10
|
}
|
|
11
11
|
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
|
|
2
2
|
export default {
|
|
3
3
|
async run(){
|
|
4
|
-
const
|
|
5
|
-
const name = this.inflector.snakeify(extractArg(''));
|
|
4
|
+
const name = this.inflector.snakeify(this.params.name || '');
|
|
6
5
|
if(name == ''){
|
|
7
|
-
console.error('A component name must be given.');
|
|
6
|
+
console.error('A component --name must be given.');
|
|
8
7
|
process.exit();
|
|
9
8
|
}
|
|
10
9
|
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
|
|
2
2
|
export default {
|
|
3
3
|
async run(){
|
|
4
|
-
const { extractArg, extractFields, extractOptions } = this.cliUtils;
|
|
5
4
|
|
|
6
|
-
const suffix = this.inflector.snakeify(
|
|
7
|
-
|
|
8
|
-
const {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
5
|
+
const suffix = this.inflector.snakeify(this.params.suffix || 'migration');
|
|
6
|
+
|
|
7
|
+
const { fields = '' } = this.params;
|
|
8
|
+
const normalizedFields = this.cliUtils.normalizeFields(fields);
|
|
9
|
+
|
|
10
|
+
const table = this.params.table || (() => {
|
|
11
|
+
const matches = suffix.match(/_to_(.+)$/);
|
|
12
|
+
if(matches){
|
|
13
|
+
return matches[1];
|
|
14
|
+
}
|
|
15
|
+
})();
|
|
16
16
|
|
|
17
17
|
const unixTime = Math.floor(new Date().getTime() / 1000);
|
|
18
18
|
const name = `${unixTime}_${suffix}`;
|
|
@@ -33,10 +33,10 @@ export default {
|
|
|
33
33
|
indent(() => {
|
|
34
34
|
line(`async migrate(){`);
|
|
35
35
|
indent(() => {
|
|
36
|
-
if(table &&
|
|
36
|
+
if(table && normalizedFields.length){
|
|
37
37
|
line(`await this.database.table('${table}', async ${table} => {`);
|
|
38
38
|
indent(() => {
|
|
39
|
-
|
|
39
|
+
normalizedFields.forEach(({ name, type }) => {
|
|
40
40
|
line(`await ${table}.addColumn('${name}', '${type}');`);
|
|
41
41
|
});
|
|
42
42
|
})
|
|
@@ -2,20 +2,17 @@
|
|
|
2
2
|
export default {
|
|
3
3
|
async run(){
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
const name = this.inflector.snakeify(extractArg(''));
|
|
5
|
+
const name = this.inflector.snakeify(this.params.name || '');
|
|
7
6
|
if(name == ''){
|
|
8
|
-
console.error('A model name must be given.');
|
|
7
|
+
console.error('A model --name must be given.');
|
|
9
8
|
process.exit();
|
|
10
9
|
}
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
|
|
11
|
+
let { fields = '' } = this.params;
|
|
12
|
+
|
|
13
13
|
const collectionName = this.inflector.camelize(this.inflector.pluralize(name));
|
|
14
14
|
if(!await this.database[collectionName]){
|
|
15
|
-
|
|
16
|
-
return `${ mandatory ? '^' : '' }${name}:${type}`
|
|
17
|
-
});
|
|
18
|
-
await this.runCommand('generate-migration', `create_${name}`, ...denormalizedFields, '--table', collectionName)
|
|
15
|
+
await this.runCommand('generate-migration', { name: `create_${name}`, fields, table: collectionName});
|
|
19
16
|
}
|
|
20
17
|
|
|
21
18
|
const { inProjectRootDir, generateFile, line, indent } = this.fsBuilder;
|
|
@@ -7,18 +7,23 @@ const defaultDependencies = [
|
|
|
7
7
|
];
|
|
8
8
|
|
|
9
9
|
export default {
|
|
10
|
-
|
|
10
|
+
meta(){
|
|
11
|
+
this.assignProps({
|
|
12
|
+
external: true,
|
|
13
|
+
internal: false
|
|
14
|
+
});
|
|
15
|
+
},
|
|
11
16
|
|
|
12
|
-
|
|
13
|
-
const name =
|
|
17
|
+
async run(){
|
|
18
|
+
const name = this.params.name || '';
|
|
14
19
|
if(name == ''){
|
|
15
|
-
console.error('A project name must be given.');
|
|
20
|
+
console.error('A project --name must be given.');
|
|
16
21
|
process.exit();
|
|
17
22
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
|
|
24
|
+
let { with: dependencies = '', core = false } = this.params;
|
|
25
|
+
|
|
26
|
+
dependencies = dependencies.split(/\s+/).map(dependency => dependency.trim());
|
|
22
27
|
|
|
23
28
|
if(!core) defaultDependencies.forEach(dependency => {
|
|
24
29
|
if(!dependencies.includes(dependency)) dependencies.unshift(dependency);
|
|
@@ -6,9 +6,7 @@ import { App, View } from 'pinstripe';
|
|
|
6
6
|
export default {
|
|
7
7
|
async run(){
|
|
8
8
|
|
|
9
|
-
const {
|
|
10
|
-
|
|
11
|
-
const { app = 'main' } = extractOptions();
|
|
9
|
+
const { app = 'main' } = this.params;
|
|
12
10
|
|
|
13
11
|
const { viewNames } = View.mapperFor(App.create(app, this.context).compose());
|
|
14
12
|
|
|
@@ -4,10 +4,10 @@ import { readFile } from 'fs/promises';
|
|
|
4
4
|
|
|
5
5
|
export default {
|
|
6
6
|
async run(){
|
|
7
|
-
const
|
|
7
|
+
const { name = '' } = this.params;
|
|
8
8
|
let normalizedName = name.replace(/^\//, '');
|
|
9
9
|
if(name == ''){
|
|
10
|
-
console.error('A view name must be given.');
|
|
10
|
+
console.error('A view --name must be given.');
|
|
11
11
|
process.exit();
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -4,9 +4,7 @@ import { App, View } from 'pinstripe';
|
|
|
4
4
|
|
|
5
5
|
export default {
|
|
6
6
|
run(){
|
|
7
|
-
const {
|
|
8
|
-
|
|
9
|
-
const { app = 'main' } = extractOptions();
|
|
7
|
+
const { app = 'main' } = this.params;
|
|
10
8
|
|
|
11
9
|
const { viewNames } = View.mapperFor(App.create(app, this.context).compose());
|
|
12
10
|
console.log('');
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
2
|
export default {
|
|
3
3
|
async run(){
|
|
4
|
-
const
|
|
4
|
+
const { name = '' } = this.params;
|
|
5
5
|
if(name == ''){
|
|
6
|
-
console.error('A background job name must be given.');
|
|
6
|
+
console.error('A background job --name must be given.');
|
|
7
7
|
process.exit();
|
|
8
8
|
}
|
|
9
9
|
this.runBackgroundJob(name);
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
|
|
2
2
|
export default {
|
|
3
3
|
run(){
|
|
4
|
-
const {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
withoutBot: false
|
|
9
|
-
});
|
|
10
|
-
|
|
4
|
+
const {
|
|
5
|
+
app = `main:${process.env.HOST || '127.0.0.1'}:${parseInt(process.env.PORT || '3000')}`,
|
|
6
|
+
withoutBot = false
|
|
7
|
+
} = this.params;
|
|
11
8
|
|
|
12
9
|
const apps = [];
|
|
13
10
|
let currentPort = 3000;
|
package/lib/project.js
CHANGED
|
@@ -40,8 +40,6 @@ export const Project = Class.extend().include({
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
this.entryPath = this.exports['.'] || this.main;
|
|
43
|
-
|
|
44
|
-
this.localPinstripePath = (await findInPath('node_modules/.bin/pinstripe', process.cwd())).shift();
|
|
45
43
|
|
|
46
44
|
this.nodePaths = await findInPath('node_modules/', process.cwd());
|
|
47
45
|
},
|
package/lib/registry.js
CHANGED
|
@@ -1,77 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
const optionPattern = /^-([a-z]|-[a-z\-]+)$/;
|
|
3
|
-
|
|
4
1
|
export default {
|
|
5
2
|
create(){
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
return {
|
|
4
|
+
normalizeFields: fields => {
|
|
5
|
+
let out = fields;
|
|
6
|
+
if(typeof out == 'string') out = out.split(/\s+/).map(field => field.trim()).filter(field => field).map(arg => {
|
|
7
|
+
const matches = arg.match(/^(\^|)([^:]*)(:|)(.*)$/);
|
|
8
|
+
const mandatory = matches[1] == '^';
|
|
9
|
+
const name = this.inflector.camelize(matches[2]);
|
|
10
|
+
const type = matches[4];
|
|
11
|
+
return {
|
|
12
|
+
mandatory,
|
|
13
|
+
name,
|
|
14
|
+
type
|
|
15
|
+
};
|
|
16
|
+
});
|
|
17
|
+
out.forEach(field => {
|
|
18
|
+
field.mandatory ??= false;
|
|
19
|
+
field.type ||= 'string';
|
|
20
|
+
});
|
|
21
|
+
return out;
|
|
13
22
|
}
|
|
14
|
-
return _default;
|
|
15
23
|
};
|
|
16
|
-
|
|
17
|
-
const extractArgs = () => {
|
|
18
|
-
const out = [];
|
|
19
|
-
while(args[0] && !args[0].match(optionPattern)){
|
|
20
|
-
out.push(args.shift())
|
|
21
|
-
}
|
|
22
|
-
return out;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const extractFields = () => extractArgs().map(arg => {
|
|
26
|
-
const matches = arg.match(/^(\^|)([^:]*)(:|)(.*)$/);
|
|
27
|
-
const mandatory = matches[1] == '^';
|
|
28
|
-
const name = this.inflector.camelize(matches[2]);
|
|
29
|
-
const type = matches[4] || 'string';
|
|
30
|
-
return {
|
|
31
|
-
mandatory,
|
|
32
|
-
name,
|
|
33
|
-
type
|
|
34
|
-
};
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
const extractOptions = (_default = {}) => {
|
|
38
|
-
const out = {};
|
|
39
|
-
let currentName;
|
|
40
|
-
while(args.length){
|
|
41
|
-
const arg = args.shift();
|
|
42
|
-
const matches = arg.match(optionPattern);
|
|
43
|
-
if(matches){
|
|
44
|
-
currentName = this.inflector.camelize(matches[1]);
|
|
45
|
-
if(out[currentName] === undefined){
|
|
46
|
-
out[currentName] = [];
|
|
47
|
-
}
|
|
48
|
-
} else if(currentName){
|
|
49
|
-
out[currentName].push(arg);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
Object.keys({ ...out, ..._default }).forEach(name => {
|
|
53
|
-
const value = out[name];
|
|
54
|
-
if(value === undefined){
|
|
55
|
-
out[name] = _default[name];
|
|
56
|
-
} else if(!value.length){
|
|
57
|
-
out[name] = true;
|
|
58
|
-
} else if(!Array.isArray(_default[name])){
|
|
59
|
-
out[name] = value.join(' ');
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
return out;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const resetArgs = () => args = [..._args];
|
|
66
|
-
|
|
67
|
-
this.context.cliUtils = {
|
|
68
|
-
extractArg,
|
|
69
|
-
extractArgs,
|
|
70
|
-
extractFields,
|
|
71
|
-
extractOptions,
|
|
72
|
-
resetArgs
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
return this.context.cliUtils;
|
|
76
24
|
}
|
|
77
25
|
};
|
package/lib/services/server.js
CHANGED
|
@@ -70,7 +70,7 @@ export default {
|
|
|
70
70
|
parseBody(request){
|
|
71
71
|
return new Promise((resolve) => {
|
|
72
72
|
const out = {};
|
|
73
|
-
const busboy =
|
|
73
|
+
const busboy = Busboy({ headers: request.headers });
|
|
74
74
|
|
|
75
75
|
busboy.on('file', function(fieldname, file, filename, encoding, mimeType) {
|
|
76
76
|
const chunks = [];
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "pinstripe",
|
|
4
4
|
"description": "A slick web framework for Node.js.",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.33.0",
|
|
6
6
|
"author": "Jody Salt",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"exports": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"scripts": {
|
|
18
18
|
"clean": "rm -rf ./node_modules",
|
|
19
|
-
"start": "
|
|
19
|
+
"start": "pinstripe start-server",
|
|
20
20
|
"test": "npm run test:unit",
|
|
21
21
|
"test:unit": "jest lib"
|
|
22
22
|
},
|
|
@@ -24,13 +24,13 @@
|
|
|
24
24
|
"@babel/core": "^7.9.0",
|
|
25
25
|
"@babel/plugin-transform-modules-commonjs": "^7.18.6",
|
|
26
26
|
"@babel/preset-env": "^7.9.0",
|
|
27
|
-
"babel-jest": "^
|
|
27
|
+
"babel-jest": "^29.7.0",
|
|
28
28
|
"jest": "^28.0.1",
|
|
29
29
|
"jest-environment-jsdom": "^29.1.2"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"bcrypt": "^5.0.1",
|
|
33
|
-
"busboy": "^
|
|
33
|
+
"busboy": "^1.6.0",
|
|
34
34
|
"chalk": "^4.1.0",
|
|
35
35
|
"cron-parser": "^4.3.0",
|
|
36
36
|
"css": "^3.0.0",
|
|
@@ -41,10 +41,11 @@
|
|
|
41
41
|
"markdown-it": "^12.2.0",
|
|
42
42
|
"memfs": "^3.2.2",
|
|
43
43
|
"mime-types": "^2.1.28",
|
|
44
|
-
"mysql2": "^
|
|
45
|
-
"nodemailer": "^6.
|
|
44
|
+
"mysql2": "^3.10.1",
|
|
45
|
+
"nodemailer": "^6.9.14",
|
|
46
46
|
"punycode": "^2.3.0",
|
|
47
|
-
"sqlite3": "^5.
|
|
47
|
+
"sqlite3": "^5.1.7",
|
|
48
|
+
"start-server-and-test": "2.0.4",
|
|
48
49
|
"tmp": "^0.2.1",
|
|
49
50
|
"unionfs": "^4.4.0"
|
|
50
51
|
},
|