Skip to content

Commit

Permalink
2024.03.1
Browse files Browse the repository at this point in the history
  • Loading branch information
lovedder1995 committed Mar 26, 2024
1 parent 3233be0 commit 28320a2
Show file tree
Hide file tree
Showing 19 changed files with 501 additions and 161 deletions.
85 changes: 58 additions & 27 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const { existsSync, mkdirSync, readFileSync, writeFileSync, rmSync } = require('fs')
const EventEmitter = require('events')
const chokidar = require('chokidar')
const phpArrayReader = require('php-array-reader')

const eventEmitter = new EventEmitter()

Expand All @@ -10,13 +11,13 @@ const watcher = chokidar.watch('index.mhp', {

watcher.on('change', () => eventEmitter.emit('compile'))

const indentation = ({ file, filename }) => {
const compile = ({ file, filename }) => {
const lines = file.split('\n')

const rules = [
'clutter',
'end_of_file',
'spaces',
'spacing',
'indentation',
'comments',
'logical_operators',
Expand All @@ -26,21 +27,29 @@ const indentation = ({ file, filename }) => {
'assignments',
'expressions',
'comparison_operators',
'strings',
'text',
'blank_lines'
]

rules.every(rule => require(`./rules/${rule}.js`)({ lines, filename }))
const compiled = rules.every(rule => require(`./rules/${rule}.js`)({ lines, filename }))

return lines.join('\n')
if (!compiled) {
return { error: true }
}

return { compiled: lines.join('\n') }
}

const aModuleFilename = /(?<=module\(")(.*?)(?="\))/
const aModuleExpression = /module\("(.*?)"\)/

const closure = code => `(function () {
const closure = parameters => {
const { name, code } = parameters

return `define("${name}", function () {
${code}
})()`
})`
}

const resoveModule = ({ file, moduleFilename }) => {
if (!moduleFilename) moduleFilename = file.match(aModuleFilename)
Expand All @@ -59,17 +68,28 @@ const resoveModule = ({ file, moduleFilename }) => {
if (moduleFile.startsWith('<?php')) {
moduleFile = moduleFile.replace('<?php\n', '')
} else {
moduleFile = indentation({ file: moduleFile, filename: moduleFilename })
moduleFile = compile({ file: moduleFile, filename: moduleFilename })
if (moduleFile.error) {
return
}

moduleFile = moduleFile.compiled
}

moduleFile = moduleFile.split('\n').map(line => {
if (line === '') return line
return ` ${line}`
}).join('\n')
moduleFile = moduleFile.split('\n').map(line => line).join('\n')

moduleFile = closure(moduleFile.trimEnd())
moduleFile = closure({
name: moduleFilename,
code: moduleFile.trimEnd()
})

const bundle = file.replace(aModuleExpression, moduleFile)
let bundle = file.replace(aModuleExpression, `constant("${moduleFilename}")()`)
if (!bundle.includes('# </php-modules>\n')) {
bundle = `\n# <php-modules>\n\n# </php-modules>\n\n${bundle}`
}
if (!bundle.includes(moduleFile)) {
bundle = bundle.replace('# </php-modules>\n', `${moduleFile};\n\n# </php-modules>\n`)
}

const anotherModuleFilename = bundle.match(aModuleFilename)

Expand All @@ -86,33 +106,40 @@ const resoveModule = ({ file, moduleFilename }) => {
const handleFile = () => {
console.clear()
const mainFile = readFileSync('index.mhp', 'utf-8')
if (mainFile === '') {
return
}

let bundle = indentation({ file: mainFile, filename: 'index.mhp' })
bundle = resoveModule({ file: bundle })
let bundle = compile({ file: mainFile, filename: 'index.mhp' })
if (bundle.error) {
return
}

bundle = resoveModule({ file: bundle.compiled })

writeFileSync('index.php', `<?php\n${bundle}`)
}

if (!existsSync('modules.mhp')) {
if (!existsSync('manifest.mhp')) {
handleFile()
}

if (existsSync('modules.mhp')) {
if (existsSync('manifest.mhp')) {
if (!existsSync('php_modules')) {
mkdirSync('php_modules')
}

let needUpdate

const modulesFile = readFileSync('modules.mhp', 'utf-8')
const manifestFile = readFileSync('manifest.mhp', 'utf-8')

if (!existsSync('php_modules/modules.mhp')) {
if (!existsSync('php_modules/manifest.mhp')) {
needUpdate = true
}

if (existsSync('php_modules/modules.mhp')) {
const installedModules = readFileSync('php_modules/modules.mhp', 'utf-8')
if (installedModules !== modulesFile) {
if (existsSync('php_modules/manifest.mhp')) {
const installedModules = readFileSync('php_modules/manifest.mhp', 'utf-8')
if (installedModules !== manifestFile) {
needUpdate = true
}
}
Expand All @@ -122,15 +149,19 @@ if (existsSync('modules.mhp')) {
}

if (needUpdate) {
writeFileSync('php_modules/modules.mhp', modulesFile)
let modules = indentation({ file: modulesFile, filename: 'modules.mhp' })
modules = eval(`(function () { ${modules} })()`)
writeFileSync('php_modules/manifest.mhp', manifestFile)
let manifest = compile({ file: manifestFile, filename: 'manifest.mhp' })
if (manifest.error) {
throw Error(manifest.error)
}
manifest = phpArrayReader.fromString(manifest.compiled.replace('return ', ''))
const modules = manifest.modules
modules.every(async (module, index) => {
let moduleFile = await fetch(module).then(async response => {
const text = await response.text()
if (response.status === 404) {
console.log(text)
rmSync('php_modules/modules.mhp')
rmSync('php_modules/manifest.mhp')
return false
}
return text
Expand Down
2 changes: 1 addition & 1 deletion lib/array_add.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module.exports = parameters => {
})

if (missingParameter) {
throw Error(`Expected an parameter called ${missingParameter} in arrayAdd()`)
throw Error(`Expected a parameter called ${missingParameter} in arrayAdd()`)
}

const { array, carry: initialValue, iteration } = parameters
Expand Down
30 changes: 30 additions & 0 deletions lib/array_every.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module.exports = parameters => {
const expectedParameters = [
'array',
'iteration'
]

const missingParameter = expectedParameters.find(parameter => {
return !Object.keys(parameters).includes(parameter)
})

if (missingParameter) {
throw Error(`Expected a parameter called ${missingParameter} in arrayEvery()`)
}

const { array, iteration } = parameters

if (array.length === 0) {
throw Error('arrayEvery() cannot be used in empty arrays.')
}

const callback = (currentValue, index, array) => {
return iteration({
value: currentValue,
index,
array
})
}

return array.every(callback)
}
41 changes: 41 additions & 0 deletions lib/array_match.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
module.exports = parameters => {
const expectedParameters = [
'value',
'default',
'array'
]

const missingParameter = expectedParameters.find(parameter => {
return !Object.keys(parameters).includes(parameter)
})

if (missingParameter) {
throw Error(`Expected an parameter called ${missingParameter} in arrayMatch()`)
}

const { array, value } = parameters
const _default = parameters.default

const _case = array.find(element => {
const expectedParameters = [
'case',
'assign'
]

const missingParameter = expectedParameters.find(parameter => {
return !Object.keys(element).includes(parameter)
})

if (missingParameter) {
throw Error(`Expected a parameter called ${missingParameter} in array argument of arrayMatch()`)
}

return element.case === value
})

if (!_case) {
return _default
}

return _case.assign
}
44 changes: 44 additions & 0 deletions lib/ignore_text.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const arrayAdd = require('php-bundler/lib/array_add.js')

module.exports = (parameters) => {
const expectedParameters = [
'text',
'transform'
]

const missingParameter = expectedParameters.find(parameter => {
return !Object.keys(parameters).includes(parameter)
})

if (missingParameter) {
throw Error(`Expected a parameter called ${missingParameter} in ignoreText()`)
}

let { text, transform } = parameters
const betweenBackticks = /`(?<=`).+?(?=`)`/g
let matchedText = [...text.matchAll(betweenBackticks)]
if (matchedText === undefined) {
text = transform(text)
if (typeof text !== 'string') {
throw Error('transform() expected to return a value of type text')
}
}

matchedText = matchedText.map(text => text[0])

text = text.replaceAll(betweenBackticks, '<STRING>')
text = transform(text)
if (typeof text !== 'string') {
throw Error('transform() expected to return a value of type text')
}
return arrayAdd({
array: matchedText,
carry: text,
iteration: parameters => {
const text = parameters.carry
const match = parameters.value

return text.replace('<STRING>', match)
}
})
}
61 changes: 61 additions & 0 deletions lib/match_multiline_text.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
module.exports = ({ lines, index, filename, multilineString }) => {
if (lines[index].endsWith('<<<STRING')) {
const indentation = lines[index].length - lines[index].trimStart().length
multilineString = { line: lines[index], index, indentation }
return multilineString
}

if (lines[index].trimStart().startsWith('STRING')) {
multilineString = {}
return multilineString
}

if (!lines[index].endsWith('`')) {
return multilineString
}

if (multilineString.line && lines[index].trimStart() === '`') {
const indentation = lines[index].length - lines[index].trimStart().length

if (indentation !== multilineString.indentation) {
return multilineString
}

const linesAfter = [
lines[index + 1],
lines[index + 2]
]

if (indentation === 0 && (linesAfter[0] !== '' || linesAfter[1] === '')) {
console.log(`${filename} ${index + 1}`, '- There must be one blank line after each top level multiline string')
return { error: true }
}

lines[index] = `${' '.repeat(indentation)}STRING`
multilineString = {}
return multilineString
}

const multilineStringDeclaration = ([...lines[index].matchAll(/`/g)].length % 2) !== 0
if (!multilineString.line && multilineStringDeclaration) {
const linesBefore = [
lines[index - 1],
lines[index - 2]
]

if (linesBefore[0] !== undefined) {
if (!lines[index].startsWith(' ')) {
if (linesBefore[0] !== '' || linesBefore[1] === '') {
console.log(`${filename} ${index + 1}`, '- There must be one blank line before each top level multiline string')
return { error: true }
}
}
}

lines[index] = `${lines[index].slice(0, -1)}<<<STRING`
const indentation = lines[index].length - lines[index].trimStart().length
multilineString = { line: lines[index], index, indentation }
}

return multilineString
}
Loading

0 comments on commit 28320a2

Please sign in to comment.