hackmud-script-manager 0.19.0 → 0.19.1-4bde221

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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",
3
+ "version": "0.19.1-4bde221",
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 }