hackmud-script-manager 0.19.0-fa82f73 → 0.19.1-27bbd7d

Sign up to get free protection for your applications and to get access to all the features.
@@ -1 +1,68 @@
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
+ const generateTypeDeclaration = async (sourceDirectory, hackmudPath) => {
4
+ const users = new Set()
5
+ if (hackmudPath)
6
+ for (const dirent of await readdir(hackmudPath, { withFileTypes: !0 }))
7
+ dirent.isFile() && dirent.name.endsWith(".key") && users.add(basename(dirent.name, ".key"))
8
+ const wildScripts = [],
9
+ wildAnyScripts = [],
10
+ allScripts = {},
11
+ allAnyScripts = {}
12
+ await Promise.all(
13
+ (await readdir(sourceDirectory, { withFileTypes: !0 })).map(async dirent => {
14
+ if (dirent.isFile())
15
+ dirent.name.endsWith(".ts") ?
16
+ dirent.name.endsWith(".d.ts") || wildScripts.push(basename(dirent.name, ".ts"))
17
+ : dirent.name.endsWith(".js") && wildAnyScripts.push(basename(dirent.name, ".js"))
18
+ else if (dirent.isDirectory()) {
19
+ const scripts = [],
20
+ anyScripts = []
21
+ allScripts[dirent.name] = scripts
22
+ allAnyScripts[dirent.name] = anyScripts
23
+ users.add(dirent.name)
24
+ for (const file of await readdir(resolve(sourceDirectory, dirent.name), { withFileTypes: !0 }))
25
+ file.isFile() &&
26
+ (file.name.endsWith(".ts") ?
27
+ dirent.name.endsWith(".d.ts") || scripts.push(basename(file.name, ".ts"))
28
+ : file.name.endsWith(".js") && anyScripts.push(basename(file.name, ".js")))
29
+ }
30
+ })
31
+ )
32
+ sourceDirectory = resolve(sourceDirectory)
33
+ let o = ""
34
+ for (const script of wildScripts) o += `type $${script}$ = typeof import("${sourceDirectory}/${script}").default\n`
35
+ o += "\n"
36
+ for (const user in allScripts) {
37
+ const scripts = allScripts[user]
38
+ for (const script of scripts)
39
+ o += `type $${user}$${script}$ = typeof import("${sourceDirectory}/${user}/${script}").default\n`
40
+ }
41
+ o +=
42
+ "\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"
43
+ for (const script of wildScripts) o += `\t${script}: Subscript<$${script}$>\n`
44
+ for (const script of wildAnyScripts) o += `\t${script}: (...args: any) => any\n`
45
+ o += "}\n\ninterface PlayerFullsec {"
46
+ let lastWasMultiLine = !0
47
+ for (const user of users) {
48
+ const scripts = allScripts[user],
49
+ anyScripts = allAnyScripts[user]
50
+ if ((scripts && scripts.length) || (anyScripts && anyScripts.length)) {
51
+ lastWasMultiLine = !0
52
+ o += `\n\t${user}: WildFullsec & {\n`
53
+ if (scripts) for (const script of scripts) o += `\t\t${script}: Subscript<$${user}$${script}$>\n`
54
+ if (anyScripts) for (const script of anyScripts) o += `\t\t${script}: (...args: any) => any\n`
55
+ o += "\t}"
56
+ } else {
57
+ if (lastWasMultiLine) {
58
+ o += "\n"
59
+ lastWasMultiLine = !1
60
+ }
61
+ o += `\t${user}: WildFullsec`
62
+ }
63
+ o += "\n"
64
+ }
65
+ o += "}\n"
66
+ return o
67
+ }
68
+ export { generateTypeDeclaration as default, generateTypeDeclaration }
package/index.js CHANGED
@@ -1 +1,50 @@
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";
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/Cache"
49
+ import "@samual/lib/writeFilePersistent"
50
+ import "chokidar"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hackmud-script-manager",
3
- "version": "0.19.0-fa82f73",
3
+ "version": "0.19.1-27bbd7d",
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,50 +27,51 @@
27
27
  "url": "https://github.com/samualtnorman/hackmud-script-manager.git"
28
28
  },
