hackmud-script-manager 0.20.3 → 0.20.4-0dd1d9b

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,6 @@
1
1
  import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
2
2
  import { basename, resolve } from "path"
3
+ import * as PathPosix from "path/posix"
3
4
  async function generateTypeDeclaration(sourceDirectory, hackmudPath) {
4
5
  const users = new Set()
5
6
  if (hackmudPath)
@@ -29,7 +30,7 @@ async function generateTypeDeclaration(sourceDirectory, hackmudPath) {
29
30
  }
30
31
  })
31
32
  )
32
- sourceDirectory = resolve(sourceDirectory)
33
+ sourceDirectory = PathPosix.resolve(sourceDirectory)
33
34
  let o = ""
34
35
  for (const script of wildScripts) o += `type $${script}$ = typeof import("${sourceDirectory}/${script}").default\n`
35
36
  o += "\n"
package/index.js CHANGED
@@ -7,6 +7,7 @@ export { syncMacros } from "./syncMacros.js"
7
7
  export { watch } from "./watch.js"
8
8
  import "@samual/lib/readDirectoryWithStats"
9
9
  import "path"
10
+ import "path/posix"
10
11
  import "@babel/generator"
11
12
  import "@babel/parser"
12
13
  import "@babel/plugin-proposal-decorators"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hackmud-script-manager",
3
- "version": "0.20.3",
3
+ "version": "0.20.4-0dd1d9b",
4
4
  "description": "Script manager for game hackmud, with minification, TypeScript support, and player script type definition generation.",
