hackmud-script-manager 0.20.4-4605f71 → 0.20.4-484afbe

Sign up to get free protection for your applications and to get access to all the features.
@@ -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) {
@@ -49,6 +47,9 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
49
47
  if (program.scope.hasGlobal("_SCRIPT_NAME"))
50
48
  for (const referencePath of getReferencePathsToGlobal("_SCRIPT_NAME", program))
51
49
  referencePath.replaceWith(t.stringLiteral(1 == scriptName ? `$${uniqueId}$SCRIPT_NAME$` : scriptName))
50
+ if (program.scope.hasGlobal("_SCRIPT_SUBNAME"))
51
+ for (const referencePath of getReferencePathsToGlobal("_SCRIPT_SUBNAME", program))
52
+ referencePath.replaceWith(t.stringLiteral(1 == scriptName ? `$${uniqueId}$SCRIPT_NAME$` : scriptName))
52
53
  if (program.scope.hasGlobal("_FULL_SCRIPT_NAME"))
53
54
  for (const referencePath of getReferencePathsToGlobal("_FULL_SCRIPT_NAME", program))
54
55
  if (1 == scriptUser || 1 == scriptName)
@@ -70,30 +71,30 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
70
71
  const referencePath = FunctionReferencePaths[0]
71
72
  assert(
72
73
  "MemberExpression" == referencePath.parent.type,
73
- "src/processScript/transform.ts:105:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
74
+ "src/processScript/transform.ts:108:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
74
75
  )
75
76
  assert(
76
77
  "Identifier" == referencePath.parent.property.type,
77
- "src/processScript/transform.ts:110:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
78
+ "src/processScript/transform.ts:113:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
78
79
  )
79
80
  assert(
80
81
  "prototype" == referencePath.parent.property.name,
81
- "src/processScript/transform.ts:115:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
82
+ "src/processScript/transform.ts:118:8 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
82
83
  )
83
84
  referencePath.parentPath.replaceWith(createGetFunctionPrototypeNode())
84
85
  } else {
85
86
  for (const referencePath of FunctionReferencePaths) {
86
87
  assert(
87
88
  "MemberExpression" == referencePath.parent.type,
88
- "src/processScript/transform.ts:123:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
89
+ "src/processScript/transform.ts:126:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
89
90
  )
90
91
  assert(
91
92
  "Identifier" == referencePath.parent.property.type,
92
- "src/processScript/transform.ts:128:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
93
+ "src/processScript/transform.ts:131:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
93
94
  )
94
95
  assert(
95
96
  "prototype" == referencePath.parent.property.name,
96
- "src/processScript/transform.ts:133:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
97
+ "src/processScript/transform.ts:136:9 `Function` isn't available in hackmud, only `Function.prototype` is accessible"
97
98
  )
98
99
  functionDotPrototypeIsReferencedMultipleTimes = !0
99
100
  referencePath.parentPath.replaceWith(t.identifier(`_${uniqueId}_FUNCTION_DOT_PROTOTYPE_`))
@@ -101,40 +102,40 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
101
102
  functionDotPrototypeIsReferencedMultipleTimes = !0
102
103
  }
103
104
  }
104
- const neededSubscriptLets = new Set()
105
+ const neededSubscriptLets = new Map()
105
106
  let detectedSeclevel = 4
106
107
  for (const fakeSubscriptObjectName of ["$fs", "$4s", "$s"])
107
- program.scope.hasGlobal(fakeSubscriptObjectName) && processFakeSubscriptObject(fakeSubscriptObjectName)
108
+ program.scope.hasGlobal(fakeSubscriptObjectName) && processFakeSubscriptObject(fakeSubscriptObjectName, 4)
108
109
  for (const fakeSubscriptObjectName of ["$hs", "$3s"])
109
110
  if (program.scope.hasGlobal(fakeSubscriptObjectName)) {
110
111
  detectedSeclevel = 3
111
- processFakeSubscriptObject(fakeSubscriptObjectName)
112
+ processFakeSubscriptObject(fakeSubscriptObjectName, 3)
112
113
  }
113
114
  for (const fakeSubscriptObjectName of ["$ms", "$2s"])