29
29
  "dependencies": {
30
- "@babel/generator": "^7.23.6",
31
- "@babel/parser": "^7.23.6",
32
- "@babel/plugin-proposal-decorators": "^7.23.7",
33
- "@babel/plugin-proposal-destructuring-private": "^7.23.3",
34
- "@babel/plugin-proposal-do-expressions": "^7.23.3",
35
- "@babel/plugin-proposal-explicit-resource-management": "^7.23.3",
36
- "@babel/plugin-proposal-function-bind": "^7.23.3",
37
- "@babel/plugin-proposal-function-sent": "^7.23.3",
38
- "@babel/plugin-proposal-partial-application": "^7.23.3",
39
- "@babel/plugin-proposal-pipeline-operator": "^7.23.3",
40
- "@babel/plugin-proposal-record-and-tuple": "^7.23.3",
41
- "@babel/plugin-proposal-throw-expressions": "^7.23.3",
42
- "@babel/plugin-transform-class-properties": "^7.23.3",
43
- "@babel/plugin-transform-class-static-block": "^7.23.4",
44
- "@babel/plugin-transform-exponentiation-operator": "^7.23.3",
45
- "@babel/plugin-transform-json-strings": "^7.23.4",
46
- "@babel/plugin-transform-logical-assignment-operators": "^7.23.4",
47
- "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4",
48
- "@babel/plugin-transform-numeric-separator": "^7.23.4",
49
- "@babel/plugin-transform-object-rest-spread": "^7.23.4",
50
- "@babel/plugin-transform-optional-catch-binding": "^7.23.4",
51
- "@babel/plugin-transform-optional-chaining": "^7.23.4",
52
- "@babel/plugin-transform-private-property-in-object": "^7.23.4",
53
- "@babel/plugin-transform-typescript": "^7.23.6",
54
- "@babel/plugin-transform-unicode-sets-regex": "^7.23.3",
55
- "@babel/traverse": "^7.23.7",
56
- "@babel/types": "^7.23.6",
30
+ "@babel/generator": "^7.24.4",
31
+ "@babel/parser": "^7.24.4",
32
+ "@babel/plugin-proposal-decorators": "^7.24.1",
33
+ "@babel/plugin-proposal-destructuring-private": "^7.24.1",
34
+ "@babel/plugin-proposal-do-expressions": "^7.24.1",
35
+ "@babel/plugin-proposal-explicit-resource-management": "^7.24.1",
36
+ "@babel/plugin-proposal-function-bind": "^7.24.1",
37
+ "@babel/plugin-proposal-function-sent": "^7.24.1",
38
+ "@babel/plugin-proposal-partial-application": "^7.24.1",
39
+ "@babel/plugin-proposal-pipeline-operator": "^7.24.1",
40
+ "@babel/plugin-proposal-record-and-tuple": "^7.24.1",
41
+ "@babel/plugin-proposal-throw-expressions": "^7.24.1",
42
+ "@babel/plugin-transform-class-properties": "^7.24.1",
43
+ "@babel/plugin-transform-class-static-block": "^7.24.4",
44
+ "@babel/plugin-transform-exponentiation-operator": "^7.24.1",
45
+ "@babel/plugin-transform-json-strings": "^7.24.1",
46
+ "@babel/plugin-transform-logical-assignment-operators": "^7.24.1",
47
+ "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1",
48
+ "@babel/plugin-transform-numeric-separator": "^7.24.1",
49
+ "@babel/plugin-transform-object-rest-spread": "^7.24.1",
50
+ "@babel/plugin-transform-optional-catch-binding": "^7.24.1",
51
+ "@babel/plugin-transform-optional-chaining": "^7.24.1",
52
+ "@babel/plugin-transform-private-property-in-object": "^7.24.1",
53
+ "@babel/plugin-transform-typescript": "^7.24.4",
54
+ "@babel/plugin-transform-unicode-sets-regex": "^7.24.1",
55
+ "@babel/traverse": "^7.24.1",
56
+ "@babel/types": "^7.24.0",
57
57
  "@bloomberg/record-tuple-polyfill": "^0.0.4",
58
58
  "@rollup/plugin-babel": "^6.0.4",
59
59
  "@rollup/plugin-commonjs": "^25.0.7",
60
60
  "@rollup/plugin-json": "^6.1.0",
61
61
  "@rollup/plugin-node-resolve": "^15.2.3",
62
- "@samual/lib": "^0.9.1",
62
+ "@samual/lib": "^0.10.1",
63
63
  "acorn": "^8.11.3",
64
64
  "chalk": "^5.3.0",
65
- "chokidar": "^3.5.3",
65
+ "chokidar": "^3.6.0",
66
66
  "import-meta-resolve": "^4.0.0",
67
- "prettier": "^3.2.2",
67
+ "prettier": "^3.2.5",
68
68
  "proxy-polyfill": "^0.3.2",
69
- "rollup": "^4.9.5",
70
- "terser": "^5.26.0"
69
+ "rollup": "^4.14.2",
70
+ "terser": "^5.30.3"
71
71
  },
