hackmud-script-manager 0.19.0-43367ba → 0.19.0-c12fd7c

Sign up to get free protection for your applications and to get access to all the features.
package/constants.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare const supportedExtensions: string[];
2
+ export declare const validDBMethods: string[];
package/constants.js ADDED
@@ -0,0 +1,4 @@
1
+ const supportedExtensions = [`.js`, `.ts`];
2
+ const validDBMethods = [`i`, `r`, `f`, `u`, `u1`, `us`, `ObjectId`];
3
+
4
+ export { supportedExtensions, validDBMethods };
@@ -1 +1,94 @@
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};
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 };
package/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- export { supportedExtensions } from "./constants.json";
1
+ export { supportedExtensions } from "./constants";
2
2
  export { generateTypeDeclaration } from "./generateTypeDeclaration";
3
3
  export { processScript } from "./processScript";
4
4
  export { pull } from "./pull";
5
5
  export { push } from "./push";
6
6
  export { syncMacros } from "./syncMacros";
7
7
  export { watch } from "./watch";
8
- export declare type Info = {
8
+ export type Info = {
9
9
  file: string;
10
10
  users: string[];
11
11
  minLength: number;
package/index.js CHANGED
@@ -1 +1,47 @@
1
- export{s as supportedExtensions}from"./constants-9bb78688.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-class-properties";import"@babel/plugin-proposal-class-static-block";import"@babel/plugin-proposal-decorators";import"@babel/plugin-proposal-json-strings";import"@babel/plugin-proposal-logical-assignment-operators";import"@babel/plugin-proposal-nullish-coalescing-operator";import"@babel/plugin-proposal-numeric-separator";import"@babel/plugin-proposal-object-rest-spread";import"@babel/plugin-proposal-optional-catch-binding";import"@babel/plugin-proposal-optional-chaining";import"@babel/plugin-proposal-private-property-in-object";import"@babel/plugin-transform-exponentiation-operator";import"@babel/traverse";import"@babel/types";import"@rollup/plugin-babel";import"@rollup/plugin-commonjs";import"@rollup/plugin-json";import"@rollup/plugin-node-resolve";import"prettier";import"rollup";import"./processScript/minify.js";import"acorn";import"terser";import"./processScript/shared.js";import"./assert-22a7ef8a.js";import"./spliceString-0e6b5d6d.js";import"./countHackmudCharacters-a08a265f.js";import"./processScript/postprocess.js";import"./processScript/preprocess.js";import"import-meta-resolve";import"./processScript/transform.js";import"fs";import"./writeFilePersistent-ee9c9bfd.js";import"chokidar";
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-class-properties';
13
+ import '@babel/plugin-proposal-class-static-block';
14
+ import '@babel/plugin-proposal-decorators';
15
+ import '@babel/plugin-proposal-json-strings';
16
+ import '@babel/plugin-proposal-logical-assignment-operators';
17
+ import '@babel/plugin-proposal-nullish-coalescing-operator';
18
+ import '@babel/plugin-proposal-numeric-separator';
19
+ import '@babel/plugin-proposal-object-rest-spread';
20
+ import '@babel/plugin-proposal-optional-catch-binding';
21
+ import '@babel/plugin-proposal-optional-chaining';
22
+ import '@babel/plugin-proposal-private-property-in-object';
23
+ import '@babel/plugin-transform-exponentiation-operator';
24
+ import '@babel/traverse';
25
+ import '@babel/types';
26
+ import '@rollup/plugin-babel';
27
+ import '@rollup/plugin-commonjs';
28
+ import '@rollup/plugin-json';
29
+ import '@rollup/plugin-node-resolve';
30
+ import '@samual/lib/assert';
31
+ import 'prettier';
32
+ import 'rollup';
33
+ import './processScript/minify.js';
34
+ import '@samual/lib/countHackmudCharacters';
35
+ import '@samual/lib/spliceString';
36
+ import 'acorn';
37
+ import 'terser';
38
+ import './processScript/shared.js';
39
+ import './processScript/postprocess.js';
40
+ import './processScript/preprocess.js';
41
+ import 'import-meta-resolve';
42
+ import './processScript/transform.js';
43
+ import '@samual/lib/clearObject';
44
+ import '@samual/lib/copyFilePersistent';
45
+ import '@samual/lib/DynamicMap';
46
+ import '@samual/lib/writeFilePersistent';
47
+ import 'chokidar';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hackmud-script-manager",
3
- "version": "0.19.0-43367ba",
3
+ "version": "0.19.0-c12fd7c",
4
4
  "description": "Script manager for game hackmud, with minification, TypeScript support, and player script type definition generation.",
5
5
  "keywords": [
6
6
  "api",
@@ -27,98 +27,56 @@
27
27
  "url": "https://github.com/samualtnorman/hackmud-script-manager.git"
28
28
  },
29
29
  "dependencies": {
30
- "@babel/core": "^7.18.9",
31
- "@babel/generator": "^7.18.9",
32
- "@babel/parser": "^7.18.9",
30
+ "@babel/generator": "^7.22.9",
31
+ "@babel/parser": "^7.22.7",
33
32
  "@babel/plugin-proposal-class-properties": "^7.18.6",
34
- "@babel/plugin-proposal-class-static-block": "^7.18.6",
35
- "@babel/plugin-proposal-decorators": "^7.18.9",
36
- "@babel/plugin-proposal-do-expressions": "^7.18.6",
37
- "@babel/plugin-proposal-function-bind": "^7.18.9",
38
- "@babel/plugin-proposal-function-sent": "^7.18.6",
33
+ "@babel/plugin-proposal-class-static-block": "^7.21.0",
34
+ "@babel/plugin-proposal-decorators": "^7.22.7",
35
+ "@babel/plugin-proposal-do-expressions": "^7.22.5",
36
+ "@babel/plugin-proposal-function-bind": "^7.22.5",
37
+ "@babel/plugin-proposal-function-sent": "^7.22.5",
39
38
  "@babel/plugin-proposal-json-strings": "^7.18.6",
40
- "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9",
39
+ "@babel/plugin-proposal-logical-assignment-operators": "^7.20.7",
41
40
  "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
42
41
  "@babel/plugin-proposal-numeric-separator": "^7.18.6",
43
- "@babel/plugin-proposal-object-rest-spread": "^7.18.9",
42
+ "@babel/plugin-proposal-object-rest-spread": "^7.20.7",
44
43
  "@babel/plugin-proposal-optional-catch-binding": "^7.18.6",
45
- "@babel/plugin-proposal-optional-chaining": "^7.18.9",
46
- "@babel/plugin-proposal-partial-application": "^7.18.9",
47
- "@babel/plugin-proposal-pipeline-operator": "^7.18.9",
48
- "@babel/plugin-proposal-private-property-in-object": "^7.18.6",
49
- "@babel/plugin-proposal-record-and-tuple": "^7.18.6",
50
- "@babel/plugin-proposal-throw-expressions": "^7.18.6",
51
- "@babel/plugin-transform-exponentiation-operator": "^7.18.6",
52
- "@babel/plugin-transform-typescript": "^7.18.8",
53
- "@babel/traverse": "^7.18.9",
54
- "@babel/types": "^7.18.9",
44
+ "@babel/plugin-proposal-optional-chaining": "^7.21.0",
45
+ "@babel/plugin-proposal-partial-application": "^7.22.5",
46
+ "@babel/plugin-proposal-pipeline-operator": "^7.22.5",
47
+ "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
48
+ "@babel/plugin-proposal-record-and-tuple": "^7.22.5",
49
+ "@babel/plugin-proposal-throw-expressions": "^7.22.5",
50
+ "@babel/plugin-transform-exponentiation-operator": "^7.22.5",
51
+ "@babel/plugin-transform-typescript": "^7.22.9",
52
+ "@babel/traverse": "^7.22.8",
53
+ "@babel/types": "^7.22.5",
55
54
  "@bloomberg/record-tuple-polyfill": "^0.0.4",
56
- "@rollup/plugin-babel": "^5.3.1",
57
- "@rollup/plugin-commonjs": "^22.0.1",
58
- "@rollup/plugin-json": "^4.1.0",
59
- "@rollup/plugin-node-resolve": "^13.3.0",
60
- "acorn": "^8.7.1",
61
- "chalk": "^5.0.1",
55
+ "@rollup/plugin-babel": "^6.0.3",
56
+ "@rollup/plugin-commonjs": "^25.0.2",
57
+ "@rollup/plugin-json": "^6.0.0",
58
+ "@rollup/plugin-node-resolve": "^15.1.0",
59
+ "@samual/lib": "^0.8.1",
60
+ "acorn": "^8.10.0",
61
+ "chalk": "^5.3.0",
62
62
  "chokidar": "^3.5.3",
63
- "import-meta-resolve": "^2.0.3",
64
- "prettier": "^2.7.1",
63
+ "import-meta-resolve": "^3.0.0",
64
+ "prettier": "^3.0.0",
65
65
  "proxy-polyfill": "^0.3.2",
66
- "rollup": "^2.77.0",
67
- "terser": "^5.14.2"
68
- },
69
- "devDependencies": {
70
- "@babel/preset-env": "^7.18.9",
71
- "@babel/preset-typescript": "^7.18.6",
72
- "@samual/lib": "^0.3.4",
73
- "@types/babel__core": "^7.1.19",
74
- "@types/babel__generator": "^7.6.4",
75
- "@types/babel__traverse": "^7.17.1",
76
- "@types/node": "^14.18.22",
77
- "@types/prettier": "^2.6.3",
78
- "@types/semver": "^7.3.10",
79
- "@typescript-eslint/eslint-plugin": "^5.30.7",
80
- "@typescript-eslint/parser": "^5.30.7",
81
- "eslint": "^8.20.0",
82
- "eslint-plugin-array-func": "^3.1.7",
83
- "eslint-plugin-eslint-comments": "^3.2.0",
84
- "eslint-plugin-regexp": "^1.7.0",
85
- "eslint-plugin-unicorn": "^43.0.2",
86
- "latest-version": "^7.0.0",
87
- "rollup-plugin-preserve-shebang": "^1.0.1",
88
- "rollup-plugin-terser": "^7.0.2",
89
- "semver": "^7.3.7",
90
- "typescript": "^4.7.4"
91
- },
92
- "optionalDependencies": {
93
- "deasync": "^0.1.27"
66
+ "rollup": "^3.26.2",
67
+ "terser": "^5.19.0"
94
68
  },
95
69
  "engines": {
96
- "node": ">=14"
70
+ "node": ">=16"
97
71
  },
98
72
  "types": "index.d.ts",
99
73
  "type": "module",
100
74
  "exports": {
101
- ".": {
102
- "import": "./index.js",
103
- "require": "./index.cjs"
104
- },
105
- "./*": "./*",
106
- "./generateTypeDeclaration": "./generateTypeDeclaration.js",
107
- "./index": "./index.js",
108
- "./pull": "./pull.js",
109
- "./push": "./push.js",
110
- "./syncMacros": "./syncMacros.js",
111
- "./watch": "./watch.js",
112
- "./bin/hsm": "./bin/hsm.js",
113
- "./processScript/index": "./processScript/index.js",
114
- "./processScript": "./processScript/index.js",
115
- "./processScript/minify": "./processScript/minify.js",
116
- "./processScript/postprocess": "./processScript/postprocess.js",
117
- "./processScript/preprocess": "./processScript/preprocess.js",
118
- "./processScript/shared": "./processScript/shared.js",
119
- "./processScript/transform": "./processScript/transform.js"
75
+ "./*": "./*.js",
76
+ "./*.js": "./*.js"
120
77
  },
121
78
  "bin": {
122
- "hsm": "./bin/hsm.js"
79
+ "hsm.d": "bin/hsm.d.ts",
80
+ "hsm": "bin/hsm.js"
123
81
  }
124
82
  }
@@ -1,9 +1,9 @@
1
- import { LaxPartial } from "@samual/lib";
1
+ import type { LaxPartial } from "@samual/lib";
2
2
  export { minify } from "./minify";
3
3
  export { postprocess } from "./postprocess";
4
4
  export { preprocess } from "./preprocess";
5
5
  export { transform } from "./transform";
6
- export declare type ProcessOptions = {
6
+ export type ProcessOptions = {
7
7
  /** whether to minify the given code */
8
8
  minify: boolean;
9
9
  /** 11 a-z 0-9 characters */
@@ -1 +1,310 @@
1
- import e from"@babel/generator";import{parse as o}from"@babel/parser";import r from"@babel/plugin-proposal-class-properties";import t from"@babel/plugin-proposal-class-static-block";import a from"@babel/plugin-proposal-decorators";import p from"@babel/plugin-proposal-json-strings";import s from"@babel/plugin-proposal-logical-assignment-operators";import l from"@babel/plugin-proposal-nullish-coalescing-operator";import i from"@babel/plugin-proposal-numeric-separator";import n from"@babel/plugin-proposal-object-rest-spread";import m from"@babel/plugin-proposal-optional-catch-binding";import c from"@babel/plugin-proposal-optional-chaining";import u from"@babel/plugin-proposal-private-property-in-object";import f from"@babel/plugin-transform-exponentiation-operator";import d from"@babel/traverse";import b from"@babel/types";import g from"@rollup/plugin-babel";import h from"@rollup/plugin-commonjs";import y from"@rollup/plugin-json";import w from"@rollup/plugin-node-resolve";import{resolve as k}from"path";import x from"prettier";import{rollup as j}from"rollup";import{s as v}from"../constants-9bb78688.js";import{minify as C}from"./minify.js";export{minify}from"./minify.js";import{postprocess as E}from"./postprocess.js";export{postprocess}from"./postprocess.js";import{preprocess as S}from"./preprocess.js";export{preprocess}from"./preprocess.js";import{includesIllegalString as L,replaceUnsafeStrings as $}from"./shared.js";import{transform as N}from"./transform.js";export{transform}from"./transform.js";import{a as I}from"../assert-22a7ef8a.js";import"acorn";import"terser";import"../spliceString-0e6b5d6d.js";import"../countHackmudCharacters-a08a265f.js";import"import-meta-resolve";const{default:P}=g,{format:D}=x,{default:_}=e,{default:M}=d,processScript=async(e,{minify:d=!0,uniqueID:g=Math.floor(Math.random()*2**52).toString(36).padStart(11,"0"),scriptUser:x="UNKNOWN",scriptName:O="UNKNOWN",filePath:T,mangleNames:U=!1,forceQuineCheats:W}={})=>{I(/^\w{11}$/.exec(g));const q=e;let F,H;const z=/^function\s*\(.+\/\/(?<autocomplete>.+)/.exec(e);if(z)e=`export default ${e}`,({autocomplete:F}=z.groups);else for(const o of e.split("\n")){const e=/^\s*\/\/(?<commentContent>.+)/.exec(o);if(!e)break;const r=e.groups.commentContent.trim();if(r.startsWith("@autocomplete "))F=r.slice(14).trimStart();else if(r.startsWith("@seclevel ")){const e=r.slice(10).trimStart().toLowerCase();switch(e){case"fullsec":case"full":case"fs":case"4s":case"f":case"4":H=4;break;case"highsec":case"high":case"hs":case"3s":case"h":case"3":H=3;break;case"midsec":case"mid":case"ms":case"2s":case"m":case"2":H=2;break;case"lowsec":case"low":case"ls":case"1s":case"l":case"1":H=1;break;case"nullsec":case"null":case"ns":case"0s":case"n":case"0":H=0;break;default:throw new Error(`unrecognised seclevel "${e}"`)}}}I(/^\w{11}$/.exec(g));const K=[[a.default,{decoratorsBeforeExport:!0}],[r.default],[t.default],[u.default],[s.default],[i.default],[l.default],[c.default],[m.default],[p.default],[n.default],[f.default]];let Q;if(T)if(Q=k(T),T.endsWith(".ts"))K.push([(await import("@babel/plugin-transform-typescript")).default,{allowDeclareFields:!0,optimizeConstEnums:!0}]);else{const[e,o,r,t,a,p,s]=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")]);K.push([e.default],[o.default],[r.default],[t.default],[a.default,{proposal:"hack",topicToken:"%"}],[p.default],[s.default,{syntaxType:"hash",importPolyfill:!0}])}else{Q=`${g}.ts`;const[e,o,r,t,a,p,s,l]=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")]);K.push([e.default,{allowDeclareFields:!0,optimizeConstEnums:!0}],[o.default],[r.default],[t.default],[a.default],[p.default,{proposal:"hack",topicToken:"%"}],[s.default],[l.default,{syntaxType:"hash",importPolyfill:!0}])}const V=await j({input:Q,plugins:[{name:"hackmud-script-manager",transform:async e=>(await S(e,{uniqueID:g})).code},P({babelHelpers:"bundled",plugins:K,configFile:!1,extensions:v}),h(),w({extensions:v}),y()],treeshake:{moduleSideEffects:!1}}),A=["NULLSEC","LOWSEC","MIDSEC","HIGHSEC","FULLSEC"];e=(await V.generate({})).output[0].code;const{file:B,seclevel:G}=N(o(e,{sourceType:"module"}),q,{uniqueID:g,scriptUser:x,scriptName:O});if(null!=H&&G<H)throw new Error(`detected seclevel ${A[G]} is lower than stated seclevel ${A[H]}`);if(e=_(B).code,d?e=await C(B,{uniqueID:g,mangleNames:U,forceQuineCheats:W,autocomplete:F}):(M(B,{MemberExpression({node:e}){e.computed||(I("Identifier"==e.property.type),"prototype"==e.property.name?(e.computed=!0,e.property=b.stringLiteral("prototype")):"__proto__"==e.property.name?(e.computed=!0,e.property=b.stringLiteral("__proto__")):L(e.property.name)&&(e.computed=!0,e.property=b.stringLiteral($(g,e.property.name))))},VariableDeclarator(e){const renameVariables=o=>{switch(o.type){case"Identifier":L(o.name)&&e.scope.rename(o.name,`$${Math.floor(Math.random()*2**52).toString(36).padStart(11,"0")}`);break;case"ObjectPattern":for(const e of o.properties)I("ObjectProperty"==e.type),renameVariables(e.value);break;case"ArrayPattern":for(const e of o.elements)e&&renameVariables(e);break;default:throw new Error(`unknown lValue type "${o.type}"`)}};renameVariables(e.node.id)},ObjectProperty({node:e}){"Identifier"==e.key.type&&L(e.key.name)&&(e.key=b.stringLiteral($(g,e.key.name)),e.shorthand=!1)},StringLiteral({node:e}){e.value=$(g,e.value)},TemplateLiteral({node:e}){for(const o of e.quasis)o.value.cooked?(o.value.cooked=$(g,o.value.cooked),o.value.raw=o.value.cooked.replace(/\\/g,"\\\\").replace(/`/g,"\\`").replace(/\$\{/g,"$\\{")):o.value.raw=$(g,o.value.raw)},RegExpLiteral(e){e.node.pattern=$(g,e.node.pattern),delete e.node.extra}}),e=D(_(B,{comments:!1}).code,{parser:"babel",arrowParens:"avoid",semi:!1,trailingComma:"none"})),e=E(e,G,g),L(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,processScript};
1
+ import babelGenerator from '@babel/generator';
2
+ import { parse } from '@babel/parser';
3
+ import babelPluginProposalClassProperties from '@babel/plugin-proposal-class-properties';
4
+ import babelPluginProposalClassStaticBlock from '@babel/plugin-proposal-class-static-block';
5
+ import babelPluginProposalDecorators from '@babel/plugin-proposal-decorators';
6
+ import babelPluginProposalJSONStrings from '@babel/plugin-proposal-json-strings';
7
+ import babelPluginProposalLogicalAssignmentOperators from '@babel/plugin-proposal-logical-assignment-operators';
8
+ import babelPluginProposalNullishCoalescingOperator from '@babel/plugin-proposal-nullish-coalescing-operator';
9
+ import babelPluginProposalNumericSeparator from '@babel/plugin-proposal-numeric-separator';
10
+ import babelPluginProposalObjectRestSpread from '@babel/plugin-proposal-object-rest-spread';
11
+ import babelPluginProposalOptionalCatchBinding from '@babel/plugin-proposal-optional-catch-binding';
12
+ import babelPluginProposalOptionalChaining from '@babel/plugin-proposal-optional-chaining';
13
+ import babelPluginProposalPrivatePropertyInObject from '@babel/plugin-proposal-private-property-in-object';
14
+ import babelPluginTransformExponentiationOperator from '@babel/plugin-transform-exponentiation-operator';
15
+ import babelTraverse from '@babel/traverse';
16
+ import t from '@babel/types';
17
+ import { babel } from '@rollup/plugin-babel';
18
+ import rollupPluginCommonJS from '@rollup/plugin-commonjs';
19
+ import rollupPluginJSON from '@rollup/plugin-json';
20
+ import rollupPluginNodeResolve from '@rollup/plugin-node-resolve';
21
+ import { assert } from '@samual/lib/assert';
22
+ import { resolve } from 'path';
23
+ import prettier from 'prettier';
24
+ import { rollup } from 'rollup';
25
+ import { supportedExtensions } from '../constants.js';
26
+ import { minify } from './minify.js';
27
+ import { postprocess } from './postprocess.js';
28
+ import { preprocess } from './preprocess.js';
29
+ import { includesIllegalString, replaceUnsafeStrings } from './shared.js';
30
+ import { transform } from './transform.js';
31
+ import '@samual/lib/countHackmudCharacters';
32
+ import '@samual/lib/spliceString';
33
+ import 'acorn';
34
+ import 'terser';
35
+ import 'import-meta-resolve';
36
+ import '@samual/lib/clearObject';
37
+
38
+ const {
39
+ format
40
+ } = prettier;
41
+ // eslint-disable-next-line @typescript-eslint/consistent-type-imports
42
+ const {
43
+ default: generate
44
+ } = babelGenerator;
45
+ // eslint-disable-next-line @typescript-eslint/consistent-type-imports
46
+ const {
47
+ default: traverse
48
+ } = babelTraverse;
49
+ /**
50
+ * Minifies a given script
51
+ *
52
+ * @param code JavaScript or TypeScript code
53
+ * @param options {@link ProcessOptions details}
54
+ */
55
+ const processScript = async (code, {
56
+ minify: shouldMinify = true,
57
+ uniqueID = Math.floor(Math.random() * 2 ** 52).toString(36).padStart(11, `0`),
58
+ scriptUser = `UNKNOWN`,
59
+ scriptName = `UNKNOWN`,
60
+ filePath,
61
+ mangleNames = false,
62
+ forceQuineCheats
63
+ } = {}) => {
64
+ assert(/^\w{11}$/.exec(uniqueID));
65
+ const sourceCode = code;
66
+ let autocomplete;
67
+ let statedSeclevel;
68
+
69
+ // TODO do seclevel detection and verification per module
70
+
71
+ const autocompleteMatch = /^function\s*\(.+\/\/(?<autocomplete>.+)/.exec(code);
72
+ if (autocompleteMatch) {
73
+ code = `export default ${code}`;
74
+ ({
75
+ autocomplete
76
+ } = autocompleteMatch.groups);
77
+ } else {
78
+ for (const line of code.split(`\n`)) {
79
+ const comment = /^\s*\/\/(?<commentContent>.+)/.exec(line);
80
+ if (!comment) break;
81
+ const commentContent = comment.groups.commentContent.trim();
82
+ if (commentContent.startsWith(`@autocomplete `)) autocomplete = commentContent.slice(14).trimStart();else if (commentContent.startsWith(`@seclevel `)) {
83
+ const seclevelString = commentContent.slice(10).trimStart().toLowerCase();
84
+ switch (seclevelString) {
85
+ case `fullsec`:
86
+ case `full`:
87
+ case `fs`:
88
+ case `4s`:
89
+ case `f`:
90
+ case `4`:
91
+ {
92
+ statedSeclevel = 4;
93
+ }
94
+ break;
95
+ case `highsec`:
96
+ case `high`:
97
+ case `hs`:
98
+ case `3s`:
99
+ case `h`:
100
+ case `3`:
101
+ {
102
+ statedSeclevel = 3;
103
+ }
104
+ break;
105
+ case `midsec`:
106
+ case `mid`:
107
+ case `ms`:
108
+ case `2s`:
109
+ case `m`:
110
+ case `2`:
111
+ {
112
+ statedSeclevel = 2;
113
+ }
114
+ break;
115
+ case `lowsec`:
116
+ case `low`:
117
+ case `ls`:
118
+ case `1s`:
119
+ case `l`:
120
+ case `1`:
121
+ {
122
+ statedSeclevel = 1;
123
+ }
124
+ break;
125
+ case `nullsec`:
126
+ case `null`:
127
+ case `ns`:
128
+ case `0s`:
129
+ case `n`:
130
+ case `0`:
131
+ {
132
+ statedSeclevel = 0;
133
+ }
134
+ break;
135
+ default:
136
+ // TODO turn into warninig when I get round to those
137
+ throw new Error(`unrecognised seclevel "${seclevelString}"`);
138
+ }
139
+ }
140
+ }
141
+ }
142
+ assert(/^\w{11}$/.exec(uniqueID));
143
+ const plugins = [[babelPluginProposalDecorators.default, {
144
+ decoratorsBeforeExport: true
145
+ }], [babelPluginProposalClassProperties.default], [babelPluginProposalClassStaticBlock.default], [babelPluginProposalPrivatePropertyInObject.default], [babelPluginProposalLogicalAssignmentOperators.default], [babelPluginProposalNumericSeparator.default], [babelPluginProposalNullishCoalescingOperator.default], [babelPluginProposalOptionalChaining.default], [babelPluginProposalOptionalCatchBinding.default], [babelPluginProposalJSONStrings.default], [babelPluginProposalObjectRestSpread.default], [babelPluginTransformExponentiationOperator.default]];
146
+ let filePathResolved;
147
+ if (filePath) {
148
+ filePathResolved = resolve(filePath);
149
+ if (filePath.endsWith(`.ts`)) plugins.push([(await import('@babel/plugin-transform-typescript')).default, {
150
+ allowDeclareFields: true,
151
+ optimizeConstEnums: true
152
+ }]);else {
153
+ 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')]);
154
+ plugins.push([babelPluginProposalDoExpressions.default], [babelPluginProposalFunctionBind.default], [babelPluginProposalFunctionSent.default], [babelPluginProposalPartialApplication.default], [babelPluginProposalPipelineOperator.default, {
155
+ proposal: `hack`,
156
+ topicToken: `%`
157
+ }], [babelPluginProposalThrowExpressions.default], [babelPluginProposalRecordAndTuple.default, {
158
+ syntaxType: `hash`,
159
+ importPolyfill: true
160
+ }]);
161
+ }
162
+ } else {
163
+ filePathResolved = `${uniqueID}.ts`;
164
+ 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')]);
165
+ plugins.push([babelPluginTransformTypescript.default, {
166
+ allowDeclareFields: true,
167
+ optimizeConstEnums: true
168
+ }], [babelPluginProposalDoExpressions.default], [babelPluginProposalFunctionBind.default], [babelPluginProposalFunctionSent.default], [babelPluginProposalPartialApplication.default], [babelPluginProposalPipelineOperator.default, {
169
+ proposal: `hack`,
170
+ topicToken: `%`
171
+ }], [babelPluginProposalThrowExpressions.default], [babelPluginProposalRecordAndTuple.default, {
172
+ syntaxType: `hash`,
173
+ importPolyfill: true
174
+ }]);
175
+ }
176
+ const bundle = await rollup({
177
+ input: filePathResolved,
178
+ plugins: [{
179
+ name: `hackmud-script-manager`,
180
+ transform: async code => (await preprocess(code, {
181
+ uniqueID
182
+ })).code
183
+ }, babel({
184
+ babelHelpers: `bundled`,
185
+ plugins,
186
+ configFile: false,
187
+ extensions: supportedExtensions
188
+ }), rollupPluginCommonJS(), rollupPluginNodeResolve({
189
+ extensions: supportedExtensions
190
+ }), rollupPluginJSON()],
191
+ treeshake: {
192
+ moduleSideEffects: false
193
+ }
194
+ });
195
+ const seclevelNames = [`NULLSEC`, `LOWSEC`, `MIDSEC`, `HIGHSEC`, `FULLSEC`];
196
+ code = (await bundle.generate({})).output[0].code;
197
+ const {
198
+ file,
199
+ seclevel
200
+ } = transform(parse(code, {
201
+ sourceType: `module`
202
+ }), sourceCode, {
203
+ uniqueID,
204
+ scriptUser,
205
+ scriptName
206
+ });
207
+ if (statedSeclevel != undefined && seclevel < statedSeclevel)
208
+ // TODO replace with a warning and build script anyway
209
+ throw new Error(`detected seclevel ${seclevelNames[seclevel]} is lower than stated seclevel ${seclevelNames[statedSeclevel]}`);
210
+ code = generate(file).code;
211
+ if (shouldMinify) code = await minify(file, {
212
+ uniqueID,
213
+ mangleNames,
214
+ forceQuineCheats,
215
+ autocomplete
216
+ });else {
217
+ traverse(file, {
218
+ MemberExpression({
219
+ node: memberExpression
220
+ }) {
221
+ if (memberExpression.computed) return;
222
+ assert(memberExpression.property.type == `Identifier`);
223
+ if (memberExpression.property.name == `prototype`) {
224
+ memberExpression.computed = true;
225
+ memberExpression.property = t.stringLiteral(`prototype`);
226
+ } else if (memberExpression.property.name == `__proto__`) {
227
+ memberExpression.computed = true;
228
+ memberExpression.property = t.stringLiteral(`__proto__`);
229
+ } else if (includesIllegalString(memberExpression.property.name)) {
230
+ memberExpression.computed = true;
231
+ memberExpression.property = t.stringLiteral(replaceUnsafeStrings(uniqueID, memberExpression.property.name));
232
+ }
233
+ },
234
+ VariableDeclarator(path) {
235
+ const renameVariables = lValue => {
236
+ switch (lValue.type) {
237
+ case `Identifier`:
238
+ {
239
+ if (includesIllegalString(lValue.name)) path.scope.rename(lValue.name, `$${Math.floor(Math.random() * 2 ** 52).toString(36).padStart(11, `0`)}`);
240
+ }
241
+ break;
242
+ case `ObjectPattern`:
243
+ {
244
+ for (const property of lValue.properties) {
245
+ assert(property.type == `ObjectProperty`);
246
+ renameVariables(property.value);
247
+ }
248
+ }
249
+ break;
250
+ case `ArrayPattern`:
251
+ {
252
+ for (const element of lValue.elements) {
253
+ if (element) renameVariables(element);
254
+ }
255
+ }
256
+ break;
257
+ default:
258
+ throw new Error(`unknown lValue type "${lValue.type}"`);
259
+ }
260
+ };
261
+ renameVariables(path.node.id);
262
+ },
263
+ ObjectProperty({
264
+ node: objectProperty
265
+ }) {
266
+ if (objectProperty.key.type == `Identifier` && includesIllegalString(objectProperty.key.name)) {
267
+ objectProperty.key = t.stringLiteral(replaceUnsafeStrings(uniqueID, objectProperty.key.name));
268
+ objectProperty.shorthand = false;
269
+ }
270
+ },
271
+ StringLiteral({
272
+ node
273
+ }) {
274
+ node.value = replaceUnsafeStrings(uniqueID, node.value);
275
+ },
276
+ TemplateLiteral({
277
+ node
278
+ }) {
279
+ for (const templateElement of node.quasis) {
280
+ if (templateElement.value.cooked) {
281
+ templateElement.value.cooked = replaceUnsafeStrings(uniqueID, templateElement.value.cooked);
282
+ templateElement.value.raw = templateElement.value.cooked.replaceAll(`\\`, `\\\\`).replaceAll(`\``, `\\\``).replaceAll(`\${`, `$\\{`);
283
+ } else templateElement.value.raw = replaceUnsafeStrings(uniqueID, templateElement.value.raw);
284
+ }
285
+ },
286
+ RegExpLiteral(path) {
287
+ path.node.pattern = replaceUnsafeStrings(uniqueID, path.node.pattern);
288
+ delete path.node.extra;
289
+ }
290
+ });
291
+
292
+ // we can't have comments because they may contain illegal strings
293
+ code = await format(generate(file, {
294
+ comments: false
295
+ }).code, {
296
+ parser: `babel`,
297
+ arrowParens: `avoid`,
298
+ semi: false,
299
+ trailingComma: `none`
300
+ });
301
+ }
302
+ code = postprocess(code, seclevel, uniqueID);
303
+ 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`);
304
+ return {
305
+ script: code,
306
+ warnings: []
307
+ };
308
+ };
309
+
310
+ export { processScript as default, minify, postprocess, preprocess, processScript, transform };