114
115
  if (program.scope.hasGlobal(fakeSubscriptObjectName)) {
115
116
  detectedSeclevel = 2
116
- processFakeSubscriptObject(fakeSubscriptObjectName)
117
+ processFakeSubscriptObject(fakeSubscriptObjectName, 2)
117
118
  }
118
119
  for (const fakeSubscriptObjectName of ["$ls", "$1s"])
119
120
  if (program.scope.hasGlobal(fakeSubscriptObjectName)) {
120
121
  detectedSeclevel = 1
121
- processFakeSubscriptObject(fakeSubscriptObjectName)
122
+ processFakeSubscriptObject(fakeSubscriptObjectName, 1)
122
123
  }
123
124
  for (const fakeSubscriptObjectName of ["$ns", "$0s"])
124
125
  if (program.scope.hasGlobal(fakeSubscriptObjectName)) {
125
126
  detectedSeclevel = 0
126
- processFakeSubscriptObject(fakeSubscriptObjectName)
127
+ processFakeSubscriptObject(fakeSubscriptObjectName, 0)
127
128
  }
128
129
  seclevel = Math.min(seclevel, detectedSeclevel)
129
130
  const neededDbMethodLets = new Set()
130
131
  if (program.scope.hasGlobal("$db"))
131
132
  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")
133
+ assert("MemberExpression" == referencePath.parentPath.node.type, "src/processScript/transform.ts:190:69")
134
+ assert("Identifier" == referencePath.parentPath.node.property.type, "src/processScript/transform.ts:191:72")
134
135
  const databaseOpMethodName = referencePath.parentPath.node.property.name
135
136
  assert(
136
137
  validDBMethods.includes(databaseOpMethodName),
137
- `src/processScript/transform.ts:194:8 invalid db method "${databaseOpMethodName}", valid db methods are "${validDBMethods.join('", "')}"`
138
+ `src/processScript/transform.ts:197:8 invalid db method "${databaseOpMethodName}", valid db methods are "${validDBMethods.join('", "')}"`
138
139
  )
139
140
  if ("CallExpression" == referencePath.parentPath.parentPath?.type)
140
141
  referencePath.parentPath.replaceWith(t.identifier(`$${uniqueId}$DB$${databaseOpMethodName}$`))
@@ -157,27 +158,32 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
157
158
  if (program.scope.hasGlobal("$FMCL"))
158
159
  for (const referencePath of getReferencePathsToGlobal("$FMCL", program))
159
160
  referencePath.replaceWith(t.identifier(`$${uniqueId}$FMCL$`))
160
- if (program.scope.hasGlobal("$G"))
161
+ let needG = program.scope.hasGlobal("$G")
162
+ if (needG)
161
163
  for (const referencePath of getReferencePathsToGlobal("$G", program))
162
- referencePath.replaceWith(t.identifier(`$${uniqueId}$GLOBAL$`))
164
+ referencePath.replaceWith(t.identifier(`_${uniqueId}_G_`))
163
165
  if (program.scope.hasGlobal("_SECLEVEL"))
164
166
  for (const referencePath of getReferencePathsToGlobal("_SECLEVEL", program))
165
167
  referencePath.replaceWith(t.numericLiteral(seclevel))
166
- let needGetPrototypeOf = !1
168
+ let needGetPrototypeOf = !1,
169
+ needHasOwn = !1
167
170
  if (program.scope.hasGlobal("Object"))
168
171
  for (const referencePath of getReferencePathsToGlobal("Object", program))
169
172
  if ("MemberExpression" == referencePath.parent.type && !referencePath.parent.computed) {
170
- assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:241:64")
173
+ assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:247:64")
171
174
  if ("getPrototypeOf" == referencePath.parent.property.name) {
172
175
  referencePath.parentPath.replaceWith(t.identifier(`_${uniqueId}_GET_PROTOTYPE_OF_`))
173
176
  needGetPrototypeOf = !0
177
+ } else if ("hasOwn" == referencePath.parent.property.name) {
178
+ referencePath.parentPath.replaceWith(t.identifier(`_${uniqueId}_HAS_OWN_`))
179
+ needHasOwn = !0
174
180
  }
175
181
  }