72
72
  "engines": {
73
- "node": ">=20"
73
+ "node": "^18 || >=20",
74
+ "pnpm": "^8.15.7"
74
75
  },
75
76
  "type": "module",
76
77
  "exports": {
@@ -1 +1,316 @@
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};
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
+ const { format } = prettier,
41
+ { default: generate } = babelGenerator,
42
+ { default: traverse } = babelTraverse,
43
+ processScript = async (
44
+ code,
45
+ {
46
+ minify: shouldMinify = !0,
47
+ uniqueID = Math.floor(Math.random() * 2 ** 52)
48
+ .toString(36)
49
+ .padStart(11, "0"),
50
+ scriptUser = "UNKNOWN",
51
+ scriptName = "UNKNOWN",
52
+ filePath,
53
+ mangleNames = !1,
54
+ forceQuineCheats
55
+ } = {}
56
+ ) => {
57
+ assert(/^\w{11}$/.exec(uniqueID))
58
+ const sourceCode = code
59
+ let autocomplete, statedSeclevel
60
+ const autocompleteMatch = /^function\s*\(.+\/\/(?<autocomplete>.+)/.exec(code)
61
+ if (autocompleteMatch) {
62
+ code = "export default " + code
63
+ ;({ autocomplete } = autocompleteMatch.groups)
64
+ } else
65
+ for (const line of code.split("\n")) {
66
+ const comment = /^\s*\/\/(?<commentContent>.+)/.exec(line)
67
+ if (!comment) break
68
+ const commentContent = comment.groups.commentContent.trim()
69
+ if (commentContent.startsWith("@autocomplete ")) autocomplete = commentContent.slice(14).trimStart()
70
+ else if (commentContent.startsWith("@seclevel ")) {
71
+ const seclevelString = commentContent.slice(10).trimStart().toLowerCase()
72
+ switch (seclevelString) {
73
+ case "fullsec":
74
+ case "full":
75
+ case "fs":
76
+ case "4s":
77
+ case "f":
78
+ case "4":
79
+ statedSeclevel = 4
80
+ break
81
+ case "highsec":
82
+ case "high":
83
+ case "hs":
84
+ case "3s":
85
+ case "h":
86
+ case "3":
87
+ statedSeclevel = 3
88
+ break
89
+ case "midsec":
90
+ case "mid":
91
+ case "ms":
92
+ case "2s":
93
+ case "m":
94
+ case "2":
95
+ statedSeclevel = 2
96
+ break
97
+ case "lowsec":
98
+ case "low":
99
+ case "ls":
100
+ case "1s":
101
+ case "l":
102
+ case "1":
103
+ statedSeclevel = 1
104
+ break
105
+ case "nullsec":
106
+ case "null":
107
+ case "ns":
108
+ case "0s":
109
+ case "n":
110
+ case "0":
111
+ statedSeclevel = 0
112
+ break
113
+ default:
114
+ throw Error(`unrecognised seclevel "${seclevelString}"`)
115
+ }
116
+ }
117
+ }
118
+ assert(/^\w{11}$/.exec(uniqueID))
119
+ const plugins = [
120
+ [babelPluginProposalDecorators.default, { decoratorsBeforeExport: !0 }],
121
+ [babelPluginTransformClassProperties.default],
122
+ [babelPluginTransformClassStaticBlock.default],
123
+ [babelPluginTransformPrivatePropertyInObject.default],
124
+ [babelPluginTransformLogicalAssignmentOperators.default],
125
+ [babelPluginTransformNumericSeparator.default],
126
+ [babelPluginTransformNullishCoalescingOperator.default],
127
+ [babelPluginTransformOptionalChaining.default],
128
+ [babelPluginTransformOptionalCatchBinding.default],
129
+ [babelPluginTransformJsonStrings.default],
130
+ [babelPluginTransformObjectRestSpread.default],
131
+ [babelPluginTransformExponentiationOperator.default],
132
+ [babelPluginTransformUnicodeSetsRegex.default],
133
+ [babelPluginProposalDestructuringPrivate.default],
134
+ [babelPluginProposalExplicitResourceManagement.default]
135
+ ]
136
+ let filePathResolved
137
+ if (filePath) {
138
+ filePathResolved = resolve(filePath)
139
+ if (filePath.endsWith(".ts"))
140
+ plugins.push([
141
+ (await import("@babel/plugin-transform-typescript")).default,
142
+ { allowDeclareFields: !0, optimizeConstEnums: !0 }
143
+ ])
144
+ else {
145
+ const [
146
+ babelPluginProposalDoExpressions,
147
+ babelPluginProposalFunctionBind,
148
+ babelPluginProposalFunctionSent,
149
+ babelPluginProposalPartialApplication,
150
+ babelPluginProposalPipelineOperator,
151
+ babelPluginProposalThrowExpressions,
152
+ babelPluginProposalRecordAndTuple
153
+ ] = await Promise.all([
154
+ import("@babel/plugin-proposal-do-expressions"),
155
+ import("@babel/plugin-proposal-function-bind"),
156
+ import("@babel/plugin-proposal-function-sent"),
157
+ import("@babel/plugin-proposal-partial-application"),
158
+ import("@babel/plugin-proposal-pipeline-operator"),
159
+ import("@babel/plugin-proposal-throw-expressions"),
160
+ import("@babel/plugin-proposal-record-and-tuple")
161
+ ])
162
+ plugins.push(
163
+ [babelPluginProposalDoExpressions.default],
164
+ [babelPluginProposalFunctionBind.default],
165
+ [babelPluginProposalFunctionSent.default],
166
+ [babelPluginProposalPartialApplication.default],
167
+ [babelPluginProposalPipelineOperator.default, { proposal: "hack", topicToken: "%" }],
168
+ [babelPluginProposalThrowExpressions.default],
169
+ [babelPluginProposalRecordAndTuple.default, { syntaxType: "hash", importPolyfill: !0 }]
170
+ )
171
+ }
172
+ } else {
173
+ filePathResolved = uniqueID + ".ts"
174
+ const [
175
+ babelPluginTransformTypescript,
176
+ babelPluginProposalDoExpressions,
177
+ babelPluginProposalFunctionBind,
178
+ babelPluginProposalFunctionSent,
179
+ babelPluginProposalPartialApplication,
180
+ babelPluginProposalPipelineOperator,
181
+ babelPluginProposalThrowExpressions,
182
+ babelPluginProposalRecordAndTuple
183
+ ] = await Promise.all([
184
+ import("@babel/plugin-transform-typescript"),
185
+ import("@babel/plugin-proposal-do-expressions"),
186
+ import("@babel/plugin-proposal-function-bind"),
187
+ import("@babel/plugin-proposal-function-sent"),
188
+ import("@babel/plugin-proposal-partial-application"),
189
+ import("@babel/plugin-proposal-pipeline-operator"),
190
+ import("@babel/plugin-proposal-throw-expressions"),
191
+ import("@babel/plugin-proposal-record-and-tuple")
192
+ ])
193
+ plugins.push(
194
+ [babelPluginTransformTypescript.default, { allowDeclareFields: !0, optimizeConstEnums: !0 }],
195
+ [babelPluginProposalDoExpressions.default],
196
+ [babelPluginProposalFunctionBind.default],
197
+ [babelPluginProposalFunctionSent.default],
198
+ [babelPluginProposalPartialApplication.default],
199
+ [babelPluginProposalPipelineOperator.default, { proposal: "hack", topicToken: "%" }],
200
+ [babelPluginProposalThrowExpressions.default],
201
+ [babelPluginProposalRecordAndTuple.default, { syntaxType: "hash", importPolyfill: !0 }]
202
+ )
203
+ }
204
+ const bundle = await rollup({
205
+ input: filePathResolved,
206
+ plugins: [
207
+ {
208
+ name: "hackmud-script-manager",
209
+ transform: async code => (await preprocess(code, { uniqueID })).code
210
+ },
211
+ babel({ babelHelpers: "bundled", plugins, configFile: !1, extensions: supportedExtensions }),
212
+ rollupPluginCommonJS(),
213
+ rollupPluginNodeResolve({ extensions: supportedExtensions }),
214
+ rollupPluginJSON()
215
+ ],
216
+ treeshake: { moduleSideEffects: !1 }
217
+ }),
218
+ seclevelNames = ["NULLSEC", "LOWSEC", "MIDSEC", "HIGHSEC", "FULLSEC"]
219
+ code = (await bundle.generate({})).output[0].code
220
+ const { file, seclevel } = transform(parse(code, { sourceType: "module" }), sourceCode, {
221
+ uniqueID,
222
+ scriptUser,
223
+ scriptName
224
+ })
225
+ if (null != statedSeclevel && seclevel < statedSeclevel)
226
+ throw Error(
227
+ `detected seclevel ${seclevelNames[seclevel]} is lower than stated seclevel ${seclevelNames[statedSeclevel]}`
228
+ )
229
+ code = generate(file).code
230
+ if (shouldMinify) code = await minify(file, { uniqueID, mangleNames, forceQuineCheats, autocomplete })
231
+ else {
232
+ traverse(file, {
233
+ MemberExpression({ node: memberExpression }) {
234
+ if (!memberExpression.computed) {
235
+ assert("Identifier" == memberExpression.property.type)
236
+ if ("prototype" == memberExpression.property.name) {
237
+ memberExpression.computed = !0
238
+ memberExpression.property = t.stringLiteral("prototype")
239
+ } else if ("__proto__" == memberExpression.property.name) {
240
+ memberExpression.computed = !0
241
+ memberExpression.property = t.stringLiteral("__proto__")
242
+ } else if (includesIllegalString(memberExpression.property.name)) {
243
+ memberExpression.computed = !0
244
+ memberExpression.property = t.stringLiteral(
245
+ replaceUnsafeStrings(uniqueID, memberExpression.property.name)
246
+ )
247
+ }
248
+ }
249
+ },
250
+ VariableDeclarator(path) {
251
+ const renameVariables = lValue => {
252
+ switch (lValue.type) {
253
+ case "Identifier":
254
+ includesIllegalString(lValue.name) &&
255
+ path.scope.rename(
256
+ lValue.name,
257
+ "$" +
258
+ Math.floor(Math.random() * 2 ** 52)
259
+ .toString(36)
260
+ .padStart(11, "0")
261
+ )
262
+ break
263
+ case "ObjectPattern":
264
+ for (const property of lValue.properties) {
265
+ assert("ObjectProperty" == property.type)
266
+ renameVariables(property.value)
267
+ }
268
+ break
269
+ case "ArrayPattern":
270
+ for (const element of lValue.elements) element && renameVariables(element)
271
+ break
272
+ default:
273
+ throw Error(`unknown lValue type "${lValue.type}"`)
274
+ }
275
+ }
276
+ renameVariables(path.node.id)
277
+ },
278
+ ObjectProperty({ node: objectProperty }) {
279
+ if ("Identifier" == objectProperty.key.type && includesIllegalString(objectProperty.key.name)) {
280
+ objectProperty.key = t.stringLiteral(replaceUnsafeStrings(uniqueID, objectProperty.key.name))
281
+ objectProperty.shorthand = !1
282
+ }
283
+ },
284
+ StringLiteral({ node }) {
285
+ node.value = replaceUnsafeStrings(uniqueID, node.value)
286
+ },
287
+ TemplateLiteral({ node }) {
288
+ for (const templateElement of node.quasis)
289
+ if (templateElement.value.cooked) {
290
+ templateElement.value.cooked = replaceUnsafeStrings(uniqueID, templateElement.value.cooked)
291
+ templateElement.value.raw = templateElement.value.cooked
292
+ .replaceAll("\\", "\\\\")
293
+ .replaceAll("`", "\\`")
294
+ .replaceAll("${", "$\\{")
295
+ } else templateElement.value.raw = replaceUnsafeStrings(uniqueID, templateElement.value.raw)
296
+ },
297
+ RegExpLiteral(path) {
298
+ path.node.pattern = replaceUnsafeStrings(uniqueID, path.node.pattern)
299
+ delete path.node.extra
300
+ }
301
+ })
302
+ code = await format(generate(file, { comments: !1 }).code, {
303
+ parser: "babel",
304
+ arrowParens: "avoid",
305
+ semi: !1,
306
+ trailingComma: "none"
307
+ })
308
+ }
309
+ code = postprocess(code, seclevel, uniqueID)
310
+ if (includesIllegalString(code))
311
+ throw Error(
312
+ 'you found a weird edge case where I wasn\'t able to replace illegal strings like "SC$", please report thx'
313
+ )
314
+ return { script: code, warnings: [] }
315
+ }
316
+ export { processScript as default, minify, postprocess, preprocess, processScript, transform }