spyne-cli 0.6.0 → 0.6.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/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"spyne-cli": "index.js"
|
|
5
5
|
},
|
|
6
6
|
"type": "module",
|
|
7
|
-
"version": "0.6.
|
|
7
|
+
"version": "0.6.2",
|
|
8
8
|
"description": "Generates spyne objects and saves them to standard spyne.",
|
|
9
9
|
"main": "index.js",
|
|
10
10
|
"scripts": {
|
|
@@ -35,7 +35,6 @@
|
|
|
35
35
|
"ora": "^8.1.1",
|
|
36
36
|
"package-up": "^5.0.0",
|
|
37
37
|
"pkg-dir": "^8.0.0",
|
|
38
|
-
"pkg-up": "^5.0.0",
|
|
39
38
|
"ramda": "^0.30.1",
|
|
40
39
|
"read-pkg": "^9.0.1",
|
|
41
40
|
"recast": "^0.23.9",
|
package/src/spyne-file-prompt.js
CHANGED
|
@@ -8,6 +8,7 @@ import GenerateFileString from './templates/generate-file-string.js';
|
|
|
8
8
|
import {onSaveSpyneFileToDir} from './utils/file-utils.js';
|
|
9
9
|
import {generatePromptOutput} from './templates/generate-prompt-output.js';
|
|
10
10
|
import {addChannelToIndexJS} from './utils/add-channel-to-index-file.js';
|
|
11
|
+
import {insertChannelStrings} from './utils/insert-channel-strings-to-index-file.js';
|
|
11
12
|
|
|
12
13
|
export default class SpyneFilePrompt {
|
|
13
14
|
|
|
@@ -46,7 +47,8 @@ export default class SpyneFilePrompt {
|
|
|
46
47
|
let channelHasRegistered = false;
|
|
47
48
|
|
|
48
49
|
if (fileType === 'Channel'){
|
|
49
|
-
const savedChannelToIndexProps = addChannelToIndexJS(className, fileName);
|
|
50
|
+
//const savedChannelToIndexProps = addChannelToIndexJS(className, fileName);
|
|
51
|
+
const savedChannelToIndexProps = insertChannelStrings(className, fileName);
|
|
50
52
|
|
|
51
53
|
// check if channel has been registered
|
|
52
54
|
channelHasRegistered = savedChannelToIndexProps.fileHasSaved;
|
|
@@ -45,7 +45,12 @@ export async function createNewApp(appName) {
|
|
|
45
45
|
}).start();
|
|
46
46
|
|
|
47
47
|
try {
|
|
48
|
-
await git.clone(repoUrl, targetDir, [
|
|
48
|
+
await git.clone(repoUrl, targetDir, [
|
|
49
|
+
'--branch=main',
|
|
50
|
+
'--single-branch',
|
|
51
|
+
'--depth=1'
|
|
52
|
+
]);
|
|
53
|
+
|
|
49
54
|
spinner.succeed(c.greenBright('Starter App cloned successfully!'));
|
|
50
55
|
} catch (err) {
|
|
51
56
|
spinner.fail(c.red(`Failed to clone the repository: ${err.message}`));
|
|
@@ -1,96 +1,70 @@
|
|
|
1
1
|
const _viewStreamTemplate = (props)=> {
|
|
2
|
-
return `import {ViewStream} from 'spyne';
|
|
2
|
+
return `import { ViewStream } from 'spyne';
|
|
3
3
|
|
|
4
4
|
export class ${props.className} extends ViewStream {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
// return nested array(s)
|
|
13
|
-
return [];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
broadcastEvents() {
|
|
17
|
-
// return nested array(s)
|
|
18
|
-
return [];
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
onRendered() {
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
}
|
|
5
|
+
constructor(props = {}) {
|
|
6
|
+
super(props);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
addActionListeners() {
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
26
12
|
|
|
13
|
+
broadcastEvents() {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
onRendered() {}
|
|
18
|
+
}
|
|
27
19
|
`
|
|
28
20
|
}
|
|
29
21
|
|
|
30
22
|
const _domElementTemplate = (props) => {
|
|
31
|
-
return `import {DomElement} from 'spyne';
|
|
32
|
-
|
|
23
|
+
return `import { DomElement } from 'spyne';
|
|
24
|
+
|
|
33
25
|
export class ${props.className} extends DomElement {
|
|
34
|
-
|
|
35
|
-
constructor(props={}) {
|
|
36
|
-
|
|
26
|
+
constructor(props = {}) {
|
|
37
27
|
super(props);
|
|
38
28
|
}
|
|
39
|
-
|
|
40
29
|
}
|
|
41
|
-
|
|
42
30
|
`
|
|
43
31
|
}
|
|
44
32
|
|
|
45
33
|
|
|
46
34
|
const _channelTemplate = (props)=> {
|
|
47
|
-
return `import {
|
|
48
|
-
import {Channel} from 'spyne';
|
|
49
|
-
|
|
50
|
-
export class ${props.className} extends Channel{
|
|
35
|
+
return `import { Channel } from 'spyne';
|
|
51
36
|
|
|
52
|
-
|
|
53
|
-
|
|
37
|
+
export class ${props.className} extends Channel {
|
|
38
|
+
constructor(name, props = {}) {
|
|
39
|
+
name = '${props.channelName}';
|
|
54
40
|
props.sendCachedPayload = ${props.replayLastPayload};
|
|
55
|
-
|
|
56
41
|
super(name, props);
|
|
57
42
|
}
|
|
58
43
|
|
|
59
|
-
onRegistered(){
|
|
60
|
-
|
|
61
|
-
}
|
|
44
|
+
onRegistered() {}
|
|
62
45
|
|
|
63
46
|
addRegisteredActions() {
|
|
64
|
-
|
|
65
47
|
return [];
|
|
66
48
|
}
|
|
67
49
|
|
|
68
|
-
onViewStreamInfo(
|
|
69
|
-
let data = obj.props();
|
|
70
|
-
}
|
|
71
|
-
|
|
50
|
+
onViewStreamInfo() {}
|
|
72
51
|
}
|
|
73
|
-
|
|
74
52
|
`
|
|
75
53
|
}
|
|
76
54
|
|
|
77
55
|
const _spyneTraitTemplate = (props)=>{
|
|
78
|
-
return `import {SpyneTrait} from 'spyne';
|
|
56
|
+
return `import { SpyneTrait } from 'spyne';
|
|
79
57
|
|
|
80
58
|
export class ${props.className} extends SpyneTrait {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
let traitPrefix = "${props.methodPrefix}";
|
|
84
|
-
|
|
59
|
+
constructor(context) {
|
|
60
|
+
let traitPrefix = '${props.methodPrefix}';
|
|
85
61
|
super(context, traitPrefix);
|
|
86
62
|
}
|
|
87
|
-
|
|
88
|
-
static ${props.methodPrefix}HelloWorld(){
|
|
89
|
-
return
|
|
63
|
+
|
|
64
|
+
static ${props.methodPrefix}HelloWorld() {
|
|
65
|
+
return 'Hello World';
|
|
90
66
|
}
|
|
91
|
-
|
|
92
67
|
}
|
|
93
|
-
|
|
94
68
|
`
|
|
95
69
|
}
|
|
96
70
|
|
package/src/ui.js
CHANGED
|
@@ -5,7 +5,7 @@ export class SpyneCliUI {
|
|
|
5
5
|
|
|
6
6
|
constructor() {}
|
|
7
7
|
static title(){
|
|
8
|
-
const figletTxt = figlet.textSync('spyne-cli 6.
|
|
8
|
+
const figletTxt = figlet.textSync('spyne-cli 6.2', {
|
|
9
9
|
horizontalLayout: 'universal smushing'
|
|
10
10
|
})
|
|
11
11
|
const chalkOutput = chalk.blue(figletTxt);
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import c from 'ansi-colors';
|
|
4
|
+
//import {Data} from '../spyne-template-prompts.js';
|
|
5
|
+
//const {appPath} = Data;
|
|
6
|
+
|
|
7
|
+
export function insertChannelStrings(channelClassName, channelFileName, indexJsPath="./src/index.js" ) {
|
|
8
|
+
//console.log("INFO IS ",{appPath, channelClassName, channelFileName, indexJsPath})
|
|
9
|
+
try {
|
|
10
|
+
if (!fs.existsSync(indexJsPath)) {
|
|
11
|
+
console.log(c.red(`Error: ./src/index.js not found at ${indexJsPath}`));
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let fileContent = fs.readFileSync(indexJsPath, 'utf-8');
|
|
16
|
+
let lines = fileContent.split('\n');
|
|
17
|
+
|
|
18
|
+
// 1) Find the last import line
|
|
19
|
+
let lastImportIndex = -1;
|
|
20
|
+
for (let i = 0; i < lines.length; i++) {
|
|
21
|
+
// A naive check: line starts with "import "
|
|
22
|
+
// or you can also check .match(/^import\s+/)
|
|
23
|
+
if (lines[i].trim().startsWith('import ')) {
|
|
24
|
+
lastImportIndex = i;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// 2) Find the line with SpyneApp.init(...) or spyneApp.init(...)
|
|
29
|
+
// We'll store the first occurrence
|
|
30
|
+
let initIndex = -1;
|
|
31
|
+
const initRegex = /(SpyneApp\.init\s*\()|(spyneApp\.init\s*\()/;
|
|
32
|
+
for (let i = 0; i < lines.length; i++) {
|
|
33
|
+
if (initRegex.test(lines[i])) {
|
|
34
|
+
initIndex = i;
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 3) Build the import snippet
|
|
40
|
+
// e.g. "import {ChannelTest_1} from 'channels/channel-test-1.js';"
|
|
41
|
+
const importSnippet = `import { ${channelClassName} } from 'channels/${channelFileName}';`;
|
|
42
|
+
|
|
43
|
+
// 4) Decide where to insert the import line
|
|
44
|
+
// - Must be AFTER the last import
|
|
45
|
+
// - Must be BEFORE the init line (if init line is after the last import)
|
|
46
|
+
// If init line doesn't exist or it's above the last import, we'll just place after last import.
|
|
47
|
+
let importInsertionIndex = lastImportIndex + 1;
|
|
48
|
+
if (initIndex !== -1 && initIndex > lastImportIndex) {
|
|
49
|
+
// If there's space to place it exactly before the init line
|
|
50
|
+
// we'll insert at the init line index. That effectively
|
|
51
|
+
// pushes the init line down by 1 line.
|
|
52
|
+
importInsertionIndex = Math.min(initIndex, lastImportIndex + 1);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Insert the import line
|
|
56
|
+
lines.splice(importInsertionIndex, 0, importSnippet);
|
|
57
|
+
|
|
58
|
+
// 5) Build the registerChannel snippet
|
|
59
|
+
// e.g. "SpyneApp.registerChannel(new ChannelTest_1());"
|
|
60
|
+
const registerSnippet = `SpyneApp.registerChannel(new ${channelClassName}());`;
|
|
61
|
+
|
|
62
|
+
// 6) Insert the register snippet right AFTER the init line, if found
|
|
63
|
+
if (initIndex !== -1) {
|
|
64
|
+
// Because we inserted one line before the init,
|
|
65
|
+
// the init line is now at initIndex+1, so the place to insert
|
|
66
|
+
// is initIndex+2. But let's re-scan for the init line to be safe,
|
|
67
|
+
// or simply adjust.
|
|
68
|
+
let updatedInitIndex = -1;
|
|
69
|
+
for (let i = 0; i < lines.length; i++) {
|
|
70
|
+
if (initRegex.test(lines[i])) {
|
|
71
|
+
updatedInitIndex = i;
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (updatedInitIndex !== -1) {
|
|
77
|
+
lines.splice(updatedInitIndex + 1, 0, registerSnippet);
|
|
78
|
+
} else {
|
|
79
|
+
// If we somehow lost the init line, fallback to end
|
|
80
|
+
lines.push(registerSnippet);
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
// No init line found, let's just push it at the end or skip
|
|
84
|
+
console.log(c.yellow('Warning: SpyneApp.init(...) not found. Skipping registerChannel insertion.'));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 7) Write the updated content back
|
|
88
|
+
fs.writeFileSync(indexJsPath, lines.join('\n'), 'utf-8');
|
|
89
|
+
//console.log(c.green(`✔ Successfully updated ./src/index.js to import and register "${channelClassName}".`));
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
fileHasSaved: true,
|
|
93
|
+
errorType: null
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
} catch (error) {
|
|
98
|
+
let errorType = 'UnknownError';
|
|
99
|
+
if (error.code === 'ENOENT') {
|
|
100
|
+
errorType = 'FileNotFound';
|
|
101
|
+
} else if (error.name === 'SyntaxError') {
|
|
102
|
+
errorType = 'SyntaxError';
|
|
103
|
+
} else if (error.name === 'TypeError') {
|
|
104
|
+
errorType = 'TypeError';
|
|
105
|
+
} else if (error.name === 'PermissionError') {
|
|
106
|
+
errorType = 'PermissionError';
|
|
107
|
+
}
|
|
108
|
+
//console.warn(`spyne-cli register channel, ${errorType} incomplete `,error)
|
|
109
|
+
|
|
110
|
+
// Fail silently and return error information
|
|
111
|
+
return {
|
|
112
|
+
fileHasSaved: false,
|
|
113
|
+
errorType
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
//console.error(c.red(`Error updating index.js: ${err.message}`));
|
|
118
|
+
}
|
|
119
|
+
}
|