hackmud-script-manager 0.19.0-7c69a3b → 0.19.0-b5e2c0b

Sign up to get free protection for your applications and to get access to all the features.
package/constants.js CHANGED
@@ -1,4 +1 @@
1
- const supportedExtensions = [`.js`, `.ts`];
2
- const validDBMethods = [`i`, `r`, `f`, `u`, `u1`, `us`, `ObjectId`];
3
-
4
- export { supportedExtensions, validDBMethods };
1
+ const s=[".js",".ts"],t=["i","r","f","u","u1","us","ObjectId"];export{s as supportedExtensions,t as validDBMethods};
@@ -1,94 +1 @@
1
- import { readdir } from 'fs/promises';
2
- import { basename, resolve } from 'path';
3
-
4
- const generateTypeDeclaration = async (sourceDirectory, hackmudPath) => {
5
- const users = new Set();
6
- if (hackmudPath) {
7
- for (const dirent of await readdir(hackmudPath, {
8
- withFileTypes: true
9
- })) {
10
- if (dirent.isFile() && dirent.name.endsWith(`.key`)) users.add(basename(dirent.name, `.key`));
11
- }
12
- }
13
- const wildScripts = [];
14
- const wildAnyScripts = [];
15
- const allScripts = {};
16
- const allAnyScripts = {};
17
- await Promise.all((await readdir(sourceDirectory, {
18
- withFileTypes: true
19
- })).map(async dirent => {
20
- if (dirent.isFile()) {
21
- if (dirent.name.endsWith(`.ts`)) {
22
- if (!dirent.name.endsWith(`.d.ts`)) wildScripts.push(basename(dirent.name, `.ts`));
23
- } else if (dirent.name.endsWith(`.js`)) wildAnyScripts.push(basename(dirent.name, `.js`));
24
- } else if (dirent.isDirectory()) {
25
- const scripts = [];
26
- const anyScripts = [];
27
- allScripts[dirent.name] = scripts;
28
- allAnyScripts[dirent.name] = anyScripts;
29
- users.add(dirent.name);
30
- for (const file of await readdir(resolve(sourceDirectory, dirent.name), {
31
- withFileTypes: true
32
- })) {
33
- if (file.isFile()) {
34
- if (file.name.endsWith(`.ts`)) {
35
- if (!dirent.name.endsWith(`.d.ts`)) scripts.push(basename(file.name, `.ts`));
36
- } else if (file.name.endsWith(`.js`)) anyScripts.push(basename(file.name, `.js`));
37
- }
38
- }
39
- }
40
- }));
41
- sourceDirectory = resolve(sourceDirectory);
42
- let o = ``;
43
- for (const script of wildScripts) o += `type $${script}$ = typeof import("${sourceDirectory}/${script}").default\n`;
44
- o += `\n`;
45
- for (const user in allScripts) {
46
- const scripts = allScripts[user];
47
- for (const script of scripts) o += `type $${user}$${script}$ = typeof import("${sourceDirectory}/${user}/${script}").default\n`;
48
- }
49
-
50
- // TODO detect security level and generate apropriate code
51
-
52
- // TODO accurate function signatures
53
- // I lose the generic-ness of my functions when I wrap them
54
- // regexing isn't enough and it looks like I'm going to need to parse the files in TypeScript to extract the signature
55
-
56
- o += `
57
- type ArrayRemoveFirst<A> = A extends [ infer FirstItem, ...infer Rest ] ? Rest : never
58
-
59
- type Subscript<T extends (...args: any) => any> =
60
- (...args: ArrayRemoveFirst<Parameters<T>>) => ReturnType<T> | ScriptFailure
61
-
62
- type WildFullsec = Record<string, () => ScriptFailure> & {
63
- `;
64
- for (const script of wildScripts) o += `\t${script}: Subscript<$${script}$>\n`;
65
- for (const script of wildAnyScripts) o += `\t${script}: (...args: any) => any\n`;
66
- o += `}\n\ninterface PlayerFullsec {`;
67
- let lastWasMultiLine = true;
68
- for (const user of users) {
69
- const scripts = allScripts[user];
70
- const anyScripts = allAnyScripts[user];
71
- if (scripts && scripts.length || anyScripts && anyScripts.length) {
72
- lastWasMultiLine = true;
73
- o += `\n\t${user}: WildFullsec & {\n`;
74
- if (scripts) {
75
- for (const script of scripts) o += `\t\t${script}: Subscript<$${user}$${script}$>\n`;
76
- }
77
- if (anyScripts) {
78
- for (const script of anyScripts) o += `\t\t${script}: (...args: any) => any\n`;
79
- }
80
- o += `\t}`;
81
- } else {
82
- if (lastWasMultiLine) {
83
- o += `\n`;
84
- lastWasMultiLine = false;
85
- }
86
- o += `\t${user}: WildFullsec`;
87
- }
88
- o += `\n`;
89
- }
90
- o += `}\n`;
91
- return o;
92
- };
93
-
94
- export { generateTypeDeclaration as default, generateTypeDeclaration };
1
+ import{readdir as e}from"fs/promises";import{basename as t,resolve as n}from"path";const generateTypeDeclaration=async(s,i)=>{const a=new Set;if(i)for(const n of await e(i,{withFileTypes:!0}))n.isFile()&&n.name.endsWith(".key")&&a.add(t(n.name,".key"));const r=[],o=[],f={},l={};await Promise.all((await e(s,{withFileTypes:!0})).map((async i=>{if(i.isFile())i.name.endsWith(".ts")?i.name.endsWith(".d.ts")||r.push(t(i.name,".ts")):i.name.endsWith(".js")&&o.push(t(i.name,".js"));else if(i.isDirectory()){const r=[],o=[];f[i.name]=r,l[i.name]=o,a.add(i.name);for(const a of await e(n(s,i.name),{withFileTypes:!0}))a.isFile()&&(a.name.endsWith(".ts")?i.name.endsWith(".d.ts")||r.push(t(a.name,".ts")):a.name.endsWith(".js")&&o.push(t(a.name,".js")))}}))),s=n(s);let c="";for(const e of r)c+=`type $${e}$ = typeof import("${s}/${e}").default\n`;c+="\n";for(const e in f){const t=f[e];for(const n of t)c+=`type $${e}$${n}$ = typeof import("${s}/${e}/${n}").default\n`}c+="\ntype ArrayRemoveFirst<A> = A extends [ infer FirstItem, ...infer Rest ] ? Rest : never\n\ntype Subscript<T extends (...args: any) => any> =\n\t(...args: ArrayRemoveFirst<Parameters<T>>) => ReturnType<T> | ScriptFailure\n\ntype WildFullsec = Record<string, () => ScriptFailure> & {\n";for(const e of r)c+=`\t${e}: Subscript<$${e}$>\n`;for(const e of o)c+=`\t${e}: (...args: any) => any\n`;c+="}\n\ninterface PlayerFullsec {";let m=!0;for(const e of a){const t=f[e],n=l[e];if(t&&t.length||n&&n.length){if(m=!0,c+=`\n\t${e}: WildFullsec & {\n`,t)for(const n of t)c+=`\t\t${n}: Subscript<$${e}$${n}$>\n`;if(n)for(const e of n)c+=`\t\t${e}: (...args: any) => any\n`;c+="\t}"}else m&&(c+="\n",m=!1),c+=`\t${e}: WildFullsec`;c+="\n"}return c+="}\n",c};export{generateTypeDeclaration as default,generateTypeDeclaration};
package/index.js CHANGED
@@ -1,50 +1 @@
1
- export { supportedExtensions } from './constants.js';
2
- export { generateTypeDeclaration } from './generateTypeDeclaration.js';
3
- export { processScript } from './processScript/index.js';
4
- export { pull } from './pull.js';
5
- export { push } from './push.js';
6
- export { syncMacros } from './syncMacros.js';
7
- export { watch } from './watch.js';
8
- import 'fs/promises';
9
- import 'path';
10
- import '@babel/generator';
11
- import '@babel/parser';
12
- import '@babel/plugin-proposal-decorators';
13
- import '@babel/plugin-proposal-destructuring-private';
14
- import '@babel/plugin-proposal-explicit-resource-management';
15
- import '@babel/plugin-transform-class-properties';
16
- import '@babel/plugin-transform-class-static-block';
17
- import '@babel/plugin-transform-exponentiation-operator';
18
- import '@babel/plugin-transform-json-strings';
19
- import '@babel/plugin-transform-logical-assignment-operators';
20
- import '@babel/plugin-transform-nullish-coalescing-operator';
21
- import '@babel/plugin-transform-numeric-separator';
22
- import '@babel/plugin-transform-object-rest-spread';
23
- import '@babel/plugin-transform-optional-catch-binding';
24
- import '@babel/plugin-transform-optional-chaining';
25
- import '@babel/plugin-transform-private-property-in-object';
26
- import '@babel/plugin-transform-unicode-sets-regex';
27
- import '@babel/traverse';
28
- import '@babel/types';
29
- import '@rollup/plugin-babel';
30
- import '@rollup/plugin-commonjs';
31
- import '@rollup/plugin-json';
32
- import '@rollup/plugin-node-resolve';
33
- import '@samual/lib/assert';
34
- import 'prettier';
35
- import 'rollup';
36
- import './processScript/minify.js';
37
- import '@samual/lib/countHackmudCharacters';
38
- import '@samual/lib/spliceString';
39
- import 'acorn';
40
- import 'terser';
41
- import './processScript/shared.js';
42
- import './processScript/postprocess.js';
43
- import './processScript/preprocess.js';
44
- import 'import-meta-resolve';
45
- import './processScript/transform.js';
46
- import '@samual/lib/clearObject';
47
- import '@samual/lib/copyFilePersistent';
48
- import '@samual/lib/DynamicMap';
49
- import '@samual/lib/writeFilePersistent';
50
- import 'chokidar';
1
+ export{supportedExtensions}from"./constants.js";export{generateTypeDeclaration}from"./generateTypeDeclaration.js";export{processScript}from"./processScript/index.js";export{pull}from"./pull.js";export{push}from"./push.js";export{syncMacros}from"./syncMacros.js";export{watch}from"./watch.js";import"fs/promises";import"path";import"@babel/generator";import"@babel/parser";import"@babel/plugin-proposal-decorators";import"@babel/plugin-proposal-destructuring-private";import"@babel/plugin-proposal-explicit-resource-management";import"@babel/plugin-transform-class-properties";import"@babel/plugin-transform-class-static-block";import"@babel/plugin-transform-exponentiation-operator";import"@babel/plugin-transform-json-strings";import"@babel/plugin-transform-logical-assignment-operators";import"@babel/plugin-transform-nullish-coalescing-operator";import"@babel/plugin-transform-numeric-separator";import"@babel/plugin-transform-object-rest-spread";import"@babel/plugin-transform-optional-catch-binding";import"@babel/plugin-transform-optional-chaining";import"@babel/plugin-transform-private-property-in-object";import"@babel/plugin-transform-unicode-sets-regex";import"@babel/traverse";import"@babel/types";import"@rollup/plugin-babel";import"@rollup/plugin-commonjs";import"@rollup/plugin-json";import"@rollup/plugin-node-resolve";import"@samual/lib/assert";import"prettier";import"rollup";import"./processScript/minify.js";import"@samual/lib/countHackmudCharacters";import"@samual/lib/spliceString";import"acorn";import"terser";import"./processScript/shared.js";import"./processScript/postprocess.js";import"./processScript/preprocess.js";import"import-meta-resolve";import"./processScript/transform.js";import"@samual/lib/clearObject";import"@samual/lib/copyFilePersistent";import"@samual/lib/DynamicMap";import"@samual/lib/writeFilePersistent";import"chokidar";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hackmud-script-manager",
3
- "version": "0.19.0-7c69a3b",
3
+ "version": "0.19.0-b5e2c0b",
4
4
  "description": "Script manager for game hackmud, with minification, TypeScript support, and player script type definition generation.",