176
182
  const consoleMethodsReferenced = new Set()
177
183
  if (program.scope.hasGlobal("console"))
178
184
  for (const referencePath of getReferencePathsToGlobal("console", program))
179
185
  if ("MemberExpression" == referencePath.parent.type && !referencePath.parent.computed) {
180
- assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:256:64")
186
+ assert("Identifier" == referencePath.parent.property.type, "src/processScript/transform.ts:265:64")
181
187
  referencePath.parentPath.replaceWith(
182
188
  t.identifier(`_${uniqueId}_CONSOLE_METHOD_${referencePath.parent.property.name}_`)
183
189
  )
@@ -185,19 +191,20 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
185
191
  }
186
192
  const lastStatement = program.node.body.at(-1)
187
193
  let exportDefaultName
188
- assert(lastStatement, "src/processScript/transform.ts:270:27 program is empty")
194
+ assert(lastStatement, "src/processScript/transform.ts:279:27 program is empty")
189
195
  if ("ExportNamedDeclaration" == lastStatement.type) {
190
196
  program.node.body.pop()
191
197
  for (const specifier of lastStatement.specifiers) {
192
198
  assert(
193
199
  "ExportSpecifier" == specifier.type,
194
- `src/processScript/transform.ts:276:51 ${specifier.type} is currently unsupported`
200
+ `src/processScript/transform.ts:285:51 ${specifier.type} is currently unsupported`
201
+ )
202
+ if (
203
+ "default" !=
204
+ ("Identifier" == specifier.exported.type ? specifier.exported.name : specifier.exported.value)
195
205
  )
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)
206
+ throw Error("Only default exports are supported")
207
+ exportDefaultName = specifier.local.name
201
208
  }
202
209
  }
203
210
  const globalBlock = t.blockStatement([])
@@ -223,10 +230,6 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
223
230
  t.returnStatement(t.callExpression(t.identifier(exportDefaultName), []))
224
231
  ])
225
232
  ))
226
- if ("const" != statement.kind && exports.has(identifierName)) {
227
- liveExports.set(identifierName, exports.get(identifierName))
228
- exports.delete(identifierName)
229
- }
230
233
  globalBlock.body.push(
231
234
  t.variableDeclaration("let", [t.variableDeclarator(t.identifier(identifierName))])
232
235
  )
@@ -291,34 +294,16 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
291
294
  }
292
295
  program.node.body = [mainFunction]
293
296
  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
297
  program.scope.crawl()
313
298
  const globalBlockVariables = new Set()
314
299
  let hoistedGlobalBlockFunctions = 0
315
300
  for (const [globalBlockIndex, globalBlockStatement] of [...globalBlock.body.entries()].reverse())
