@forgehive/forge-cli 0.2.3 → 0.2.4
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/runner.js +2 -2
- package/dist/tasks/conf/info.d.ts +1 -5
- package/dist/tasks/conf/info.js +13 -5
- package/dist/tasks/task/publish.d.ts +3 -1
- package/dist/tasks/task/publish.js +44 -15
- package/package.json +2 -2
- package/src/runner.ts +2 -2
- package/src/tasks/conf/info.ts +13 -5
- package/src/tasks/task/publish.ts +53 -19
package/dist/runner.js
CHANGED
|
@@ -26,7 +26,7 @@ const runner = new runner_1.Runner((data) => {
|
|
|
26
26
|
const { _, ...filteredObj } = data;
|
|
27
27
|
return {
|
|
28
28
|
taskName: String(_[0]),
|
|
29
|
-
action:
|
|
29
|
+
action: _[1] ?? '',
|
|
30
30
|
args: filteredObj
|
|
31
31
|
};
|
|
32
32
|
});
|
|
@@ -53,7 +53,7 @@ runner.setHandler(async (data) => {
|
|
|
53
53
|
const parsedArgs = runner.parseArguments(data);
|
|
54
54
|
const { taskName, action, args } = parsedArgs;
|
|
55
55
|
console.log('========================================');
|
|
56
|
-
console.log(
|
|
56
|
+
console.log(`Running: ${taskName} ${action ? action : ''} ${JSON.stringify(args)}`);
|
|
57
57
|
console.log('========================================');
|
|
58
58
|
const task = runner.getTask(taskName);
|
|
59
59
|
if (!task) {
|
|
@@ -3,11 +3,7 @@ export declare const info: import("@forgehive/task").TaskInstanceType<(argv: {},
|
|
|
3
3
|
loadCurrentProfile: (args: {}) => Promise<Promise<import("../types").Profile>>;
|
|
4
4
|
}>) => Promise<{
|
|
5
5
|
version: any;
|
|
6
|
-
profile: {
|
|
7
|
-
name: string;
|
|
8
|
-
url: string;
|
|
9
|
-
apiKey: string;
|
|
10
|
-
};
|
|
6
|
+
profile: {};
|
|
11
7
|
}>, {
|
|
12
8
|
readFile: (filePath: string) => Promise<string>;
|
|
13
9
|
loadCurrentProfile: (args: {}) => Promise<Promise<import("../types").Profile>>;
|
package/dist/tasks/conf/info.js
CHANGED
|
@@ -51,13 +51,21 @@ exports.info = (0, task_1.createTask)(schema, boundaries, async function (_argv,
|
|
|
51
51
|
const packageJsonPath = path.join(__dirname, '../../../package.json');
|
|
52
52
|
const packageJsonContent = await readFile(packageJsonPath);
|
|
53
53
|
const packageJson = JSON.parse(packageJsonContent);
|
|
54
|
-
const
|
|
55
|
-
return {
|
|
54
|
+
const info = {
|
|
56
55
|
version: packageJson.version,
|
|
57
|
-
profile: {
|
|
56
|
+
profile: {}
|
|
57
|
+
};
|
|
58
|
+
let profile;
|
|
59
|
+
try {
|
|
60
|
+
profile = await loadCurrentProfile({});
|
|
61
|
+
info.profile = {
|
|
58
62
|
name: profile.name,
|
|
59
63
|
url: profile.url,
|
|
60
64
|
apiKey: profile.apiKey
|
|
61
|
-
}
|
|
62
|
-
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
console.log('No default profile set. Please run forge task:run auth:add to create a profile.');
|
|
69
|
+
}
|
|
70
|
+
return info;
|
|
63
71
|
});
|
|
@@ -17,10 +17,11 @@ export declare const publish: import("@forgehive/task").TaskInstanceType<(argv:
|
|
|
17
17
|
readFileUtf8: (filePath: string) => Promise<string>;
|
|
18
18
|
readFileBinary: (filePath: string) => Promise<Buffer>;
|
|
19
19
|
publishTask: (data: any, profile: Profile) => Promise<any>;
|
|
20
|
+
uploadBundleWithPresignedUrl: (presignedUrl: string, bundleContent: Buffer) => Promise<any>;
|
|
20
21
|
ensureBuildsFolder: () => Promise<string>;
|
|
21
22
|
}>) => Promise<{
|
|
22
23
|
descriptor: import("../types").TaskDescriptor;
|
|
23
|
-
|
|
24
|
+
publish: boolean;
|
|
24
25
|
}>, {
|
|
25
26
|
getCwd: () => Promise<string>;
|
|
26
27
|
loadConf: (args: {}) => Promise<Promise<import("../types").ForgeConf>>;
|
|
@@ -37,5 +38,6 @@ export declare const publish: import("@forgehive/task").TaskInstanceType<(argv:
|
|
|
37
38
|
readFileUtf8: (filePath: string) => Promise<string>;
|
|
38
39
|
readFileBinary: (filePath: string) => Promise<Buffer>;
|
|
39
40
|
publishTask: (data: any, profile: Profile) => Promise<any>;
|
|
41
|
+
uploadBundleWithPresignedUrl: (presignedUrl: string, bundleContent: Buffer) => Promise<any>;
|
|
40
42
|
ensureBuildsFolder: () => Promise<string>;
|
|
41
43
|
}>;
|
|
@@ -37,15 +37,32 @@ const boundaries = {
|
|
|
37
37
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
38
|
publishTask: async (data, profile) => {
|
|
39
39
|
const publishUrl = `${profile.url}/api/tasks/publish`;
|
|
40
|
-
console.log(`Publishing task to ${publishUrl}...`);
|
|
41
40
|
const authToken = `${profile.apiKey}:${profile.apiSecret}`;
|
|
42
|
-
|
|
41
|
+
try {
|
|
42
|
+
const response = await axios_1.default.post(publishUrl, data, {
|
|
43
|
+
headers: {
|
|
44
|
+
Authorization: `Bearer ${authToken}`,
|
|
45
|
+
'Content-Type': 'application/json'
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
return response.data;
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
if (error.response?.data?.error.includes('Bundle size')) {
|
|
53
|
+
throw new Error('Bundle size exceeds the maximum allowed size of 25MB');
|
|
54
|
+
}
|
|
55
|
+
throw new Error('Failed to publish task source code and metadata');
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
59
|
+
uploadBundleWithPresignedUrl: async (presignedUrl, bundleContent) => {
|
|
60
|
+
const response = await axios_1.default.put(presignedUrl, bundleContent, {
|
|
43
61
|
headers: {
|
|
44
|
-
|
|
45
|
-
'Content-Type': 'application/json'
|
|
62
|
+
'Content-Type': 'application/octet-stream'
|
|
46
63
|
}
|
|
47
64
|
});
|
|
48
|
-
return response.
|
|
65
|
+
return response.status === 200;
|
|
49
66
|
},
|
|
50
67
|
ensureBuildsFolder: async () => {
|
|
51
68
|
const buildsPath = path_1.default.join(os_1.default.homedir(), '.forge', 'builds');
|
|
@@ -58,7 +75,7 @@ const boundaries = {
|
|
|
58
75
|
return buildsPath;
|
|
59
76
|
}
|
|
60
77
|
};
|
|
61
|
-
exports.publish = (0, task_1.createTask)(schema, boundaries, async function ({ descriptorName }, { getCwd, ensureBuildsFolder, loadConf, bundleCreate, bundleLoad, readFileUtf8, readFileBinary, publishTask, loadCurrentProfile }) {
|
|
78
|
+
exports.publish = (0, task_1.createTask)(schema, boundaries, async function ({ descriptorName }, { getCwd, ensureBuildsFolder, loadConf, bundleCreate, bundleLoad, readFileUtf8, readFileBinary, publishTask, loadCurrentProfile, uploadBundleWithPresignedUrl }) {
|
|
62
79
|
const cwd = await getCwd();
|
|
63
80
|
const forgeJson = await loadConf({});
|
|
64
81
|
const profile = await loadCurrentProfile({});
|
|
@@ -70,14 +87,12 @@ exports.publish = (0, task_1.createTask)(schema, boundaries, async function ({ d
|
|
|
70
87
|
const entryPoint = path_1.default.join(cwd, taskDescriptor.path);
|
|
71
88
|
const buildsPath = await ensureBuildsFolder();
|
|
72
89
|
const outputFile = path_1.default.join(buildsPath, `${descriptorName}.js`);
|
|
73
|
-
console.log('entryPoint:', entryPoint);
|
|
74
|
-
console.log('buildsPath:', buildsPath);
|
|
75
|
-
console.log('outputFile:', outputFile);
|
|
76
90
|
// Bundle the task
|
|
77
91
|
await bundleCreate({
|
|
78
92
|
entryPoint,
|
|
79
93
|
outputFile
|
|
80
94
|
});
|
|
95
|
+
console.log('Bundle created...');
|
|
81
96
|
// Load the bundled task
|
|
82
97
|
const bundle = await bundleLoad({
|
|
83
98
|
bundlePath: outputFile
|
|
@@ -87,9 +102,12 @@ exports.publish = (0, task_1.createTask)(schema, boundaries, async function ({ d
|
|
|
87
102
|
const description = task.getDescription() ?? '';
|
|
88
103
|
const schema = task.getSchema() || new schema_1.Schema({});
|
|
89
104
|
const schemaDescriptor = schema.describe();
|
|
90
|
-
// Read the task file content
|
|
105
|
+
// Read the task file content
|
|
91
106
|
const sourceCode = await readFileUtf8(entryPoint);
|
|
92
107
|
const bundleContent = await readFileBinary(outputFile);
|
|
108
|
+
// Get bundle size
|
|
109
|
+
const bundleSize = bundleContent.length;
|
|
110
|
+
// First, publish task metadata and get presigned URL for bundle upload
|
|
93
111
|
const data = {
|
|
94
112
|
...taskDescriptor,
|
|
95
113
|
taskName: descriptorName,
|
|
@@ -97,10 +115,21 @@ exports.publish = (0, task_1.createTask)(schema, boundaries, async function ({ d
|
|
|
97
115
|
description,
|
|
98
116
|
schemaDescriptor: JSON.stringify(schemaDescriptor),
|
|
99
117
|
sourceCode,
|
|
100
|
-
|
|
118
|
+
bundleSize
|
|
101
119
|
};
|
|
102
|
-
// Publish to hive api server
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
120
|
+
// Publish metadata to hive api server
|
|
121
|
+
console.log(`Publishing metadata and source code to ${profile.url}...`);
|
|
122
|
+
const publishResponse = await publishTask(data, profile);
|
|
123
|
+
// Upload bundle using the presigned URL
|
|
124
|
+
if (publishResponse.bundleUploadUrl) {
|
|
125
|
+
console.log('Uploading bundle...');
|
|
126
|
+
await uploadBundleWithPresignedUrl(publishResponse.bundleUploadUrl, bundleContent);
|
|
127
|
+
return {
|
|
128
|
+
descriptor: taskDescriptor,
|
|
129
|
+
publish: true
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
throw new Error('Bundle upload failed');
|
|
134
|
+
}
|
|
106
135
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgehive/forge-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "TypeScript CLI application",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"esbuild": "^0.25.0",
|
|
26
26
|
"handlebars": "^4.7.8",
|
|
27
27
|
"minimist": "^1.2.8",
|
|
28
|
+
"@forgehive/task": "0.1.5",
|
|
28
29
|
"@forgehive/record-tape": "0.0.2",
|
|
29
30
|
"@forgehive/runner": "0.1.5",
|
|
30
|
-
"@forgehive/task": "0.1.5",
|
|
31
31
|
"@forgehive/schema": "0.1.4"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
package/src/runner.ts
CHANGED
|
@@ -33,7 +33,7 @@ const runner = new Runner((data: ParsedArgs): CliParsedArguments => {
|
|
|
33
33
|
|
|
34
34
|
return {
|
|
35
35
|
taskName: String(_[0]),
|
|
36
|
-
action:
|
|
36
|
+
action: _[1] ?? '',
|
|
37
37
|
args: filteredObj
|
|
38
38
|
}
|
|
39
39
|
})
|
|
@@ -66,7 +66,7 @@ runner.setHandler(async (data: ParsedArgs): Promise<unknown> => {
|
|
|
66
66
|
const { taskName, action, args } = parsedArgs
|
|
67
67
|
|
|
68
68
|
console.log('========================================')
|
|
69
|
-
console.log(
|
|
69
|
+
console.log(`Running: ${taskName} ${action ? action : ''} ${JSON.stringify(args)}`)
|
|
70
70
|
console.log('========================================')
|
|
71
71
|
|
|
72
72
|
const task = runner.getTask(taskName)
|
package/src/tasks/conf/info.ts
CHANGED
|
@@ -22,19 +22,27 @@ export const info = createTask(
|
|
|
22
22
|
async function (_argv, { loadCurrentProfile, readFile }) {
|
|
23
23
|
const packageJsonPath = path.join(__dirname, '../../../package.json')
|
|
24
24
|
|
|
25
|
-
|
|
26
25
|
const packageJsonContent = await readFile(packageJsonPath)
|
|
27
26
|
const packageJson = JSON.parse(packageJsonContent)
|
|
28
27
|
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
return {
|
|
28
|
+
const info = {
|
|
32
29
|
version: packageJson.version,
|
|
33
|
-
profile: {
|
|
30
|
+
profile: {}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let profile
|
|
34
|
+
try {
|
|
35
|
+
profile = await loadCurrentProfile({})
|
|
36
|
+
|
|
37
|
+
info.profile = {
|
|
34
38
|
name: profile.name,
|
|
35
39
|
url: profile.url,
|
|
36
40
|
apiKey: profile.apiKey
|
|
37
41
|
}
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.log('No default profile set. Please run forge task:run auth:add to create a profile.')
|
|
38
44
|
}
|
|
45
|
+
|
|
46
|
+
return info
|
|
39
47
|
}
|
|
40
48
|
)
|
|
@@ -37,17 +37,34 @@ const boundaries = {
|
|
|
37
37
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
38
|
publishTask: async (data: any, profile: Profile): Promise<any> => {
|
|
39
39
|
const publishUrl = `${profile.url}/api/tasks/publish`
|
|
40
|
-
|
|
41
|
-
console.log(`Publishing task to ${publishUrl}...`)
|
|
42
40
|
const authToken = `${profile.apiKey}:${profile.apiSecret}`
|
|
43
|
-
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
const response = await axios.post(publishUrl, data, {
|
|
44
|
+
headers: {
|
|
45
|
+
Authorization: `Bearer ${authToken}`,
|
|
46
|
+
'Content-Type': 'application/json'
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
return response.data
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
52
|
+
} catch (error: any) {
|
|
53
|
+
if (error.response?.data?.error.includes('Bundle size')) {
|
|
54
|
+
throw new Error('Bundle size exceeds the maximum allowed size of 25MB')
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
throw new Error('Failed to publish task source code and metadata')
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
61
|
+
uploadBundleWithPresignedUrl: async (presignedUrl: string, bundleContent: Buffer): Promise<any> => {
|
|
62
|
+
const response = await axios.put(presignedUrl, bundleContent, {
|
|
44
63
|
headers: {
|
|
45
|
-
|
|
46
|
-
'Content-Type': 'application/json'
|
|
64
|
+
'Content-Type': 'application/octet-stream'
|
|
47
65
|
}
|
|
48
66
|
})
|
|
49
|
-
|
|
50
|
-
return response.data
|
|
67
|
+
return response.status === 200
|
|
51
68
|
},
|
|
52
69
|
|
|
53
70
|
ensureBuildsFolder: async (): Promise<string> => {
|
|
@@ -74,7 +91,8 @@ export const publish = createTask(
|
|
|
74
91
|
readFileUtf8,
|
|
75
92
|
readFileBinary,
|
|
76
93
|
publishTask,
|
|
77
|
-
loadCurrentProfile
|
|
94
|
+
loadCurrentProfile,
|
|
95
|
+
uploadBundleWithPresignedUrl
|
|
78
96
|
}) {
|
|
79
97
|
const cwd = await getCwd()
|
|
80
98
|
const forgeJson = await loadConf({})
|
|
@@ -91,16 +109,14 @@ export const publish = createTask(
|
|
|
91
109
|
const buildsPath = await ensureBuildsFolder()
|
|
92
110
|
const outputFile = path.join(buildsPath, `${descriptorName}.js`)
|
|
93
111
|
|
|
94
|
-
console.log('entryPoint:', entryPoint)
|
|
95
|
-
console.log('buildsPath:', buildsPath)
|
|
96
|
-
console.log('outputFile:', outputFile)
|
|
97
|
-
|
|
98
112
|
// Bundle the task
|
|
99
113
|
await bundleCreate({
|
|
100
114
|
entryPoint,
|
|
101
115
|
outputFile
|
|
102
116
|
})
|
|
103
117
|
|
|
118
|
+
console.log('Bundle created...')
|
|
119
|
+
|
|
104
120
|
// Load the bundled task
|
|
105
121
|
const bundle = await bundleLoad({
|
|
106
122
|
bundlePath: outputFile
|
|
@@ -112,10 +128,14 @@ export const publish = createTask(
|
|
|
112
128
|
const schema = task.getSchema() || new Schema({})
|
|
113
129
|
const schemaDescriptor = schema.describe()
|
|
114
130
|
|
|
115
|
-
// Read the task file content
|
|
131
|
+
// Read the task file content
|
|
116
132
|
const sourceCode = await readFileUtf8(entryPoint)
|
|
117
133
|
const bundleContent = await readFileBinary(outputFile)
|
|
118
134
|
|
|
135
|
+
// Get bundle size
|
|
136
|
+
const bundleSize = bundleContent.length
|
|
137
|
+
|
|
138
|
+
// First, publish task metadata and get presigned URL for bundle upload
|
|
119
139
|
const data = {
|
|
120
140
|
...taskDescriptor,
|
|
121
141
|
taskName: descriptorName,
|
|
@@ -123,13 +143,27 @@ export const publish = createTask(
|
|
|
123
143
|
description,
|
|
124
144
|
schemaDescriptor: JSON.stringify(schemaDescriptor),
|
|
125
145
|
sourceCode,
|
|
126
|
-
|
|
146
|
+
bundleSize
|
|
127
147
|
}
|
|
128
148
|
|
|
129
|
-
// Publish to hive api server
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
149
|
+
// Publish metadata to hive api server
|
|
150
|
+
console.log(`Publishing metadata and source code to ${profile.url}...`)
|
|
151
|
+
const publishResponse = await publishTask(data, profile)
|
|
152
|
+
|
|
153
|
+
// Upload bundle using the presigned URL
|
|
154
|
+
if (publishResponse.bundleUploadUrl) {
|
|
155
|
+
console.log('Uploading bundle...')
|
|
156
|
+
await uploadBundleWithPresignedUrl(
|
|
157
|
+
publishResponse.bundleUploadUrl,
|
|
158
|
+
bundleContent
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
descriptor: taskDescriptor,
|
|
163
|
+
publish: true
|
|
164
|
+
}
|
|
165
|
+
} else {
|
|
166
|
+
throw new Error('Bundle upload failed')
|
|
167
|
+
}
|
|
134
168
|
}
|
|
135
169
|
)
|