5
5
  "keywords": [
6
6
  "api",
@@ -1,313 +1 @@
1
- import babelGenerator from '@babel/generator';
2
- import { parse } from '@babel/parser';
3
- import babelPluginProposalDecorators from '@babel/plugin-proposal-decorators';
4
- import babelPluginProposalDestructuringPrivate from '@babel/plugin-proposal-destructuring-private';
5
- import babelPluginProposalExplicitResourceManagement from '@babel/plugin-proposal-explicit-resource-management';
6
- import babelPluginTransformClassProperties from '@babel/plugin-transform-class-properties';
7
- import babelPluginTransformClassStaticBlock from '@babel/plugin-transform-class-static-block';
8
- import babelPluginTransformExponentiationOperator from '@babel/plugin-transform-exponentiation-operator';
9
- import babelPluginTransformJsonStrings from '@babel/plugin-transform-json-strings';
10
- import babelPluginTransformLogicalAssignmentOperators from '@babel/plugin-transform-logical-assignment-operators';
11
- import babelPluginTransformNullishCoalescingOperator from '@babel/plugin-transform-nullish-coalescing-operator';
12
- import babelPluginTransformNumericSeparator from '@babel/plugin-transform-numeric-separator';
13
- import babelPluginTransformObjectRestSpread from '@babel/plugin-transform-object-rest-spread';
14
- import babelPluginTransformOptionalCatchBinding from '@babel/plugin-transform-optional-catch-binding';
15
- import babelPluginTransformOptionalChaining from '@babel/plugin-transform-optional-chaining';
16
- import babelPluginTransformPrivatePropertyInObject from '@babel/plugin-transform-private-property-in-object';
17
- import babelPluginTransformUnicodeSetsRegex from '@babel/plugin-transform-unicode-sets-regex';
18
- import babelTraverse from '@babel/traverse';
19
- import t from '@babel/types';
20
- import { babel } from '@rollup/plugin-babel';
21
- import rollupPluginCommonJS from '@rollup/plugin-commonjs';
22
- import rollupPluginJSON from '@rollup/plugin-json';
23
- import rollupPluginNodeResolve from '@rollup/plugin-node-resolve';
24
- import { assert } from '@samual/lib/assert';
25
- import { resolve } from 'path';
26
- import prettier from 'prettier';
27
- import { rollup } from 'rollup';
28
- import { supportedExtensions } from '../constants.js';
29
- import { minify } from './minify.js';
30
- import { postprocess } from './postprocess.js';
31
- import { preprocess } from './preprocess.js';
32
- import { includesIllegalString, replaceUnsafeStrings } from './shared.js';
33
- import { transform } from './transform.js';
34
- import '@samual/lib/countHackmudCharacters';
35
- import '@samual/lib/spliceString';
36
- import 'acorn';
37
- import 'terser';
38
- import 'import-meta-resolve';
39
- import '@samual/lib/clearObject';
40
-
41
- const {
42
- format
43
- } = prettier;
44
- // eslint-disable-next-line @typescript-eslint/consistent-type-imports
45
- const {
46
- default: generate
47
- } = babelGenerator;
48
- // eslint-disable-next-line @typescript-eslint/consistent-type-imports
49
- const {
50
- default: traverse
51
- } = babelTraverse;
52
- /**
53
- * Minifies a given script
54
- *
55
- * @param code JavaScript or TypeScript code
56
- * @param options {@link ProcessOptions details}
57
- */
58
- const processScript = async (code, {
59
- minify: shouldMinify = true,
60
- uniqueID = Math.floor(Math.random() * 2 ** 52).toString(36).padStart(11, `0`),
61
- scriptUser = `UNKNOWN`,
62
- scriptName = `UNKNOWN`,
63
- filePath,
64
- mangleNames = false,
65
- forceQuineCheats
66
- } = {}) => {
67
- assert(/^\w{11}$/.exec(uniqueID));
68
- const sourceCode = code;
69
- let autocomplete;
70
- let statedSeclevel;
71
-
72
- // TODO do seclevel detection and verification per module
73
-
74
- const autocompleteMatch = /^function\s*\(.+\/\/(?<autocomplete>.+)/.exec(code);
75
- if (autocompleteMatch) {
76
- code = `export default ${code}`;
77
- ({
78
- autocomplete
79
- } = autocompleteMatch.groups);
80
- } else {
81
- for (const line of code.split(`\n`)) {
82
- const comment = /^\s*\/\/(?<commentContent>.+)/.exec(line);
83
- if (!comment) break;
84
- const commentContent = comment.groups.commentContent.trim();
85
- if (commentContent.startsWith(`@autocomplete `)) autocomplete = commentContent.slice(14).trimStart();else if (commentContent.startsWith(`@seclevel `)) {
86
- const seclevelString = commentContent.slice(10).trimStart().toLowerCase();
87
- switch (seclevelString) {
88
- case `fullsec`:
89
- case `full`:
90
- case `fs`:
91
- case `4s`:
92
- case `f`:
93
- case `4`:
94
- {
95
- statedSeclevel = 4;
96
- }
97
- break;
98
- case `highsec`:
99
- case `high`:
100
- case `hs`:
101
- case `3s`:
102
- case `h`:
103
- case `3`:
104
- {
105
- statedSeclevel = 3;
106
- }
107
- break;
108
- case `midsec`:
109
- case `mid`:
110
- case `ms`:
111
- case `2s`:
112
- case `m`:
113
- case `2`:
114
- {
115
- statedSeclevel = 2;
116
- }
117
- break;
118
- case `lowsec`:
119
- case `low`:
120
- case `ls`:
121
- case `1s`:
122
- case `l`:
123
- case `1`:
124
- {
125
- statedSeclevel = 1;
126
- }
127
- break;
128
- case `nullsec`:
129
- case `null`:
130
- case `ns`:
131
- case `0s`:
132
- case `n`:
133
- case `0`:
134
- {
135
- statedSeclevel = 0;
136
- }
137
- break;
138
- default:
139
- // TODO turn into warning when I get round to those
140
- throw new Error(`unrecognised seclevel "${seclevelString}"`);
141
- }
142
- }
143
- }
144
- }
145
- assert(/^\w{11}$/.exec(uniqueID));
146
- const plugins = [[babelPluginProposalDecorators.default, {
147
- decoratorsBeforeExport: true
148
- }], [babelPluginTransformClassProperties.default], [babelPluginTransformClassStaticBlock.default], [babelPluginTransformPrivatePropertyInObject.default], [babelPluginTransformLogicalAssignmentOperators.default], [babelPluginTransformNumericSeparator.default], [babelPluginTransformNullishCoalescingOperator.default], [babelPluginTransformOptionalChaining.default], [babelPluginTransformOptionalCatchBinding.default], [babelPluginTransformJsonStrings.default], [babelPluginTransformObjectRestSpread.default], [babelPluginTransformExponentiationOperator.default], [babelPluginTransformUnicodeSetsRegex.default], [babelPluginProposalDestructuringPrivate.default], [babelPluginProposalExplicitResourceManagement.default]];
149
- let filePathResolved;
150
- if (filePath) {
151
- filePathResolved = resolve(filePath);
152
- if (filePath.endsWith(`.ts`)) plugins.push([(await import('@babel/plugin-transform-typescript')).default, {
153
- allowDeclareFields: true,
154
- optimizeConstEnums: true
155
- }]);else {
156
- const [babelPluginProposalDoExpressions, babelPluginProposalFunctionBind, babelPluginProposalFunctionSent, babelPluginProposalPartialApplication, babelPluginProposalPipelineOperator, babelPluginProposalThrowExpressions, babelPluginProposalRecordAndTuple] = await Promise.all([import('@babel/plugin-proposal-do-expressions'), import('@babel/plugin-proposal-function-bind'), import('@babel/plugin-proposal-function-sent'), import('@babel/plugin-proposal-partial-application'), import('@babel/plugin-proposal-pipeline-operator'), import('@babel/plugin-proposal-throw-expressions'), import('@babel/plugin-proposal-record-and-tuple')]);
157
- plugins.push([babelPluginProposalDoExpressions.default], [babelPluginProposalFunctionBind.default], [babelPluginProposalFunctionSent.default], [babelPluginProposalPartialApplication.default], [babelPluginProposalPipelineOperator.default, {
158
- proposal: `hack`,
159
- topicToken: `%`
160
- }], [babelPluginProposalThrowExpressions.default], [babelPluginProposalRecordAndTuple.default, {
161
- syntaxType: `hash`,
162
- importPolyfill: true
163
- }]);
164
- }
165
- } else {
166
- filePathResolved = `${uniqueID}.ts`;
167
- const [babelPluginTransformTypescript, babelPluginProposalDoExpressions, babelPluginProposalFunctionBind, babelPluginProposalFunctionSent, babelPluginProposalPartialApplication, babelPluginProposalPipelineOperator, babelPluginProposalThrowExpressions, babelPluginProposalRecordAndTuple] = await Promise.all([import('@babel/plugin-transform-typescript'), import('@babel/plugin-proposal-do-expressions'), import('@babel/plugin-proposal-function-bind'), import('@babel/plugin-proposal-function-sent'), import('@babel/plugin-proposal-partial-application'), import('@babel/plugin-proposal-pipeline-operator'), import('@babel/plugin-proposal-throw-expressions'), import('@babel/plugin-proposal-record-and-tuple')]);
168
- plugins.push([babelPluginTransformTypescript.default, {
169
- allowDeclareFields: true,
170
- optimizeConstEnums: true
171
- }], [babelPluginProposalDoExpressions.default], [babelPluginProposalFunctionBind.default], [babelPluginProposalFunctionSent.default], [babelPluginProposalPartialApplication.default], [babelPluginProposalPipelineOperator.default, {
172
- proposal: `hack`,
173
- topicToken: `%`
174
- }], [babelPluginProposalThrowExpressions.default], [babelPluginProposalRecordAndTuple.default, {
175
- syntaxType: `hash`,
176
- importPolyfill: true
177
- }]);
178
- }
179
- const bundle = await rollup({
180
- input: filePathResolved,
181
- plugins: [{
182
- name: `hackmud-script-manager`,
183
- transform: async code => (await preprocess(code, {
184
- uniqueID
185
- })).code
186
- }, babel({
187
- babelHelpers: `bundled`,
188
- plugins,
189
- configFile: false,
190
- extensions: supportedExtensions
191
- }), rollupPluginCommonJS(), rollupPluginNodeResolve({
192
- extensions: supportedExtensions
193
- }), rollupPluginJSON()],
194
- treeshake: {
195
- moduleSideEffects: false
196
- }
197
- });
198
- const seclevelNames = [`NULLSEC`, `LOWSEC`, `MIDSEC`, `HIGHSEC`, `FULLSEC`];
199
- code = (await bundle.generate({})).output[0].code;
200
- const {
201
- file,
202
- seclevel
203
- } = transform(parse(code, {
204
- sourceType: `module`
205
- }), sourceCode, {
206
- uniqueID,
207
- scriptUser,
208
- scriptName
209
- });
210
- if (statedSeclevel != undefined && seclevel < statedSeclevel)
211
- // TODO replace with a warning and build script anyway
212
- throw new Error(`detected seclevel ${seclevelNames[seclevel]} is lower than stated seclevel ${seclevelNames[statedSeclevel]}`);
213
- code = generate(file).code;
214
- if (shouldMinify) code = await minify(file, {
215
- uniqueID,
216
- mangleNames,
217
- forceQuineCheats,
218
- autocomplete
219
- });else {
220
- traverse(file, {
221
- MemberExpression({
222
- node: memberExpression
223
- }) {
224
- if (memberExpression.computed) return;
225
- assert(memberExpression.property.type == `Identifier`);
226
- if (memberExpression.property.name == `prototype`) {
227
- memberExpression.computed = true;
228
- memberExpression.property = t.stringLiteral(`prototype`);
229
- } else if (memberExpression.property.name == `__proto__`) {
230
- memberExpression.computed = true;
231
- memberExpression.property = t.stringLiteral(`__proto__`);
232
- } else if (includesIllegalString(memberExpression.property.name)) {
233
- memberExpression.computed = true;
234
- memberExpression.property = t.stringLiteral(replaceUnsafeStrings(uniqueID, memberExpression.property.name));
235
- }
236
- },
237
- VariableDeclarator(path) {
238
- const renameVariables = lValue => {
239
- switch (lValue.type) {
240
- case `Identifier`:
241
- {
242
- if (includesIllegalString(lValue.name)) path.scope.rename(lValue.name, `$${Math.floor(Math.random() * 2 ** 52).toString(36).padStart(11, `0`)}`);
243
- }
244
- break;
245
- case `ObjectPattern`:
246
- {
247
- for (const property of lValue.properties) {
248
- assert(property.type == `ObjectProperty`);
249
- renameVariables(property.value);
250
- }
251
- }
252
- break;
253
- case `ArrayPattern`:
254
- {
255
- for (const element of lValue.elements) {
256
- if (element) renameVariables(element);
257
- }
258
- }
259
- break;
260
- default:
261
- throw new Error(`unknown lValue type "${lValue.type}"`);
262
- }
263
- };
264
- renameVariables(path.node.id);
265
- },
266
- ObjectProperty({
267
- node: objectProperty
268
- }) {
269
- if (objectProperty.key.type == `Identifier` && includesIllegalString(objectProperty.key.name)) {
270
- objectProperty.key = t.stringLiteral(replaceUnsafeStrings(uniqueID, objectProperty.key.name));
271
- objectProperty.shorthand = false;
272
- }
273
- },
274
- StringLiteral({
275
- node
276
- }) {
277
- node.value = replaceUnsafeStrings(uniqueID, node.value);
278
- },
279
- TemplateLiteral({
280
- node
281
- }) {
282
- for (const templateElement of node.quasis) {
283
- if (templateElement.value.cooked) {
284
- templateElement.value.cooked = replaceUnsafeStrings(uniqueID, templateElement.value.cooked);
285
- templateElement.value.raw = templateElement.value.cooked.replaceAll(`\\`, `\\\\`).replaceAll(`\``, `\\\``).replaceAll(`\${`, `$\\{`);
286
- } else templateElement.value.raw = replaceUnsafeStrings(uniqueID, templateElement.value.raw);
287
- }
288
- },
289
- RegExpLiteral(path) {
290
- path.node.pattern = replaceUnsafeStrings(uniqueID, path.node.pattern);
291
- delete path.node.extra;
292
- }
293
- });
294
-
295
- // we can't have comments because they may contain illegal strings
296
- code = await format(generate(file, {
297
- comments: false
298
- }).code, {
299
- parser: `babel`,
300
- arrowParens: `avoid`,
301
- semi: false,
302
- trailingComma: `none`
303
- });
304
- }
305
- code = postprocess(code, seclevel, uniqueID);
306
- if (includesIllegalString(code)) throw new Error(`you found a weird edge case where I wasn't able to replace illegal strings like "SC$", please report thx`);
307
- return {
308
- script: code,
309
- warnings: []
310
- };
311
- };
312
-
313
- export { processScript as default, minify, postprocess, preprocess, processScript, transform };
1
+ import e from"@babel/generator";import{parse as r}from"@babel/parser";import o from"@babel/plugin-proposal-decorators";import t from"@babel/plugin-proposal-destructuring-private";import a from"@babel/plugin-proposal-explicit-resource-management";import l from"@babel/plugin-transform-class-properties";import p from"@babel/plugin-transform-class-static-block";import s from"@babel/plugin-transform-exponentiation-operator";import i from"@babel/plugin-transform-json-strings";import n from"@babel/plugin-transform-logical-assignment-operators";import m from"@babel/plugin-transform-nullish-coalescing-operator";import c from"@babel/plugin-transform-numeric-separator";import u from"@babel/plugin-transform-object-rest-spread";import f from"@babel/plugin-transform-optional-catch-binding";import b from"@babel/plugin-transform-optional-chaining";import d from"@babel/plugin-transform-private-property-in-object";import g from"@babel/plugin-transform-unicode-sets-regex";import h from"@babel/traverse";import y from"@babel/types";import{babel as w}from"@rollup/plugin-babel";import k from"@rollup/plugin-commonjs";import x from"@rollup/plugin-json";import v from"@rollup/plugin-node-resolve";import{assert as j}from"@samual/lib/assert";import{resolve as C}from"path";import E from"prettier";import{rollup as S}from"rollup";import{supportedExtensions as L}from"../constants.js";import{minify as $}from"./minify.js";import{postprocess as N}from"./postprocess.js";import{preprocess as I}from"./preprocess.js";import{includesIllegalString as P,replaceUnsafeStrings as D}from"./shared.js";import{transform as _}from"./transform.js";import"@samual/lib/countHackmudCharacters";import"@samual/lib/spliceString";import"acorn";import"terser";import"import-meta-resolve";import"@samual/lib/clearObject";const{format:O}=E,{default:M}=e,{default:T}=h,processScript=async(e,{minify:h=!0,uniqueID:E=Math.floor(Math.random()*2**52).toString(36).padStart(11,"0"),scriptUser:U="UNKNOWN",scriptName:W="UNKNOWN",filePath:q,mangleNames:A=!1,forceQuineCheats:F}={})=>{j(/^\w{11}$/.exec(E));const H=e;let z,K;const Q=/^function\s*\(.+\/\/(?<autocomplete>.+)/.exec(e);if(Q)e=`export default ${e}`,({autocomplete:z}=Q.groups);else for(const r of e.split("\n")){const e=/^\s*\/\/(?<commentContent>.+)/.exec(r);if(!e)break;const o=e.groups.commentContent.trim();if(o.startsWith("@autocomplete "))z=o.slice(14).trimStart();else if(o.startsWith("@seclevel ")){const e=o.slice(10).trimStart().toLowerCase();switch(e){case"fullsec":case"full":case"fs":case"4s":case"f":case"4":K=4;break;case"highsec":case"high":case"hs":case"3s":case"h":case"3":K=3;break;case"midsec":case"mid":case"ms":case"2s":case"m":case"2":K=2;break;case"lowsec":case"low":case"ls":case"1s":case"l":case"1":K=1;break;case"nullsec":case"null":case"ns":case"0s":case"n":case"0":K=0;break;default:throw new Error(`unrecognised seclevel "${e}"`)}}}j(/^\w{11}$/.exec(E));const V=[[o.default,{decoratorsBeforeExport:!0}],[l.default],[p.default],[d.default],[n.default],[c.default],[m.default],[b.default],[f.default],[i.default],[u.default],[s.default],[g.default],[t.default],[a.default]];let B;if(q)if(B=C(q),q.endsWith(".ts"))V.push([(await import("@babel/plugin-transform-typescript")).default,{allowDeclareFields:!0,optimizeConstEnums:!0}]);else{const[e,r,o,t,a,l,p]=await Promise.all([import("@babel/plugin-proposal-do-expressions"),import("@babel/plugin-proposal-function-bind"),import("@babel/plugin-proposal-function-sent"),import("@babel/plugin-proposal-partial-application"),import("@babel/plugin-proposal-pipeline-operator"),import("@babel/plugin-proposal-throw-expressions"),import("@babel/plugin-proposal-record-and-tuple")]);V.push([e.default],[r.default],[o.default],[t.default],[a.default,{proposal:"hack",topicToken:"%"}],[l.default],[p.default,{syntaxType:"hash",importPolyfill:!0}])}else{B=`${E}.ts`;const[e,r,o,t,a,l,p,s]=await Promise.all([import("@babel/plugin-transform-typescript"),import("@babel/plugin-proposal-do-expressions"),import("@babel/plugin-proposal-function-bind"),import("@babel/plugin-proposal-function-sent"),import("@babel/plugin-proposal-partial-application"),import("@babel/plugin-proposal-pipeline-operator"),import("@babel/plugin-proposal-throw-expressions"),import("@babel/plugin-proposal-record-and-tuple")]);V.push([e.default,{allowDeclareFields:!0,optimizeConstEnums:!0}],[r.default],[o.default],[t.default],[a.default],[l.default,{proposal:"hack",topicToken:"%"}],[p.default],[s.default,{syntaxType:"hash",importPolyfill:!0}])}const G=await S({input:B,plugins:[{name:"hackmud-script-manager",transform:async e=>(await I(e,{uniqueID:E})).code},w({babelHelpers:"bundled",plugins:V,configFile:!1,extensions:L}),k(),v({extensions:L}),x()],treeshake:{moduleSideEffects:!1}}),R=["NULLSEC","LOWSEC","MIDSEC","HIGHSEC","FULLSEC"];e=(await G.generate({})).output[0].code;const{file:J,seclevel:X}=_(r(e,{sourceType:"module"}),H,{uniqueID:E,scriptUser:U,scriptName:W});if(null!=K&&X<K)throw new Error(`detected seclevel ${R[X]} is lower than stated seclevel ${R[K]}`);if(e=M(J).code,h?e=await $(J,{uniqueID:E,mangleNames:A,forceQuineCheats:F,autocomplete:z}):(T(J,{MemberExpression({node:e}){e.computed||(j("Identifier"==e.property.type),"prototype"==e.property.name?(e.computed=!0,e.property=y.stringLiteral("prototype")):"__proto__"==e.property.name?(e.computed=!0,e.property=y.stringLiteral("__proto__")):P(e.property.name)&&(e.computed=!0,e.property=y.stringLiteral(D(E,e.property.name))))},VariableDeclarator(e){const renameVariables=r=>{switch(r.type){case"Identifier":P(r.name)&&e.scope.rename(r.name,`$${Math.floor(Math.random()*2**52).toString(36).padStart(11,"0")}`);break;case"ObjectPattern":for(const e of r.properties)j("ObjectProperty"==e.type),renameVariables(e.value);break;case"ArrayPattern":for(const e of r.elements)e&&renameVariables(e);break;default:throw new Error(`unknown lValue type "${r.type}"`)}};renameVariables(e.node.id)},ObjectProperty({node:e}){"Identifier"==e.key.type&&P(e.key.name)&&(e.key=y.stringLiteral(D(E,e.key.name)),e.shorthand=!1)},StringLiteral({node:e}){e.value=D(E,e.value)},TemplateLiteral({node:e}){for(const r of e.quasis)r.value.cooked?(r.value.cooked=D(E,r.value.cooked),r.value.raw=r.value.cooked.replaceAll("\\","\\\\").replaceAll("`","\\`").replaceAll("${","$\\{")):r.value.raw=D(E,r.value.raw)},RegExpLiteral(e){e.node.pattern=D(E,e.node.pattern),delete e.node.extra}}),e=await O(M(J,{comments:!1}).code,{parser:"babel",arrowParens:"avoid",semi:!1,trailingComma:"none"})),e=N(e,X,E),P(e))throw new Error('you found a weird edge case where I wasn\'t able to replace illegal strings like "SC$", please report thx');return{script:e,warnings:[]}};export{processScript as default,$ as minify,N as postprocess,I as preprocess,processScript,_ as transform};