@kirigami/php-prepros 1.1.0 → 1.6.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/README.md +1593 -869
- package/index.d.ts +145 -2
- package/index.js +1 -1
- package/package.json +4 -4
- package/src/imagebatch.php +67 -0
- package/src/libraries/aliases.inc.php +836 -0
- package/src/libraries/curl.class.php +20 -3
- package/src/libraries/fs.class.php +161 -6
- package/src/libraries/html.class.php +92 -22
- package/src/libraries/img.class.php +372 -17
- package/src/libraries/ld.class.php +804 -0
- package/src/libraries/md.class.php +502 -173
- package/src/libraries/md.plugins.php +25 -19
- package/src/libraries/normalizer.class.php +310 -0
- package/src/libraries/prepros.class.php +149 -10
- package/src/libraries/prepros.plugins.php +56 -6
- package/src/libraries/schema.class.php +550 -0
- package/src/libraries/scraper.class.php +64 -59
- package/src/libraries/std.class.php +3 -0
- package/src/libraries/str.class.php +50 -16
- package/src/libraries/yaml.class.php +66 -66
- package/src/phpjs/fstat.js +9 -0
- package/src/prepros.js +126 -47
- package/src/prepros.php +9 -2
- package/src/runenv.php +5 -2
- package/src/utils/getfilestats.js +30 -0
- package/src/utils/isbinary.js +14 -14
- package/src/utils.inc.php +20 -9
package/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* @example
|
|
11
11
|
* ```js
|
|
12
|
-
* import { render, sitemap } from '@kirigami/php-prepros';
|
|
12
|
+
* import { render, sitemap, runenv, mountPath } from '@kirigami/php-prepros';
|
|
13
13
|
*
|
|
14
14
|
* // Compile a single page
|
|
15
15
|
* const result = await render('src/index.php');
|
|
@@ -19,6 +19,18 @@
|
|
|
19
19
|
*
|
|
20
20
|
* // Generate sitemap.xml
|
|
21
21
|
* const sitemap = await sitemap();
|
|
22
|
+
*
|
|
23
|
+
* // Run an arbitrary PHP script in the same sandboxed environment
|
|
24
|
+
* const result = await runenv('scripts/purge-cache.php');
|
|
25
|
+
*
|
|
26
|
+
* // Mount a local file/directory into the sandbox before rendering
|
|
27
|
+
* await mountPath('assets/data/team.yaml');
|
|
28
|
+
*
|
|
29
|
+
* // Resize images / extract palettes through the IMG class (GD + Imagick)
|
|
30
|
+
* const { files, colors } = await processImages([
|
|
31
|
+
* { op: 'resize', src: 'hero.jpg', width: 1200, dests: ['/project/src/images/hero-1200w.webp'] },
|
|
32
|
+
* { op: 'palette', src: 'hero.jpg', count: 5 },
|
|
33
|
+
* ]);
|
|
22
34
|
* ```
|
|
23
35
|
*/
|
|
24
36
|
|
|
@@ -106,4 +118,135 @@ export function render(file?: string): Promise<PreprosResult>;
|
|
|
106
118
|
* @returns A {@link PreprosResult} with `files` containing the path to the
|
|
107
119
|
* generated `sitemap.xml`.
|
|
108
120
|
*/
|
|
109
|
-
export function sitemap(dir?: string): Promise<PreprosResult>;
|
|
121
|
+
export function sitemap(dir?: string): Promise<PreprosResult>;
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Run an arbitrary PHP script — not a page template — inside the same
|
|
126
|
+
* sandboxed WASM environment used by {@link render}, with the full
|
|
127
|
+
* `php-prepros` class library autoloaded and `kirigami.yaml`'s `kirigami`
|
|
128
|
+
* block available as `PREPROS::$config->data`.
|
|
129
|
+
*
|
|
130
|
+
* Useful for one-off maintenance scripts, data migrations, or CLI-style
|
|
131
|
+
* tooling that needs `CACHE`, `SCRAPER`, `IMG`, etc. without going through
|
|
132
|
+
* the page-rendering pipeline.
|
|
133
|
+
*
|
|
134
|
+
* ```js
|
|
135
|
+
* // Run a standalone PHP script
|
|
136
|
+
* const result = await runenv('scripts/purge-cache.php');
|
|
137
|
+
*
|
|
138
|
+
* // Also mount extra local paths/files into the sandbox before running
|
|
139
|
+
* const result = await runenv('scripts/build-og-images.php', ['assets/photos']);
|
|
140
|
+
*
|
|
141
|
+
* // Extra arguments are appended and available as $argv[2], $argv[3], … in the script
|
|
142
|
+
* const result = await runenv('scripts/import.php', [], '--force');
|
|
143
|
+
* ```
|
|
144
|
+
*
|
|
145
|
+
* @param script Path to a PHP file inside the project, executed with
|
|
146
|
+
* `require_once`.
|
|
147
|
+
* @param paths Extra local paths (files or directories) to mount into the
|
|
148
|
+
* sandbox before the script runs.
|
|
149
|
+
* @param args Extra string arguments appended to the script's `$argv`.
|
|
150
|
+
*
|
|
151
|
+
* @returns A {@link PreprosResult} describing what was written. Call
|
|
152
|
+
* `PREPROS::exportFile()` inside the script for any file you want
|
|
153
|
+
* listed in `result.files`.
|
|
154
|
+
*
|
|
155
|
+
* @throws When no `script` path is given.
|
|
156
|
+
* @throws When `script` resolves outside the project root, or doesn't exist.
|
|
157
|
+
*/
|
|
158
|
+
export function runenv(script: string, paths?: string[], ...args: string[]): Promise<PreprosResult>;
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* The JavaScript-side counterpart to `PREPROS::mount()`. Mounts a local
|
|
163
|
+
* file or directory — recursively, preserving structure — into the WASM
|
|
164
|
+
* sandbox's virtual filesystem, ahead of (or between) calls to
|
|
165
|
+
* {@link render}, {@link sitemap}, or {@link runenv}.
|
|
166
|
+
*
|
|
167
|
+
* Mounting a directory only copies files whose extension is one of the
|
|
168
|
+
* defaults (`.php`, `.json`, `.yaml`, `.yml`, `.md`, `.db`, `.txt`) or
|
|
169
|
+
* listed in `prepros.mountext`, same as automatic root mounting. Mounting a
|
|
170
|
+
* single file directly copies it regardless of extension.
|
|
171
|
+
*
|
|
172
|
+
* ```js
|
|
173
|
+
* // Mount a single file at its natural virtual path (/project/<relative path>)
|
|
174
|
+
* await mountPath('assets/data/team.yaml');
|
|
175
|
+
*
|
|
176
|
+
* // Mount a whole directory, at a custom virtual path
|
|
177
|
+
* await mountPath('vendor/fonts', '/project/fonts');
|
|
178
|
+
* ```
|
|
179
|
+
*
|
|
180
|
+
* @param localPath Path to a local file or directory. Relative paths are
|
|
181
|
+
* resolved against the project root.
|
|
182
|
+
* @param virtualDir Destination path inside the WASM filesystem. Defaults
|
|
183
|
+
* to `/project/<localPath relative to the project root>`
|
|
184
|
+
* when omitted.
|
|
185
|
+
* @param php WASM PHP instance to mount into. Defaults to the shared
|
|
186
|
+
* singleton instance (creating it if needed).
|
|
187
|
+
*/
|
|
188
|
+
export function mountPath(localPath: string, virtualDir?: string, php?: unknown): Promise<void>;
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* A single unit of work for {@link processImages}.
|
|
193
|
+
*
|
|
194
|
+
* - **`resize`** — decode `src` (resolved against `image.source`), optionally
|
|
195
|
+
* resize it, and encode a copy to every path in `dests` (each an absolute
|
|
196
|
+
* virtual path, e.g. `/project/src/images/hero-800w.webp`, already carrying
|
|
197
|
+
* the target extension). Omitting both `width` and `height` re-encodes at the
|
|
198
|
+
* source size. Staleness must be decided by the caller — every job passed in
|
|
199
|
+
* is executed.
|
|
200
|
+
* - **`palette`** — extract `count` representative colours from `src` via
|
|
201
|
+
* `IMG::palette()` (cached in `.cache.db`); returned in `colors`, not written.
|
|
202
|
+
*/
|
|
203
|
+
export type ImageJob =
|
|
204
|
+
| {
|
|
205
|
+
op: "resize";
|
|
206
|
+
/** Source path, relative to `image.source` in `kirigami.yaml`. */
|
|
207
|
+
src: string;
|
|
208
|
+
/** Target width in px. `0`/omitted = derive from height (or keep). */
|
|
209
|
+
width?: number;
|
|
210
|
+
/** Target height in px. `0`/omitted = derive from width (or keep). */
|
|
211
|
+
height?: number;
|
|
212
|
+
/** Crop to fill instead of fitting inside `width`×`height`. */
|
|
213
|
+
cover?: boolean;
|
|
214
|
+
/** Encoder quality (0-100) for lossy formats. Defaults to 82. */
|
|
215
|
+
quality?: number;
|
|
216
|
+
/** Absolute virtual destination paths to write the encoded image to. */
|
|
217
|
+
dests: string[];
|
|
218
|
+
}
|
|
219
|
+
| {
|
|
220
|
+
op: "palette";
|
|
221
|
+
/** Source path, relative to `image.source` in `kirigami.yaml`. */
|
|
222
|
+
src: string;
|
|
223
|
+
/** Number of colours to extract. Defaults to 5. */
|
|
224
|
+
count?: number;
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Result of {@link processImages}: a {@link PreprosResult} whose `files` lists
|
|
230
|
+
* every image written back to the host, plus the palettes that were requested.
|
|
231
|
+
*/
|
|
232
|
+
export interface ImageBatchResult extends PreprosResult {
|
|
233
|
+
/** Extracted palettes, keyed `"<src>:<count>"`, each a list of `#rrggbb`. */
|
|
234
|
+
colors: Record<string, string[]>;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Run a batch of image jobs through the same `IMG` class (GD, with the Imagick
|
|
240
|
+
* fallback) used by `IMG::asset()` and the `<img asset>` tag.
|
|
241
|
+
*
|
|
242
|
+
* This is the engine behind `@kirigami/kirigami`'s Sass `img-asset()` and
|
|
243
|
+
* `colors()` functions: one implementation, one `image:` config, one set of
|
|
244
|
+
* output filenames across Sass, PHP and HTML — no native image dependency.
|
|
245
|
+
*
|
|
246
|
+
* @param jobs List of {@link ImageJob}s. An empty list is a no-op (the WASM
|
|
247
|
+
* runtime is not started).
|
|
248
|
+
*
|
|
249
|
+
* @returns An {@link ImageBatchResult}. Resized files are also copied to the
|
|
250
|
+
* host at the project-relative equivalent of each `dests` entry.
|
|
251
|
+
*/
|
|
252
|
+
export function processImages(jobs?: ImageJob[]): Promise<ImageBatchResult>;
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { render, sitemap, runenv } from "./src/prepros.js";
|
|
1
|
+
export { render, sitemap, runenv, mountPath, processImages } from "./src/prepros.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kirigami/php-prepros",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "PHP preprocessor for the Kirigami static site generator. Compile PHP page templates to clean, deployable HTML — with zero server dependency.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"kirigami",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"README.md"
|
|
29
29
|
],
|
|
30
30
|
"engines": {
|
|
31
|
-
"node": ">=
|
|
31
|
+
"node": ">=24.0.0",
|
|
32
32
|
"npm": ">=10.2.3"
|
|
33
33
|
},
|
|
34
34
|
"exports": {
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@kirigami/php-wasm": "8.5.10-
|
|
48
|
-
"@kirigami/struct-walker": "1.0.
|
|
47
|
+
"@kirigami/php-wasm": "8.5.10-5",
|
|
48
|
+
"@kirigami/struct-walker": "1.0.4",
|
|
49
49
|
"picomatch": "^4.0.7"
|
|
50
50
|
},
|
|
51
51
|
"repository": {
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Batch image worker for the Kirigami build pipeline.
|
|
5
|
+
*
|
|
6
|
+
* Driven by @kirigami/kirigami's `sass` task (see processImages() in
|
|
7
|
+
* prepros.js): it receives a JSON list of jobs on $argv[2] and runs them
|
|
8
|
+
* through the IMG class (GD, with the Imagick fallback) so that the Sass
|
|
9
|
+
* `img-asset()` / `colors()` functions and the PHP `IMG::asset()` /
|
|
10
|
+
* `<img asset>` tag all share one engine.
|
|
11
|
+
*
|
|
12
|
+
* Job shapes:
|
|
13
|
+
* { "op": "resize", "src": "hero.jpg", "width": 800, "height": 0,
|
|
14
|
+
* "cover": false, "quality": 82,
|
|
15
|
+
* "dests": ["/project/dist/images/hero-800w.webp",
|
|
16
|
+
* "/project/src/images/hero-800w.webp"] }
|
|
17
|
+
* { "op": "palette", "src": "hero.jpg", "count": 5 }
|
|
18
|
+
*
|
|
19
|
+
* `src` is resolved against `image.source`; `dests` are absolute virtual
|
|
20
|
+
* paths already carrying the target extension. Staleness is decided on the
|
|
21
|
+
* JS side, so every job listed here is meant to run. Generated files are
|
|
22
|
+
* returned through PREPROS::exportFile() (STD::succeed copies them back to
|
|
23
|
+
* the host); extracted palettes ride back in the `colors` map.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
include(__DIR__ . '/utils.inc.php');
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
|
|
30
|
+
$jobs = json_decode($argv[2] ?? '[]');
|
|
31
|
+
if (!is_array($jobs)) throw new Exception("Invalid jobs payload.");
|
|
32
|
+
|
|
33
|
+
$colors = [];
|
|
34
|
+
|
|
35
|
+
foreach ($jobs as $job) {
|
|
36
|
+
|
|
37
|
+
if (($job->op ?? '') === 'palette') {
|
|
38
|
+
$count = (int) ($job->count ?? 5);
|
|
39
|
+
$colors[$job->src . ':' . $count] = IMG::palette($job->src, $count);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// op: resize
|
|
44
|
+
$srcfile = FS::pathJoin(PREPROS::$config->image->source, $job->src);
|
|
45
|
+
if (!$mounted = PREPROS::mount($srcfile)) throw new Exception("Can't mount image: {$job->src}");
|
|
46
|
+
$localfile = current($mounted);
|
|
47
|
+
if (!is_file($localfile)) throw new Exception("Can't mount image: {$job->src}");
|
|
48
|
+
|
|
49
|
+
$width = (int) ($job->width ?? 0);
|
|
50
|
+
$height = (int) ($job->height ?? 0);
|
|
51
|
+
$cover = (bool) ($job->cover ?? false);
|
|
52
|
+
$quality = isset($job->quality) ? (int) $job->quality : null;
|
|
53
|
+
|
|
54
|
+
$img = new IMG($localfile);
|
|
55
|
+
if ($width && $height) $img->resize($width, $height, $cover);
|
|
56
|
+
elseif ($width) $img->resize($width);
|
|
57
|
+
elseif ($height) $img->resize((int) round($img->width * $height / $img->height), $height);
|
|
58
|
+
// neither: no resize, just re-encode to the target format
|
|
59
|
+
|
|
60
|
+
foreach ($job->dests as $dest) $img->save($dest, $quality);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
STD::succeed(['files' => PREPROS::getExportedFiles(), 'colors' => $colors]);
|
|
64
|
+
|
|
65
|
+
} catch (Throwable $e) {
|
|
66
|
+
STD::error($e->getMessage());
|
|
67
|
+
}
|