@orieljs/framework 0.1.0-alpha.4 → 0.1.0-alpha.5
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/dist/{chunk-3DETYZMZ.js → chunk-A5XRLEWM.js} +3 -3
- package/dist/{chunk-WSGWYXAO.js → chunk-BSQKOLSK.js} +3 -1
- package/dist/chunk-BSQKOLSK.js.map +1 -0
- package/dist/{chunk-DCI2T7WJ.js → chunk-PM5YTG57.js} +117 -3
- package/dist/chunk-PM5YTG57.js.map +1 -0
- package/dist/{chunk-SBZQ6L3Z.js → chunk-WNJP46B7.js} +563 -73
- package/dist/chunk-WNJP46B7.js.map +1 -0
- package/dist/contracts.d.ts +43 -1
- package/dist/contracts.js +3 -1
- package/dist/index.d.ts +391 -52
- package/dist/index.js +610 -144
- package/dist/index.js.map +1 -1
- package/dist/jsx-runtime.js +3 -3
- package/dist/{testing-D3dCOkTm.d.ts → testing-BErengYY.d.ts} +89 -12
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +3 -3
- package/package.json +30 -30
- package/dist/chunk-DCI2T7WJ.js.map +0 -1
- package/dist/chunk-SBZQ6L3Z.js.map +0 -1
- package/dist/chunk-WSGWYXAO.js.map +0 -1
- /package/dist/{chunk-3DETYZMZ.js.map → chunk-A5XRLEWM.js.map} +0 -0
|
@@ -8,8 +8,9 @@ import {
|
|
|
8
8
|
Str,
|
|
9
9
|
currentContainer,
|
|
10
10
|
facade,
|
|
11
|
+
fileType_exports,
|
|
11
12
|
inject
|
|
12
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-PM5YTG57.js";
|
|
13
14
|
import {
|
|
14
15
|
Application,
|
|
15
16
|
AuthFactory,
|
|
@@ -32,6 +33,7 @@ import {
|
|
|
32
33
|
MailManager,
|
|
33
34
|
MiddlewareCallbacks,
|
|
34
35
|
NotificationDispatcher,
|
|
36
|
+
PaginationState,
|
|
35
37
|
PipelineFactory,
|
|
36
38
|
QueueManager,
|
|
37
39
|
Redirector,
|
|
@@ -43,7 +45,7 @@ import {
|
|
|
43
45
|
ValidationFactory,
|
|
44
46
|
ViewFactory,
|
|
45
47
|
token
|
|
46
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-BSQKOLSK.js";
|
|
47
49
|
|
|
48
50
|
// ../Config/dist/index.js
|
|
49
51
|
import { existsSync, readFileSync } from "fs";
|
|
@@ -490,7 +492,7 @@ var Application2 = class _Application extends Container {
|
|
|
490
492
|
this.scoped(Vite, () => new Vite(this));
|
|
491
493
|
}
|
|
492
494
|
base;
|
|
493
|
-
version = "0.1.0-alpha.
|
|
495
|
+
version = "0.1.0-alpha.5";
|
|
494
496
|
providers = [];
|
|
495
497
|
bootingCallbacks = [];
|
|
496
498
|
bootedCallbacks = [];
|
|
@@ -885,20 +887,60 @@ function mimeFromExtension(pathOrExtension) {
|
|
|
885
887
|
function extensionFromMime(type) {
|
|
886
888
|
return EXTENSIONS[type.split(";")[0].trim().toLowerCase()];
|
|
887
889
|
}
|
|
888
|
-
var
|
|
889
|
-
|
|
890
|
+
var NEVER_CLAIMED = /* @__PURE__ */ new Set([
|
|
891
|
+
...fileType_exports.BINARY_AND_MARKUP_TYPES.flatMap(({ extensions }) => extensions),
|
|
892
|
+
"jpe",
|
|
893
|
+
"svgz",
|
|
894
|
+
"xhtml",
|
|
895
|
+
"xht",
|
|
896
|
+
"shtml",
|
|
897
|
+
"xsl",
|
|
898
|
+
"xslt",
|
|
899
|
+
"mht",
|
|
900
|
+
"mhtml",
|
|
901
|
+
"js",
|
|
902
|
+
"mjs",
|
|
903
|
+
"rss",
|
|
904
|
+
"atom",
|
|
905
|
+
"rdf",
|
|
906
|
+
"mathml",
|
|
907
|
+
"mml",
|
|
908
|
+
"xul"
|
|
909
|
+
]);
|
|
910
|
+
var PLAIN_EXTENSION = /^[a-z0-9]+$/;
|
|
911
|
+
var FormUploadedFile = class _FormUploadedFile {
|
|
912
|
+
constructor(file, detected) {
|
|
890
913
|
this.file = file;
|
|
914
|
+
this.detected = detected;
|
|
891
915
|
this.clientName = file.name ?? "";
|
|
892
916
|
this.mimeType = file.type === "" ? "application/octet-stream" : file.type;
|
|
893
917
|
this.size = file.size;
|
|
894
918
|
}
|
|
895
919
|
file;
|
|
920
|
+
detected;
|
|
896
921
|
clientName;
|
|
897
922
|
mimeType;
|
|
898
923
|
size;
|
|
899
|
-
/**
|
|
924
|
+
/**
|
|
925
|
+
* Reads the leading bytes first, so extension(), hashName() and store() name the file by its content. The request
|
|
926
|
+
* builds its uploads this way.
|
|
927
|
+
*/
|
|
928
|
+
static async fromFile(file) {
|
|
929
|
+
return new _FormUploadedFile(file, fileType_exports.detectFileType(new Uint8Array(await file.slice(0, fileType_exports.SNIFF_BYTES).arrayBuffer())));
|
|
930
|
+
}
|
|
931
|
+
/**
|
|
932
|
+
* Laravel's extension(): the type the bytes show (guessExtension()), when they were read and match a known format.
|
|
933
|
+
* Text and bytes no format matches keep the client's claim (its MIME type, else its file name) when it is a plain
|
|
934
|
+
* extension, unless it names a format the bytes would have shown or one a browser renders or runs: otherwise 'txt'
|
|
935
|
+
* for text, '' for the rest. Unread (built directly), the client's claim when it is a plain extension, else ''.
|
|
936
|
+
*/
|
|
900
937
|
extension() {
|
|
901
|
-
|
|
938
|
+
const claimed = extensionFromMime(this.mimeType) ?? this.clientExtension();
|
|
939
|
+
const detected = this.detected;
|
|
940
|
+
if (detected === void 0) return PLAIN_EXTENSION.test(claimed) ? claimed : "";
|
|
941
|
+
if (detected !== fileType_exports.TEXT && detected.extensions.length > 0) return detected.extensions[0];
|
|
942
|
+
if (PLAIN_EXTENSION.test(claimed) && !NEVER_CLAIMED.has(claimed)) return claimed;
|
|
943
|
+
return detected === fileType_exports.TEXT ? "txt" : "";
|
|
902
944
|
}
|
|
903
945
|
clientExtension() {
|
|
904
946
|
const dot = this.clientName.lastIndexOf(".");
|
|
@@ -1078,7 +1120,7 @@ var IncomingRequest = class {
|
|
|
1078
1120
|
this.#content = new TextDecoder().decode(bytes);
|
|
1079
1121
|
this.#body = fromEntries(new URLSearchParams(this.#content).entries());
|
|
1080
1122
|
} else {
|
|
1081
|
-
this.#parseForm(await new Response(bytes, { headers: { "content-type": this.raw.headers.get("content-type") ?? "" } }).formData());
|
|
1123
|
+
await this.#parseForm(await new Response(bytes, { headers: { "content-type": this.raw.headers.get("content-type") ?? "" } }).formData());
|
|
1082
1124
|
}
|
|
1083
1125
|
} catch {
|
|
1084
1126
|
}
|
|
@@ -1103,12 +1145,12 @@ var IncomingRequest = class {
|
|
|
1103
1145
|
if (Array.isArray(parsed)) return sanitize({ ...parsed });
|
|
1104
1146
|
return isPlainObject(parsed) ? sanitize(parsed) : {};
|
|
1105
1147
|
}
|
|
1106
|
-
#parseForm(form) {
|
|
1148
|
+
async #parseForm(form) {
|
|
1107
1149
|
const fields = [];
|
|
1108
1150
|
const files = [];
|
|
1109
1151
|
for (const [name, value] of form.entries()) {
|
|
1110
1152
|
if (typeof value === "string") fields.push([name, value]);
|
|
1111
|
-
else if (!((value.name ?? "") === "" && value.size === 0)) files.push([name,
|
|
1153
|
+
else if (!((value.name ?? "") === "" && value.size === 0)) files.push([name, await FormUploadedFile.fromFile(value)]);
|
|
1112
1154
|
}
|
|
1113
1155
|
this.#body = fromEntries(fields);
|
|
1114
1156
|
this.#files = fromEntries(files);
|
|
@@ -2458,12 +2500,13 @@ var HttpServiceProvider = class extends ServiceProvider {
|
|
|
2458
2500
|
// ../Live/dist/index.js
|
|
2459
2501
|
import { AssertionError } from "assert";
|
|
2460
2502
|
import { isDeepStrictEqual } from "util";
|
|
2461
|
-
import { AsyncLocalStorage } from "async_hooks";
|
|
2503
|
+
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
2462
2504
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
2463
2505
|
import { createHmac, timingSafeEqual } from "crypto";
|
|
2464
2506
|
import { existsSync as existsSync5, readdirSync as readdirSync2 } from "fs";
|
|
2465
2507
|
import { join as join5, relative as relative2, sep as sep2 } from "path";
|
|
2466
2508
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
2509
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
2467
2510
|
import { existsSync as existsSync22 } from "fs";
|
|
2468
2511
|
import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
|
|
2469
2512
|
import { dirname as dirname2, join as join23, relative as relative22, sep as sep22 } from "path";
|
|
@@ -2673,6 +2716,20 @@ var Component = class {
|
|
|
2673
2716
|
return inject(LiveManager).page(this);
|
|
2674
2717
|
}
|
|
2675
2718
|
};
|
|
2719
|
+
function trackFlash(session, { saved = true } = {}) {
|
|
2720
|
+
if (session === void 0) return () => void 0;
|
|
2721
|
+
const before = new Set(session.get("_flash.new", []));
|
|
2722
|
+
return (redirected) => {
|
|
2723
|
+
if (redirected) return;
|
|
2724
|
+
const flashed = session.get("_flash.new", []);
|
|
2725
|
+
const fresh = flashed.filter((key) => !before.has(key));
|
|
2726
|
+
if (fresh.length === 0) return;
|
|
2727
|
+
session.put("_flash.new", flashed.filter((key) => before.has(key)));
|
|
2728
|
+
if (!saved) return session.forget(...fresh);
|
|
2729
|
+
const old = session.get("_flash.old", []);
|
|
2730
|
+
session.put("_flash.old", [...old, ...fresh.filter((key) => !old.includes(key))]);
|
|
2731
|
+
};
|
|
2732
|
+
}
|
|
2676
2733
|
var LiveError = class extends Error {
|
|
2677
2734
|
name = "LiveError";
|
|
2678
2735
|
kind = "Server";
|
|
@@ -2773,6 +2830,15 @@ function requestScope2() {
|
|
|
2773
2830
|
const container = currentContainer() ?? Container.getInstance();
|
|
2774
2831
|
return container?.bound(TestRequestScope) === true ? container.make(TestRequestScope) : (run) => run();
|
|
2775
2832
|
}
|
|
2833
|
+
function currentSession() {
|
|
2834
|
+
const container = currentContainer();
|
|
2835
|
+
if (container?.bound(Session) !== true) return void 0;
|
|
2836
|
+
try {
|
|
2837
|
+
return container.make(Session);
|
|
2838
|
+
} catch {
|
|
2839
|
+
return void 0;
|
|
2840
|
+
}
|
|
2841
|
+
}
|
|
2776
2842
|
var Testable = class _Testable {
|
|
2777
2843
|
constructor(manager, scope, result) {
|
|
2778
2844
|
this.manager = manager;
|
|
@@ -2827,7 +2893,12 @@ var Testable = class _Testable {
|
|
|
2827
2893
|
return this.#update({}, [{ method: "$refresh", params: [] }]);
|
|
2828
2894
|
}
|
|
2829
2895
|
async #update(updates, calls) {
|
|
2830
|
-
const result = await this.scope(() =>
|
|
2896
|
+
const result = await this.scope(async () => {
|
|
2897
|
+
const flashed = trackFlash(currentSession(), { saved: false });
|
|
2898
|
+
const updated = await this.manager.updateComponent(this.#snapshot, updates, calls);
|
|
2899
|
+
flashed(updated.effects.redirect !== void 0);
|
|
2900
|
+
return updated;
|
|
2901
|
+
});
|
|
2831
2902
|
this.#snapshot = JSON.stringify(result.snapshot);
|
|
2832
2903
|
if (result.html !== void 0) this.#html = result.html;
|
|
2833
2904
|
this.#effects = result.effects;
|
|
@@ -2958,10 +3029,11 @@ async function discover(directory) {
|
|
|
2958
3029
|
}
|
|
2959
3030
|
return found;
|
|
2960
3031
|
}
|
|
2961
|
-
var PERSISTENT_MIDDLEWARE = ["auth", "verified", "guest"];
|
|
3032
|
+
var PERSISTENT_MIDDLEWARE = ["auth", "verified", "guest", "can"];
|
|
3033
|
+
var ROUTER_METHODS = ["getRoutesByMatchOrder", "getPatterns", "getPatternVersion", "getMiddleware", "getMiddlewareGroups", "substituteBindings"];
|
|
2962
3034
|
function canMatch(router) {
|
|
2963
3035
|
const methods = router;
|
|
2964
|
-
return
|
|
3036
|
+
return ROUTER_METHODS.every((name) => typeof methods[name] === "function");
|
|
2965
3037
|
}
|
|
2966
3038
|
function isMatchingRoute(route2) {
|
|
2967
3039
|
const candidate = route2;
|
|
@@ -2990,7 +3062,7 @@ function expand(references, aliases, groups, out = [], visiting = /* @__PURE__ *
|
|
|
2990
3062
|
}
|
|
2991
3063
|
return out;
|
|
2992
3064
|
}
|
|
2993
|
-
function
|
|
3065
|
+
function persistentPass(router, persistent, method, path) {
|
|
2994
3066
|
if (!canMatch(router)) throw new LiveError("Live re-applies the page route's middleware to updates, which needs Oriel's router.");
|
|
2995
3067
|
const routes = router.getRoutesByMatchOrder();
|
|
2996
3068
|
if (!Array.isArray(routes) || !routes.every(isMatchingRoute)) throw new LiveError("Live re-applies the page route's middleware to updates, which needs Oriel's routes.");
|
|
@@ -2998,36 +3070,80 @@ function persistentMiddleware(router, persistent, method, path) {
|
|
|
2998
3070
|
const target2 = routePath(path);
|
|
2999
3071
|
const patterns = router.getPatterns();
|
|
3000
3072
|
const version = router.getPatternVersion();
|
|
3001
|
-
|
|
3002
|
-
|
|
3073
|
+
let matched;
|
|
3074
|
+
for (const candidate of routes) {
|
|
3075
|
+
const values2 = candidate.methods.includes(verb) ? candidate.match(target2, patterns, version) : void 0;
|
|
3076
|
+
if (values2 !== void 0) {
|
|
3077
|
+
matched = { route: candidate, values: values2 };
|
|
3078
|
+
break;
|
|
3079
|
+
}
|
|
3080
|
+
}
|
|
3081
|
+
if (matched === void 0) return void 0;
|
|
3082
|
+
const { route: route2, values } = matched;
|
|
3003
3083
|
const aliases = router.getMiddleware();
|
|
3004
3084
|
const groups = router.getMiddlewareGroups();
|
|
3005
3085
|
const wanted = new Set(persistent.flatMap((name) => Object.hasOwn(aliases, name) ? [aliases[name]] : []));
|
|
3006
3086
|
const excluded = new Set(expand(route2.excludedMiddleware(), aliases, groups).map((entry) => entry.cls));
|
|
3007
3087
|
const ids = /* @__PURE__ */ new Map();
|
|
3008
3088
|
const seen = /* @__PURE__ */ new Set();
|
|
3009
|
-
|
|
3089
|
+
const middleware = expand(route2.gatherMiddleware(), aliases, groups).filter((entry) => {
|
|
3010
3090
|
if (!ids.has(entry.cls)) ids.set(entry.cls, ids.size);
|
|
3011
3091
|
const key = `${ids.get(entry.cls)}:${entry.parameters.join(",")}`;
|
|
3012
3092
|
if (!wanted.has(entry.cls) || excluded.has(entry.cls) || seen.has(key)) return false;
|
|
3013
3093
|
seen.add(key);
|
|
3014
3094
|
return true;
|
|
3015
3095
|
});
|
|
3096
|
+
const early = new Set(expand(["web", "api"], aliases, groups).map((entry) => entry.cls));
|
|
3097
|
+
for (const name of ["auth", "guest"]) if (Object.hasOwn(aliases, name)) early.add(aliases[name]);
|
|
3098
|
+
const before = middleware.filter((entry) => early.has(entry.cls));
|
|
3099
|
+
const after = middleware.filter((entry) => !early.has(entry.cls));
|
|
3100
|
+
return { router, route: route2, values, middleware: [...before, ...after], at: before.length };
|
|
3101
|
+
}
|
|
3102
|
+
function persistentMiddleware(router, persistent, method, path) {
|
|
3103
|
+
return [...persistentPass(router, persistent, method, path)?.middleware ?? []];
|
|
3104
|
+
}
|
|
3105
|
+
function currentRoute(container) {
|
|
3106
|
+
if (!container.bound(CurrentRoute)) return void 0;
|
|
3107
|
+
try {
|
|
3108
|
+
return container.make(CurrentRoute);
|
|
3109
|
+
} catch {
|
|
3110
|
+
return void 0;
|
|
3111
|
+
}
|
|
3016
3112
|
}
|
|
3017
|
-
async function throughMiddleware(container, request2,
|
|
3113
|
+
async function throughMiddleware(container, request2, pass, destination) {
|
|
3114
|
+
const original = currentRoute(container);
|
|
3115
|
+
const page = { route: pass.route, parameters: { ...pass.values }, middleware: [] };
|
|
3116
|
+
let swapped = false;
|
|
3117
|
+
const show = () => {
|
|
3118
|
+
container.instance(CurrentRoute, page);
|
|
3119
|
+
swapped = true;
|
|
3120
|
+
};
|
|
3121
|
+
const restore = () => {
|
|
3122
|
+
if (!swapped) return;
|
|
3123
|
+
if (original === void 0) container.forgetInstance(CurrentRoute);
|
|
3124
|
+
else container.instance(CurrentRoute, original);
|
|
3125
|
+
swapped = false;
|
|
3126
|
+
};
|
|
3018
3127
|
let ran;
|
|
3019
3128
|
const run = async (index) => {
|
|
3020
|
-
if (index ===
|
|
3129
|
+
if (index === pass.at) Object.assign(page.parameters, await pass.router.substituteBindings(pass.route, pass.values, container));
|
|
3130
|
+
if (index === pass.middleware.length) {
|
|
3131
|
+
restore();
|
|
3021
3132
|
ran = { result: await destination() };
|
|
3022
3133
|
return new Response(null, { status: 204 });
|
|
3023
3134
|
}
|
|
3024
|
-
const { cls, parameters } = middleware[index];
|
|
3135
|
+
const { cls, parameters } = pass.middleware[index];
|
|
3025
3136
|
const instance = container.make(cls);
|
|
3026
3137
|
const next = () => run(index + 1);
|
|
3027
3138
|
return instance.handle(request2, next, ...parameters);
|
|
3028
3139
|
};
|
|
3029
|
-
|
|
3030
|
-
|
|
3140
|
+
show();
|
|
3141
|
+
try {
|
|
3142
|
+
const response2 = await run(0);
|
|
3143
|
+
return ran ? ran.result : response2;
|
|
3144
|
+
} finally {
|
|
3145
|
+
restore();
|
|
3146
|
+
}
|
|
3031
3147
|
}
|
|
3032
3148
|
function isModel(value) {
|
|
3033
3149
|
if (typeof value !== "object" || value === null) return false;
|
|
@@ -3167,8 +3283,64 @@ function isUpdatable(instance, path) {
|
|
|
3167
3283
|
}
|
|
3168
3284
|
return !isModel(node) && !(node instanceof Collection);
|
|
3169
3285
|
}
|
|
3170
|
-
var
|
|
3171
|
-
|
|
3286
|
+
var PAGINATED = /* @__PURE__ */ Symbol.for("oriel:live.pagination");
|
|
3287
|
+
function toPage(value) {
|
|
3288
|
+
const page = typeof value === "number" ? value : typeof value === "string" && value.trim() !== "" ? Number(value) : Number.NaN;
|
|
3289
|
+
return Number.isFinite(page) && page >= 1 ? Math.min(Math.floor(page), Number.MAX_SAFE_INTEGER) : 1;
|
|
3290
|
+
}
|
|
3291
|
+
async function hook(instance, name, ...args) {
|
|
3292
|
+
const method = instance[name];
|
|
3293
|
+
if (typeof method === "function") await method.apply(instance, args);
|
|
3294
|
+
}
|
|
3295
|
+
function WithPagination(Base) {
|
|
3296
|
+
class WithPaginationMixin extends Base {
|
|
3297
|
+
page = 1;
|
|
3298
|
+
nextPage() {
|
|
3299
|
+
return this.setPage(toPage(this.page) + 1);
|
|
3300
|
+
}
|
|
3301
|
+
previousPage() {
|
|
3302
|
+
return this.setPage(Math.max(toPage(this.page) - 1, 1));
|
|
3303
|
+
}
|
|
3304
|
+
gotoPage(page) {
|
|
3305
|
+
return this.setPage(page);
|
|
3306
|
+
}
|
|
3307
|
+
resetPage() {
|
|
3308
|
+
return this.setPage(1);
|
|
3309
|
+
}
|
|
3310
|
+
async setPage(page) {
|
|
3311
|
+
const next = toPage(page);
|
|
3312
|
+
await hook(this, "updatingPage", next);
|
|
3313
|
+
this.page = next;
|
|
3314
|
+
await hook(this, "updatedPage", next);
|
|
3315
|
+
}
|
|
3316
|
+
}
|
|
3317
|
+
Object.defineProperty(WithPaginationMixin.prototype, PAGINATED, { value: true });
|
|
3318
|
+
return WithPaginationMixin;
|
|
3319
|
+
}
|
|
3320
|
+
function isPaginated(component) {
|
|
3321
|
+
return component[PAGINATED] === true;
|
|
3322
|
+
}
|
|
3323
|
+
var rendering = new AsyncLocalStorage();
|
|
3324
|
+
function renderPaginated(component, url2, run) {
|
|
3325
|
+
return rendering.run(isPaginated(component) ? { component, url: url2 } : void 0, run);
|
|
3326
|
+
}
|
|
3327
|
+
function outsidePagination(run) {
|
|
3328
|
+
return rendering.run(void 0, run);
|
|
3329
|
+
}
|
|
3330
|
+
var livePaginationState = {
|
|
3331
|
+
currentPage(pageName) {
|
|
3332
|
+
const current = rendering.getStore();
|
|
3333
|
+
if (current === void 0 || pageName !== "page") return void 0;
|
|
3334
|
+
const page = toPage(current.component.page);
|
|
3335
|
+
current.component.page = page;
|
|
3336
|
+
return page;
|
|
3337
|
+
},
|
|
3338
|
+
currentPath() {
|
|
3339
|
+
return rendering.getStore()?.url;
|
|
3340
|
+
}
|
|
3341
|
+
};
|
|
3342
|
+
var renderContext = new AsyncLocalStorage2();
|
|
3343
|
+
var pageRequest = new AsyncLocalStorage2();
|
|
3172
3344
|
function optional(container, token2) {
|
|
3173
3345
|
if (!container.bound(token2)) return void 0;
|
|
3174
3346
|
try {
|
|
@@ -3181,7 +3353,7 @@ var isRecord = (value) => typeof value === "object" && value !== null && !Array.
|
|
|
3181
3353
|
function setOwn(object, key, value) {
|
|
3182
3354
|
Object.defineProperty(object, key, { value, enumerable: true, writable: true, configurable: true });
|
|
3183
3355
|
}
|
|
3184
|
-
async function
|
|
3356
|
+
async function hook2(instance, name, ...args) {
|
|
3185
3357
|
const method = instance[name];
|
|
3186
3358
|
if (typeof method === "function") await method.apply(instance, args);
|
|
3187
3359
|
}
|
|
@@ -3232,7 +3404,7 @@ var LiveComponentManager = class {
|
|
|
3232
3404
|
setOwn(context.children, childKey, existing);
|
|
3233
3405
|
return `<${existing[0]} o:id="${escapeAttribute2(existing[1])}"></${existing[0]}>`;
|
|
3234
3406
|
}
|
|
3235
|
-
const result = await this.mountComponent(component, params);
|
|
3407
|
+
const result = await outsidePagination(() => this.mountComponent(component, params));
|
|
3236
3408
|
setOwn(context.children, childKey, [result.tag, result.snapshot.memo.id]);
|
|
3237
3409
|
return result.html;
|
|
3238
3410
|
}
|
|
@@ -3244,14 +3416,14 @@ var LiveComponentManager = class {
|
|
|
3244
3416
|
const state = stateOf(instance);
|
|
3245
3417
|
state.id = randomBytes2(15).toString("base64url");
|
|
3246
3418
|
state.name = name;
|
|
3247
|
-
await
|
|
3419
|
+
await hook2(instance, "boot");
|
|
3248
3420
|
for (const [property, value] of Object.entries(params)) {
|
|
3249
3421
|
if (Object.hasOwn(instance, property)) instance[property] = value;
|
|
3250
3422
|
}
|
|
3251
3423
|
this.prepareComputed(instance);
|
|
3252
|
-
await hook(instance, "mount", params);
|
|
3253
3424
|
const request2 = optional(this.container(), HttpRequest);
|
|
3254
3425
|
const page = pageRequest.getStore() ?? { path: request2?.path() ?? "", method: request2?.method() ?? "GET" };
|
|
3426
|
+
await renderPaginated(instance, this.pageUrl(page.path), () => hook2(instance, "mount", params));
|
|
3255
3427
|
const memo = { id: state.id, name, path: page.path, method: page.method, children: {}, errors: {} };
|
|
3256
3428
|
const { html, tag } = await this.render(instance, memo, {});
|
|
3257
3429
|
const effects = this.effects(instance);
|
|
@@ -3279,22 +3451,24 @@ var LiveComponentManager = class {
|
|
|
3279
3451
|
state.id = snapshot.memo.id;
|
|
3280
3452
|
state.name = snapshot.memo.name;
|
|
3281
3453
|
state.errors = { ...snapshot.memo.errors };
|
|
3282
|
-
await
|
|
3454
|
+
await hook2(instance, "boot");
|
|
3283
3455
|
const registry = this.registry();
|
|
3284
3456
|
for (const [property, value] of Object.entries(snapshot.data)) {
|
|
3285
3457
|
Object.defineProperty(instance, property, { value: await hydrate(value, registry), enumerable: true, writable: true, configurable: true });
|
|
3286
3458
|
}
|
|
3287
3459
|
this.prepareComputed(instance);
|
|
3288
|
-
await hook(instance, "hydrate");
|
|
3289
3460
|
const returns = [];
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3461
|
+
await renderPaginated(instance, this.pageUrl(snapshot.memo.path), async () => {
|
|
3462
|
+
await hook2(instance, "hydrate");
|
|
3463
|
+
try {
|
|
3464
|
+
for (const [path, value] of Object.entries(updates)) await this.applyUpdate(instance, path, value);
|
|
3465
|
+
for (const call of calls) returns.push(await this.call(instance, call.method, call.params));
|
|
3466
|
+
} catch (error) {
|
|
3467
|
+
const errors = error.errors;
|
|
3468
|
+
if (error.kind !== "Validation" || !isRecord(errors)) throw error;
|
|
3469
|
+
state.errors = { ...errors };
|
|
3470
|
+
}
|
|
3471
|
+
});
|
|
3298
3472
|
const memo = { ...snapshot.memo, children: { ...snapshot.memo.children } };
|
|
3299
3473
|
const effects = this.effects(instance);
|
|
3300
3474
|
let html;
|
|
@@ -3309,25 +3483,30 @@ var LiveComponentManager = class {
|
|
|
3309
3483
|
return { instance, snapshot: await this.snapshot(instance, memo), effects, html, tag };
|
|
3310
3484
|
}
|
|
3311
3485
|
/**
|
|
3312
|
-
* The route action of POST /oriel/live/update. Each component's update runs behind the
|
|
3313
|
-
* that rendered its page (Livewire's
|
|
3314
|
-
*
|
|
3486
|
+
* The route action of POST /oriel/live/update. Each component's update runs behind the persistent middleware of the
|
|
3487
|
+
* route that rendered its page (Livewire's): `auth`, `verified`, `guest` and `can`, with the page route's parameters
|
|
3488
|
+
* bound again. A signed-out tab gets a 401, a revoked ability a 403 and a deleted model a 404, before the component
|
|
3489
|
+
* hydrates. When a middleware answers instead (a redirect), that is the response. A key first flashed during the
|
|
3490
|
+
* update shows in this response only, unless the update redirects.
|
|
3315
3491
|
*/
|
|
3316
3492
|
async handle(request2) {
|
|
3317
3493
|
if (!this.isLiveRequest(request2)) throw new InvalidLiveRequestError("Live update requests need the X-Oriel-Live header.");
|
|
3318
3494
|
const container = this.container();
|
|
3319
3495
|
const persistent = optional(container, ConfigRepository)?.get("live.persistent_middleware", PERSISTENT_MIDDLEWARE) ?? PERSISTENT_MIDDLEWARE;
|
|
3320
3496
|
const components = [];
|
|
3497
|
+
const flashed = trackFlash(optional(container, Session));
|
|
3321
3498
|
for (const component of this.payload(request2).components) {
|
|
3322
3499
|
const { memo } = this.verify(component.snapshot);
|
|
3323
|
-
const
|
|
3500
|
+
const pass = persistentPass(container.make(Router), persistent, memo.method, memo.path);
|
|
3501
|
+
const update = () => this.updateComponent(component.snapshot, component.updates, component.calls);
|
|
3324
3502
|
const result = await pageRequest.run(
|
|
3325
3503
|
{ path: memo.path, method: memo.method },
|
|
3326
|
-
() =>
|
|
3504
|
+
() => pass === void 0 || pass.middleware.length === 0 ? update() : throughMiddleware(container, request2, pass, update)
|
|
3327
3505
|
);
|
|
3328
3506
|
if (result instanceof Response) return result;
|
|
3329
3507
|
components.push({ snapshot: JSON.stringify(result.snapshot), effects: result.effects });
|
|
3330
3508
|
}
|
|
3509
|
+
flashed(components.some((component) => component.effects.redirect !== void 0));
|
|
3331
3510
|
return { components };
|
|
3332
3511
|
}
|
|
3333
3512
|
/** A full-page component (Route.get('/counter', Counter)): mounted with the route parameters, inside the layout. */
|
|
@@ -3402,8 +3581,8 @@ var LiveComponentManager = class {
|
|
|
3402
3581
|
const [root, ...rest] = path.split(".");
|
|
3403
3582
|
const key = rest.length > 0 ? rest.join(".") : void 0;
|
|
3404
3583
|
const studly = Str.studly(root);
|
|
3405
|
-
await
|
|
3406
|
-
await
|
|
3584
|
+
await hook2(instance, "updating", path, value);
|
|
3585
|
+
await hook2(instance, `updating${studly}`, value, key);
|
|
3407
3586
|
const target2 = instance;
|
|
3408
3587
|
if (rest.length === 0) target2[root] = value;
|
|
3409
3588
|
else {
|
|
@@ -3421,8 +3600,8 @@ var LiveComponentManager = class {
|
|
|
3421
3600
|
assertSlot(node, last);
|
|
3422
3601
|
Object.defineProperty(node, last, { value, enumerable: true, writable: true, configurable: true });
|
|
3423
3602
|
}
|
|
3424
|
-
await
|
|
3425
|
-
await
|
|
3603
|
+
await hook2(instance, "updated", path, value);
|
|
3604
|
+
await hook2(instance, `updated${studly}`, value, key);
|
|
3426
3605
|
}
|
|
3427
3606
|
/** Runs one call from the browser: a magic action, an event, or a public method. Returns its return value. */
|
|
3428
3607
|
async call(instance, method, params) {
|
|
@@ -3450,18 +3629,35 @@ var LiveComponentManager = class {
|
|
|
3450
3629
|
if (!isCallable(instance, method)) throw new MethodNotCallableError(method, name);
|
|
3451
3630
|
return instance[method](...params);
|
|
3452
3631
|
}
|
|
3453
|
-
/**
|
|
3632
|
+
/**
|
|
3633
|
+
* Renders the component (rendering/rendered hooks, nested children tracked) and checks for a single root. A
|
|
3634
|
+
* WithPagination component's page and page URL are what paginate() reads while it renders, as in its mount() and in
|
|
3635
|
+
* its update's hooks and actions.
|
|
3636
|
+
*/
|
|
3454
3637
|
async render(instance, memo, previous) {
|
|
3455
|
-
await
|
|
3638
|
+
await hook2(instance, "rendering");
|
|
3456
3639
|
const context = { previous, children: {}, index: 0 };
|
|
3457
|
-
const html = await renderContext.run(
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3640
|
+
const html = await renderContext.run(
|
|
3641
|
+
context,
|
|
3642
|
+
() => renderPaginated(instance, this.pageUrl(memo.path), async () => {
|
|
3643
|
+
const output = await instance.render();
|
|
3644
|
+
return typeof output === "string" ? output : this.container().make(ViewFactory).renderToString(output);
|
|
3645
|
+
})
|
|
3646
|
+
);
|
|
3647
|
+
await hook2(instance, "rendered", html);
|
|
3462
3648
|
memo.children = context.children;
|
|
3463
3649
|
return { html: html.trim(), tag: rootTag(html, memo.name) };
|
|
3464
3650
|
}
|
|
3651
|
+
/** The absolute URL of the page a memo path belongs to, on the current request's origin ('/' + path without one). */
|
|
3652
|
+
pageUrl(path) {
|
|
3653
|
+
const relative3 = `/${path.replace(/^\/+/, "")}`;
|
|
3654
|
+
const url2 = optional(this.container(), HttpRequest)?.url();
|
|
3655
|
+
try {
|
|
3656
|
+
return url2 === void 0 ? relative3 : new URL(relative3, url2).href;
|
|
3657
|
+
} catch {
|
|
3658
|
+
return relative3;
|
|
3659
|
+
}
|
|
3660
|
+
}
|
|
3465
3661
|
/** Dispatches, redirects: the effects every response carries. */
|
|
3466
3662
|
effects(instance) {
|
|
3467
3663
|
const state = stateOf(instance);
|
|
@@ -3480,7 +3676,7 @@ var LiveComponentManager = class {
|
|
|
3480
3676
|
}
|
|
3481
3677
|
/** dehydrate() hook, then the state as snapshot data, the error bag, and the checksum over both. */
|
|
3482
3678
|
async snapshot(instance, memo) {
|
|
3483
|
-
await
|
|
3679
|
+
await hook2(instance, "dehydrate");
|
|
3484
3680
|
const registry = this.registry();
|
|
3485
3681
|
const data = {};
|
|
3486
3682
|
for (const [property, value] of Object.entries(instance)) data[property] = dehydrate(value, registry, `${memo.name}.${property}`);
|
|
@@ -3553,6 +3749,7 @@ var LiveServiceProvider = class extends ServiceProvider {
|
|
|
3553
3749
|
this.mergeConfigFrom({ class_path: this.app.appPath("Live"), layout: "components.layouts.app", persistent_middleware: [...PERSISTENT_MIDDLEWARE] }, "live");
|
|
3554
3750
|
this.app.singleton(LiveComponentManager, () => new LiveComponentManager(this.app));
|
|
3555
3751
|
this.app.singleton(LiveManager, (container) => container.make(LiveComponentManager));
|
|
3752
|
+
this.app.singleton(PaginationState, () => livePaginationState);
|
|
3556
3753
|
}
|
|
3557
3754
|
async boot() {
|
|
3558
3755
|
const manager = this.app.make(LiveComponentManager);
|
|
@@ -3566,6 +3763,40 @@ var LiveServiceProvider = class extends ServiceProvider {
|
|
|
3566
3763
|
}
|
|
3567
3764
|
}
|
|
3568
3765
|
};
|
|
3766
|
+
function urlWindow(current, last, onEachSide) {
|
|
3767
|
+
const range = (from, to) => Array.from({ length: Math.max(to - from + 1, 0) }, (_, index) => from + index);
|
|
3768
|
+
if (last < onEachSide * 2 + 8) return range(1, last);
|
|
3769
|
+
const size = onEachSide + 4;
|
|
3770
|
+
if (current <= size) return [...range(1, size + onEachSide), "...", ...range(last - 1, last)];
|
|
3771
|
+
if (current > last - size) return [...range(1, 2), "...", ...range(last - (size + (onEachSide - 1)), last)];
|
|
3772
|
+
return [...range(1, 2), "...", ...range(current - onEachSide, current + onEachSide), "...", ...range(last - 1, last)];
|
|
3773
|
+
}
|
|
3774
|
+
function button(label, action, attributes = "") {
|
|
3775
|
+
const live2 = action === void 0 ? " disabled" : ` o:click="${escapeAttribute2(action)}"`;
|
|
3776
|
+
return `<button type="button" class="btn btn-secondary"${attributes}${live2}>${escapeAttribute2(label)}</button>`;
|
|
3777
|
+
}
|
|
3778
|
+
function Pagination({ paginator, class: className }) {
|
|
3779
|
+
if (typeof paginator.nextCursor === "function") {
|
|
3780
|
+
throw new LiveError("<Pagination> needs paginate() or simplePaginate(): a cursor paginator has no page numbers.");
|
|
3781
|
+
}
|
|
3782
|
+
const current = paginator.currentPage();
|
|
3783
|
+
const onFirst = paginator.onFirstPage();
|
|
3784
|
+
const hasMore = paginator.hasMorePages();
|
|
3785
|
+
if (onFirst && !hasMore) return { toHtml: () => "" };
|
|
3786
|
+
const parts = [button("\xAB Previous", onFirst ? void 0 : "previousPage")];
|
|
3787
|
+
if (typeof paginator.lastPage === "function") {
|
|
3788
|
+
const onEachSide = Number.isInteger(paginator.onEachSideCount) && paginator.onEachSideCount >= 0 ? paginator.onEachSideCount : 3;
|
|
3789
|
+
for (const page of urlWindow(current, paginator.lastPage(), onEachSide)) {
|
|
3790
|
+
if (page === "...") parts.push('<span aria-hidden="true">...</span>');
|
|
3791
|
+
else if (page === current) parts.push(`<button type="button" class="btn" aria-current="page" disabled>${page}</button>`);
|
|
3792
|
+
else parts.push(button(String(page), `gotoPage(${page})`, ` aria-label="Go to page ${page}"`));
|
|
3793
|
+
}
|
|
3794
|
+
}
|
|
3795
|
+
parts.push(button("Next \xBB", hasMore ? "nextPage" : void 0));
|
|
3796
|
+
const classes = className === void 0 || className === "" ? "" : ` class="${escapeAttribute2(className)}"`;
|
|
3797
|
+
const html = `<nav aria-label="Pagination"${classes}>${parts.join("")}</nav>`;
|
|
3798
|
+
return { toHtml: () => html };
|
|
3799
|
+
}
|
|
3569
3800
|
|
|
3570
3801
|
// ../Testing/dist/index.js
|
|
3571
3802
|
import { AssertionError as AssertionError2 } from "assert";
|
|
@@ -3577,6 +3808,7 @@ import { randomUUID } from "crypto";
|
|
|
3577
3808
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
3578
3809
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
3579
3810
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
3811
|
+
import { posix } from "path";
|
|
3580
3812
|
import { deflateSync } from "zlib";
|
|
3581
3813
|
function fail2(message, details = {}) {
|
|
3582
3814
|
const error = new AssertionError2({ message, actual: details.actual, expected: details.expected, operator: "fail" });
|
|
@@ -5495,7 +5727,7 @@ var QUEUE_OPTIONS = ["connection", "queue", "delay", "tries", "backoff", "timeou
|
|
|
5495
5727
|
function isQueueable(job) {
|
|
5496
5728
|
if (typeof job !== "object" || job === null) return false;
|
|
5497
5729
|
const members = job;
|
|
5498
|
-
if (members[SHOULD_QUEUE] === true) return true;
|
|
5730
|
+
if (members.shouldQueue === true || members[SHOULD_QUEUE] === true) return true;
|
|
5499
5731
|
if (QUEUE_OPTIONS.some((option) => members[option] !== void 0)) return true;
|
|
5500
5732
|
return typeof members.uniqueId === "function" || typeof members.retryUntil === "function";
|
|
5501
5733
|
}
|
|
@@ -6313,8 +6545,74 @@ var MIME = {
|
|
|
6313
6545
|
mp4: "video/mp4"
|
|
6314
6546
|
};
|
|
6315
6547
|
function guessMimeType(path) {
|
|
6316
|
-
const
|
|
6317
|
-
|
|
6548
|
+
const base = path.slice(path.lastIndexOf("/") + 1);
|
|
6549
|
+
const dot = base.lastIndexOf(".");
|
|
6550
|
+
const extension = dot === -1 ? "" : base.slice(dot + 1).toLowerCase();
|
|
6551
|
+
return Object.hasOwn(MIME, extension) ? MIME[extension] : void 0;
|
|
6552
|
+
}
|
|
6553
|
+
var DISK_TYPES = {
|
|
6554
|
+
txt: "text/plain",
|
|
6555
|
+
html: "text/html",
|
|
6556
|
+
htm: "text/html",
|
|
6557
|
+
css: "text/css",
|
|
6558
|
+
csv: "text/csv",
|
|
6559
|
+
md: "text/markdown",
|
|
6560
|
+
js: "text/javascript",
|
|
6561
|
+
mjs: "text/javascript",
|
|
6562
|
+
json: "application/json",
|
|
6563
|
+
xml: "application/xml",
|
|
6564
|
+
pdf: "application/pdf",
|
|
6565
|
+
zip: "application/zip",
|
|
6566
|
+
gz: "application/gzip",
|
|
6567
|
+
tar: "application/x-tar",
|
|
6568
|
+
"7z": "application/x-7z-compressed",
|
|
6569
|
+
rar: "application/vnd.rar",
|
|
6570
|
+
epub: "application/epub+zip",
|
|
6571
|
+
rtf: "application/rtf",
|
|
6572
|
+
doc: "application/msword",
|
|
6573
|
+
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
6574
|
+
xls: "application/vnd.ms-excel",
|
|
6575
|
+
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
6576
|
+
ppt: "application/vnd.ms-powerpoint",
|
|
6577
|
+
pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
6578
|
+
odt: "application/vnd.oasis.opendocument.text",
|
|
6579
|
+
ods: "application/vnd.oasis.opendocument.spreadsheet",
|
|
6580
|
+
odp: "application/vnd.oasis.opendocument.presentation",
|
|
6581
|
+
png: "image/png",
|
|
6582
|
+
jpg: "image/jpeg",
|
|
6583
|
+
jpeg: "image/jpeg",
|
|
6584
|
+
gif: "image/gif",
|
|
6585
|
+
webp: "image/webp",
|
|
6586
|
+
avif: "image/avif",
|
|
6587
|
+
svg: "image/svg+xml",
|
|
6588
|
+
ico: "image/x-icon",
|
|
6589
|
+
bmp: "image/bmp",
|
|
6590
|
+
tif: "image/tiff",
|
|
6591
|
+
tiff: "image/tiff",
|
|
6592
|
+
heic: "image/heic",
|
|
6593
|
+
heif: "image/heif",
|
|
6594
|
+
mp3: "audio/mpeg",
|
|
6595
|
+
m4a: "audio/mp4",
|
|
6596
|
+
wav: "audio/wav",
|
|
6597
|
+
ogg: "audio/ogg",
|
|
6598
|
+
oga: "audio/ogg",
|
|
6599
|
+
opus: "audio/ogg",
|
|
6600
|
+
flac: "audio/flac",
|
|
6601
|
+
aac: "audio/aac",
|
|
6602
|
+
mp4: "video/mp4",
|
|
6603
|
+
mov: "video/quicktime",
|
|
6604
|
+
webm: "video/webm",
|
|
6605
|
+
ogv: "video/ogg",
|
|
6606
|
+
avi: "video/x-msvideo",
|
|
6607
|
+
woff: "font/woff",
|
|
6608
|
+
woff2: "font/woff2",
|
|
6609
|
+
ttf: "font/ttf",
|
|
6610
|
+
otf: "font/otf",
|
|
6611
|
+
wasm: "application/wasm"
|
|
6612
|
+
};
|
|
6613
|
+
function diskType(extension) {
|
|
6614
|
+
const key = extension.replace(/^\./, "").toLowerCase();
|
|
6615
|
+
return Object.hasOwn(DISK_TYPES, key) ? DISK_TYPES[key] : void 0;
|
|
6318
6616
|
}
|
|
6319
6617
|
function hashName(file) {
|
|
6320
6618
|
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
@@ -6370,17 +6668,24 @@ var FakeDisk = class {
|
|
|
6370
6668
|
async put(path, contents, options = {}) {
|
|
6371
6669
|
const key = normalize(path);
|
|
6372
6670
|
const bytes = typeof contents === "string" ? new TextEncoder().encode(contents) : contents instanceof Uint8Array ? contents.slice() : await collect(contents);
|
|
6373
|
-
this.
|
|
6671
|
+
this.write(key, bytes, options.mimeType ?? diskType(posix.extname(key)), options);
|
|
6374
6672
|
return true;
|
|
6375
6673
|
}
|
|
6376
6674
|
putFile(directory, file, options = {}) {
|
|
6377
6675
|
return this.putFileAs(directory, file, hashName(file), options);
|
|
6378
6676
|
}
|
|
6677
|
+
/**
|
|
6678
|
+
* The upload's own type, as the S3 disk sends it: its extension(), never the MIME type the client sent as such nor
|
|
6679
|
+
* the stored name's type.
|
|
6680
|
+
*/
|
|
6379
6681
|
async putFileAs(directory, file, name, options = {}) {
|
|
6380
6682
|
const path = normalize(`${directory}/${name}`);
|
|
6381
|
-
|
|
6683
|
+
this.write(path, new Uint8Array(await file.arrayBuffer()), options.mimeType ?? diskType(file.extension()), options);
|
|
6382
6684
|
return path;
|
|
6383
6685
|
}
|
|
6686
|
+
write(key, bytes, mimeType, options) {
|
|
6687
|
+
this.stored.set(key, { bytes, visibility: options.visibility ?? "private", mimeType, modified: /* @__PURE__ */ new Date() });
|
|
6688
|
+
}
|
|
6384
6689
|
async delete(paths) {
|
|
6385
6690
|
for (const path of [paths].flat()) this.stored.delete(normalize(path));
|
|
6386
6691
|
return true;
|
|
@@ -6574,6 +6879,37 @@ var StorageFake = class _StorageFake {
|
|
|
6574
6879
|
return this.disk().path(path);
|
|
6575
6880
|
}
|
|
6576
6881
|
};
|
|
6882
|
+
var ascii = (text) => [...text].map((char) => char.charCodeAt(0));
|
|
6883
|
+
var u16be = (n) => [n >>> 8 & 255, n & 255];
|
|
6884
|
+
var u16le = (n) => [n & 255, n >>> 8 & 255];
|
|
6885
|
+
var u32le = (n) => [n & 255, n >>> 8 & 255, n >>> 16 & 255, n >>> 24 & 255];
|
|
6886
|
+
function concat(...parts) {
|
|
6887
|
+
const out = new Uint8Array(parts.reduce((n, part) => n + part.length, 0));
|
|
6888
|
+
let offset = 0;
|
|
6889
|
+
for (const part of parts) {
|
|
6890
|
+
out.set(part, offset);
|
|
6891
|
+
offset += part.length;
|
|
6892
|
+
}
|
|
6893
|
+
return out;
|
|
6894
|
+
}
|
|
6895
|
+
var BitWriter = class {
|
|
6896
|
+
bytes = [];
|
|
6897
|
+
buffer = 0;
|
|
6898
|
+
count = 0;
|
|
6899
|
+
write(value, bits) {
|
|
6900
|
+
this.buffer |= value << this.count;
|
|
6901
|
+
this.count += bits;
|
|
6902
|
+
while (this.count >= 8) {
|
|
6903
|
+
this.bytes.push(this.buffer & 255);
|
|
6904
|
+
this.buffer >>>= 8;
|
|
6905
|
+
this.count -= 8;
|
|
6906
|
+
}
|
|
6907
|
+
}
|
|
6908
|
+
finish() {
|
|
6909
|
+
if (this.count > 0) this.bytes.push(this.buffer & 255);
|
|
6910
|
+
return Uint8Array.from(this.bytes);
|
|
6911
|
+
}
|
|
6912
|
+
};
|
|
6577
6913
|
var CRC_TABLE = Array.from({ length: 256 }, (_, n) => {
|
|
6578
6914
|
let c = n;
|
|
6579
6915
|
for (let k = 0; k < 8; k++) c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
|
|
@@ -6601,23 +6937,175 @@ function png(width, height) {
|
|
|
6601
6937
|
header.set([8, 2, 0, 0, 0], 8);
|
|
6602
6938
|
const rows = new Uint8Array((width * 3 + 1) * height).fill(255);
|
|
6603
6939
|
for (let y = 0; y < height; y++) rows[y * (width * 3 + 1)] = 0;
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6940
|
+
return concat([137, 80, 78, 71, 13, 10, 26, 10], chunk("IHDR", header), chunk("IDAT", deflateSync(rows)), chunk("IEND", new Uint8Array()));
|
|
6941
|
+
}
|
|
6942
|
+
var oneCodeTable = (tableClass) => [255, 196, ...u16be(20), tableClass, 1, ...new Array(15).fill(0), 0];
|
|
6943
|
+
function jpeg(width, height) {
|
|
6944
|
+
const bits = Math.ceil(width / 8) * Math.ceil(height / 8) * 2;
|
|
6945
|
+
const scan = new Uint8Array(Math.ceil(bits / 8));
|
|
6946
|
+
const padding = scan.length * 8 - bits;
|
|
6947
|
+
if (padding > 0) scan[scan.length - 1] = (1 << padding) - 1;
|
|
6948
|
+
return concat(
|
|
6949
|
+
[255, 216],
|
|
6950
|
+
// SOI
|
|
6951
|
+
[255, 224, ...u16be(16), ...ascii("JFIF"), 0, 1, 1, 0, 0, 1, 0, 1, 0, 0],
|
|
6952
|
+
// APP0
|
|
6953
|
+
[255, 219, ...u16be(67), 0, ...new Array(64).fill(1)],
|
|
6954
|
+
// DQT: table 0, all ones
|
|
6955
|
+
[255, 192, ...u16be(11), 8, ...u16be(height), ...u16be(width), 1, 1, 17, 0],
|
|
6956
|
+
// SOF0: one component
|
|
6957
|
+
oneCodeTable(0),
|
|
6958
|
+
// DHT: DC table 0
|
|
6959
|
+
oneCodeTable(16),
|
|
6960
|
+
// DHT: AC table 0
|
|
6961
|
+
[255, 218, ...u16be(8), 1, 1, 0, 0, 63, 0],
|
|
6962
|
+
// SOS
|
|
6963
|
+
scan,
|
|
6964
|
+
[255, 217]
|
|
6965
|
+
// EOI
|
|
6966
|
+
);
|
|
6967
|
+
}
|
|
6968
|
+
function lzwZeros(pixels, minCodeSize) {
|
|
6969
|
+
const clear = 1 << minCodeSize;
|
|
6970
|
+
const end = clear + 1;
|
|
6971
|
+
const out = new BitWriter();
|
|
6972
|
+
const table = /* @__PURE__ */ new Map();
|
|
6973
|
+
let codeSize = minCodeSize + 1;
|
|
6974
|
+
let next = end + 1;
|
|
6975
|
+
let current = 0;
|
|
6976
|
+
out.write(clear, codeSize);
|
|
6977
|
+
for (let i = 1; i < pixels; i++) {
|
|
6978
|
+
const key = current << 8;
|
|
6979
|
+
const known = table.get(key);
|
|
6980
|
+
if (known !== void 0) {
|
|
6981
|
+
current = known;
|
|
6982
|
+
continue;
|
|
6983
|
+
}
|
|
6984
|
+
out.write(current, codeSize);
|
|
6985
|
+
if (next === 4096) {
|
|
6986
|
+
out.write(clear, codeSize);
|
|
6987
|
+
table.clear();
|
|
6988
|
+
codeSize = minCodeSize + 1;
|
|
6989
|
+
next = end + 1;
|
|
6990
|
+
} else {
|
|
6991
|
+
if (next >= 1 << codeSize) codeSize++;
|
|
6992
|
+
table.set(key, next++);
|
|
6993
|
+
}
|
|
6994
|
+
current = 0;
|
|
6995
|
+
}
|
|
6996
|
+
out.write(current, codeSize);
|
|
6997
|
+
out.write(end, codeSize);
|
|
6998
|
+
return out.finish();
|
|
6999
|
+
}
|
|
7000
|
+
function gif(width, height) {
|
|
7001
|
+
const data = lzwZeros(width * height, 2);
|
|
7002
|
+
const blocks = [];
|
|
7003
|
+
for (let offset = 0; offset < data.length; offset += 255) {
|
|
7004
|
+
const block = data.subarray(offset, offset + 255);
|
|
7005
|
+
blocks.push(block.length, ...block);
|
|
7006
|
+
}
|
|
7007
|
+
return concat(
|
|
7008
|
+
ascii("GIF89a"),
|
|
7009
|
+
[...u16le(width), ...u16le(height), 128, 0, 0],
|
|
7010
|
+
// a global palette of two colours
|
|
7011
|
+
[255, 255, 255, 0, 0, 0],
|
|
7012
|
+
[44, 0, 0, 0, 0, ...u16le(width), ...u16le(height), 0],
|
|
7013
|
+
// the image descriptor
|
|
7014
|
+
[2],
|
|
7015
|
+
blocks,
|
|
7016
|
+
[0, 59]
|
|
7017
|
+
// the end of the data, the trailer
|
|
7018
|
+
);
|
|
7019
|
+
}
|
|
7020
|
+
function webp(width, height) {
|
|
7021
|
+
const bits = new BitWriter();
|
|
7022
|
+
bits.write(47, 8);
|
|
7023
|
+
bits.write(width - 1, 14);
|
|
7024
|
+
bits.write(height - 1, 14);
|
|
7025
|
+
bits.write(0, 4);
|
|
7026
|
+
bits.write(0, 3);
|
|
7027
|
+
for (const symbol of [255, 255, 255, 255, 0]) {
|
|
7028
|
+
bits.write(1, 1);
|
|
7029
|
+
bits.write(0, 1);
|
|
7030
|
+
bits.write(1, 1);
|
|
7031
|
+
bits.write(symbol, 8);
|
|
7032
|
+
}
|
|
7033
|
+
const data = bits.finish();
|
|
7034
|
+
const padded = data.length % 2 === 0 ? data : concat(data, [0]);
|
|
7035
|
+
return concat(ascii("RIFF"), u32le(12 + padded.length), ascii("WEBP"), ascii("VP8L"), u32le(data.length), padded);
|
|
7036
|
+
}
|
|
7037
|
+
function bmp(width, height) {
|
|
7038
|
+
const row = Math.ceil(width * 3 / 4) * 4;
|
|
7039
|
+
const out = new Uint8Array(54 + row * height);
|
|
7040
|
+
const view = new DataView(out.buffer);
|
|
7041
|
+
out.set(ascii("BM"));
|
|
7042
|
+
view.setUint32(2, out.length, true);
|
|
7043
|
+
view.setUint32(10, 54, true);
|
|
7044
|
+
view.setUint32(14, 40, true);
|
|
7045
|
+
view.setInt32(18, width, true);
|
|
7046
|
+
view.setInt32(22, height, true);
|
|
7047
|
+
view.setUint16(26, 1, true);
|
|
7048
|
+
view.setUint16(28, 24, true);
|
|
7049
|
+
view.setUint32(34, row * height, true);
|
|
7050
|
+
for (let y = 0; y < height; y++) out.fill(255, 54 + y * row, 54 + y * row + width * 3);
|
|
7051
|
+
return out;
|
|
7052
|
+
}
|
|
7053
|
+
var IMAGE_FORMATS = {
|
|
7054
|
+
png: { type: "image/png", encode: png },
|
|
7055
|
+
jpg: { type: "image/jpeg", encode: jpeg },
|
|
7056
|
+
jpeg: { type: "image/jpeg", encode: jpeg },
|
|
7057
|
+
gif: { type: "image/gif", encode: gif },
|
|
7058
|
+
webp: { type: "image/webp", encode: webp },
|
|
7059
|
+
bmp: { type: "image/bmp", encode: bmp }
|
|
7060
|
+
};
|
|
7061
|
+
var extensionOf = (name) => name.includes(".") ? name.slice(name.lastIndexOf(".") + 1).toLowerCase() : "";
|
|
7062
|
+
var MORE_MIME_TYPES = {
|
|
7063
|
+
bmp: "image/bmp",
|
|
7064
|
+
avif: "image/avif",
|
|
7065
|
+
xml: "text/xml",
|
|
7066
|
+
htm: "text/html",
|
|
7067
|
+
md: "text/markdown",
|
|
7068
|
+
tsv: "text/tab-separated-values",
|
|
7069
|
+
text: "text/plain"
|
|
7070
|
+
};
|
|
7071
|
+
var LEADING_BYTES = {
|
|
7072
|
+
"image/jpeg": { bytes: [255, 216, 255, 224, ...u16be(16), ...ascii("JFIF"), 0, 1, 1, 0, 0, 1, 0, 1, 0, 0] },
|
|
7073
|
+
"image/png": { bytes: [137, 80, 78, 71, 13, 10, 26, 10] },
|
|
7074
|
+
"image/gif": { bytes: "GIF89a" },
|
|
7075
|
+
"image/webp": { bytes: "RIFF\0\0\0\0WEBP" },
|
|
7076
|
+
"image/avif": { bytes: [0, 0, 0, 20, ...ascii("ftypavif"), 0, 0, 0, 0, ...ascii("avifmif1")] },
|
|
7077
|
+
"image/bmp": { bytes: [...ascii("BM"), 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 40, 0, 0, 0] },
|
|
7078
|
+
"application/pdf": { bytes: "%PDF-1.4\n" },
|
|
7079
|
+
"image/svg+xml": { bytes: '<svg xmlns="http://www.w3.org/2000/svg"/>\n', text: true },
|
|
7080
|
+
"text/html": { bytes: "<!doctype html>\n", text: true },
|
|
7081
|
+
"text/xml": { bytes: '<?xml version="1.0"?>\n', text: true }
|
|
7082
|
+
};
|
|
7083
|
+
function contentFor(type, size) {
|
|
7084
|
+
const text = type.startsWith("text/") || type === "application/json";
|
|
7085
|
+
const leading = LEADING_BYTES[type] ?? { bytes: text ? "\n" : [], text };
|
|
7086
|
+
const head = typeof leading.bytes === "string" ? new TextEncoder().encode(leading.bytes) : Uint8Array.from(leading.bytes);
|
|
7087
|
+
const out = new Uint8Array(Math.max(size, head.length, 1)).fill(leading.text ? 32 : 0);
|
|
7088
|
+
out.set(head);
|
|
6611
7089
|
return out;
|
|
6612
7090
|
}
|
|
6613
7091
|
var FakeFile = {
|
|
6614
|
-
/**
|
|
7092
|
+
/**
|
|
7093
|
+
* A file of `kilobytes` KiB typed by `mimeType` or the name's extension. Validation reads a file's bytes, so the
|
|
7094
|
+
* file starts like its type (a PDF's `%PDF-`, a PNG's signature, text for text types) and passes `mimes` for its
|
|
7095
|
+
* name, as Laravel's fakes do. It is at least its type's leading bytes and never empty, whatever the size asked for.
|
|
7096
|
+
* An image made this way has no readable size: use image() for `dimensions`.
|
|
7097
|
+
*/
|
|
6615
7098
|
create(name, kilobytes = 0, mimeType) {
|
|
6616
|
-
|
|
7099
|
+
const type = mimeType ?? guessMimeType(name) ?? MORE_MIME_TYPES[extensionOf(name)] ?? "application/octet-stream";
|
|
7100
|
+
return new File([contentFor(type, Math.round(kilobytes * 1024))], name, { type });
|
|
6617
7101
|
},
|
|
6618
|
-
/**
|
|
7102
|
+
/**
|
|
7103
|
+
* A real white image of the given size in the format the name's extension asks for: png, jpg/jpeg, gif, webp or
|
|
7104
|
+
* bmp (any other name gets a JPEG, as Laravel's fakes do), so image, mimes and dimensions pass on it.
|
|
7105
|
+
*/
|
|
6619
7106
|
image(name, width = 10, height = 10) {
|
|
6620
|
-
|
|
7107
|
+
const format2 = IMAGE_FORMATS[extensionOf(name)] ?? IMAGE_FORMATS.jpeg;
|
|
7108
|
+
return new File([format2.encode(width, height)], name, { type: guessMimeType(name) ?? format2.type });
|
|
6621
7109
|
}
|
|
6622
7110
|
};
|
|
6623
7111
|
|
|
@@ -6718,9 +7206,11 @@ export {
|
|
|
6718
7206
|
componentName,
|
|
6719
7207
|
PERSISTENT_MIDDLEWARE,
|
|
6720
7208
|
persistentMiddleware,
|
|
7209
|
+
WithPagination,
|
|
6721
7210
|
LiveComponentManager,
|
|
6722
7211
|
UPDATE_URI,
|
|
6723
7212
|
LiveServiceProvider,
|
|
7213
|
+
Pagination,
|
|
6724
7214
|
PendingCommand,
|
|
6725
7215
|
RefreshDatabaseState,
|
|
6726
7216
|
runCommand,
|
|
@@ -6766,4 +7256,4 @@ export {
|
|
|
6766
7256
|
StorageFake,
|
|
6767
7257
|
FakeFile
|
|
6768
7258
|
};
|
|
6769
|
-
//# sourceMappingURL=chunk-
|
|
7259
|
+
//# sourceMappingURL=chunk-WNJP46B7.js.map
|