hackmud-script-manager 0.20.3 → 0.20.4-0dd1d9b

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,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[]>;