316
301
  if ("VariableDeclaration" == globalBlockStatement.type) {
317
- assert(1 == globalBlockStatement.declarations.length, "src/processScript/transform.ts:410:59")
302
+ assert(1 == globalBlockStatement.declarations.length, "src/processScript/transform.ts:399:59")
318
303
  const declarator = globalBlockStatement.declarations[0]
319
304
  assert(
320
305
  "Identifier" == declarator.id.type,
321
- `src/processScript/transform.ts:414:51 declarator.id.type was "${declarator.id.type}"`
306
+ `src/processScript/transform.ts:403:51 declarator.id.type was "${declarator.id.type}"`
322
307
  )
323
308
  program.scope.crawl()
324
309
  if (program.scope.hasGlobal(declarator.id.name)) {
@@ -333,15 +318,16 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
333
318
  Object.keys(program.scope.globals).some(global => globalBlockVariables.has(global))
334
319
  ) {
335
320
  const binding = program.scope.getBinding(declarator.id.name)
336
- assert(binding, "src/processScript/transform.ts:433:23")
321
+ assert(binding, "src/processScript/transform.ts:422:23")
337
322
  for (const referencePath of binding.referencePaths) {
338
- assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:436:56")
323
+ assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:425:56")
339
324
  referencePath.replaceWith(
340
325
  t.memberExpression(
341
- t.identifier(`$${uniqueId}$GLOBAL$`),
326
+ t.identifier(`_${uniqueId}_G_`),
342
327
  t.identifier(referencePath.node.name)
343
328
  )
344
329
  )
330
+ needG = !0
345
331
  }
346
332
  for (const referencePath of binding.constantViolations)
347
333
  if ("AssignmentExpression" == referencePath.node.type)
@@ -350,12 +336,13 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
350
336
  clearObject(node)
351
337
  Object.assign(
352
338
  node,
353
- t.memberExpression(t.identifier(`$${uniqueId}$GLOBAL$`), t.identifier(name))
339
+ t.memberExpression(t.identifier(`_${uniqueId}_G_`), t.identifier(name))
354
340
  )
341
+ needG = !0
355
342
  }
356
343
  globalBlockPath.remove()
357
344
  globalBlockStatementPath.remove()
358
- declarator.init &&
345
+ if (declarator.init) {
359
346
  globalBlock.body.splice(
360
347
  globalBlockIndex,
361
348
  0,
@@ -363,13 +350,15 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
363
350
  t.assignmentExpression(
364
351
  "=",
365
352
  t.memberExpression(
366
- t.identifier(`$${uniqueId}$GLOBAL$`),
353
+ t.identifier(`_${uniqueId}_G_`),
367
354
  t.identifier(declarator.id.name)
368
355
  ),
369
356
  declarator.init
370
357
  )
371
358
  )
372
359
  )
360
+ needG = !0
361
+ }
373
362
  } else {
374
363
  globalBlockPath.remove()
375
364
  globalBlockStatementPath.remove()
@@ -379,22 +368,20 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
379
368
  } else globalBlockVariables.add(declarator.id.name)
380
369
  } else if ("ClassDeclaration" == globalBlockStatement.type) {
381
370
  program.scope.crawl()
382
- assert(globalBlockStatement.id, "src/processScript/transform.ts:487:37")
371
+ assert(globalBlockStatement.id, "src/processScript/transform.ts:482:37")
383
372
  if (program.scope.hasGlobal(globalBlockStatement.id.name)) {
384
373
  globalBlock.body.splice(globalBlockIndex, 1)
385
374
  const [globalBlockPath] = program.unshiftContainer("body", globalBlock),
386
375
  [globalBlockStatementPath] = program.unshiftContainer("body", globalBlockStatement)
387
376
  program.scope.crawl()
388
377
  const binding = program.scope.getBinding(globalBlockStatement.id.name)
389
- assert(binding, "src/processScript/transform.ts:499:22")
378
+ assert(binding, "src/processScript/transform.ts:494:22")
390
379
  for (const referencePath of binding.referencePaths) {
391
- assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:502:55")
380
+ assert("Identifier" == referencePath.node.type, "src/processScript/transform.ts:497:55")
392
381
  referencePath.replaceWith(
393
- t.memberExpression(
394
- t.identifier(`$${uniqueId}$GLOBAL$`),
395
- t.identifier(referencePath.node.name)
396
- )
382
+ t.memberExpression(t.identifier(`_${uniqueId}_G_`), t.identifier(referencePath.node.name))
397
383
  )
384
+ needG = !0
398
385
  }
399
386
  globalBlockPath.remove()
400
387
  globalBlockStatementPath.remove()
@@ -405,7 +392,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
405
392
  t.assignmentExpression(
406
393
  "=",
407
394
  t.memberExpression(
408
- t.identifier(`$${uniqueId}$GLOBAL$`),
395
+ t.identifier(`_${uniqueId}_G_`),
409
396
  t.identifier(globalBlockStatement.id.name)
410
397
  ),
411
398
  t.classExpression(
@@ -417,13 +404,9 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
417
404
  )
418
405
  )
419
406
  )
407
+ needG = !0
420
408
  }
421
409
  }
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
410
  globalBlock.body.length &&
428
411
  mainFunction.body.body.splice(
429
412
  hoistedGlobalBlockFunctions,
@@ -472,6 +455,31 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
472
455
  )
473
456
  ])
474
457
  )