5
5
  "keywords": [
6
6
  "api",
@@ -20,7 +20,11 @@
20
20
  "homepage": "https://github.com/samualtnorman/hackmud-script-manager#readme",
21
21
  "bugs": "https://github.com/samualtnorman/hackmud-script-manager/issues",
22
22
  "license": "MIT",
23
- "author": "Samual Norman",
23
+ "author": "Samual Norman <me@samual.uk> (https://samual.uk/)",
24
+ "contributors": [
25
+ "Daniel Swann (https://github.com/danswann)",
26
+ "Longboyy"
27
+ ],
24
28
  "main": "index.js",
25
29
  "repository": {
26
30
  "type": "git",
@@ -204,6 +204,7 @@ async function processScript(
204
204
  const bundle = await rollup({
205
205
  input: filePathResolved,
206
206
  plugins: [
207
+ rollupPluginJSON({ preferConst: !0 }),
207
208
  {
208
209
  name: "hackmud-script-manager",
209
210
  async transform(code, id) {
@@ -227,8 +228,7 @@ async function processScript(
227
228
  },
228
229
  babel({ babelHelpers: "bundled", plugins, configFile: !1, extensions: supportedExtensions }),
229
230
  rollupPluginCommonJS(),
230
- rollupPluginNodeResolve({ extensions: supportedExtensions }),
231
- rollupPluginJSON()
231
+ rollupPluginNodeResolve({ extensions: supportedExtensions })
232
232
  ],
233
233
  treeshake: { moduleSideEffects: !1 }
234
234
  }),
@@ -323,7 +323,7 @@ async function processScript(
323
323
  trailingComma: "none"
324
324
  })
325
325
  }
326
- code = postprocess(code, seclevel, uniqueId)
326
+ code = postprocess(code, uniqueId)
327
327
  if (includesIllegalString(code))
328
328
  throw Error(
329
329
  'you found a weird edge case where I wasn\'t able to replace illegal strings like "SC$", please report thx'
@@ -43,15 +43,6 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
43
43
  )
44
44
  }
45
45
  }
46
- const hashGReferencePaths = getReferencePathsToGlobal(`$${uniqueId}$GLOBAL$`, program)
47
- if (hashGReferencePaths.length > 3) {
48
- for (const path of hashGReferencePaths) path.replaceWith(t.identifier(`_${uniqueId}_G_`))
49
- mainFunctionPath.node.body.body.unshift(
50
- t.variableDeclaration("let", [
51
- t.variableDeclarator(t.identifier(`_${uniqueId}_G_`), t.identifier(`$${uniqueId}$GLOBAL$`))
52
- ])
53
- )
54
- }
55
46
  const jsonValues = []
56
47
  let scriptBeforeJSONValueReplacement,
57
48
  comment,
@@ -61,7 +52,7 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
61
52
  traverse(fileBeforeJSONValueReplacement, {
62
53
  MemberExpression({ node: memberExpression }) {
63
54
  if (!memberExpression.computed) {
64
- assert("Identifier" == memberExpression.property.type, "src/processScript/minify.ts:127:60")
55
+ assert("Identifier" == memberExpression.property.type, "src/processScript/minify.ts:115:60")
65
56
  if ("prototype" == memberExpression.property.name) {
66
57
  memberExpression.computed = !0
67
58
  memberExpression.property = t.identifier(`_${uniqueId}_PROTOTYPE_PROPERTY_`)
@@ -136,7 +127,8 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
136
127
  const promises = []
137
128
  traverse(file, {
138
129
  FunctionDeclaration(path) {
139
- path.traverse({
130
+ const body = path.get("body")
131
+ body.traverse({
140
132
  Function(path) {
141
133
  "CallExpression" != path.parent.type && "callee" != path.parentKey && path.skip()
142
134
  },
@@ -152,7 +144,7 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
152
144
  path.replaceWith(t.identifier(`_${uniqueId}_JSON_VALUE_${jsonValues.push(o) - 1}_`))
153
145
  }
154
146
  })
155
- path.traverse({
147
+ body.traverse({
156
148
  TemplateLiteral(path) {
157
149
  if ("TaggedTemplateExpression" == path.parent.type) return
158
150
  const templateLiteral = path.node
@@ -172,7 +164,7 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
172
164
  },
173
165
  MemberExpression({ node: memberExpression }) {
174
166
  if (!memberExpression.computed) {
175
- assert("Identifier" == memberExpression.property.type, "src/processScript/minify.ts:259:62")
167
+ assert("Identifier" == memberExpression.property.type, "src/processScript/minify.ts:249:62")
176
168
  if (!(memberExpression.property.name.length < 3)) {
177
169
  memberExpression.computed = !0
178
170
  memberExpression.property = t.stringLiteral(memberExpression.property.name)
@@ -220,8 +212,10 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
220
212
  )
221
213
  },
222
214
  StringLiteral(path) {
223
- path.node.value = replaceUnsafeStrings(uniqueId, path.node.value)
224
- if (JSON.stringify(path.node.value).includes("\\u00") || path.toString().length < 4) return
215
+ if (JSON.stringify(path.node.value).includes("\\u00") || path.toString().length < 4) {
216
+ path.node.value = replaceUnsafeStrings(uniqueId, path.node.value)
217
+ return
218
+ }
225
219
  "key" == path.parentKey && "ObjectProperty" == path.parent.type && (path.parent.computed = !0)
226
220
  let jsonValueIndex = jsonValues.indexOf(path.node.value)
227
221
  ;-1 == jsonValueIndex && (jsonValueIndex += jsonValues.push(path.node.value))
@@ -244,7 +238,7 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
244
238
  })
245
239
  await Promise.all(promises)
246
240
  const functionDeclaration = file.program.body[0]
247
- assert("FunctionDeclaration" == functionDeclaration.type, "src/processScript/minify.ts:363:61")
241
+ assert("FunctionDeclaration" == functionDeclaration.type, "src/processScript/minify.ts:354:61")
248
242
  if (jsonValues.length) {
249
243
  hasComment = !0
250
244
  if (1 == jsonValues.length)
@@ -256,7 +250,10 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
256
250
  t.memberExpression(
257
251
  t.taggedTemplateExpression(
258
252
  t.memberExpression(
259
- t.callExpression(t.identifier(`$${uniqueId}$SUBSCRIPT$scripts$quine$`), []),
253
+ t.callExpression(
254
+ t.identifier(`$${uniqueId}$4$SUBSCRIPT$scripts$quine$`),
255
+ []
256
+ ),
260
257
  t.identifier("split")
261
258
  ),
262
259
  t.templateLiteral([t.templateElement({ raw: "\t", cooked: "\t" }, !0)], [])
@@ -280,7 +277,7 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
280
277
  t.memberExpression(
281
278
  t.taggedTemplateExpression(
282
279
  t.memberExpression(
283
- t.callExpression(t.identifier(`$${uniqueId}$SUBSCRIPT$scripts$quine$`), []),
280
+ t.callExpression(t.identifier(`$${uniqueId}$4$SUBSCRIPT$scripts$quine$`), []),
284
281
  t.identifier("split")
285
282
  ),
286
283
  t.templateLiteral([t.templateElement({ raw: "\t", cooked: "\t" }, !0)], [])
@@ -305,7 +302,7 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
305
302
  t.memberExpression(
306
303
  t.taggedTemplateExpression(
307
304
  t.memberExpression(
308
- t.callExpression(t.identifier(`$${uniqueId}$SUBSCRIPT$scripts$quine$`), []),
305
+ t.callExpression(t.identifier(`$${uniqueId}$4$SUBSCRIPT$scripts$quine$`), []),
309
306
  t.identifier("split")
310
307
  ),
311
308
  t.templateLiteral([t.templateElement({ raw: "\t", cooked: "\t" }, !0)], [])
@@ -361,7 +358,7 @@ async function minify(file, { uniqueId = "00000000000", mangleNames = !1, forceQ
361
358
  )
362
359
  }
363
360
  if (1 == forceQuineCheats) return code
364
- assert(scriptBeforeJSONValueReplacement, "src/processScript/minify.ts:494:43")
361
+ assert(scriptBeforeJSONValueReplacement, "src/processScript/minify.ts:485:43")
365
362
  return (
366
363
  countHackmudCharacters(scriptBeforeJSONValueReplacement) <=
367
364
  countHackmudCharacters(code) + Number(hasComment)
@@ -377,7 +374,7 @@ function parseObjectExpression(node, o) {
377
374
  "Identifier" == property.key.type ||
378
375
  "NumericLiteral" == property.key.type ||
379
376
  "StringLiteral" == property.key.type,
380
- "src/processScript/minify.ts:516:4"
377
+ "src/processScript/minify.ts:507:4"
381
378
  )
382
379
  if ("ArrayExpression" == property.value.type) {
383
380
  const childArray = []
@@ -1 +1 @@
1
- export declare const postprocess: (code: string, seclevel: number, uniqueId: string) => string;
1
+ export declare const postprocess: (code: string, uniqueId: string) => string;
@@ -1,12 +1,12 @@
1
- const postprocess = (code, seclevel, uniqueId) =>
1
+ const postprocess = (code, uniqueId) =>
2
2
  code
3
- .replace(/^function\s*\w+\(/, "function(")
3
+ .replace(/^function\s*[\w$]+\(/, "function(")
4
4
  .replace(RegExp(`\\$${uniqueId}\\$\\\\(?:\\\\)?\\$SC_DOLLAR\\$`, "g"), "S\\C$")
5
5
  .replace(RegExp(`\\$${uniqueId}\\$\\\\(?:\\\\)?\\$DB_DOLLAR\\$`, "g"), "D\\B$")
6
6
  .replace(RegExp(`\\$${uniqueId}\\$\\\\(?:\\\\)?\\$D\\$`, "g"), "_\\_D_S")
7
7
  .replace(RegExp(`\\$${uniqueId}\\$\\\\(?:\\\\)?\\$FMCL\\$`, "g"), "_\\_FMCL_")
8
8
  .replace(RegExp(`\\$${uniqueId}\\$\\\\(?:\\\\)?\\$G\\$`, "g"), "_\\_G_")
9
- .replace(RegExp(`\\$${uniqueId}\\$SUBSCRIPT\\$(\\w+)\\$(\\w+)\\$`, "g"), `#${"nlmhf"[seclevel]}s.$1.$2`)
9
+ .replace(RegExp(`\\$${uniqueId}\\$(\\d)\\$SUBSCRIPT\\$(\\w+)\\$(\\w+)\\$`, "g"), "#$1s.$2.$3")
10
10
  .replace(RegExp(`\\$${uniqueId}\\$DEBUG\\$`, "g"), "#D")
11
11
  .replace(RegExp(`\\$${uniqueId}\\$FMCL\\$`, "g"), "#FMCL")
12
12
  .replace(RegExp(`\\$${uniqueId}\\$GLOBAL\\$`, "g"), "#G")
@@ -98,8 +98,10 @@ async function preprocess(code, { uniqueId = "00000000000" } = {}) {
98
98
  t.stringLiteral(resolve("proxy-polyfill/src/proxy.js", import.meta.url).slice(7))
99
99
  )
100
100
  )
101
- return 1 == program.node.body.length && "FunctionDeclaration" == program.node.body[0].type ?
102
- { code: "export default " + generate(file).code }
103
- : { code: generate(file).code }
101
+ if (1 == program.node.body.length && "FunctionDeclaration" == program.node.body[0].type)
102
+ throw Error(
103
+ "Scripts that only contain a single function declaration are no longer supported.\nPrefix the function declaration with `export default`."
104
+ )
105
+ return { code: generate(file).code }
104
106
  }
105
107
  export { preprocess }
@@ -22,9 +22,7 @@ const { default: traverse } = babelTraverse,
22
22
  "BigInt"
23
23
  ]
24
24
  function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scriptName, seclevel = 4 }) {
25
- const topFunctionName = `_${uniqueId}_SCRIPT_`,
26
- exports = new Map(),
27
- liveExports = new Map()
25
+ const topFunctionName = `_${uniqueId}_SCRIPT_`
28
26
  let program
29
27
  traverse(file, {
30
28
  Program(path) {
@@ -70,30 +68,30 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
70
68
  const referencePath = FunctionReferencePaths[0]
71
69
  assert(
72
70
  "MemberExpression" == referencePath.parent.type,
73
- "src/processScript/transform.ts:105:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
71
+ "src/processScript/transform.ts:103:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
74
72
  )
75
73
  assert(
76
74
  "Identifier" == referencePath.parent.property.type,
77
- "src/processScript/transform.ts:110:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
75
+ "src/processScript/transform.ts:108:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
78
76
  )
79
77
  assert(
80
78
  "prototype" == referencePath.parent.property.name,
81
- "src/processScript/transform.ts:115:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
79
+ "src/processScript/transform.ts:113:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
82
80
  )
83
81
  referencePath.parentPath.replaceWith(createGetFunctionPrototypeNode())
84
82
  } else {
85
83
  for (const referencePath of FunctionReferencePaths) {
86
84
  assert(
87
85
  "MemberExpression" == referencePath.parent.type,
88
- "src/processScript/transform.ts:123:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
86
+ "src/processScript/transform.ts:121:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
89
87
  )
90
88
  assert(
91
89
  "Identifier" == referencePath.parent.property.type,
92
- "src/processScript/transform.ts:128:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
90
+ "src/processScript/transform.ts:126:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
93
91
  )
94
92
  assert(
95
93
  "prototype" == referencePath.parent.property.name,
96
- "src/processScript/transform.ts:133:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
94
+ "src/processScript/transform.ts:131:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
97
95
  )
98
96
  functionDotPrototypeIsReferencedMultipleTimes = !0
99
97
  referencePath.parentPath.replaceWith(t.identifier(`_${uniqueId}_FUNCTION_DOT_PROTOTYPE_`))
@@ -101,40 +99,40 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
101
99
  functionDotPrototypeIsReferencedMultipleTimes = !0
102
100
  }
103
101
  }
104
- const neededSubscriptLets = new Set()
102
+ const neededSubscriptLets = new Map()
105
103
  let detectedSeclevel = 4
106
104
  for (const fakeSubscriptObjectName of ["$fs", "$4s", "$s"])
107
- program.scope.hasGlobal(fakeSubscriptObjectName) && processFakeSubscriptObject(fakeSubscriptObjectName)
105
+ program.scope.hasGlobal(fakeSubscriptObjectName) && processFakeSubscriptObject(fakeSubscriptObjectName, 4)
108
106
  for (const fakeSubscriptObjectName of ["$hs", "$3s"])
109
107
  if (program.scope.hasGlobal(fakeSubscriptObjectName)) {
110
108
  detectedSeclevel = 3
111
- processFakeSubscriptObject(fakeSubscriptObjectName)
109
+ processFakeSubscriptObject(fakeSubscriptObjectName, 3)
112
110
  }
113
111
  for (const fakeSubscriptObjectName of ["$ms", "$2s"])
114
112
  if (program.scope.hasGlobal(fakeSubscriptObjectName)) {
115
113
  detectedSeclevel = 2
116
- processFakeSubscriptObject(fakeSubscriptObjectName)
114
+ processFakeSubscriptObject(fakeSubscriptObjectName, 2)
117
115
  }
118
116
  for (const fakeSubscriptObjectName of ["$ls", "$1s"])
119
117
  if (program.scope.hasGlobal(fakeSubscriptObjectName)) {
120
118
  detectedSeclevel = 1
121
- processFakeSubscriptObject(fakeSubscriptObjectName)
119
+ processFakeSubscriptObject(fakeSubscriptObjectName, 1)
122
120
  }
123
121
  for (const fakeSubscriptObjectName of ["$ns", "$0s"])
124
122
  if (program.scope.hasGlobal(fakeSubscriptObjectName)) {
125
123
  detectedSeclevel = 0
126
- processFakeSubscriptObject(fakeSubscriptObjectName)
124
+ processFakeSubscriptObject(fakeSubscriptObjectName, 0)
127
125
  }
128
126
  seclevel = Math.min(seclevel, detectedSeclevel)
129
127
  const neededDbMethodLets = new Set()
130
128
  if (program.scope.hasGlobal("$db"))
131
129
  for (const referencePath of getReferencePathsToGlobal("$db", program)) {
132
- assert("MemberExpression" == referencePath.parentPath.node.type, "src/processScript/transform.ts:187:69")
133
- assert("Identifier" == referencePath.parentPath.node.property.type, "src/processScript/transform.ts:188:72")
130
+ assert("MemberExpression" == referencePath.parentPath.node.type, "src/processScript/transform.ts:185:69")
131
+ assert("Identifier" == referencePath.parentPath.node.property.type, "src/processScript/transform.ts:186:72")
134
132
  const databaseOpMethodName = referencePath.parentPath.node.property.name
135
133
  assert(
136
134
  validDBMethods.includes(databaseOpMethodName),
137
- `src/processScript/transform.ts:194:8 invalid db method "${databaseOpMethodName}", valid db methods are "${validDBMethods.join('", "')}"`
135
+ `src/processScript/transform.ts:192:8 invalid db method "${databaseOpMethodName}", valid db methods are "${validDBMethods.join('", "')}"`
138
136
  )
139
137
  if ("CallExpression" == referencePath.parentPath.parentPath?.type)
140
138
  referencePath.parentPath.replaceWith(t.identifier(`$${uniqueId}$DB$${databaseOpMethodName}$`))
@@ -157,9 +155,10 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
157
155
  if (program.scope.hasGlobal("$FMCL"))
158
156
  for (const referencePath of getReferencePathsToGlobal("$FMCL", program))
159
157
  referencePath.replaceWith(t.identifier(`$${uniqueId}$FMCL$`))
160
- if (program.scope.hasGlobal("$G"))
158
+ let needG = program.scope.hasGlobal("$G")
159
+ if (needG)
161
160
  for (const referencePath of getReferencePathsToGlobal("$G", program))
162
- referencePath.replaceWith(t.identifier(`$${uniqueId}$GLOBAL$`))
161
+ referencePath.replaceWith(t.identifier(`_${uniqueId}_G_`))
163
162
  if (program.scope.hasGlobal("_SECLEVEL"))
164
163
  for (const referencePath of getReferencePathsToGlobal("_SECLEVEL", program))
165
164
  referencePath.replaceWith(t.numericLiteral(seclevel))
@@ -193,11 +192,12 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
193
192
  "ExportSpecifier" == specifier.type,
194
193
  `src/processScript/transform.ts:276:51 ${specifier.type} is currently unsupported`
195
194
  )
196
- const exportedName =
197
- "Identifier" == specifier.exported.type ? specifier.exported.name : specifier.exported.value
198
- "default" == exportedName ?
199
- (exportDefaultName = specifier.local.name)
200
- : exports.set(specifier.local.name, exportedName)
195
+ if (
196
+ "default" !=
197
+ ("Identifier" == specifier.exported.type ? specifier.exported.name : specifier.exported.value)
198
+ )
199
+ throw Error("Only default exports are supported")
200
+ exportDefaultName = specifier.local.name
201
201
  }
202
202
  }
203
203
  const globalBlock = t.blockStatement([])
@@ -223,10 +223,6 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
223
223
  t.returnStatement(t.callExpression(t.identifier(exportDefaultName), []))
224
224
  ])
225
225
  ))
226
- if ("const" != statement.kind && exports.has(identifierName)) {
227
- liveExports.set(identifierName, exports.get(identifierName))
228
- exports.delete(identifierName)
229
- }
230
226
  globalBlock.body.push(
231
227
  t.variableDeclaration("let", [t.variableDeclarator(t.identifier(identifierName))])
232
228
  )
@@ -291,34 +287,16 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
291
287
  }
292
288
  program.node.body = [mainFunction]
293
289
  if (globalBlock.body.length) {
294
- ;(exports.size || liveExports.size) &&
295
- mainFunction.body.body.push(
296
- t.returnStatement(
297
- t.objectExpression([
298
- ...[...exports].map(([local, exported]) =>
299
- t.objectProperty(t.identifier(exported), t.identifier(local))
300
- ),
301
- ...[...liveExports].map(([local, exported]) =>
302
- t.objectMethod(
303
- "get",
304
- t.identifier(exported),
305
- [],
306
- t.blockStatement([t.returnStatement(t.identifier(local))])
307
- )
308
- )
309
- ])
310
- )
311
- )
312
290
  program.scope.crawl()
313
291
  const globalBlockVariables = new Set()
314
292
  let hoistedGlobalBlockFunctions = 0
315
293
  for (const [globalBlockIndex, globalBlockStatement] of [...globalBlock.body.entries()].reverse())
316
294
  if ("VariableDeclaration" == globalBlockStatement.type) {
317
- assert(1 == globalBlockStatement.declarations.length, "src/processScript/transform.ts:410:59")
295
+ assert(1 == globalBlockStatement.declarations.length, "src/processScript/transform.ts:390:59")
318
296
  const declarator = globalBlockStatement.declarations[0]
319
297
  assert(
320
298
  "Identifier" == declarator.id.type,
321
- `src/processScript/transform.ts:414:51 declarator.id.type was "${declarator.id.type}"`
299
+ `src/processScript/transform.ts:394:51 declarator.id.type was "${declarator.id.type}"`
322
300
  )
323
301
  program.scope.crawl()
324
302
  if (program.scope.hasGlobal(declarator.id.name)) {
@@ -333,15 +311,16 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
333
311
  Object.keys(program.scope.globals).some(global => globalBlockVariables.has(global))
334
312
  ) {
335
313
  const binding = program.scope.getBinding(declarator.id.name)
336
- assert(binding, "src/processScript/transform.ts:433:23")
314
+ assert(binding, "src/processScript/transform.ts:413:23")
337
315
  for (const referencePath of binding.referencePaths) {
338
- assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:436:56")
316
+ assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:416:56")
339
317
  referencePath.replaceWith(
340
318
  t.memberExpression(
341
- t.identifier(`$${uniqueId}$GLOBAL$`),
319
+ t.identifier(`_${uniqueId}_G_`),
342
320
  t.identifier(referencePath.node.name)
343
321
  )
344
322
  )
323
+ needG = !0
345
324
  }
346
325
  for (const referencePath of binding.constantViolations)
347
326
  if ("AssignmentExpression" == referencePath.node.type)
@@ -350,12 +329,13 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
350
329
  clearObject(node)
351
330
  Object.assign(
352
331
  node,
353
- t.memberExpression(t.identifier(`$${uniqueId}$GLOBAL$`), t.identifier(name))
332
+ t.memberExpression(t.identifier(`_${uniqueId}_G_`), t.identifier(name))
354
333
  )
334
+ needG = !0
355
335
  }
356
336
  globalBlockPath.remove()
357
337
  globalBlockStatementPath.remove()
358
- declarator.init &&
338
+ if (declarator.init) {
359
339
  globalBlock.body.splice(
360
340
  globalBlockIndex,
361
341
  0,
@@ -363,13 +343,15 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
363
343
  t.assignmentExpression(
364
344
  "=",
365
345
  t.memberExpression(
366
- t.identifier(`$${uniqueId}$GLOBAL$`),
346
+ t.identifier(`_${uniqueId}_G_`),
367
347
  t.identifier(declarator.id.name)
368
348
  ),
369
349
  declarator.init
370
350
  )
371
351
  )
372
352
  )
353
+ needG = !0
354
+ }
373
355
  } else {
374
356
  globalBlockPath.remove()
375
357
  globalBlockStatementPath.remove()
@@ -379,22 +361,20 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
379
361
  } else globalBlockVariables.add(declarator.id.name)
380
362
  } else if ("ClassDeclaration" == globalBlockStatement.type) {
381
363
  program.scope.crawl()
382
- assert(globalBlockStatement.id, "src/processScript/transform.ts:487:37")
364
+ assert(globalBlockStatement.id, "src/processScript/transform.ts:473:37")
383
365
  if (program.scope.hasGlobal(globalBlockStatement.id.name)) {
384
366
  globalBlock.body.splice(globalBlockIndex, 1)
385
367
  const [globalBlockPath] = program.unshiftContainer("body", globalBlock),
386
368
  [globalBlockStatementPath] = program.unshiftContainer("body", globalBlockStatement)
387
369
  program.scope.crawl()
388
370
  const binding = program.scope.getBinding(globalBlockStatement.id.name)
389
- assert(binding, "src/processScript/transform.ts:499:22")
371
+ assert(binding, "src/processScript/transform.ts:485:22")
390
372
  for (const referencePath of binding.referencePaths) {
391
- assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:502:55")
373
+ assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:488:55")
392
374
  referencePath.replaceWith(
393
- t.memberExpression(
394
- t.identifier(`$${uniqueId}$GLOBAL$`),
395
- t.identifier(referencePath.node.name)
396
- )
375
+ t.memberExpression(t.identifier(`_${uniqueId}_G_`), t.identifier(referencePath.node.name))
397
376
  )
377
+ needG = !0
398
378
  }
399
379
  globalBlockPath.remove()
400
380
  globalBlockStatementPath.remove()
@@ -405,7 +385,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
405
385
  t.assignmentExpression(
406
386
  "=",
407
387
  t.memberExpression(
408
- t.identifier(`$${uniqueId}$GLOBAL$`),
388
+ t.identifier(`_${uniqueId}_G_`),
409
389
  t.identifier(globalBlockStatement.id.name)
410
390
  ),
411
391
  t.classExpression(
@@ -417,13 +397,9 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
417
397
  )
418
398
  )
419
399
  )
400
+ needG = !0
420
401
  }
421
402
  }
422
- if (program.scope.hasGlobal("_EXPORTS"))
423
- for (const referencePath of getReferencePathsToGlobal("_EXPORTS", program))
424
- referencePath.replaceWith(
425
- t.arrayExpression([...exports.keys(), ...liveExports.keys()].map(name => t.stringLiteral(name)))
426
- )
427
403
  globalBlock.body.length &&
428
404
  mainFunction.body.body.splice(
429
405
  hoistedGlobalBlockFunctions,
@@ -522,12 +498,12 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
522
498
  mainFunction.body.body.unshift(
523
499
  t.variableDeclaration(
524
500
  "let",
525
- [...neededSubscriptLets].map(name =>
501
+ [...neededSubscriptLets].map(([name, seclevel]) =>
526
502
  t.variableDeclarator(
527
503
  t.identifier(`_${uniqueId}_SUBSCRIPT_${name}_`),
528
504
  t.arrowFunctionExpression(
529
505
  [t.restElement(t.identifier("args"))],
530
- t.callExpression(t.identifier(`$${uniqueId}$SUBSCRIPT$${name}$`), [
506
+ t.callExpression(t.identifier(`$${uniqueId}$${seclevel}$SUBSCRIPT$${name}$`), [
531
507
  t.spreadElement(t.identifier("args"))
532
508
  ])
533
509
  )
@@ -535,6 +511,12 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
535
511
  )
536
512
  )
537
513
  )
514
+ needG &&
515
+ mainFunction.body.body.unshift(
516
+ t.variableDeclaration("let", [
517
+ t.variableDeclarator(t.identifier(`_${uniqueId}_G_`), t.identifier(`$${uniqueId}$GLOBAL$`))
518
+ ])
519
+ )
538
520
  traverse(file, {
539
521
  BlockStatement({ node: blockStatement }) {
540
522
  for (const [index, functionDeclaration] of blockStatement.body.entries())
@@ -555,7 +537,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
555
537
  }
556
538
  },
557
539
  ClassBody({ node: classBody, scope, parent }) {
558
- assert(t.isClass(parent), "src/processScript/transform.ts:669:30")
540
+ assert(t.isClass(parent), "src/processScript/transform.ts:658:30")
559
541
  let thisIsReferenced = !1
560
542
  for (const classMethod of classBody.body) {
561
543
  if ("ClassMethod" != classMethod.type) continue
@@ -631,7 +613,9 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
631
613
  VariableDeclaration({ node: variableDeclaration }) {
632
614
  "const" == variableDeclaration.kind && (variableDeclaration.kind = "let")
633
615
  },
634
- ThisExpression: path => path.replaceWith(t.identifier("undefined")),
616
+ ThisExpression: path => {
617
+ path.replaceWith(t.identifier("undefined"))
618
+ },
635
619
  BigIntLiteral(path) {
636
620
  const bigIntAsNumber = Number(path.node.value)
637
621
  path.replaceWith(
@@ -645,50 +629,43 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
645
629
  })
646
630
  return { file, seclevel }
647
631
  function createGetFunctionPrototypeNode() {
648
- for (const globalFunction of globalFunctionsUnder7Characters)
649
- if (!program.scope.hasOwnBinding(globalFunction))
650
- return t.memberExpression(
651
- t.memberExpression(t.identifier(globalFunction), t.identifier("constructor")),
652
- t.identifier("prototype")
653
- )
632
+ const name = globalFunctionsUnder7Characters.find(name => !program.scope.hasOwnBinding(name))
654
633
  return t.memberExpression(
655
- t.memberExpression(
656
- t.arrowFunctionExpression([t.identifier("_")], t.identifier("_")),
657
- t.identifier("constructor")
658
- ),
659
- t.identifier("prototype")
634
+ name ? t.identifier(name) : t.arrowFunctionExpression([t.identifier("_")], t.identifier("_")),
635
+ t.identifier("__proto__")
660
636
  )
661
637
  }
662
- function processFakeSubscriptObject(fakeSubscriptObjectName) {
638
+ function processFakeSubscriptObject(fakeSubscriptObjectName, seclevel) {
663
639
  for (const referencePath of getReferencePathsToGlobal(fakeSubscriptObjectName, program)) {
664
- assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:783:60")
640
+ assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:764:60")
665
641
  assert("Identifier" == referencePath.parent.property.type)
666
642
  assert(
667
643
  "MemberExpression" == referencePath.parentPath.parentPath?.node.type,
668
- "src/processScript/transform.ts:785:81"
644
+ "src/processScript/transform.ts:766:81"
669
645
  )
670
646
  assert(
671
647
  "Identifier" == referencePath.parentPath.parentPath.node.property.type,
672
- "src/processScript/transform.ts:786:83"
648
+ "src/processScript/transform.ts:767:83"
673
649
  )
674
650
  assert(
675
651
  /^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parent.property.name),
676
- `src/processScript/transform.ts:790:8 invalid user "${referencePath.parent.property.name}" in subscript`
652
+ `src/processScript/transform.ts:771:8 invalid user "${referencePath.parent.property.name}" in subscript`
677
653
  )
678
654
  assert(
679
655
  /^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parentPath.parentPath.node.property.name),
680
- `src/processScript/transform.ts:795:8 invalid script name "${referencePath.parentPath.parentPath.node.property.name}" in subscript`
656
+ `src/processScript/transform.ts:776:8 invalid script name "${referencePath.parentPath.parentPath.node.property.name}" in subscript`
681
657
  )
682
658
  if ("CallExpression" == referencePath.parentPath.parentPath.parentPath?.type)
683
659
  referencePath.parentPath.parentPath.replaceWith(
684
660
  t.identifier(
685
- `$${uniqueId}$SUBSCRIPT$${referencePath.parent.property.name}$${referencePath.parentPath.parentPath.node.property.name}$`
661
+ `$${uniqueId}$${seclevel}$SUBSCRIPT$${referencePath.parent.property.name}$${referencePath.parentPath.parentPath.node.property.name}$`
686
662
  )
687
663
  )
688
664
  else {
689
665
  const name = `${referencePath.parent.property.name}$${referencePath.parentPath.parentPath.node.property.name}`
690
666
  referencePath.parentPath.parentPath.replaceWith(t.identifier(`_${uniqueId}_SUBSCRIPT_${name}_`))
691
- neededSubscriptLets.add(name)
667
+ const maxSecLevel = Math.max(neededSubscriptLets.get(name) || 0, seclevel)
668
+ neededSubscriptLets.set(name, maxSecLevel)
692
669
  }
693
670
  }
694
671
  }
package/push.d.ts CHANGED
@@ -18,6 +18,14 @@ export type PushOptions = LaxPartial<{
18
18
  */
19
19
  forceQuineCheats: boolean;
20
20
  }>;
21
+ export declare class MissingSourceFolderError extends Error {
22
+ }
23
+ export declare class MissingHackmudFolderError extends Error {
24
+ }
25
+ export declare class NoUsersError extends Error {
26
+ }
27
+ export declare class NoScriptsError extends Error {
28
+ }
21
29
  /** Push scripts from a source directory to the hackmud directory.
22
30
  *
23
31
  * Pushes files directly in the source folder to all users
@@ -25,4 +33,4 @@ export type PushOptions = LaxPartial<{
25
33
  * @param hackmudPath directory created by hackmud containing user data including scripts
26
34
  * @param options {@link PushOptions details}
27
35
  * @returns array of info on pushed scripts */
28
- export declare function push(sourcePath: string, hackmudPath: string, { scripts, onPush, minify, mangleNames, forceQuineCheats }?: PushOptions): Promise<Info[]>;
36
+ export declare function push(sourcePath: string, hackmudPath: string, { scripts, onPush, minify, mangleNames, forceQuineCheats }?: PushOptions): Promise<MissingSourceFolderError | MissingHackmudFolderError | NoUsersError | NoScriptsError | Info[]>;