@steambrew/ttc 1.0.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/Compiler.ts +245 -0
- package/Linter.ts +44 -0
- package/Logger.ts +49 -0
- package/Parameters.ts +72 -0
- package/VersionMon.ts +28 -0
- package/dist/index.js +389 -0
- package/index.ts +60 -0
- package/package.json +35 -0
- package/rollup.config.js +28 -0
- package/tsconfig.json +24 -0
package/Compiler.ts
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { OutputOptions, RollupOptions, rollup } from "rollup";
|
|
2
|
+
import json from '@rollup/plugin-json';
|
|
3
|
+
import commonjs from '@rollup/plugin-commonjs';
|
|
4
|
+
import replace from '@rollup/plugin-replace';
|
|
5
|
+
import typescript from '@rollup/plugin-typescript';
|
|
6
|
+
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
|
7
|
+
import terser from '@rollup/plugin-terser';
|
|
8
|
+
|
|
9
|
+
import chalk from 'chalk'
|
|
10
|
+
import { Logger } from "./Logger";
|
|
11
|
+
import fs from 'fs';
|
|
12
|
+
|
|
13
|
+
declare global {
|
|
14
|
+
interface Window {
|
|
15
|
+
PLUGIN_LIST: any
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
declare const pluginName: string, millennium_main: any, MILLENNIUM_BACKEND_IPC: any
|
|
20
|
+
|
|
21
|
+
export interface TranspilerProps {
|
|
22
|
+
bTersePlugin?: boolean,
|
|
23
|
+
strPluginInternalName: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const WrappedCallServerMethod = "const __call_server_method__ = (methodName, kwargs) => Millennium.callServerMethod(pluginName, methodName, kwargs)"
|
|
27
|
+
const WrappedCallable = "const __wrapped_callable__ = (route) => MILLENNIUM_API.callable(__call_server_method__, route)"
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @description Append the active plugin to the global plugin
|
|
31
|
+
* list and notify that the frontend Loaded.
|
|
32
|
+
*/
|
|
33
|
+
function ExecutePluginModule() {
|
|
34
|
+
// Assign the plugin on plugin list.
|
|
35
|
+
Object.assign(window.PLUGIN_LIST[pluginName], millennium_main)
|
|
36
|
+
// Run the rolled up plugins default exported function
|
|
37
|
+
millennium_main["default"]();
|
|
38
|
+
MILLENNIUM_BACKEND_IPC.postMessage(1, { pluginName: pluginName })
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @description Append the active plugin to the global plugin
|
|
43
|
+
* list and notify that the frontend Loaded.
|
|
44
|
+
*/
|
|
45
|
+
function ExecuteWebkitModule() {
|
|
46
|
+
// Assign the plugin on plugin list.
|
|
47
|
+
Object.assign(window.PLUGIN_LIST[pluginName], millennium_main)
|
|
48
|
+
// Run the rolled up plugins default exported function
|
|
49
|
+
millennium_main["default"]();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @description Simple bootstrap function that initializes PLUGIN_LIST
|
|
54
|
+
* for current plugin given that is doesnt exist.
|
|
55
|
+
*/
|
|
56
|
+
function InitializePlugins() {
|
|
57
|
+
/**
|
|
58
|
+
* This function is called n times depending on n plugin count,
|
|
59
|
+
* Create the plugin list if it wasn't already created
|
|
60
|
+
*/
|
|
61
|
+
!window.PLUGIN_LIST && (window.PLUGIN_LIST = {})
|
|
62
|
+
|
|
63
|
+
// initialize a container for the plugin
|
|
64
|
+
if (!window.PLUGIN_LIST[pluginName]) {
|
|
65
|
+
window.PLUGIN_LIST[pluginName] = {};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function InsertMillennium(props: TranspilerProps)
|
|
70
|
+
{
|
|
71
|
+
const ContructFunctions = (parts: any) => { return parts.join('\n'); }
|
|
72
|
+
|
|
73
|
+
const generateBundle = (_: unknown, bundle: any) => {
|
|
74
|
+
|
|
75
|
+
for (const fileName in bundle)
|
|
76
|
+
{
|
|
77
|
+
if (bundle[fileName].type != 'chunk') {
|
|
78
|
+
continue
|
|
79
|
+
}
|
|
80
|
+
Logger.Info("Injecting Millennium shims into module... " + chalk.green.bold("okay"))
|
|
81
|
+
|
|
82
|
+
bundle[fileName].code = ContructFunctions([
|
|
83
|
+
`const pluginName = "${props.strPluginInternalName}";`,
|
|
84
|
+
// insert the bootstrap function and call it
|
|
85
|
+
InitializePlugins.toString(), InitializePlugins.name + "()",
|
|
86
|
+
WrappedCallServerMethod,
|
|
87
|
+
WrappedCallable,
|
|
88
|
+
bundle[fileName].code,
|
|
89
|
+
ExecutePluginModule.toString(), ExecutePluginModule.name + "()"
|
|
90
|
+
])
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
name: 'add-plugin-main', generateBundle
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function InsertWebkitMillennium(props: TranspilerProps)
|
|
100
|
+
{
|
|
101
|
+
const ContructFunctions = (parts: any) => { return parts.join('\n'); }
|
|
102
|
+
|
|
103
|
+
const generateBundle = (_: unknown, bundle: any) => {
|
|
104
|
+
|
|
105
|
+
for (const fileName in bundle)
|
|
106
|
+
{
|
|
107
|
+
if (bundle[fileName].type != 'chunk') {
|
|
108
|
+
continue
|
|
109
|
+
}
|
|
110
|
+
Logger.Info("Injecting Millennium shims into webkit module... " + chalk.green.bold("okay"))
|
|
111
|
+
|
|
112
|
+
bundle[fileName].code = ContructFunctions([
|
|
113
|
+
// define the plugin name at the top of the bundle, so it can be used in wrapped functions
|
|
114
|
+
`const pluginName = "${props.strPluginInternalName}";`,
|
|
115
|
+
// insert the bootstrap function and call it
|
|
116
|
+
InitializePlugins.toString(), InitializePlugins.name + "()",
|
|
117
|
+
// TODO
|
|
118
|
+
WrappedCallServerMethod, WrappedCallable, bundle[fileName].code,
|
|
119
|
+
ExecuteWebkitModule.toString(), ExecuteWebkitModule.name + "()"
|
|
120
|
+
])
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
name: 'add-plugin-main', generateBundle
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function GetPluginComponents(props: TranspilerProps) {
|
|
130
|
+
const pluginList = [
|
|
131
|
+
/**
|
|
132
|
+
* @brief resolve millennium, edit the exported bundle to work with millennium
|
|
133
|
+
*/
|
|
134
|
+
InsertMillennium(props),
|
|
135
|
+
typescript(), nodeResolve(), commonjs(), json(),
|
|
136
|
+
replace({
|
|
137
|
+
preventAssignment: true,
|
|
138
|
+
'process.env.NODE_ENV': JSON.stringify('production'),
|
|
139
|
+
// replace callServerMethod with wrapped replacement function.
|
|
140
|
+
'Millennium.callServerMethod': `__call_server_method__`,
|
|
141
|
+
'client.callable': `__wrapped_callable__`,
|
|
142
|
+
delimiters: ['', ''],
|
|
143
|
+
'client.pluginSelf': 'window.PLUGIN_LIST[pluginName]',
|
|
144
|
+
'client.Millennium.exposeObj(': 'client.Millennium.exposeObj(exports, '
|
|
145
|
+
}),
|
|
146
|
+
]
|
|
147
|
+
|
|
148
|
+
if (props.bTersePlugin) {
|
|
149
|
+
pluginList.push(terser())
|
|
150
|
+
}
|
|
151
|
+
return pluginList
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function GetWebkitPluginComponents(props: TranspilerProps) {
|
|
155
|
+
const pluginList = [
|
|
156
|
+
InsertWebkitMillennium(props), typescript(), nodeResolve(), commonjs(), json(),
|
|
157
|
+
replace({
|
|
158
|
+
preventAssignment: true,
|
|
159
|
+
// replace callServerMethod with wrapped replacement function.
|
|
160
|
+
'Millennium.callServerMethod': `__call_server_method__`,
|
|
161
|
+
'client.callable': `__wrapped_callable__`,
|
|
162
|
+
delimiters: ['', ''],
|
|
163
|
+
}),
|
|
164
|
+
]
|
|
165
|
+
|
|
166
|
+
if (props.bTersePlugin) {
|
|
167
|
+
pluginList.push(terser())
|
|
168
|
+
}
|
|
169
|
+
return pluginList
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const GetFrontEndDirectory = () => {
|
|
173
|
+
const pluginJsonPath = './plugin.json';
|
|
174
|
+
|
|
175
|
+
try {
|
|
176
|
+
const pluginJson = JSON.parse(fs.readFileSync(pluginJsonPath, 'utf8'));
|
|
177
|
+
const frontendDirectory = pluginJson?.frontend;
|
|
178
|
+
|
|
179
|
+
return frontendDirectory ? frontendDirectory : "frontend";
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
return "frontend";
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export const TranspilerPluginComponent = async (props: TranspilerProps) => {
|
|
187
|
+
|
|
188
|
+
const frontendRollupConfig: RollupOptions = {
|
|
189
|
+
input: `./${GetFrontEndDirectory()}/index.tsx`,
|
|
190
|
+
plugins: GetPluginComponents(props),
|
|
191
|
+
context: 'window',
|
|
192
|
+
external: ['react', 'react-dom', '@steambrew/client'],
|
|
193
|
+
output: {
|
|
194
|
+
name: "millennium_main",
|
|
195
|
+
file: ".millennium/Dist/index.js",
|
|
196
|
+
globals: {
|
|
197
|
+
react: "window.SP_REACT",
|
|
198
|
+
"react-dom": "window.SP_REACTDOM",
|
|
199
|
+
"@steambrew/client": "window.MILLENNIUM_API"
|
|
200
|
+
},
|
|
201
|
+
exports: 'named',
|
|
202
|
+
format: 'iife'
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const webkitRollupConfig: RollupOptions = {
|
|
207
|
+
input: `./webkit/index.ts`,
|
|
208
|
+
plugins: GetWebkitPluginComponents(props),
|
|
209
|
+
context: 'window',
|
|
210
|
+
external: ['@steambrew/client'],
|
|
211
|
+
output: {
|
|
212
|
+
name: "millennium_main",
|
|
213
|
+
file: ".millennium/Dist/webkit.js",
|
|
214
|
+
exports: 'named',
|
|
215
|
+
format: 'iife',
|
|
216
|
+
globals: {
|
|
217
|
+
"@steambrew/client": "window.MILLENNIUM_API"
|
|
218
|
+
},
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
Logger.Info("Starting build; this may take a few moments...")
|
|
223
|
+
// Load the Rollup configuration file
|
|
224
|
+
try {
|
|
225
|
+
const bundle = await rollup(frontendRollupConfig);
|
|
226
|
+
const outputOptions = frontendRollupConfig.output as OutputOptions;
|
|
227
|
+
|
|
228
|
+
await bundle.write(outputOptions);
|
|
229
|
+
|
|
230
|
+
// check if the webkit file exists
|
|
231
|
+
if (fs.existsSync(`./webkit/index.ts`)) {
|
|
232
|
+
Logger.Info("Compiling webkit module...")
|
|
233
|
+
|
|
234
|
+
const bundle1 = await rollup(webkitRollupConfig);
|
|
235
|
+
const outputOptions1 = webkitRollupConfig.output as OutputOptions;
|
|
236
|
+
|
|
237
|
+
await bundle1.write(outputOptions1);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
Logger.Info('Build succeeded!', Number((performance.now() - global.PerfStartTime).toFixed(3)), 'ms elapsed.')
|
|
241
|
+
}
|
|
242
|
+
catch (exception) {
|
|
243
|
+
Logger.Error('Build failed!', exception)
|
|
244
|
+
}
|
|
245
|
+
}
|
package/Linter.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import chalk from 'chalk'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import { existsSync, readFile } from 'fs'
|
|
4
|
+
|
|
5
|
+
export const ValidatePlugin = (target: string): Promise<any> => {
|
|
6
|
+
|
|
7
|
+
return new Promise<any>((resolve, reject) => {
|
|
8
|
+
if (!existsSync(target)) {
|
|
9
|
+
console.error(chalk.red.bold(`\n[-] --target [${target}] `) + chalk.red("is not a valid system path"))
|
|
10
|
+
reject()
|
|
11
|
+
return
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const pluginModule = path.join(target, "plugin.json")
|
|
15
|
+
|
|
16
|
+
if (!existsSync(pluginModule)) {
|
|
17
|
+
console.error(chalk.red.bold(`\n[-] --target [${target}] `) + chalk.red("is not a valid plugin (missing plugin.json)"))
|
|
18
|
+
reject()
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
readFile(pluginModule, 'utf8', (err, data) => {
|
|
23
|
+
if (err) {
|
|
24
|
+
console.error(chalk.red.bold(`\n[-] couldn't read plugin.json from [${pluginModule}]`))
|
|
25
|
+
reject()
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
if (!("name" in JSON.parse(data))) {
|
|
31
|
+
console.error(chalk.red.bold(`\n[-] target plugin doesn't contain "name" in plugin.json [${pluginModule}]`))
|
|
32
|
+
reject()
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
resolve(JSON.parse(data))
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch (parseError) {
|
|
39
|
+
console.error(chalk.red.bold(`\n[-] couldn't parse JSON in plugin.json from [${pluginModule}]`))
|
|
40
|
+
reject()
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
})
|
|
44
|
+
}
|
package/Logger.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import chalk from 'chalk'
|
|
2
|
+
|
|
3
|
+
const Logger = {
|
|
4
|
+
|
|
5
|
+
Info: (...LogMessage: any) => {
|
|
6
|
+
console.log(chalk.magenta.bold("[+]"), ...LogMessage)
|
|
7
|
+
},
|
|
8
|
+
|
|
9
|
+
Warn: (...LogMessage: any) => {
|
|
10
|
+
console.log(chalk.yellow.bold("[*]"), ...LogMessage)
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
Error: (...LogMessage: any) => {
|
|
14
|
+
console.log(chalk.red.bold("[-]"), ...LogMessage)
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
Tree: (strTitle: string, LogObject: any) => {
|
|
18
|
+
|
|
19
|
+
console.log(chalk.magenta.bold("[┬]"), strTitle);
|
|
20
|
+
|
|
21
|
+
const isLocalPath = (strTestPath: string): boolean => {
|
|
22
|
+
// Regular expression to match common file path patterns
|
|
23
|
+
const filePathRegex = /^(\/|\.\/|\.\.\/|\w:\/)?([\w-.]+\/)*[\w-.]+\.\w+$/;
|
|
24
|
+
return filePathRegex.test(strTestPath);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const entries = Object.entries(LogObject);
|
|
28
|
+
const totalEntries = entries.length;
|
|
29
|
+
|
|
30
|
+
for (const [index, [key, value]] of entries.entries()) {
|
|
31
|
+
|
|
32
|
+
const connector = index === totalEntries - 1 ? "└" : "├"
|
|
33
|
+
let color = chalk.white
|
|
34
|
+
|
|
35
|
+
switch (typeof value) {
|
|
36
|
+
case typeof String(): {
|
|
37
|
+
color = isLocalPath(value as string) ? chalk.blueBright : chalk.white;
|
|
38
|
+
break
|
|
39
|
+
}
|
|
40
|
+
case typeof Boolean(): color = chalk.green; break
|
|
41
|
+
case typeof Number(): color = chalk.yellow; break
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
console.log(chalk.magenta.bold(` ${connector}──${key}:`), color(value))
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export { Logger }
|
package/Parameters.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import chalk from 'chalk'
|
|
2
|
+
import { Logger } from "./Logger"
|
|
3
|
+
|
|
4
|
+
/***
|
|
5
|
+
* @brief print the parameter list to the stdout
|
|
6
|
+
*/
|
|
7
|
+
export const PrintParamHelp = () => {
|
|
8
|
+
|
|
9
|
+
console.log(
|
|
10
|
+
"millennium-ttc parameter list:" +
|
|
11
|
+
"\n\t" + chalk.magenta("--help") + ": display parameter list" +
|
|
12
|
+
"\n\t" + chalk.bold.red("--build") + ": " + chalk.bold.red("(required)") + ": build type [dev, prod] (prod minifies code)" +
|
|
13
|
+
"\n\t" + chalk.magenta("--target") + ": path to plugin, default to cwd"
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export enum BuildType {
|
|
18
|
+
DevBuild, ProdBuild
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ParameterProps {
|
|
22
|
+
type: BuildType,
|
|
23
|
+
targetPlugin: string // path
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const ValidateParameters = (args: Array<string>): ParameterProps => {
|
|
27
|
+
|
|
28
|
+
let typeProp: BuildType = BuildType.DevBuild, targetProp: string = process.cwd()
|
|
29
|
+
|
|
30
|
+
if (args.includes("--help")) {
|
|
31
|
+
PrintParamHelp()
|
|
32
|
+
process.exit();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// startup args are invalid
|
|
36
|
+
if (!args.includes("--build")) {
|
|
37
|
+
Logger.Error("Received invalid arguments...");
|
|
38
|
+
PrintParamHelp();
|
|
39
|
+
process.exit();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
for (let i = 0; i < args.length; i++)
|
|
43
|
+
{
|
|
44
|
+
if (args[i] === "--build")
|
|
45
|
+
{
|
|
46
|
+
const BuildMode: string = args[i + 1]
|
|
47
|
+
|
|
48
|
+
switch (BuildMode) {
|
|
49
|
+
case "dev": typeProp = BuildType.DevBuild; break
|
|
50
|
+
case "prod": typeProp = BuildType.ProdBuild; break
|
|
51
|
+
default: {
|
|
52
|
+
Logger.Error('--build parameter must be preceded by build type [dev, prod]');
|
|
53
|
+
process.exit();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (args[i] == "--target") {
|
|
59
|
+
if (args[i + 1] === undefined) {
|
|
60
|
+
Logger.Error('--target parameter must be preceded by system path');
|
|
61
|
+
process.exit();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
targetProp = args[i + 1]
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
type: typeProp,
|
|
70
|
+
targetPlugin: targetProp
|
|
71
|
+
}
|
|
72
|
+
}
|
package/VersionMon.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import { readFile } from 'fs/promises';
|
|
4
|
+
import { dirname } from 'path';
|
|
5
|
+
import { Logger } from './Logger';
|
|
6
|
+
|
|
7
|
+
export const CheckForUpdates = async (): Promise<boolean> => {
|
|
8
|
+
return new Promise<boolean>(async (resolve) => {
|
|
9
|
+
const packageJsonPath = path.resolve(dirname(fileURLToPath(import.meta.url)), '../../package.json');
|
|
10
|
+
const packageJson = JSON.parse(await readFile(packageJsonPath, 'utf8'));
|
|
11
|
+
|
|
12
|
+
fetch("https://registry.npmjs.org/millennium-lib").then(response => response.json()).then(json => {
|
|
13
|
+
|
|
14
|
+
if (json?.["dist-tags"]?.latest != packageJson.version) {
|
|
15
|
+
|
|
16
|
+
Logger.Tree(`millennium-lib@${packageJson.version} requires update to ${json?.["dist-tags"]?.latest}`, {
|
|
17
|
+
cmd: "run `npm i millennium-lib` to get latest updates!"
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
resolve(true)
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
Logger.Info(`millennium-lib@${packageJson.version} is up-to-date!`)
|
|
24
|
+
resolve(false)
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import path, { dirname } from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { readFile } from 'fs/promises';
|
|
6
|
+
import fs, { existsSync, readFile as readFile$1 } from 'fs';
|
|
7
|
+
import { rollup } from 'rollup';
|
|
8
|
+
import json from '@rollup/plugin-json';
|
|
9
|
+
import commonjs from '@rollup/plugin-commonjs';
|
|
10
|
+
import replace from '@rollup/plugin-replace';
|
|
11
|
+
import typescript from '@rollup/plugin-typescript';
|
|
12
|
+
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
|
13
|
+
import terser from '@rollup/plugin-terser';
|
|
14
|
+
import { performance as performance$1 } from 'perf_hooks';
|
|
15
|
+
|
|
16
|
+
const Logger = {
|
|
17
|
+
Info: (...LogMessage) => {
|
|
18
|
+
console.log(chalk.magenta.bold("[+]"), ...LogMessage);
|
|
19
|
+
},
|
|
20
|
+
Warn: (...LogMessage) => {
|
|
21
|
+
console.log(chalk.yellow.bold("[*]"), ...LogMessage);
|
|
22
|
+
},
|
|
23
|
+
Error: (...LogMessage) => {
|
|
24
|
+
console.log(chalk.red.bold("[-]"), ...LogMessage);
|
|
25
|
+
},
|
|
26
|
+
Tree: (strTitle, LogObject) => {
|
|
27
|
+
console.log(chalk.magenta.bold("[┬]"), strTitle);
|
|
28
|
+
const isLocalPath = (strTestPath) => {
|
|
29
|
+
// Regular expression to match common file path patterns
|
|
30
|
+
const filePathRegex = /^(\/|\.\/|\.\.\/|\w:\/)?([\w-.]+\/)*[\w-.]+\.\w+$/;
|
|
31
|
+
return filePathRegex.test(strTestPath);
|
|
32
|
+
};
|
|
33
|
+
const entries = Object.entries(LogObject);
|
|
34
|
+
const totalEntries = entries.length;
|
|
35
|
+
for (const [index, [key, value]] of entries.entries()) {
|
|
36
|
+
const connector = index === totalEntries - 1 ? "└" : "├";
|
|
37
|
+
let color = chalk.white;
|
|
38
|
+
switch (typeof value) {
|
|
39
|
+
case typeof String(): {
|
|
40
|
+
color = isLocalPath(value) ? chalk.blueBright : chalk.white;
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
case typeof Boolean():
|
|
44
|
+
color = chalk.green;
|
|
45
|
+
break;
|
|
46
|
+
case typeof Number():
|
|
47
|
+
color = chalk.yellow;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
console.log(chalk.magenta.bold(` ${connector}──${key}:`), color(value));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/***
|
|
56
|
+
* @brief print the parameter list to the stdout
|
|
57
|
+
*/
|
|
58
|
+
const PrintParamHelp = () => {
|
|
59
|
+
console.log("millennium-ttc parameter list:" +
|
|
60
|
+
"\n\t" + chalk.magenta("--help") + ": display parameter list" +
|
|
61
|
+
"\n\t" + chalk.bold.red("--build") + ": " + chalk.bold.red("(required)") + ": build type [dev, prod] (prod minifies code)" +
|
|
62
|
+
"\n\t" + chalk.magenta("--target") + ": path to plugin, default to cwd");
|
|
63
|
+
};
|
|
64
|
+
var BuildType;
|
|
65
|
+
(function (BuildType) {
|
|
66
|
+
BuildType[BuildType["DevBuild"] = 0] = "DevBuild";
|
|
67
|
+
BuildType[BuildType["ProdBuild"] = 1] = "ProdBuild";
|
|
68
|
+
})(BuildType || (BuildType = {}));
|
|
69
|
+
const ValidateParameters = (args) => {
|
|
70
|
+
let typeProp = BuildType.DevBuild, targetProp = process.cwd();
|
|
71
|
+
if (args.includes("--help")) {
|
|
72
|
+
PrintParamHelp();
|
|
73
|
+
process.exit();
|
|
74
|
+
}
|
|
75
|
+
// startup args are invalid
|
|
76
|
+
if (!args.includes("--build")) {
|
|
77
|
+
Logger.Error("Received invalid arguments...");
|
|
78
|
+
PrintParamHelp();
|
|
79
|
+
process.exit();
|
|
80
|
+
}
|
|
81
|
+
for (let i = 0; i < args.length; i++) {
|
|
82
|
+
if (args[i] === "--build") {
|
|
83
|
+
const BuildMode = args[i + 1];
|
|
84
|
+
switch (BuildMode) {
|
|
85
|
+
case "dev":
|
|
86
|
+
typeProp = BuildType.DevBuild;
|
|
87
|
+
break;
|
|
88
|
+
case "prod":
|
|
89
|
+
typeProp = BuildType.ProdBuild;
|
|
90
|
+
break;
|
|
91
|
+
default: {
|
|
92
|
+
Logger.Error('--build parameter must be preceded by build type [dev, prod]');
|
|
93
|
+
process.exit();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (args[i] == "--target") {
|
|
98
|
+
if (args[i + 1] === undefined) {
|
|
99
|
+
Logger.Error('--target parameter must be preceded by system path');
|
|
100
|
+
process.exit();
|
|
101
|
+
}
|
|
102
|
+
targetProp = args[i + 1];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
type: typeProp,
|
|
107
|
+
targetPlugin: targetProp
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const CheckForUpdates = async () => {
|
|
112
|
+
return new Promise(async (resolve) => {
|
|
113
|
+
const packageJsonPath = path.resolve(dirname(fileURLToPath(import.meta.url)), '../../package.json');
|
|
114
|
+
const packageJson = JSON.parse(await readFile(packageJsonPath, 'utf8'));
|
|
115
|
+
fetch("https://registry.npmjs.org/millennium-lib").then(response => response.json()).then(json => {
|
|
116
|
+
if (json?.["dist-tags"]?.latest != packageJson.version) {
|
|
117
|
+
Logger.Tree(`millennium-lib@${packageJson.version} requires update to ${json?.["dist-tags"]?.latest}`, {
|
|
118
|
+
cmd: "run `npm i millennium-lib` to get latest updates!"
|
|
119
|
+
});
|
|
120
|
+
resolve(true);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
Logger.Info(`millennium-lib@${packageJson.version} is up-to-date!`);
|
|
124
|
+
resolve(false);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const ValidatePlugin = (target) => {
|
|
131
|
+
return new Promise((resolve, reject) => {
|
|
132
|
+
if (!existsSync(target)) {
|
|
133
|
+
console.error(chalk.red.bold(`\n[-] --target [${target}] `) + chalk.red("is not a valid system path"));
|
|
134
|
+
reject();
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const pluginModule = path.join(target, "plugin.json");
|
|
138
|
+
if (!existsSync(pluginModule)) {
|
|
139
|
+
console.error(chalk.red.bold(`\n[-] --target [${target}] `) + chalk.red("is not a valid plugin (missing plugin.json)"));
|
|
140
|
+
reject();
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
readFile$1(pluginModule, 'utf8', (err, data) => {
|
|
144
|
+
if (err) {
|
|
145
|
+
console.error(chalk.red.bold(`\n[-] couldn't read plugin.json from [${pluginModule}]`));
|
|
146
|
+
reject();
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
if (!("name" in JSON.parse(data))) {
|
|
151
|
+
console.error(chalk.red.bold(`\n[-] target plugin doesn't contain "name" in plugin.json [${pluginModule}]`));
|
|
152
|
+
reject();
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
resolve(JSON.parse(data));
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch (parseError) {
|
|
159
|
+
console.error(chalk.red.bold(`\n[-] couldn't parse JSON in plugin.json from [${pluginModule}]`));
|
|
160
|
+
reject();
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const WrappedCallServerMethod = "const __call_server_method__ = (methodName, kwargs) => Millennium.callServerMethod(pluginName, methodName, kwargs)";
|
|
167
|
+
const WrappedCallable = "const __wrapped_callable__ = (route) => MILLENNIUM_API.callable(__call_server_method__, route)";
|
|
168
|
+
/**
|
|
169
|
+
* @description Append the active plugin to the global plugin
|
|
170
|
+
* list and notify that the frontend Loaded.
|
|
171
|
+
*/
|
|
172
|
+
function ExecutePluginModule() {
|
|
173
|
+
// Assign the plugin on plugin list.
|
|
174
|
+
Object.assign(window.PLUGIN_LIST[pluginName], millennium_main);
|
|
175
|
+
// Run the rolled up plugins default exported function
|
|
176
|
+
millennium_main["default"]();
|
|
177
|
+
MILLENNIUM_BACKEND_IPC.postMessage(1, { pluginName: pluginName });
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* @description Append the active plugin to the global plugin
|
|
181
|
+
* list and notify that the frontend Loaded.
|
|
182
|
+
*/
|
|
183
|
+
function ExecuteWebkitModule() {
|
|
184
|
+
// Assign the plugin on plugin list.
|
|
185
|
+
Object.assign(window.PLUGIN_LIST[pluginName], millennium_main);
|
|
186
|
+
// Run the rolled up plugins default exported function
|
|
187
|
+
millennium_main["default"]();
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* @description Simple bootstrap function that initializes PLUGIN_LIST
|
|
191
|
+
* for current plugin given that is doesnt exist.
|
|
192
|
+
*/
|
|
193
|
+
function InitializePlugins() {
|
|
194
|
+
/**
|
|
195
|
+
* This function is called n times depending on n plugin count,
|
|
196
|
+
* Create the plugin list if it wasn't already created
|
|
197
|
+
*/
|
|
198
|
+
!window.PLUGIN_LIST && (window.PLUGIN_LIST = {});
|
|
199
|
+
// initialize a container for the plugin
|
|
200
|
+
if (!window.PLUGIN_LIST[pluginName]) {
|
|
201
|
+
window.PLUGIN_LIST[pluginName] = {};
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
function InsertMillennium(props) {
|
|
205
|
+
const ContructFunctions = (parts) => { return parts.join('\n'); };
|
|
206
|
+
const generateBundle = (_, bundle) => {
|
|
207
|
+
for (const fileName in bundle) {
|
|
208
|
+
if (bundle[fileName].type != 'chunk') {
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
Logger.Info("Injecting Millennium shims into module... " + chalk.green.bold("okay"));
|
|
212
|
+
bundle[fileName].code = ContructFunctions([
|
|
213
|
+
`const pluginName = "${props.strPluginInternalName}";`,
|
|
214
|
+
// insert the bootstrap function and call it
|
|
215
|
+
InitializePlugins.toString(), InitializePlugins.name + "()",
|
|
216
|
+
WrappedCallServerMethod,
|
|
217
|
+
WrappedCallable,
|
|
218
|
+
bundle[fileName].code,
|
|
219
|
+
ExecutePluginModule.toString(), ExecutePluginModule.name + "()"
|
|
220
|
+
]);
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
return {
|
|
224
|
+
name: 'add-plugin-main', generateBundle
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
function InsertWebkitMillennium(props) {
|
|
228
|
+
const ContructFunctions = (parts) => { return parts.join('\n'); };
|
|
229
|
+
const generateBundle = (_, bundle) => {
|
|
230
|
+
for (const fileName in bundle) {
|
|
231
|
+
if (bundle[fileName].type != 'chunk') {
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
Logger.Info("Injecting Millennium shims into webkit module... " + chalk.green.bold("okay"));
|
|
235
|
+
bundle[fileName].code = ContructFunctions([
|
|
236
|
+
// define the plugin name at the top of the bundle, so it can be used in wrapped functions
|
|
237
|
+
`const pluginName = "${props.strPluginInternalName}";`,
|
|
238
|
+
// insert the bootstrap function and call it
|
|
239
|
+
InitializePlugins.toString(), InitializePlugins.name + "()",
|
|
240
|
+
// TODO
|
|
241
|
+
WrappedCallServerMethod, WrappedCallable, bundle[fileName].code,
|
|
242
|
+
ExecuteWebkitModule.toString(), ExecuteWebkitModule.name + "()"
|
|
243
|
+
]);
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
return {
|
|
247
|
+
name: 'add-plugin-main', generateBundle
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
function GetPluginComponents(props) {
|
|
251
|
+
const pluginList = [
|
|
252
|
+
/**
|
|
253
|
+
* @brief resolve millennium, edit the exported bundle to work with millennium
|
|
254
|
+
*/
|
|
255
|
+
InsertMillennium(props),
|
|
256
|
+
typescript(), nodeResolve(), commonjs(), json(),
|
|
257
|
+
replace({
|
|
258
|
+
preventAssignment: true,
|
|
259
|
+
'process.env.NODE_ENV': JSON.stringify('production'),
|
|
260
|
+
// replace callServerMethod with wrapped replacement function.
|
|
261
|
+
'Millennium.callServerMethod': `__call_server_method__`,
|
|
262
|
+
'client.callable': `__wrapped_callable__`,
|
|
263
|
+
delimiters: ['', ''],
|
|
264
|
+
'client.pluginSelf': 'window.PLUGIN_LIST[pluginName]',
|
|
265
|
+
'client.Millennium.exposeObj(': 'client.Millennium.exposeObj(exports, '
|
|
266
|
+
}),
|
|
267
|
+
];
|
|
268
|
+
if (props.bTersePlugin) {
|
|
269
|
+
pluginList.push(terser());
|
|
270
|
+
}
|
|
271
|
+
return pluginList;
|
|
272
|
+
}
|
|
273
|
+
function GetWebkitPluginComponents(props) {
|
|
274
|
+
const pluginList = [
|
|
275
|
+
InsertWebkitMillennium(props), typescript(), nodeResolve(), commonjs(), json(),
|
|
276
|
+
replace({
|
|
277
|
+
preventAssignment: true,
|
|
278
|
+
// replace callServerMethod with wrapped replacement function.
|
|
279
|
+
'Millennium.callServerMethod': `__call_server_method__`,
|
|
280
|
+
'client.callable': `__wrapped_callable__`,
|
|
281
|
+
delimiters: ['', ''],
|
|
282
|
+
}),
|
|
283
|
+
];
|
|
284
|
+
if (props.bTersePlugin) {
|
|
285
|
+
pluginList.push(terser());
|
|
286
|
+
}
|
|
287
|
+
return pluginList;
|
|
288
|
+
}
|
|
289
|
+
const GetFrontEndDirectory = () => {
|
|
290
|
+
const pluginJsonPath = './plugin.json';
|
|
291
|
+
try {
|
|
292
|
+
const pluginJson = JSON.parse(fs.readFileSync(pluginJsonPath, 'utf8'));
|
|
293
|
+
const frontendDirectory = pluginJson?.frontend;
|
|
294
|
+
return frontendDirectory ? frontendDirectory : "frontend";
|
|
295
|
+
}
|
|
296
|
+
catch (error) {
|
|
297
|
+
return "frontend";
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
const TranspilerPluginComponent = async (props) => {
|
|
301
|
+
const frontendRollupConfig = {
|
|
302
|
+
input: `./${GetFrontEndDirectory()}/index.tsx`,
|
|
303
|
+
plugins: GetPluginComponents(props),
|
|
304
|
+
context: 'window',
|
|
305
|
+
external: ['react', 'react-dom', '@steambrew/client'],
|
|
306
|
+
output: {
|
|
307
|
+
name: "millennium_main",
|
|
308
|
+
file: ".millennium/Dist/index.js",
|
|
309
|
+
globals: {
|
|
310
|
+
react: "window.SP_REACT",
|
|
311
|
+
"react-dom": "window.SP_REACTDOM",
|
|
312
|
+
"@steambrew/client": "window.MILLENNIUM_API"
|
|
313
|
+
},
|
|
314
|
+
exports: 'named',
|
|
315
|
+
format: 'iife'
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
const webkitRollupConfig = {
|
|
319
|
+
input: `./webkit/index.ts`,
|
|
320
|
+
plugins: GetWebkitPluginComponents(props),
|
|
321
|
+
context: 'window',
|
|
322
|
+
external: ['@steambrew/client'],
|
|
323
|
+
output: {
|
|
324
|
+
name: "millennium_main",
|
|
325
|
+
file: ".millennium/Dist/webkit.js",
|
|
326
|
+
exports: 'named',
|
|
327
|
+
format: 'iife',
|
|
328
|
+
globals: {
|
|
329
|
+
"@steambrew/client": "window.MILLENNIUM_API"
|
|
330
|
+
},
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
Logger.Info("Starting build; this may take a few moments...");
|
|
334
|
+
// Load the Rollup configuration file
|
|
335
|
+
try {
|
|
336
|
+
const bundle = await rollup(frontendRollupConfig);
|
|
337
|
+
const outputOptions = frontendRollupConfig.output;
|
|
338
|
+
await bundle.write(outputOptions);
|
|
339
|
+
// check if the webkit file exists
|
|
340
|
+
if (fs.existsSync(`./webkit/index.ts`)) {
|
|
341
|
+
Logger.Info("Compiling webkit module...");
|
|
342
|
+
const bundle1 = await rollup(webkitRollupConfig);
|
|
343
|
+
const outputOptions1 = webkitRollupConfig.output;
|
|
344
|
+
await bundle1.write(outputOptions1);
|
|
345
|
+
}
|
|
346
|
+
Logger.Info('Build succeeded!', Number((performance.now() - global.PerfStartTime).toFixed(3)), 'ms elapsed.');
|
|
347
|
+
}
|
|
348
|
+
catch (exception) {
|
|
349
|
+
Logger.Error('Build failed!', exception);
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* this component serves as:
|
|
355
|
+
* - typescript transpiler
|
|
356
|
+
* - rollup configurator
|
|
357
|
+
*/
|
|
358
|
+
const CheckModuleUpdates = async () => {
|
|
359
|
+
return await CheckForUpdates();
|
|
360
|
+
};
|
|
361
|
+
const StartCompilerModule = () => {
|
|
362
|
+
const parameters = ValidateParameters(process.argv.slice(2));
|
|
363
|
+
const bTersePlugin = parameters.type == BuildType.ProdBuild;
|
|
364
|
+
Logger.Tree("Transpiler config: ", {
|
|
365
|
+
target: parameters.targetPlugin,
|
|
366
|
+
build: BuildType[parameters.type],
|
|
367
|
+
minify: bTersePlugin
|
|
368
|
+
});
|
|
369
|
+
ValidatePlugin(parameters.targetPlugin).then((json) => {
|
|
370
|
+
const props = {
|
|
371
|
+
bTersePlugin: bTersePlugin,
|
|
372
|
+
strPluginInternalName: json?.name
|
|
373
|
+
};
|
|
374
|
+
TranspilerPluginComponent(props);
|
|
375
|
+
})
|
|
376
|
+
/**
|
|
377
|
+
* plugin is invalid, we close the proccess as it has already been handled
|
|
378
|
+
*/
|
|
379
|
+
.catch(() => {
|
|
380
|
+
process.exit();
|
|
381
|
+
});
|
|
382
|
+
};
|
|
383
|
+
const Initialize = () => {
|
|
384
|
+
global.PerfStartTime = performance$1.now();
|
|
385
|
+
CheckModuleUpdates().then((needsUpdate) => {
|
|
386
|
+
needsUpdate ? process.exit() : StartCompilerModule();
|
|
387
|
+
});
|
|
388
|
+
};
|
|
389
|
+
Initialize();
|
package/index.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* this component serves as:
|
|
5
|
+
* - typescript transpiler
|
|
6
|
+
* - rollup configurator
|
|
7
|
+
*/
|
|
8
|
+
import { BuildType, ValidateParameters } from "./Parameters"
|
|
9
|
+
import { CheckForUpdates } from "./VersionMon"
|
|
10
|
+
import { ValidatePlugin } from './Linter'
|
|
11
|
+
import { TranspilerPluginComponent, TranspilerProps } from './Compiler'
|
|
12
|
+
import { performance } from 'perf_hooks';
|
|
13
|
+
import { Logger } from './Logger'
|
|
14
|
+
|
|
15
|
+
declare global {
|
|
16
|
+
var PerfStartTime: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const CheckModuleUpdates = async () => {
|
|
20
|
+
return await CheckForUpdates()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const StartCompilerModule = () => {
|
|
24
|
+
|
|
25
|
+
const parameters = ValidateParameters( process.argv.slice(2) );
|
|
26
|
+
const bTersePlugin = parameters.type == BuildType.ProdBuild
|
|
27
|
+
|
|
28
|
+
Logger.Tree("Transpiler config: ", {
|
|
29
|
+
target: parameters.targetPlugin,
|
|
30
|
+
build: BuildType[parameters.type],
|
|
31
|
+
minify: bTersePlugin
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
ValidatePlugin(parameters.targetPlugin).then((json: any) => {
|
|
35
|
+
|
|
36
|
+
const props: TranspilerProps = {
|
|
37
|
+
bTersePlugin: bTersePlugin,
|
|
38
|
+
strPluginInternalName: json?.name
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
TranspilerPluginComponent(props)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* plugin is invalid, we close the proccess as it has already been handled
|
|
46
|
+
*/
|
|
47
|
+
.catch(() => {
|
|
48
|
+
process.exit()
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const Initialize = () => {
|
|
53
|
+
global.PerfStartTime = performance.now();
|
|
54
|
+
|
|
55
|
+
CheckModuleUpdates().then((needsUpdate: boolean) => {
|
|
56
|
+
needsUpdate ? process.exit() : StartCompilerModule()
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
Initialize();
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@steambrew/ttc",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"millennium-ttc": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "rollup -c"
|
|
12
|
+
},
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [],
|
|
17
|
+
"author": "",
|
|
18
|
+
"license": "ISC",
|
|
19
|
+
"description": "A tiny typescript compiler for Millennium plugins.",
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@rollup/plugin-commonjs": "^28.0.1",
|
|
22
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
23
|
+
"@rollup/plugin-node-resolve": "^15.3.0",
|
|
24
|
+
"@rollup/plugin-replace": "^6.0.1",
|
|
25
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
26
|
+
"@rollup/plugin-typescript": "^12.1.1",
|
|
27
|
+
"chalk": "^5.3.0",
|
|
28
|
+
"fs": "^0.0.1-security",
|
|
29
|
+
"rollup": "^4.27.4",
|
|
30
|
+
"tslib": "^2.8.1"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^22.10.1"
|
|
34
|
+
}
|
|
35
|
+
}
|
package/rollup.config.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import commonjs from '@rollup/plugin-commonjs';
|
|
2
|
+
import typescript from '@rollup/plugin-typescript';
|
|
3
|
+
import json from '@rollup/plugin-json';
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
input: 'index.ts',
|
|
7
|
+
context: 'window',
|
|
8
|
+
output: {
|
|
9
|
+
file: 'dist/index.js'
|
|
10
|
+
},
|
|
11
|
+
plugins: [commonjs(), typescript(), json()],
|
|
12
|
+
external: [
|
|
13
|
+
"chalk",
|
|
14
|
+
"path",
|
|
15
|
+
"url",
|
|
16
|
+
"fs/promises",
|
|
17
|
+
"fs",
|
|
18
|
+
"rollup",
|
|
19
|
+
"@rollup/plugin-json",
|
|
20
|
+
"@rollup/plugin-commonjs",
|
|
21
|
+
"@rollup/plugin-replace",
|
|
22
|
+
"@rollup/plugin-typescript",
|
|
23
|
+
"@rollup/plugin-node-resolve",
|
|
24
|
+
"rollup-plugin-import-css",
|
|
25
|
+
"@rollup/plugin-terser",
|
|
26
|
+
"perf_hooks",
|
|
27
|
+
]
|
|
28
|
+
};
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"outDir": "dist",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"target": "ES2020",
|
|
6
|
+
"jsx": "react",
|
|
7
|
+
"jsxFactory": "window.SP_REACT.createElement",
|
|
8
|
+
"declaration": false,
|
|
9
|
+
"moduleResolution": "node",
|
|
10
|
+
"noUnusedLocals": true,
|
|
11
|
+
"noUnusedParameters": true,
|
|
12
|
+
"esModuleInterop": true,
|
|
13
|
+
"noImplicitReturns": true,
|
|
14
|
+
"noImplicitThis": true,
|
|
15
|
+
"noImplicitAny": true,
|
|
16
|
+
"strict": true,
|
|
17
|
+
"ignoreDeprecations": "5.0",
|
|
18
|
+
"allowSyntheticDefaultImports": true,
|
|
19
|
+
"skipLibCheck": true
|
|
20
|
+
},
|
|
21
|
+
"include": ["./"],
|
|
22
|
+
"exclude": ["node_modules"]
|
|
23
|
+
}
|
|
24
|
+
|