@kirigami/php-prepros 1.0.9 → 1.1.0

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.
package/src/prepros.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import fs from 'fs';
2
- import path, { dirname } from "path";
3
2
  import isBinary from './utils/isbinary.js';
4
3
  import joinWith from './utils/joinwith.js'
4
+ import path, { dirname } from "path";
5
5
  import { spawn } from 'child_process';
6
- import { fileURLToPath } from 'url';
6
+ import { fileURLToPath, pathToFileURL } from "url";
7
7
  import { walkFile } from '@kirigami/struct-walker';
8
8
  import { getPHPRuntime, getPHPRuntimeWithNetwork } from "@kirigami/php-wasm";
9
9
 
@@ -20,13 +20,14 @@ const config = await walkFile(__configpath);
20
20
  if(!config) throw `Invalid config file: ${__configpath}`;
21
21
 
22
22
 
23
+
23
24
  const getPHPInstance = async () => {
24
25
  if(!__php) {
25
26
  if(config?.kirigami?.root === undefined) throw `Missing prepros:root property in config file: ${__configpath}`;
26
27
  __root = path.join(__project, config.kirigami.root);
27
28
  if (!fs.existsSync(__root)) throw `Invalid prepros:root path: ${__root}`;
28
29
 
29
- const preprosConfig = config.prepros;
30
+ const preprosConfig = config.prepros || {};
30
31
  preprosConfig.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
31
32
  preprosConfig.root = joinWith('/project/', config?.kirigami?.root);
32
33
  preprosConfig.data = config.kirigami || {};
@@ -35,21 +36,49 @@ const getPHPInstance = async () => {
35
36
  __php.setSpawnHandler((command, args, options) => spawn(command, args, options));
36
37
  __php.preprosConfig = preprosConfig;
37
38
 
38
- const mountPaths = [];
39
39
  const __cache = path.join(__project, '.cache.db');
40
+ const __cookie = path.join(__project, '.cookie.txt');
40
41
  mountPath(__php, __dirname, '/prepros');
41
42
  mountPath(__php, joinWith(__project, config?.kirigami?.root), joinWith('/project', config?.kirigami?.root));
43
+
42
44
  if (fs.existsSync(__cache)) mountPath(__php, __cache, '/project/.cache.db');
45
+ if (fs.existsSync(__cookie)) mountPath(__php, __cookie, '/project/.cookie.txt');
46
+
47
+ __php.onMessage(async (data) => {
48
+ const msg = JSON.parse(data);
49
+ if(!msg.command) return { success: false, error: "Invalid command."};
50
+ const file = path.join(__dirname, 'phpjs', `${msg.command}.js`);
51
+ if(!fs.existsSync(file)) return { success: false, error: "Invalid command."};
52
+
53
+ try {
54
+ const cmdModule = await import(pathToFileURL(file).href);
55
+ const results = await cmdModule.default(__php, msg);
56
+ return JSON.stringify({
57
+ success: true,
58
+ results: results
59
+ });
60
+ } catch(e) {
61
+ return {
62
+ success: false,
63
+ error: typeof e == 'string' ? e : e.message
64
+ }
65
+ }
66
+
67
+
68
+ // console.log(msg);
69
+ // console.log(__dirname);
70
+
71
+ });
43
72
  }
44
73
  return __php;
45
74
  }
46
75
 
47
76
 
48
77
  const mountPath = (php, localPath, virtualDir) => {
49
- const includeExtensions = new Set(['.php', '.json', '.yaml', '.md', '.db', ...(config?.prepros?.mountext || [])]);
78
+ const includeExtensions = new Set(['.php', '.json', '.yaml', '.yml', '.md', '.db', '.txt', ...(config?.prepros?.mountext || [])]);
50
79
  const stat = fs.statSync(localPath);
51
80
  if (stat.isDirectory()) {
52
- php.mkdir(virtualDir);
81
+ php.mkdirTree(virtualDir);
53
82
  for (const entry of fs.readdirSync(localPath, { withFileTypes: true })) {
54
83
  mountPath(php, path.join(localPath, entry.name), virtualDir + '/' + entry.name);
55
84
  }
@@ -57,46 +86,86 @@ const mountPath = (php, localPath, virtualDir) => {
57
86
  const ext = path.extname(localPath).toLowerCase();
58
87
  if (includeExtensions.has(ext)) {
59
88
  const buf = fs.readFileSync(localPath);
89
+ const parentDir = virtualDir.substring(0, virtualDir.lastIndexOf('/'));
90
+ if (parentDir) {
91
+ php.mkdirTree(parentDir);
92
+ }
60
93
  php.writeFile(virtualDir, isBinary(buf) ? buf : buf.toString('utf8'));
61
94
  }
62
95
  }
63
96
  }
64
97
 
65
98
 
66
- const run = async (args) => {
99
+ const run = async (args = [], script = null, mountfiles = []) => {
67
100
  const php = await getPHPInstance();
101
+
102
+ await Promise.all(mountfiles.map(async item => {
103
+ const file = path.resolve(item);
104
+ if(!fs.existsSync(file)) return;
105
+ if(!path.relative(__project, file)) return;
106
+ const dest = path.join('/project', file.replace(__project, '')).replaceAll('\\', '/');
107
+ const buf = fs.readFileSync(file);
108
+ const parentDir = dest.substring(0, dest.lastIndexOf('/'));
109
+ if (parentDir) php.mkdirTree(parentDir);
110
+ php.writeFile(dest, isBinary(buf) ? buf : buf.toString('utf8'));
111
+ }));
112
+
68
113
  const output = await php.runStream({
69
- scriptPath: '/prepros/prepros.php',
114
+ scriptPath: script || '/prepros/prepros.php',
70
115
  env: {
71
- PREPROS_ARGS: JSON.stringify(args),
116
+ PREPROS_ARGS: JSON.stringify(args),
72
117
  PREPROS_CONFIG: JSON.stringify(php.preprosConfig)
73
118
  }
74
119
  });
120
+
75
121
  const stdout = await output.stdoutText;
76
122
  const stderr = await output.stderrText;
123
+
77
124
  let retobj;
125
+ const resultPath = '/internal/prepros_result.json';
126
+
78
127
  try {
79
- retobj = JSON.parse(stdout);
80
- await Promise.all(retobj.files.map(async (file, i) => {
81
- const buffer = php.readFileAsBuffer(file);
82
- const dest = file.replace(/^\/project\//i, '');
83
- fs.writeFileSync(path.join(__project, dest), buffer);
84
- retobj.files[i] = dest;
85
- }));
86
- } catch(e) {
87
- retobj = { success: false, error: 'Response parsing error.', response: stdout };
128
+ if (await php.fileExists(resultPath)) {
129
+ const buffer = php.readFileAsBuffer(resultPath);
130
+ retobj = JSON.parse(Buffer.from(buffer).toString('utf8'));
131
+ retobj.debug = stdout;
132
+
133
+ if(retobj.files) await Promise.all(retobj.files.map(async (file, i) => {
134
+ const fbuffer = php.readFileAsBuffer(file);
135
+ const dest = file.replace(/^\/project\//i, '');
136
+ const dir = dirname(path.join(__project, dest));
137
+ if(!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
138
+ fs.writeFileSync(path.join(__project, dest), fbuffer);
139
+ retobj.files[i] = dest;
140
+ }));
141
+ } else {
142
+ retobj = { success: true, files: [], debug: stdout };
143
+ }
144
+ } catch (e) {
145
+ retobj = { success: false, error: 'Response parsing error.' + e, debug: stdout, stderr };
146
+ } finally {
147
+ if (await php.fileExists(resultPath)) {
148
+ await php.unlink(resultPath);
149
+ }
88
150
  }
89
151
  if (stderr) {
90
- try {
91
- retobj = JSON.parse(stderr);
92
- } catch(e) {
93
- retobj = { success: false, error: stderr };
94
- }
152
+ retobj = { success: false, error: stderr, debug: stdout };
95
153
  }
154
+
96
155
  return retobj;
97
156
  }
98
157
 
99
158
 
159
+ const runenv = async (script, paths = [], ...args) => {
160
+ if(!script) throw "Missing PHP file.";
161
+ const file = path.resolve(script);
162
+ if(!path.relative(__project, file)) throw "PHP file outside project";
163
+ if(!fs.existsSync(file)) throw "Can't find PHP file";
164
+ const dest = path.join('/project', file.replace(__project, '')).replaceAll('\\', '/');
165
+ return run([dest, ...args], '/prepros/runenv.php', [file, ...paths]);
166
+ }
167
+
168
+
100
169
  const render = async (file = '.') => {
101
170
  const php = await getPHPInstance();
102
171
  const target = path.resolve(__project, config?.kirigami?.root, file);
@@ -123,4 +192,4 @@ const sitemap = async (dir) => {
123
192
  }
124
193
 
125
194
 
126
- export { render, sitemap };
195
+ export { runenv, render, sitemap };
package/src/prepros.php CHANGED
@@ -1,23 +1,10 @@
1
1
  <?php
2
2
 
3
- ini_set('log_errors', 1);
4
- ini_set('html_errors', 0);
5
- ini_set('display_errors', 1);
6
- ini_set('error_reporting', 32767);
7
- ini_set('error_log', 'php://stderr');
8
- error_reporting(E_ALL);
9
-
10
-
11
- $argv = array_merge(['prepros.php'], json_decode(getenv('PREPROS_ARGS'), true));
12
- $config = json_decode(getenv('PREPROS_CONFIG'));
13
-
3
+ include(__DIR__ . '/utils.inc.php');
14
4
 
15
5
  try {
16
-
17
- date_default_timezone_set($config->timezone);
18
6
  if (!isset($argv[1])) STD::error("Invalid argument.");
19
- include(__DIR__ . '/utils.inc.php');
20
- PREPROS::loadConfig($config);
7
+
21
8
  if($argv[1] == 'sitemap') {
22
9
  if(!PREPROS::sitemap()) STD::error("Can't produce the sitemap.");
23
10
  STD::succeed(['files' => PREPROS::getExportedFiles()]);
@@ -38,8 +25,8 @@ try {
38
25
  }
39
26
 
40
27
  } catch(Exception $e) {
41
- STD::error($e->getMessage());
28
+ STD::error(['message' => $e->getMessage()]);
42
29
  }
43
30
 
44
31
 
45
- STD::succeed(['files' => PREPROS::getExportedFiles()]);
32
+ STD::succeed();
package/src/runenv.php ADDED
@@ -0,0 +1,17 @@
1
+ <?php
2
+
3
+ include(__DIR__ . '/utils.inc.php');
4
+
5
+
6
+ try {
7
+
8
+ if (!isset($argv[1])) STD::error("Invalid PHP file.");
9
+ if (!is_file($argv[1])) STD::error("PHP file not found.");
10
+
11
+ require_once($argv[1]);
12
+
13
+ } catch(Exception $e) {
14
+ STD::error($e->getMessage());
15
+ }
16
+
17
+ STD::succeed(['files' => PREPROS::getExportedFiles()]);
@@ -0,0 +1,25 @@
1
+ import fs from 'fs';
2
+ import path from "path";
3
+ import picomatch from "picomatch";
4
+
5
+ export default function findFiles(pattern, cwd = process.cwd()) {
6
+ const isMatch = picomatch(pattern);
7
+ const results = [];
8
+ function walk(dir) {
9
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
10
+ for (const entry of entries) {
11
+ const fullPath = path.join(dir, entry.name);
12
+ const relativePath = path.relative(cwd, fullPath);
13
+ if (entry.isDirectory()) {
14
+ if (entry.name === 'node_modules' || entry.name === '.git') continue;
15
+ walk(fullPath);
16
+ } else if (entry.isFile()) {
17
+ if (isMatch(relativePath.split(path.sep).join('/'))) {
18
+ results.push(relativePath.replaceAll('\\', '/'));
19
+ }
20
+ }
21
+ }
22
+ }
23
+ walk(cwd);
24
+ return results;
25
+ }
package/src/utils.inc.php CHANGED
@@ -1,4 +1,11 @@
1
1
  <?php
2
+ ini_set('log_errors', 1);
3
+ ini_set('html_errors', 0);
4
+ ini_set('display_errors', 1);
5
+ ini_set('error_reporting', 32767);
6
+ ini_set('error_log', 'php://stderr');
7
+ error_reporting(E_ALL);
8
+
2
9
 
3
10
  const BR = '<br>';
4
11
  const RN = "\r\n";
@@ -14,16 +21,28 @@ function _print_r(mixed $obj) {
14
21
 
15
22
  spl_autoload_register(function ($class) {
16
23
  static $catalog = [
24
+ 'ARR' => 'arr.class.php',
17
25
  'CACHE' => 'cache.class.php',
26
+ 'CURL' => 'curl.class.php',
18
27
  'FS' => 'fs.class.php',
19
28
  'HTML' => 'html.class.php',
20
29
  'IMG' => 'img.class.php',
21
30
  'MD' => 'md.class.php',
22
31
  'OBF' => 'obf.class.php',
23
32
  'PREPROS' => 'prepros.class.php',
24
- 'STD' => 'std.class.php',
33
+ 'SCRAPER' => 'scraper.class.php',
34
+ 'STD' => 'std.class.php',
25
35
  'STR' => 'str.class.php',
26
36
  'YAML' => 'yaml.class.php',
27
37
  ];
28
38
  if (isset($catalog[$class])) require_once(__DIR__ . '/libraries/' . $catalog[$class]);
29
- }, true, true);
39
+ }, true, true);
40
+
41
+
42
+ $argv = array_merge(['prepros.php'], json_decode(getenv('PREPROS_ARGS'), true));
43
+ $config = json_decode(getenv('PREPROS_CONFIG'));
44
+ date_default_timezone_set($config->timezone);
45
+ chdir('/project');
46
+
47
+
48
+ PREPROS::loadConfig($config);