458
+ needHasOwn &&
459
+ mainFunction.body.body.unshift(
460
+ t.variableDeclaration("let", [
461
+ t.variableDeclarator(
462
+ t.identifier(`_${uniqueId}_HAS_OWN_`),
463
+ t.callExpression(
464
+ t.memberExpression(
465
+ t.memberExpression(
466
+ t.identifier(
467
+ globalFunctionsUnder7Characters.find(name => !program.scope.hasOwnBinding(name))
468
+ ),
469
+ t.identifier("call")
470
+ ),
471
+ t.identifier("bind")
472
+ ),
473
+ [
474
+ t.memberExpression(
475
+ t.memberExpression(t.identifier("Object"), t.identifier("prototype")),
476
+ t.identifier("hasOwnProperty")
477
+ )
478
+ ]
479
+ )
480
+ )
481
+ ])
482
+ )
475
483
  consoleMethodsReferenced.size &&
476
484
  mainFunction.body.body.unshift(
477
485
  t.variableDeclaration(
@@ -522,12 +530,12 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
522
530
  mainFunction.body.body.unshift(
523
531
  t.variableDeclaration(
524
532
  "let",
525
- [...neededSubscriptLets].map(name =>
533
+ [...neededSubscriptLets].map(([name, seclevel]) =>
526
534
  t.variableDeclarator(
527
535
  t.identifier(`_${uniqueId}_SUBSCRIPT_${name}_`),
528
536
  t.arrowFunctionExpression(
529
537
  [t.restElement(t.identifier("args"))],
530
- t.callExpression(t.identifier(`$${uniqueId}$SUBSCRIPT$${name}$`), [
538
+ t.callExpression(t.identifier(`$${uniqueId}$${seclevel}$SUBSCRIPT$${name}$`), [
531
539
  t.spreadElement(t.identifier("args"))
532
540
  ])
533
541
  )
@@ -535,6 +543,12 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
535
543
  )
536
544
  )
537
545
  )
546
+ needG &&
547
+ mainFunction.body.body.unshift(
548
+ t.variableDeclaration("let", [
549
+ t.variableDeclarator(t.identifier(`_${uniqueId}_G_`), t.identifier(`$${uniqueId}$GLOBAL$`))
550
+ ])
551
+ )
538
552
  traverse(file, {
539
553
  BlockStatement({ node: blockStatement }) {
540
554
  for (const [index, functionDeclaration] of blockStatement.body.entries())
@@ -555,7 +569,7 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
555
569
  }
556
570
  },
557
571
  ClassBody({ node: classBody, scope, parent }) {
558
- assert(t.isClass(parent), "src/processScript/transform.ts:669:30")
572
+ assert(t.isClass(parent), "src/processScript/transform.ts:692:30")
559
573
  let thisIsReferenced = !1
560
574
  for (const classMethod of classBody.body) {
561
575
  if ("ClassMethod" != classMethod.type) continue
@@ -647,50 +661,43 @@ function transform(file, sourceCode, { uniqueId = "00000000000", scriptUser, scr
647
661
  })
648
662
  return { file, seclevel }
649
663
  function createGetFunctionPrototypeNode() {
650
- for (const globalFunction of globalFunctionsUnder7Characters)
651
- if (!program.scope.hasOwnBinding(globalFunction))
652
- return t.memberExpression(
653
- t.memberExpression(t.identifier(globalFunction), t.identifier("constructor")),
654
- t.identifier("prototype")
655
- )
664
+ const name = globalFunctionsUnder7Characters.find(name => !program.scope.hasOwnBinding(name))
656
665
  return t.memberExpression(
657
- t.memberExpression(
658
- t.arrowFunctionExpression([t.identifier("_")], t.identifier("_")),
659
- t.identifier("constructor")
660
- ),
661
- t.identifier("prototype")
666
+ name ? t.identifier(name) : t.arrowFunctionExpression([t.identifier("_")], t.identifier("_")),
667
+ t.identifier("__proto__")
662
668
  )
663
669
  }
664
- function processFakeSubscriptObject(fakeSubscriptObjectName) {
670
+ function processFakeSubscriptObject(fakeSubscriptObjectName, seclevel) {
665
671
  for (const referencePath of getReferencePathsToGlobal(fakeSubscriptObjectName, program)) {
666
- assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:785:60")
672
+ assert("MemberExpression" == referencePath.parent.type, "src/processScript/transform.ts:798:60")
667
673
  assert("Identifier" == referencePath.parent.property.type)
668
674
  assert(
669
675
  "MemberExpression" == referencePath.parentPath.parentPath?.node.type,
670
- "src/processScript/transform.ts:787:81"
676
+ "src/processScript/transform.ts:800:81"
671
677
  )
672
678
  assert(
673
679
  "Identifier" == referencePath.parentPath.parentPath.node.property.type,
674
- "src/processScript/transform.ts:788:83"
680
+ "src/processScript/transform.ts:801:83"
675
681
  )
676
682
  assert(
677
683
  /^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parent.property.name),
678
- `src/processScript/transform.ts:792:8 invalid user "${referencePath.parent.property.name}" in subscript`
684
+ `src/processScript/transform.ts:805:8 invalid user "${referencePath.parent.property.name}" in subscript`
679
685
  )
680
686
  assert(
681
687
  /^[_a-z][\d_a-z]{0,24}$/.test(referencePath.parentPath.parentPath.node.property.name),
682
- `src/processScript/transform.ts:797:8 invalid script name "${referencePath.parentPath.parentPath.node.property.name}" in subscript`
688
+ `src/processScript/transform.ts:810:8 invalid script name "${referencePath.parentPath.parentPath.node.property.name}" in subscript`
683
689
  )
684
690
  if ("CallExpression" == referencePath.parentPath.parentPath.parentPath?.type)
685
691
  referencePath.parentPath.parentPath.replaceWith(
686
692
  t.identifier(
687
- `$${uniqueId}$SUBSCRIPT$${referencePath.parent.property.name}$${referencePath.parentPath.parentPath.node.property.name}$`
693
+ `$${uniqueId}$${seclevel}$SUBSCRIPT$${referencePath.parent.property.name}$${referencePath.parentPath.parentPath.node.property.name}$`
688
694
  )
689
695
  )
690
696
  else {
691
697
  const name = `${referencePath.parent.property.name}$${referencePath.parentPath.parentPath.node.property.name}`
692
698
  referencePath.parentPath.parentPath.replaceWith(t.identifier(`_${uniqueId}_SUBSCRIPT_${name}_`))
693
- neededSubscriptLets.add(name)
699
+ const maxSecLevel = Math.max(neededSubscriptLets.get(name) || 0, seclevel)
700
+ neededSubscriptLets.set(name, maxSecLevel)
694
701
  }
695
702
  }
696
703
  }
package/push.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Cache } from "@samual/lib/Cache"
1
+ import { AutoMap } from "@samual/lib/AutoMap"
2
2
  import { ensure, assert } from "@samual/lib/assert"
3
3
  import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
4
4
  import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
@@ -84,8 +84,8 @@ async function push(
84
84
  return new NoUsersError(
85
85
  "Could not find any users. Either provide the names of your users or log into a user in hackmud"
86
86
  )
87
- const usersToScriptsToPush = new Cache(_user => new Map()),
88
- scriptNamesToUsers = new Cache(_scriptName => new Set())
87
+ const usersToScriptsToPush = new AutoMap(_user => new Map()),
88
+ scriptNamesToUsers = new AutoMap(_scriptName => new Set())
89
89
  for (const script of scripts) {
90
90
  const [user, scriptName] = script.split(".")
91
91
  assert(user, "src/push.ts:105:16")
@@ -121,7 +121,7 @@ async function push(
121
121
  for (const user of users)
122
122
  if (!usersToScriptsToPush.get(user).has(scriptName))
123
123
  return new NoScriptsError(`Could not find script ${user}.${scriptName} to push`)
124
- const pathsToUsers = new Cache(_path => new Set())
124
+ const pathsToUsers = new AutoMap(_path => new Set())
125
125
  for (const [user, scriptsToPush] of usersToScriptsToPush)
126
126
  for (const path of scriptsToPush.values()) pathsToUsers.get(path).add(user)
127
127
  const allInfo = []
package/watch.js CHANGED
@@ -1,14 +1,15 @@
1
- import { Cache } from "@samual/lib/Cache"
1
+ import { AutoMap } from "@samual/lib/AutoMap"
2
2
  import { assert } from "@samual/lib/assert"
3
3
  import { countHackmudCharacters } from "@samual/lib/countHackmudCharacters"
4
4
  import { readDirectoryWithStats } from "@samual/lib/readDirectoryWithStats"
5
5
  import { writeFilePersistent } from "@samual/lib/writeFilePersistent"
6
6
  import { watch as watch$1 } from "chokidar"
7
- import { readFile, writeFile } from "fs/promises"
7
+ import { stat, readFile, writeFile } from "fs/promises"
8
8
  import { extname, basename, resolve } from "path"
9
9
  import { supportedExtensions } from "./constants.js"
10
10
  import { generateTypeDeclaration } from "./generateTypeDeclaration.js"
11
11
  import { processScript } from "./processScript/index.js"
12
+ import "path/posix"
12
13
  import "@babel/generator"
13
14
  import "@babel/parser"
14
15
  import "@babel/plugin-proposal-decorators"
@@ -58,7 +59,8 @@ async function watch(
58
59
  } = {}
59
60
  ) {
60
61
  if (!scripts.length) throw Error("scripts option was an empty array")
61
- const scriptNamesToUsers = new Cache(_scriptName => new Set()),
62
+ if (!(await stat(sourceDirectory)).isDirectory()) throw Error("Target folder must be a folder")
63
+ const scriptNamesToUsers = new AutoMap(_scriptName => new Set()),
62
64
  wildScriptUsers = new Set(),
63
65
  wildUserScripts = new Set()
64
66
  let pushEverything = !1
@@ -71,10 +73,11 @@ async function watch(
71
73
  : scriptName && "*" != scriptName ? wildUserScripts.add(scriptName)
72
74
  : (pushEverything = !0)
73
75
  }
74
- const watcher = watch$1(["*.ts", "*.js", "*/*.ts", "*/*.js"], {
76
+ const watcher = watch$1(".", {
75
77
  cwd: sourceDirectory,
76
78
  awaitWriteFinish: { stabilityThreshold: 100 },
77
- ignored: "*.d.ts"
79
+ ignored: (path, stats) =>
80
+ !!stats?.isFile() && !(path.endsWith(".js") || (path.endsWith(".ts") && !path.endsWith(".d.ts")))
78
81
  }).on("change", async path => {
79
82
  if (path.endsWith(".d.ts")) return
80
83
  const extension = extname(path)
@@ -90,7 +93,7 @@ async function watch(
90
93
  )
91
94
  )
92
95
  return
93
- const scriptNamesToUsersToSkip = new Cache(_scriptName => [])
96
+ const scriptNamesToUsersToSkip = new AutoMap(_scriptName => [])
94
97
  await Promise.all(
95
98
  (await readDirectoryWithStats(sourceDirectory)).map(async ({ stats, name, path }) => {
96
99
  if (stats.isDirectory())
@@ -135,7 +138,7 @@ async function watch(
135
138
  forceQuineCheats
136
139
  }))
137
140
  } catch (error) {
138
- assert(error instanceof Error, "src/watch.ts:141:36")
141
+ assert(error instanceof Error, "src/watch.ts:148:36")
139
142
  onPush?.({ path, users: [], characterCount: 0, error })
140
143
  return
141
144
  }
@@ -180,7 +183,7 @@ async function watch(
180
183
  forceQuineCheats
181
184
  }))
182
185
  } catch (error) {
183
- assert(error instanceof Error, "src/watch.ts:177:35")
186
+ assert(error instanceof Error, "src/watch.ts:184:35")
184
187
  onPush?.({ path, users: [], characterCount: 0, error })
185
188
  return
186
189
  }
@@ -195,7 +198,7 @@ async function watch(
195
198
  try {
196
199
  await writeFile(typeDeclarationPath, typeDeclaration)
197
200
  } catch (error) {
198
- assert(error instanceof Error, "src/watch.ts:210:35")
201
+ assert(error instanceof Error, "src/watch.ts:217:35")
199
202
  if ("EISDIR" != error.code) throw error
200
203
  typeDeclarationPath = resolve(typeDeclarationPath, "player.d.ts")
201
204
  await writeFile(typeDeclarationPath, typeDeclaration)