@steambrew/ttc 1.2.2 → 1.4.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/.prettierrc ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "useTabs": true,
3
+ "tabWidth": 4,
4
+ "semi": true,
5
+ "singleQuote": true,
6
+ "trailingComma": "all",
7
+ "jsxSingleQuote": false,
8
+ "printWidth": 175
9
+ }
package/Compiler.ts CHANGED
@@ -1,291 +1,226 @@
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 resolve from "@rollup/plugin-node-resolve";
7
- import terser from "@rollup/plugin-terser";
8
- import babel from "@rollup/plugin-babel";
9
-
10
- import chalk from "chalk";
11
- import { Logger } from "./Logger";
12
- import fs from "fs";
13
-
14
- import injectProcessEnv from "rollup-plugin-inject-process-env";
15
- import dotenv from "dotenv";
16
-
17
- const envConfig = dotenv.config().parsed || {};
18
-
19
- if (envConfig) {
20
- Logger.Info("Injecting environment variables...");
21
- }
22
-
23
- const envVars = Object.keys(envConfig).reduce((acc: any, key) => {
24
- acc[key] = envConfig[key];
25
- return acc;
26
- }, {});
27
-
28
- declare global {
29
- interface Window {
30
- PLUGIN_LIST: any;
31
- }
32
- }
33
-
34
- declare const pluginName: string,
35
- millennium_main: any,
36
- MILLENNIUM_BACKEND_IPC: any;
37
-
38
- export interface TranspilerProps {
39
- bTersePlugin?: boolean;
40
- strPluginInternalName: string;
41
- }
42
-
43
- const WrappedCallServerMethod =
44
- "const __call_server_method__ = (methodName, kwargs) => Millennium.callServerMethod(pluginName, methodName, kwargs)";
45
- const WrappedCallable =
46
- "const __wrapped_callable__ = (route) => MILLENNIUM_API.callable(__call_server_method__, route)";
47
-
48
- /**
49
- * @description Append the active plugin to the global plugin
50
- * list and notify that the frontend Loaded.
51
- */
52
- function ExecutePluginModule() {
53
- // Assign the plugin on plugin list.
54
- Object.assign(window.PLUGIN_LIST[pluginName], millennium_main);
55
- // Run the rolled up plugins default exported function
56
- millennium_main["default"]();
57
- MILLENNIUM_BACKEND_IPC.postMessage(1, { pluginName: pluginName });
58
- }
59
-
60
- /**
61
- * @description Append the active plugin to the global plugin
62
- * list and notify that the frontend Loaded.
63
- */
64
- function ExecuteWebkitModule() {
65
- // Assign the plugin on plugin list.
66
- Object.assign(window.PLUGIN_LIST[pluginName], millennium_main);
67
- // Run the rolled up plugins default exported function
68
- millennium_main["default"]();
69
- }
70
-
71
- /**
72
- * @description Simple bootstrap function that initializes PLUGIN_LIST
73
- * for current plugin given that is doesnt exist.
74
- */
75
- function InitializePlugins() {
76
- /**
77
- * This function is called n times depending on n plugin count,
78
- * Create the plugin list if it wasn't already created
79
- */
80
- !window.PLUGIN_LIST && (window.PLUGIN_LIST = {});
81
-
82
- // initialize a container for the plugin
83
- if (!window.PLUGIN_LIST[pluginName]) {
84
- window.PLUGIN_LIST[pluginName] = {};
85
- }
86
- }
87
-
88
- const ContructFunctions = (parts: any) => {
89
- return parts.join("\n");
90
- };
91
-
92
- function InsertMillennium(props: TranspilerProps) {
93
- const generateBundle = (_: unknown, bundle: any) => {
94
- for (const fileName in bundle) {
95
- if (bundle[fileName].type != "chunk") continue;
96
-
97
- Logger.Info(
98
- "Injecting Millennium shims into module... " + chalk.green.bold("okay")
99
- );
100
-
101
- bundle[fileName].code = ContructFunctions([
102
- `const pluginName = "${props.strPluginInternalName}";`,
103
- InitializePlugins.toString(),
104
- InitializePlugins.name + "()",
105
- WrappedCallServerMethod,
106
- WrappedCallable,
107
- bundle[fileName].code,
108
- ExecutePluginModule.toString(),
109
- ExecutePluginModule.name + "()",
110
- ]);
111
- }
112
- };
113
-
114
- return { name: String(), generateBundle };
115
- }
116
-
117
- function InsertWebkitMillennium(props: TranspilerProps) {
118
- const generateBundle = (_: unknown, bundle: any) => {
119
- for (const fileName in bundle) {
120
- if (bundle[fileName].type != "chunk") continue;
121
-
122
- Logger.Info(
123
- "Injecting Millennium shims into webkit module... " +
124
- chalk.green.bold("okay")
125
- );
126
-
127
- bundle[fileName].code = ContructFunctions([
128
- `const pluginName = "${props.strPluginInternalName}";`,
129
- InitializePlugins.toString(),
130
- InitializePlugins.name + "()",
131
- WrappedCallServerMethod,
132
- WrappedCallable,
133
- bundle[fileName].code,
134
- ExecuteWebkitModule.toString(),
135
- ExecuteWebkitModule.name + "()",
136
- ]);
137
- }
138
- };
139
-
140
- return { name: String(), generateBundle };
141
- }
142
-
143
- function GetPluginComponents(props: TranspilerProps) {
144
- let tsConfigPath = `./${GetFrontEndDirectory()}/tsconfig.json`;
145
-
146
- if (!fs.existsSync(tsConfigPath)) {
147
- tsConfigPath = "./tsconfig.json";
148
- }
149
-
150
- const pluginList = [
151
- InsertMillennium(props),
152
- typescript({
153
- tsconfig: tsConfigPath,
154
- }),
155
- resolve(),
156
- commonjs(),
157
- json(),
158
- injectProcessEnv(envVars),
159
- replace({
160
- delimiters: ["", ""],
161
- preventAssignment: true,
162
- "process.env.NODE_ENV": JSON.stringify("production"),
163
- "Millennium.callServerMethod": `__call_server_method__`,
164
- "client.callable": `__wrapped_callable__`,
165
- "client.pluginSelf": "window.PLUGIN_LIST[pluginName]",
166
- "client.Millennium.exposeObj(": "client.Millennium.exposeObj(exports, ",
167
- }),
168
- ];
169
-
170
- if (props.bTersePlugin) {
171
- pluginList.push(terser());
172
- }
173
- return pluginList;
174
- }
175
-
176
- function GetWebkitPluginComponents(props: TranspilerProps) {
177
- const pluginList = [
178
- InsertWebkitMillennium(props),
179
- typescript({
180
- tsconfig: "./webkit/tsconfig.json",
181
- }),
182
- resolve(),
183
- commonjs(),
184
- json(),
185
- injectProcessEnv(envVars),
186
- replace({
187
- delimiters: ["", ""],
188
- preventAssignment: true,
189
- "Millennium.callServerMethod": `__call_server_method__`,
190
- "webkit.callable": `__wrapped_callable__`,
191
- }),
192
- babel({
193
- presets: ["@babel/preset-env", "@babel/preset-react"],
194
- babelHelpers: "bundled",
195
- }),
196
- ];
197
-
198
- props.bTersePlugin && pluginList.push(terser());
199
- return pluginList;
200
- }
201
-
202
- const GetFrontEndDirectory = () => {
203
- const pluginJsonPath = "./plugin.json";
204
- try {
205
- return (
206
- JSON.parse(fs.readFileSync(pluginJsonPath, "utf8"))?.frontend ??
207
- "frontend"
208
- );
209
- } catch (error) {
210
- return "frontend";
211
- }
212
- };
213
-
214
- export const TranspilerPluginComponent = async (props: TranspilerProps) => {
215
- const frontendRollupConfig: RollupOptions = {
216
- input: `./${GetFrontEndDirectory()}/index.tsx`,
217
- plugins: GetPluginComponents(props),
218
- context: "window",
219
- external: (id) => {
220
- if (id === "@steambrew/webkit") {
221
- Logger.Error(
222
- "The @steambrew/webkit module should not be included in the frontend module, use @steambrew/client instead. Please remove it from the frontend module and try again."
223
- );
224
- process.exit(1);
225
- }
226
-
227
- return id === "@steambrew/client" || id === "react" || id === "react-dom";
228
- },
229
- output: {
230
- name: "millennium_main",
231
- file: ".millennium/Dist/index.js",
232
- globals: {
233
- react: "window.SP_REACT",
234
- "react-dom": "window.SP_REACTDOM",
235
- "@steambrew/client": "window.MILLENNIUM_API",
236
- },
237
- exports: "named",
238
- format: "iife",
239
- },
240
- };
241
-
242
- Logger.Info("Starting build; this may take a few moments...");
243
-
244
- try {
245
- await (
246
- await rollup(frontendRollupConfig)
247
- ).write(frontendRollupConfig.output as OutputOptions);
248
-
249
- if (fs.existsSync(`./webkit/index.tsx`)) {
250
- Logger.Info("Compiling webkit module...");
251
-
252
- const webkitRollupConfig: RollupOptions = {
253
- input: `./webkit/index.tsx`,
254
- plugins: GetWebkitPluginComponents(props),
255
- context: "window",
256
- external: (id) => {
257
- if (id === "@steambrew/client") {
258
- Logger.Error(
259
- "The @steambrew/client module should not be included in the webkit module, use @steambrew/webkit instead. Please remove it from the webkit module and try again."
260
- );
261
- process.exit(1);
262
- }
263
-
264
- return id === "@steambrew/webkit";
265
- },
266
- output: {
267
- name: "millennium_main",
268
- file: ".millennium/Dist/webkit.js",
269
- exports: "named",
270
- format: "iife",
271
- globals: {
272
- "@steambrew/webkit": "window.MILLENNIUM_API",
273
- },
274
- },
275
- };
276
-
277
- await (
278
- await rollup(webkitRollupConfig)
279
- ).write(webkitRollupConfig.output as OutputOptions);
280
- }
281
-
282
- Logger.Info(
283
- "Build succeeded!",
284
- Number((performance.now() - global.PerfStartTime).toFixed(3)),
285
- "ms elapsed."
286
- );
287
- } catch (exception) {
288
- Logger.Error("Build failed!", exception);
289
- process.exit(1);
290
- }
291
- };
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 resolve from '@rollup/plugin-node-resolve';
7
+ import terser from '@rollup/plugin-terser';
8
+ import babel from '@rollup/plugin-babel';
9
+
10
+ import chalk from 'chalk';
11
+ import { Logger } from './Logger';
12
+ import fs from 'fs';
13
+
14
+ import injectProcessEnv from 'rollup-plugin-inject-process-env';
15
+ import dotenv from 'dotenv';
16
+ import { ExecutePluginModule, InitializePlugins } from './PluginSetup';
17
+
18
+ const envConfig = dotenv.config().parsed || {};
19
+
20
+ if (envConfig) {
21
+ Logger.Info('Injecting environment variables...');
22
+ }
23
+
24
+ const envVars = Object.keys(envConfig).reduce((acc: any, key) => {
25
+ acc[key] = envConfig[key];
26
+ return acc;
27
+ }, {});
28
+
29
+ declare global {
30
+ interface Window {
31
+ PLUGIN_LIST: any;
32
+ MILLENNIUM_PLUGIN_SETTINGS_STORE: any;
33
+ }
34
+ }
35
+
36
+ declare const pluginName: string, millennium_main: any, MILLENNIUM_BACKEND_IPC: any, MILLENNIUM_IS_CLIENT_MODULE: boolean;
37
+
38
+ enum ComponentType {
39
+ Plugin,
40
+ Webkit,
41
+ }
42
+
43
+ export interface TranspilerProps {
44
+ bTersePlugin?: boolean;
45
+ strPluginInternalName: string;
46
+ }
47
+
48
+ const WrappedCallServerMethod = 'const __call_server_method__ = (methodName, kwargs) => Millennium.callServerMethod(pluginName, methodName, kwargs)';
49
+ const WrappedCallable = 'const __wrapped_callable__ = (route) => MILLENNIUM_API.callable(__call_server_method__, route)';
50
+
51
+ const ConstructFunctions = (parts: any) => {
52
+ return parts.join('\n');
53
+ };
54
+
55
+ function generate(code: string) {
56
+ /** Wrap it in a proxy */
57
+ return `let PluginEntryPointMain = function() { ${code} return millennium_main; };`;
58
+ }
59
+
60
+ function InsertMillennium(type: ComponentType, props: TranspilerProps) {
61
+ const generateBundle = (_: unknown, bundle: any) => {
62
+ for (const fileName in bundle) {
63
+ if (bundle[fileName].type != 'chunk') {
64
+ continue;
65
+ }
66
+
67
+ Logger.Info('Injecting Millennium shims into ' + ComponentType[type] + ' module... ' + chalk.green.bold('okay'));
68
+
69
+ bundle[fileName].code = ConstructFunctions([
70
+ `const MILLENNIUM_IS_CLIENT_MODULE = ${type === ComponentType.Plugin ? 'true' : 'false'};`,
71
+ `const pluginName = "${props.strPluginInternalName}";`,
72
+ InitializePlugins.toString(),
73
+ InitializePlugins.name + '()',
74
+ WrappedCallServerMethod,
75
+ WrappedCallable,
76
+ generate(bundle[fileName].code),
77
+ ExecutePluginModule.toString(),
78
+ ExecutePluginModule.name + '()',
79
+ ]);
80
+ }
81
+ };
82
+
83
+ return { name: String(), generateBundle };
84
+ }
85
+
86
+ function GetPluginComponents(props: TranspilerProps) {
87
+ let tsConfigPath = `./${GetFrontEndDirectory()}/tsconfig.json`;
88
+
89
+ if (!fs.existsSync(tsConfigPath)) {
90
+ tsConfigPath = './tsconfig.json';
91
+ }
92
+
93
+ const pluginList = [
94
+ InsertMillennium(ComponentType.Plugin, props),
95
+ typescript({
96
+ tsconfig: tsConfigPath,
97
+ }),
98
+ resolve(),
99
+ commonjs(),
100
+ json(),
101
+ injectProcessEnv(envVars),
102
+ replace({
103
+ delimiters: ['', ''],
104
+ preventAssignment: true,
105
+ 'process.env.NODE_ENV': JSON.stringify('production'),
106
+ 'Millennium.callServerMethod': `__call_server_method__`,
107
+ 'client.callable': `__wrapped_callable__`,
108
+ 'client.pluginSelf': 'window.PLUGIN_LIST[pluginName]',
109
+ 'client.Millennium.exposeObj(': 'client.Millennium.exposeObj(exports, ',
110
+ 'client.BindPluginSettings()': 'client.BindPluginSettings(pluginName)',
111
+ }),
112
+ ];
113
+
114
+ if (props.bTersePlugin) {
115
+ pluginList.push(terser());
116
+ }
117
+ return pluginList;
118
+ }
119
+
120
+ function GetWebkitPluginComponents(props: TranspilerProps) {
121
+ const pluginList = [
122
+ InsertMillennium(ComponentType.Webkit, props),
123
+ typescript({
124
+ tsconfig: './webkit/tsconfig.json',
125
+ }),
126
+ resolve(),
127
+ commonjs(),
128
+ json(),
129
+ injectProcessEnv(envVars),
130
+ replace({
131
+ delimiters: ['', ''],
132
+ preventAssignment: true,
133
+ 'Millennium.callServerMethod': `__call_server_method__`,
134
+ 'webkit.callable': `__wrapped_callable__`,
135
+ 'client.BindPluginSettings()': 'client.BindPluginSettings(pluginName)',
136
+ }),
137
+ babel({
138
+ presets: ['@babel/preset-env', '@babel/preset-react'],
139
+ babelHelpers: 'bundled',
140
+ }),
141
+ ];
142
+
143
+ props.bTersePlugin && pluginList.push(terser());
144
+ return pluginList;
145
+ }
146
+
147
+ const GetFrontEndDirectory = () => {
148
+ const pluginJsonPath = './plugin.json';
149
+ try {
150
+ return JSON.parse(fs.readFileSync(pluginJsonPath, 'utf8'))?.frontend ?? 'frontend';
151
+ } catch (error) {
152
+ return 'frontend';
153
+ }
154
+ };
155
+
156
+ export const TranspilerPluginComponent = async (props: TranspilerProps) => {
157
+ const frontendRollupConfig: RollupOptions = {
158
+ input: `./${GetFrontEndDirectory()}/index.tsx`,
159
+ plugins: GetPluginComponents(props),
160
+ context: 'window',
161
+ external: (id) => {
162
+ if (id === '@steambrew/webkit') {
163
+ Logger.Error(
164
+ 'The @steambrew/webkit module should not be included in the frontend module, use @steambrew/client instead. Please remove it from the frontend module and try again.',
165
+ );
166
+ process.exit(1);
167
+ }
168
+
169
+ return id === '@steambrew/client' || id === 'react' || id === 'react-dom' || id === 'react-dom/client';
170
+ },
171
+ output: {
172
+ name: 'millennium_main',
173
+ file: '.millennium/Dist/index.js',
174
+ globals: {
175
+ react: 'window.SP_REACT',
176
+ 'react-dom': 'window.SP_REACTDOM',
177
+ 'react-dom/client': 'window.SP_REACTDOM',
178
+ '@steambrew/client': 'window.MILLENNIUM_API',
179
+ },
180
+ exports: 'named',
181
+ format: 'iife',
182
+ },
183
+ };
184
+
185
+ Logger.Info('Starting build; this may take a few moments...');
186
+
187
+ try {
188
+ await (await rollup(frontendRollupConfig)).write(frontendRollupConfig.output as OutputOptions);
189
+
190
+ if (fs.existsSync(`./webkit/index.tsx`)) {
191
+ Logger.Info('Compiling webkit module...');
192
+
193
+ const webkitRollupConfig: RollupOptions = {
194
+ input: `./webkit/index.tsx`,
195
+ plugins: GetWebkitPluginComponents(props),
196
+ context: 'window',
197
+ external: (id) => {
198
+ if (id === '@steambrew/client') {
199
+ Logger.Error(
200
+ 'The @steambrew/client module should not be included in the webkit module, use @steambrew/webkit instead. Please remove it from the webkit module and try again.',
201
+ );
202
+ process.exit(1);
203
+ }
204
+
205
+ return id === '@steambrew/webkit';
206
+ },
207
+ output: {
208
+ name: 'millennium_main',
209
+ file: '.millennium/Dist/webkit.js',
210
+ exports: 'named',
211
+ format: 'iife',
212
+ globals: {
213
+ '@steambrew/webkit': 'window.MILLENNIUM_API',
214
+ },
215
+ },
216
+ };
217
+
218
+ await (await rollup(webkitRollupConfig)).write(webkitRollupConfig.output as OutputOptions);
219
+ }
220
+
221
+ Logger.Info('Build succeeded!', Number((performance.now() - global.PerfStartTime).toFixed(3)), 'ms elapsed.');
222
+ } catch (exception) {
223
+ Logger.Error('Build failed!', exception);
224
+ process.exit(1);
225
+ }
226
+ };
package/Linter.ts CHANGED
@@ -1,44 +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
- })
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
44
  }