effect-start 0.23.1 → 0.26.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/package.json +18 -86
- package/src/Development.ts +3 -1
- package/src/Entity.ts +17 -0
- package/src/Fetch.ts +271 -0
- package/src/SqlIntrospect.ts +64 -70
- package/src/Start.ts +21 -24
- package/src/StartApp.ts +1 -1
- package/src/bun/BunServer.ts +42 -10
- package/src/hyper/HyperHtml.ts +0 -1
- package/src/sql/bun/index.ts +1 -1
- package/src/sql/index.ts +1 -0
- package/src/sql/libsql/index.ts +173 -0
- package/src/sql/libsql/libsql.d.ts +39 -0
- package/src/sql/mssql/index.ts +1 -1
- package/dist/BlobStore.d.ts +0 -80
- package/dist/BlobStore.js +0 -19
- package/dist/ChildProcess.d.ts +0 -60
- package/dist/ChildProcess.js +0 -30
- package/dist/Commander.d.ts +0 -100
- package/dist/Commander.js +0 -326
- package/dist/ContentNegotiation.d.ts +0 -12
- package/dist/ContentNegotiation.js +0 -359
- package/dist/Cookies.d.ts +0 -47
- package/dist/Cookies.js +0 -302
- package/dist/Development.d.ts +0 -39
- package/dist/Development.js +0 -58
- package/dist/Effectify.d.ts +0 -209
- package/dist/Effectify.js +0 -19
- package/dist/Entity.d.ts +0 -47
- package/dist/Entity.js +0 -224
- package/dist/FilePathPattern.d.ts +0 -29
- package/dist/FilePathPattern.js +0 -86
- package/dist/FileRouter.d.ts +0 -56
- package/dist/FileRouter.js +0 -148
- package/dist/FileRouterCodegen.d.ts +0 -18
- package/dist/FileRouterCodegen.js +0 -227
- package/dist/FileRouterPattern.d.ts +0 -9
- package/dist/FileRouterPattern.js +0 -35
- package/dist/FileSystem.d.ts +0 -158
- package/dist/FileSystem.js +0 -70
- package/dist/Http.d.ts +0 -37
- package/dist/Http.js +0 -88
- package/dist/HttpAppExtra.d.ts +0 -7
- package/dist/HttpAppExtra.js +0 -320
- package/dist/HttpUtils.d.ts +0 -3
- package/dist/HttpUtils.js +0 -11
- package/dist/PathPattern.d.ts +0 -134
- package/dist/PathPattern.js +0 -413
- package/dist/PlatformError.d.ts +0 -38
- package/dist/PlatformError.js +0 -25
- package/dist/PlatformRuntime.d.ts +0 -27
- package/dist/PlatformRuntime.js +0 -46
- package/dist/Route.d.ts +0 -97
- package/dist/Route.js +0 -100
- package/dist/RouteBody.d.ts +0 -47
- package/dist/RouteBody.js +0 -67
- package/dist/RouteError.d.ts +0 -98
- package/dist/RouteError.js +0 -55
- package/dist/RouteHook.d.ts +0 -12
- package/dist/RouteHook.js +0 -40
- package/dist/RouteHttp.d.ts +0 -21
- package/dist/RouteHttp.js +0 -258
- package/dist/RouteHttpTracer.d.ts +0 -10
- package/dist/RouteHttpTracer.js +0 -62
- package/dist/RouteMount.d.ts +0 -86
- package/dist/RouteMount.js +0 -63
- package/dist/RouteSchema.d.ts +0 -86
- package/dist/RouteSchema.js +0 -188
- package/dist/RouteSse.d.ts +0 -21
- package/dist/RouteSse.js +0 -79
- package/dist/RouteTree.d.ts +0 -57
- package/dist/RouteTree.js +0 -93
- package/dist/RouteTrie.d.ts +0 -20
- package/dist/RouteTrie.js +0 -152
- package/dist/RouterPattern.d.ts +0 -118
- package/dist/RouterPattern.js +0 -269
- package/dist/SchemaExtra.d.ts +0 -7
- package/dist/SchemaExtra.js +0 -74
- package/dist/Socket.d.ts +0 -27
- package/dist/Socket.js +0 -29
- package/dist/Sql.d.ts +0 -34
- package/dist/Sql.js +0 -5
- package/dist/SqlIntrospect.d.ts +0 -91
- package/dist/SqlIntrospect.js +0 -466
- package/dist/Start.d.ts +0 -44
- package/dist/Start.js +0 -49
- package/dist/StartApp.d.ts +0 -19
- package/dist/StartApp.js +0 -21
- package/dist/StreamExtra.d.ts +0 -28
- package/dist/StreamExtra.js +0 -100
- package/dist/System.d.ts +0 -7
- package/dist/System.js +0 -22
- package/dist/TuplePathPattern.d.ts +0 -9
- package/dist/TuplePathPattern.js +0 -68
- package/dist/Unique.d.ts +0 -50
- package/dist/Unique.js +0 -187
- package/dist/Values.d.ts +0 -27
- package/dist/Values.js +0 -36
- package/dist/bun/BunBlobStoreDisk.d.ts +0 -6
- package/dist/bun/BunBlobStoreDisk.js +0 -116
- package/dist/bun/BunBlobStoreS3.d.ts +0 -11
- package/dist/bun/BunBlobStoreS3.js +0 -89
- package/dist/bun/BunBlobWatcherDisk.d.ts +0 -6
- package/dist/bun/BunBlobWatcherDisk.js +0 -60
- package/dist/bun/BunBlobWatcherQueue.d.ts +0 -6
- package/dist/bun/BunBlobWatcherQueue.js +0 -17
- package/dist/bun/BunBundle.d.ts +0 -11
- package/dist/bun/BunBundle.js +0 -137
- package/dist/bun/BunChildProcessSpawner.d.ts +0 -3
- package/dist/bun/BunChildProcessSpawner.js +0 -103
- package/dist/bun/BunHttpServer.d.ts +0 -44
- package/dist/bun/BunHttpServer.js +0 -186
- package/dist/bun/BunHttpServer_web.d.ts +0 -60
- package/dist/bun/BunHttpServer_web.js +0 -252
- package/dist/bun/BunImportTrackerPlugin.d.ts +0 -13
- package/dist/bun/BunImportTrackerPlugin.js +0 -69
- package/dist/bun/BunPlatformHttpServer.d.ts +0 -10
- package/dist/bun/BunPlatformHttpServer.js +0 -53
- package/dist/bun/BunRoute.d.ts +0 -48
- package/dist/bun/BunRoute.js +0 -121
- package/dist/bun/BunRuntime.d.ts +0 -2
- package/dist/bun/BunRuntime.js +0 -31
- package/dist/bun/BunServer.d.ts +0 -40
- package/dist/bun/BunServer.js +0 -157
- package/dist/bun/BunServerRequest.d.ts +0 -60
- package/dist/bun/BunServerRequest.js +0 -252
- package/dist/bun/BunSql.d.ts +0 -4
- package/dist/bun/BunSql.js +0 -81
- package/dist/bun/BunVirtualFilesPlugin.d.ts +0 -4
- package/dist/bun/BunVirtualFilesPlugin.js +0 -40
- package/dist/bun/_BunEnhancedResolve.d.ts +0 -45
- package/dist/bun/_BunEnhancedResolve.js +0 -102
- package/dist/bun/index.d.ts +0 -5
- package/dist/bun/index.js +0 -5
- package/dist/bundler/Bundle.d.ts +0 -61
- package/dist/bundler/Bundle.js +0 -48
- package/dist/bundler/BundleFiles.d.ts +0 -13
- package/dist/bundler/BundleFiles.js +0 -96
- package/dist/bundler/BundleHttp.d.ts +0 -45
- package/dist/bundler/BundleHttp.js +0 -176
- package/dist/bundler/BundleRoute.d.ts +0 -27
- package/dist/bundler/BundleRoute.js +0 -51
- package/dist/client/Overlay.d.ts +0 -2
- package/dist/client/Overlay.js +0 -32
- package/dist/client/ScrollState.d.ts +0 -6
- package/dist/client/ScrollState.js +0 -94
- package/dist/client/index.d.ts +0 -6
- package/dist/client/index.js +0 -79
- package/dist/console/Console.d.ts +0 -6
- package/dist/console/Console.js +0 -26
- package/dist/console/ConsoleErrors.d.ts +0 -3
- package/dist/console/ConsoleErrors.js +0 -200
- package/dist/console/ConsoleLogger.d.ts +0 -3
- package/dist/console/ConsoleLogger.js +0 -47
- package/dist/console/ConsoleMetrics.d.ts +0 -3
- package/dist/console/ConsoleMetrics.js +0 -61
- package/dist/console/ConsoleProcess.d.ts +0 -3
- package/dist/console/ConsoleProcess.js +0 -49
- package/dist/console/ConsoleStore.d.ts +0 -144
- package/dist/console/ConsoleStore.js +0 -61
- package/dist/console/ConsoleTracer.d.ts +0 -3
- package/dist/console/ConsoleTracer.js +0 -94
- package/dist/console/Simulation.d.ts +0 -2
- package/dist/console/Simulation.js +0 -633
- package/dist/console/index.d.ts +0 -3
- package/dist/console/index.js +0 -3
- package/dist/console/routes/errors/route.d.ts +0 -10
- package/dist/console/routes/errors/route.js +0 -47
- package/dist/console/routes/fiberDetail.d.ts +0 -16
- package/dist/console/routes/fiberDetail.js +0 -38
- package/dist/console/routes/fibers/route.d.ts +0 -10
- package/dist/console/routes/fibers/route.js +0 -19
- package/dist/console/routes/git/route.d.ts +0 -11
- package/dist/console/routes/git/route.js +0 -33
- package/dist/console/routes/layout.d.ts +0 -9
- package/dist/console/routes/layout.js +0 -3
- package/dist/console/routes/logs/route.d.ts +0 -10
- package/dist/console/routes/logs/route.js +0 -32
- package/dist/console/routes/metrics/route.d.ts +0 -10
- package/dist/console/routes/metrics/route.js +0 -17
- package/dist/console/routes/route.d.ts +0 -6
- package/dist/console/routes/route.js +0 -5
- package/dist/console/routes/routes/route.d.ts +0 -6
- package/dist/console/routes/routes/route.js +0 -20
- package/dist/console/routes/services/route.d.ts +0 -6
- package/dist/console/routes/services/route.js +0 -12
- package/dist/console/routes/system/route.d.ts +0 -10
- package/dist/console/routes/system/route.js +0 -18
- package/dist/console/routes/traceDetail.d.ts +0 -16
- package/dist/console/routes/traceDetail.js +0 -14
- package/dist/console/routes/traces/route.d.ts +0 -10
- package/dist/console/routes/traces/route.js +0 -39
- package/dist/console/routes/tree.d.ts +0 -153
- package/dist/console/routes/tree.js +0 -29
- package/dist/console/ui/Errors.d.ts +0 -4
- package/dist/console/ui/Errors.js +0 -15
- package/dist/console/ui/Fibers.d.ts +0 -24
- package/dist/console/ui/Fibers.js +0 -121
- package/dist/console/ui/Git.d.ts +0 -20
- package/dist/console/ui/Git.js +0 -95
- package/dist/console/ui/Logs.d.ts +0 -4
- package/dist/console/ui/Logs.js +0 -25
- package/dist/console/ui/Metrics.d.ts +0 -4
- package/dist/console/ui/Metrics.js +0 -26
- package/dist/console/ui/Routes.d.ts +0 -8
- package/dist/console/ui/Routes.js +0 -70
- package/dist/console/ui/Services.d.ts +0 -10
- package/dist/console/ui/Services.js +0 -246
- package/dist/console/ui/Shell.d.ts +0 -10
- package/dist/console/ui/Shell.js +0 -7
- package/dist/console/ui/System.d.ts +0 -4
- package/dist/console/ui/System.js +0 -35
- package/dist/console/ui/Traces.d.ts +0 -12
- package/dist/console/ui/Traces.js +0 -179
- package/dist/datastar/actions/fetch.d.ts +0 -30
- package/dist/datastar/actions/fetch.js +0 -403
- package/dist/datastar/actions/peek.d.ts +0 -1
- package/dist/datastar/actions/peek.js +0 -13
- package/dist/datastar/actions/setAll.d.ts +0 -1
- package/dist/datastar/actions/setAll.js +0 -12
- package/dist/datastar/actions/toggleAll.d.ts +0 -1
- package/dist/datastar/actions/toggleAll.js +0 -12
- package/dist/datastar/attributes/attr.d.ts +0 -1
- package/dist/datastar/attributes/attr.js +0 -48
- package/dist/datastar/attributes/bind.d.ts +0 -1
- package/dist/datastar/attributes/bind.js +0 -175
- package/dist/datastar/attributes/class.d.ts +0 -1
- package/dist/datastar/attributes/class.js +0 -47
- package/dist/datastar/attributes/computed.d.ts +0 -1
- package/dist/datastar/attributes/computed.js +0 -26
- package/dist/datastar/attributes/effect.d.ts +0 -1
- package/dist/datastar/attributes/effect.js +0 -9
- package/dist/datastar/attributes/indicator.d.ts +0 -1
- package/dist/datastar/attributes/indicator.js +0 -30
- package/dist/datastar/attributes/init.d.ts +0 -1
- package/dist/datastar/attributes/init.js +0 -26
- package/dist/datastar/attributes/jsonSignals.d.ts +0 -1
- package/dist/datastar/attributes/jsonSignals.js +0 -30
- package/dist/datastar/attributes/on.d.ts +0 -1
- package/dist/datastar/attributes/on.js +0 -78
- package/dist/datastar/attributes/onIntersect.d.ts +0 -1
- package/dist/datastar/attributes/onIntersect.js +0 -53
- package/dist/datastar/attributes/onInterval.d.ts +0 -1
- package/dist/datastar/attributes/onInterval.js +0 -30
- package/dist/datastar/attributes/onSignalPatch.d.ts +0 -1
- package/dist/datastar/attributes/onSignalPatch.js +0 -42
- package/dist/datastar/attributes/ref.d.ts +0 -1
- package/dist/datastar/attributes/ref.js +0 -10
- package/dist/datastar/attributes/show.d.ts +0 -1
- package/dist/datastar/attributes/show.js +0 -31
- package/dist/datastar/attributes/signals.d.ts +0 -1
- package/dist/datastar/attributes/signals.js +0 -17
- package/dist/datastar/attributes/style.d.ts +0 -1
- package/dist/datastar/attributes/style.js +0 -50
- package/dist/datastar/attributes/text.d.ts +0 -1
- package/dist/datastar/attributes/text.js +0 -26
- package/dist/datastar/engine.d.ts +0 -162
- package/dist/datastar/engine.js +0 -999
- package/dist/datastar/happydom.d.ts +0 -1
- package/dist/datastar/happydom.js +0 -8
- package/dist/datastar/index.d.ts +0 -24
- package/dist/datastar/index.js +0 -24
- package/dist/datastar/load.d.ts +0 -24
- package/dist/datastar/load.js +0 -24
- package/dist/datastar/utils.d.ts +0 -51
- package/dist/datastar/utils.js +0 -202
- package/dist/datastar/watchers/patchElements.d.ts +0 -1
- package/dist/datastar/watchers/patchElements.js +0 -399
- package/dist/datastar/watchers/patchSignals.d.ts +0 -1
- package/dist/datastar/watchers/patchSignals.js +0 -14
- package/dist/experimental/EncryptedCookies.d.ts +0 -48
- package/dist/experimental/EncryptedCookies.js +0 -212
- package/dist/experimental/SseHttpResponse.d.ts +0 -7
- package/dist/experimental/SseHttpResponse.js +0 -28
- package/dist/experimental/index.d.ts +0 -1
- package/dist/experimental/index.js +0 -1
- package/dist/hyper/Hyper.d.ts +0 -25
- package/dist/hyper/Hyper.js +0 -23
- package/dist/hyper/HyperHtml.d.ts +0 -23
- package/dist/hyper/HyperHtml.js +0 -150
- package/dist/hyper/HyperHtml.test.d.ts +0 -1
- package/dist/hyper/HyperHtml.test.js +0 -197
- package/dist/hyper/HyperNode.d.ts +0 -14
- package/dist/hyper/HyperNode.js +0 -11
- package/dist/hyper/HyperRoute.d.ts +0 -8
- package/dist/hyper/HyperRoute.js +0 -32
- package/dist/hyper/HyperRoute.test.d.ts +0 -1
- package/dist/hyper/HyperRoute.test.js +0 -83
- package/dist/hyper/html.d.ts +0 -11
- package/dist/hyper/html.js +0 -30
- package/dist/hyper/index.d.ts +0 -6
- package/dist/hyper/index.js +0 -5
- package/dist/hyper/jsx-runtime.d.ts +0 -7
- package/dist/hyper/jsx-runtime.js +0 -8
- package/dist/index.d.ts +0 -8
- package/dist/index.js +0 -8
- package/dist/inference_check.d.ts +0 -1
- package/dist/inference_check.js +0 -15
- package/dist/lint/plugin.d.ts +0 -86
- package/dist/lint/plugin.js +0 -341
- package/dist/middlewares/BasicAuthMiddleware.d.ts +0 -8
- package/dist/middlewares/BasicAuthMiddleware.js +0 -22
- package/dist/middlewares/index.d.ts +0 -1
- package/dist/middlewares/index.js +0 -1
- package/dist/node/Effectify.d.ts +0 -209
- package/dist/node/Effectify.js +0 -19
- package/dist/node/FileSystem.d.ts +0 -7
- package/dist/node/FileSystem.js +0 -420
- package/dist/node/NodeFileSystem.d.ts +0 -7
- package/dist/node/NodeFileSystem.js +0 -410
- package/dist/node/NodeUtils.d.ts +0 -2
- package/dist/node/NodeUtils.js +0 -20
- package/dist/node/PlatformError.d.ts +0 -46
- package/dist/node/PlatformError.js +0 -43
- package/dist/node/Utils.d.ts +0 -1
- package/dist/node/Utils.js +0 -19
- package/dist/repro_fail.d.ts +0 -1
- package/dist/repro_fail.js +0 -14
- package/dist/sql/bun/index.d.ts +0 -3
- package/dist/sql/bun/index.js +0 -75
- package/dist/sql/mssql/docker.d.ts +0 -2
- package/dist/sql/mssql/docker.js +0 -67
- package/dist/sql/mssql/index.d.ts +0 -21
- package/dist/sql/mssql/index.js +0 -113
- package/dist/testing/TestHttpClient.d.ts +0 -13
- package/dist/testing/TestHttpClient.js +0 -68
- package/dist/testing/TestLogger.d.ts +0 -13
- package/dist/testing/TestLogger.js +0 -32
- package/dist/testing/index.d.ts +0 -2
- package/dist/testing/index.js +0 -2
- package/dist/testing/utils.d.ts +0 -9
- package/dist/testing/utils.js +0 -39
- package/dist/x/cloudflare/CloudflareTunnel.d.ts +0 -10
- package/dist/x/cloudflare/CloudflareTunnel.js +0 -30
- package/dist/x/cloudflare/index.d.ts +0 -1
- package/dist/x/cloudflare/index.js +0 -1
- package/dist/x/datastar/Datastar.d.ts +0 -6
- package/dist/x/datastar/Datastar.js +0 -47
- package/dist/x/datastar/index.d.ts +0 -1
- package/dist/x/datastar/index.js +0 -1
- package/dist/x/tailscale/TailscaleTunnel.d.ts +0 -15
- package/dist/x/tailscale/TailscaleTunnel.js +0 -68
- package/dist/x/tailscale/index.d.ts +0 -1
- package/dist/x/tailscale/index.js +0 -1
- package/dist/x/tailwind/TailwindPlugin.d.ts +0 -23
- package/dist/x/tailwind/TailwindPlugin.js +0 -219
- package/dist/x/tailwind/compile.d.ts +0 -19
- package/dist/x/tailwind/compile.js +0 -154
- package/dist/x/tailwind/plugin.d.ts +0 -2
- package/dist/x/tailwind/plugin.js +0 -15
- /package/src/{Sql.ts → sql/Sql.ts} +0 -0
|
@@ -1,399 +0,0 @@
|
|
|
1
|
-
import { watcher } from "../engine.js";
|
|
2
|
-
import { aliasify, isHTMLOrSVG, supportsViewTransitions } from "../utils.js";
|
|
3
|
-
const isValidType = (arr, value) => arr.includes(value);
|
|
4
|
-
const PATCH_MODES = [
|
|
5
|
-
"remove",
|
|
6
|
-
"outer",
|
|
7
|
-
"inner",
|
|
8
|
-
"replace",
|
|
9
|
-
"prepend",
|
|
10
|
-
"append",
|
|
11
|
-
"before",
|
|
12
|
-
"after",
|
|
13
|
-
];
|
|
14
|
-
const NAMESPACES = ["html", "svg", "mathml"];
|
|
15
|
-
watcher({
|
|
16
|
-
name: "datastar-patch-elements",
|
|
17
|
-
apply(ctx, { selector = "", mode = "outer", namespace = "html", useViewTransition = "", elements = "" }) {
|
|
18
|
-
if (!isValidType(PATCH_MODES, mode)) {
|
|
19
|
-
throw ctx.error("PatchElementsInvalidMode", { mode });
|
|
20
|
-
}
|
|
21
|
-
if (!selector && mode !== "outer" && mode !== "replace") {
|
|
22
|
-
throw ctx.error("PatchElementsExpectedSelector");
|
|
23
|
-
}
|
|
24
|
-
if (!isValidType(NAMESPACES, namespace)) {
|
|
25
|
-
throw ctx.error("PatchElementsInvalidNamespace", { namespace });
|
|
26
|
-
}
|
|
27
|
-
const args2 = {
|
|
28
|
-
selector,
|
|
29
|
-
mode,
|
|
30
|
-
namespace,
|
|
31
|
-
useViewTransition: useViewTransition.trim() === "true",
|
|
32
|
-
elements,
|
|
33
|
-
};
|
|
34
|
-
if (supportsViewTransitions && useViewTransition) {
|
|
35
|
-
document.startViewTransition(() => onPatchElements(ctx, args2));
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
onPatchElements(ctx, args2);
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
});
|
|
42
|
-
const onPatchElements = ({ error }, { selector, mode, namespace, elements }) => {
|
|
43
|
-
const elementsWithSvgsRemoved = elements.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim, "");
|
|
44
|
-
const hasHtml = /<\/html>/.test(elementsWithSvgsRemoved);
|
|
45
|
-
const hasHead = /<\/head>/.test(elementsWithSvgsRemoved);
|
|
46
|
-
const hasBody = /<\/body>/.test(elementsWithSvgsRemoved);
|
|
47
|
-
const wrapperTag = namespace === "svg" ? "svg" : namespace === "mathml" ? "math" : "";
|
|
48
|
-
const wrappedEls = wrapperTag ? `<${wrapperTag}>${elements}</${wrapperTag}>` : elements;
|
|
49
|
-
const newDocument = new DOMParser().parseFromString(hasHtml || hasHead || hasBody ? elements : `<body><template>${wrappedEls}</template></body>`, "text/html");
|
|
50
|
-
let newContent = document.createDocumentFragment();
|
|
51
|
-
if (hasHtml) {
|
|
52
|
-
newContent.appendChild(newDocument.documentElement);
|
|
53
|
-
}
|
|
54
|
-
else if (hasHead && hasBody) {
|
|
55
|
-
newContent.appendChild(newDocument.head);
|
|
56
|
-
newContent.appendChild(newDocument.body);
|
|
57
|
-
}
|
|
58
|
-
else if (hasHead) {
|
|
59
|
-
newContent.appendChild(newDocument.head);
|
|
60
|
-
}
|
|
61
|
-
else if (hasBody) {
|
|
62
|
-
newContent.appendChild(newDocument.body);
|
|
63
|
-
}
|
|
64
|
-
else if (wrapperTag) {
|
|
65
|
-
const wrapperEl = newDocument.querySelector("template").content.querySelector(wrapperTag);
|
|
66
|
-
for (const child of wrapperEl.childNodes) {
|
|
67
|
-
newContent.appendChild(child);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
newContent = newDocument.querySelector("template").content;
|
|
72
|
-
}
|
|
73
|
-
if (!selector && (mode === "outer" || mode === "replace")) {
|
|
74
|
-
for (const child of newContent.children) {
|
|
75
|
-
let target;
|
|
76
|
-
if (child instanceof HTMLHtmlElement) {
|
|
77
|
-
target = document.documentElement;
|
|
78
|
-
}
|
|
79
|
-
else if (child instanceof HTMLBodyElement) {
|
|
80
|
-
target = document.body;
|
|
81
|
-
}
|
|
82
|
-
else if (child instanceof HTMLHeadElement) {
|
|
83
|
-
target = document.head;
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
target = document.getElementById(child.id);
|
|
87
|
-
if (!target) {
|
|
88
|
-
console.warn(error("PatchElementsNoTargetsFound"), {
|
|
89
|
-
element: { id: child.id },
|
|
90
|
-
});
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
applyToTargets(mode, child, [target]);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
const targets = document.querySelectorAll(selector);
|
|
99
|
-
if (!targets.length) {
|
|
100
|
-
console.warn(error("PatchElementsNoTargetsFound"), { selector });
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
applyToTargets(mode, newContent, targets);
|
|
104
|
-
}
|
|
105
|
-
};
|
|
106
|
-
const scripts = new WeakSet();
|
|
107
|
-
for (const script of document.querySelectorAll("script")) {
|
|
108
|
-
scripts.add(script);
|
|
109
|
-
}
|
|
110
|
-
const execute = (target) => {
|
|
111
|
-
const elScripts = target instanceof HTMLScriptElement ? [target] : target.querySelectorAll("script");
|
|
112
|
-
for (const old of elScripts) {
|
|
113
|
-
if (!scripts.has(old)) {
|
|
114
|
-
const script = document.createElement("script");
|
|
115
|
-
for (const { name, value } of old.attributes) {
|
|
116
|
-
script.setAttribute(name, value);
|
|
117
|
-
}
|
|
118
|
-
script.text = old.text;
|
|
119
|
-
old.replaceWith(script);
|
|
120
|
-
scripts.add(script);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
const applyPatchMode = (targets, element, action) => {
|
|
125
|
-
for (const target of targets) {
|
|
126
|
-
const cloned = element.cloneNode(true);
|
|
127
|
-
execute(cloned);
|
|
128
|
-
// @ts-ignore
|
|
129
|
-
target[action](cloned);
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
const applyToTargets = (mode, element, targets) => {
|
|
133
|
-
switch (mode) {
|
|
134
|
-
case "remove":
|
|
135
|
-
for (const target of targets) {
|
|
136
|
-
target.remove();
|
|
137
|
-
}
|
|
138
|
-
break;
|
|
139
|
-
case "outer":
|
|
140
|
-
case "inner":
|
|
141
|
-
for (const target of targets) {
|
|
142
|
-
morph(target, element.cloneNode(true), mode);
|
|
143
|
-
execute(target);
|
|
144
|
-
}
|
|
145
|
-
break;
|
|
146
|
-
case "replace":
|
|
147
|
-
applyPatchMode(targets, element, "replaceWith");
|
|
148
|
-
break;
|
|
149
|
-
case "prepend":
|
|
150
|
-
case "append":
|
|
151
|
-
case "before":
|
|
152
|
-
case "after":
|
|
153
|
-
applyPatchMode(targets, element, mode);
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
const ctxIdMap = new Map();
|
|
157
|
-
const ctxPersistentIds = new Set();
|
|
158
|
-
const oldIdTagNameMap = new Map();
|
|
159
|
-
const duplicateIds = new Set();
|
|
160
|
-
const ctxPantry = document.createElement("div");
|
|
161
|
-
ctxPantry.hidden = true;
|
|
162
|
-
const aliasedIgnoreMorph = aliasify("ignore-morph");
|
|
163
|
-
const aliasedIgnoreMorphAttr = `[${aliasedIgnoreMorph}]`;
|
|
164
|
-
const morph = (oldElt, newContent, mode = "outer") => {
|
|
165
|
-
if ((isHTMLOrSVG(oldElt) &&
|
|
166
|
-
isHTMLOrSVG(newContent) &&
|
|
167
|
-
oldElt.hasAttribute(aliasedIgnoreMorph) &&
|
|
168
|
-
newContent.hasAttribute(aliasedIgnoreMorph)) ||
|
|
169
|
-
oldElt.parentElement?.closest(aliasedIgnoreMorphAttr)) {
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
const normalizedElt = document.createElement("div");
|
|
173
|
-
normalizedElt.append(newContent);
|
|
174
|
-
document.body.insertAdjacentElement("afterend", ctxPantry);
|
|
175
|
-
const oldIdElements = oldElt.querySelectorAll("[id]");
|
|
176
|
-
for (const { id, tagName } of oldIdElements) {
|
|
177
|
-
if (oldIdTagNameMap.has(id)) {
|
|
178
|
-
duplicateIds.add(id);
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
oldIdTagNameMap.set(id, tagName);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
if (oldElt instanceof Element && oldElt.id) {
|
|
185
|
-
if (oldIdTagNameMap.has(oldElt.id)) {
|
|
186
|
-
duplicateIds.add(oldElt.id);
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
-
oldIdTagNameMap.set(oldElt.id, oldElt.tagName);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
ctxPersistentIds.clear();
|
|
193
|
-
const newIdElements = normalizedElt.querySelectorAll("[id]");
|
|
194
|
-
for (const { id, tagName } of newIdElements) {
|
|
195
|
-
if (ctxPersistentIds.has(id)) {
|
|
196
|
-
duplicateIds.add(id);
|
|
197
|
-
}
|
|
198
|
-
else if (oldIdTagNameMap.get(id) === tagName) {
|
|
199
|
-
ctxPersistentIds.add(id);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
for (const id of duplicateIds) {
|
|
203
|
-
ctxPersistentIds.delete(id);
|
|
204
|
-
}
|
|
205
|
-
oldIdTagNameMap.clear();
|
|
206
|
-
duplicateIds.clear();
|
|
207
|
-
ctxIdMap.clear();
|
|
208
|
-
const parent = mode === "outer" ? oldElt.parentElement : oldElt;
|
|
209
|
-
populateIdMapWithTree(parent, oldIdElements);
|
|
210
|
-
populateIdMapWithTree(normalizedElt, newIdElements);
|
|
211
|
-
morphChildren(parent, normalizedElt, mode === "outer" ? oldElt : null, oldElt.nextSibling);
|
|
212
|
-
ctxPantry.remove();
|
|
213
|
-
};
|
|
214
|
-
const morphChildren = (oldParent, newParent, insertionPoint = null, endPoint = null) => {
|
|
215
|
-
if (oldParent instanceof HTMLTemplateElement && newParent instanceof HTMLTemplateElement) {
|
|
216
|
-
oldParent = oldParent.content;
|
|
217
|
-
newParent = newParent.content;
|
|
218
|
-
}
|
|
219
|
-
insertionPoint ??= oldParent.firstChild;
|
|
220
|
-
for (const newChild of newParent.childNodes) {
|
|
221
|
-
if (insertionPoint && insertionPoint !== endPoint) {
|
|
222
|
-
const bestMatch = findBestMatch(newChild, insertionPoint, endPoint);
|
|
223
|
-
if (bestMatch) {
|
|
224
|
-
if (bestMatch !== insertionPoint) {
|
|
225
|
-
let cursor = insertionPoint;
|
|
226
|
-
while (cursor && cursor !== bestMatch) {
|
|
227
|
-
const tempNode = cursor;
|
|
228
|
-
cursor = cursor.nextSibling;
|
|
229
|
-
removeNode(tempNode);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
morphNode(bestMatch, newChild);
|
|
233
|
-
insertionPoint = bestMatch.nextSibling;
|
|
234
|
-
continue;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
if (newChild instanceof Element && ctxPersistentIds.has(newChild.id)) {
|
|
238
|
-
const movedChild = document.getElementById(newChild.id);
|
|
239
|
-
let current = movedChild;
|
|
240
|
-
while ((current = current.parentNode)) {
|
|
241
|
-
const idSet = ctxIdMap.get(current);
|
|
242
|
-
if (idSet) {
|
|
243
|
-
idSet.delete(newChild.id);
|
|
244
|
-
if (!idSet.size) {
|
|
245
|
-
ctxIdMap.delete(current);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
moveBefore(oldParent, movedChild, insertionPoint);
|
|
250
|
-
morphNode(movedChild, newChild);
|
|
251
|
-
insertionPoint = movedChild.nextSibling;
|
|
252
|
-
continue;
|
|
253
|
-
}
|
|
254
|
-
if (ctxIdMap.has(newChild)) {
|
|
255
|
-
const namespaceURI = newChild.namespaceURI;
|
|
256
|
-
const tagName = newChild.tagName;
|
|
257
|
-
const newEmptyChild = namespaceURI && namespaceURI !== "http://www.w3.org/1999/xhtml"
|
|
258
|
-
? document.createElementNS(namespaceURI, tagName)
|
|
259
|
-
: document.createElement(tagName);
|
|
260
|
-
oldParent.insertBefore(newEmptyChild, insertionPoint);
|
|
261
|
-
morphNode(newEmptyChild, newChild);
|
|
262
|
-
insertionPoint = newEmptyChild.nextSibling;
|
|
263
|
-
}
|
|
264
|
-
else {
|
|
265
|
-
const newClonedChild = document.importNode(newChild, true);
|
|
266
|
-
oldParent.insertBefore(newClonedChild, insertionPoint);
|
|
267
|
-
insertionPoint = newClonedChild.nextSibling;
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
while (insertionPoint && insertionPoint !== endPoint) {
|
|
271
|
-
const tempNode = insertionPoint;
|
|
272
|
-
insertionPoint = insertionPoint.nextSibling;
|
|
273
|
-
removeNode(tempNode);
|
|
274
|
-
}
|
|
275
|
-
};
|
|
276
|
-
const findBestMatch = (node, startPoint, endPoint) => {
|
|
277
|
-
let bestMatch = null;
|
|
278
|
-
let nextSibling = node.nextSibling;
|
|
279
|
-
let siblingSoftMatchCount = 0;
|
|
280
|
-
let displaceMatchCount = 0;
|
|
281
|
-
const nodeMatchCount = ctxIdMap.get(node)?.size || 0;
|
|
282
|
-
let cursor = startPoint;
|
|
283
|
-
while (cursor && cursor !== endPoint) {
|
|
284
|
-
if (isSoftMatch(cursor, node)) {
|
|
285
|
-
let isIdSetMatch = false;
|
|
286
|
-
const oldSet = ctxIdMap.get(cursor);
|
|
287
|
-
const newSet = ctxIdMap.get(node);
|
|
288
|
-
if (newSet && oldSet) {
|
|
289
|
-
for (const id of oldSet) {
|
|
290
|
-
if (newSet.has(id)) {
|
|
291
|
-
isIdSetMatch = true;
|
|
292
|
-
break;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
if (isIdSetMatch) {
|
|
297
|
-
return cursor;
|
|
298
|
-
}
|
|
299
|
-
if (!bestMatch && !ctxIdMap.has(cursor)) {
|
|
300
|
-
if (!nodeMatchCount) {
|
|
301
|
-
return cursor;
|
|
302
|
-
}
|
|
303
|
-
bestMatch = cursor;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
displaceMatchCount += ctxIdMap.get(cursor)?.size || 0;
|
|
307
|
-
if (displaceMatchCount > nodeMatchCount) {
|
|
308
|
-
break;
|
|
309
|
-
}
|
|
310
|
-
if (bestMatch === null && nextSibling && isSoftMatch(cursor, nextSibling)) {
|
|
311
|
-
siblingSoftMatchCount++;
|
|
312
|
-
nextSibling = nextSibling.nextSibling;
|
|
313
|
-
if (siblingSoftMatchCount >= 2) {
|
|
314
|
-
bestMatch = undefined;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
cursor = cursor.nextSibling;
|
|
318
|
-
}
|
|
319
|
-
return bestMatch || null;
|
|
320
|
-
};
|
|
321
|
-
const isSoftMatch = (oldNode, newNode) => oldNode.nodeType === newNode.nodeType &&
|
|
322
|
-
oldNode.tagName === newNode.tagName &&
|
|
323
|
-
(!oldNode.id || oldNode.id === newNode.id);
|
|
324
|
-
const removeNode = (node) => {
|
|
325
|
-
ctxIdMap.has(node) ? moveBefore(ctxPantry, node, null) : node.parentNode?.removeChild(node);
|
|
326
|
-
};
|
|
327
|
-
const moveBefore =
|
|
328
|
-
// @ts-expect-error
|
|
329
|
-
removeNode.call.bind(ctxPantry.moveBefore ?? ctxPantry.insertBefore);
|
|
330
|
-
const aliasedPreserveAttr = aliasify("preserve-attr");
|
|
331
|
-
const morphNode = (oldNode, newNode) => {
|
|
332
|
-
const type = newNode.nodeType;
|
|
333
|
-
if (type === 1) {
|
|
334
|
-
const oldElt = oldNode;
|
|
335
|
-
const newElt = newNode;
|
|
336
|
-
const shouldScopeChildren = oldElt.hasAttribute("data-scope-children");
|
|
337
|
-
if (oldElt.hasAttribute(aliasedIgnoreMorph) && newElt.hasAttribute(aliasedIgnoreMorph)) {
|
|
338
|
-
return oldNode;
|
|
339
|
-
}
|
|
340
|
-
if (oldElt instanceof HTMLInputElement &&
|
|
341
|
-
newElt instanceof HTMLInputElement &&
|
|
342
|
-
newElt.type !== "file") {
|
|
343
|
-
if (newElt.getAttribute("value") !== oldElt.getAttribute("value")) {
|
|
344
|
-
oldElt.value = newElt.getAttribute("value") ?? "";
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
else if (oldElt instanceof HTMLTextAreaElement && newElt instanceof HTMLTextAreaElement) {
|
|
348
|
-
if (newElt.value !== oldElt.value) {
|
|
349
|
-
oldElt.value = newElt.value;
|
|
350
|
-
}
|
|
351
|
-
if (oldElt.firstChild && oldElt.firstChild.nodeValue !== newElt.value) {
|
|
352
|
-
oldElt.firstChild.nodeValue = newElt.value;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
const preserveAttrs = (newNode.getAttribute(aliasedPreserveAttr) ?? "").split(" ");
|
|
356
|
-
for (const { name, value } of newElt.attributes) {
|
|
357
|
-
if (oldElt.getAttribute(name) !== value && !preserveAttrs.includes(name)) {
|
|
358
|
-
oldElt.setAttribute(name, value);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
for (let i = oldElt.attributes.length - 1; i >= 0; i--) {
|
|
362
|
-
const { name } = oldElt.attributes[i];
|
|
363
|
-
if (!newElt.hasAttribute(name) && !preserveAttrs.includes(name)) {
|
|
364
|
-
oldElt.removeAttribute(name);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
if (shouldScopeChildren && !oldElt.hasAttribute("data-scope-children")) {
|
|
368
|
-
oldElt.setAttribute("data-scope-children", "");
|
|
369
|
-
}
|
|
370
|
-
if (!oldElt.isEqualNode(newElt)) {
|
|
371
|
-
morphChildren(oldElt, newElt);
|
|
372
|
-
}
|
|
373
|
-
if (shouldScopeChildren) {
|
|
374
|
-
oldElt.dispatchEvent(new CustomEvent("datastar:scope-children", { bubbles: false }));
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
if (type === 8 || type === 3) {
|
|
378
|
-
if (oldNode.nodeValue !== newNode.nodeValue) {
|
|
379
|
-
oldNode.nodeValue = newNode.nodeValue;
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
return oldNode;
|
|
383
|
-
};
|
|
384
|
-
const populateIdMapWithTree = (root, elements) => {
|
|
385
|
-
for (const elt of elements) {
|
|
386
|
-
if (ctxPersistentIds.has(elt.id)) {
|
|
387
|
-
let current = elt;
|
|
388
|
-
while (current && current !== root) {
|
|
389
|
-
let idSet = ctxIdMap.get(current);
|
|
390
|
-
if (!idSet) {
|
|
391
|
-
idSet = new Set();
|
|
392
|
-
ctxIdMap.set(current, idSet);
|
|
393
|
-
}
|
|
394
|
-
idSet.add(elt.id);
|
|
395
|
-
current = current.parentElement;
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { mergePatch, watcher } from "../engine.js";
|
|
2
|
-
import { jsStrToObject } from "../utils.js";
|
|
3
|
-
watcher({
|
|
4
|
-
name: "datastar-patch-signals",
|
|
5
|
-
apply({ error }, { signals, onlyIfMissing }) {
|
|
6
|
-
if (signals) {
|
|
7
|
-
const ifMissing = onlyIfMissing?.trim() === "true";
|
|
8
|
-
mergePatch(jsStrToObject(signals), { ifMissing });
|
|
9
|
-
}
|
|
10
|
-
else {
|
|
11
|
-
throw error("PatchSignalsExpectedSignals");
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
});
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import * as Cookies from "../Cookies.ts";
|
|
2
|
-
import * as Context from "effect/Context";
|
|
3
|
-
import * as Effect from "effect/Effect";
|
|
4
|
-
import * as Layer from "effect/Layer";
|
|
5
|
-
type CookieValue = string | number | boolean | null | undefined | {
|
|
6
|
-
[key: string]: CookieValue | unknown;
|
|
7
|
-
} | CookieValue[];
|
|
8
|
-
declare const EncryptedCookiesError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
|
|
9
|
-
readonly _tag: "EncryptedCookiesError";
|
|
10
|
-
} & Readonly<A>;
|
|
11
|
-
export declare class EncryptedCookiesError extends EncryptedCookiesError_base<{
|
|
12
|
-
cause: unknown;
|
|
13
|
-
cookie?: Cookies.Cookie;
|
|
14
|
-
}> {
|
|
15
|
-
}
|
|
16
|
-
declare const EncryptedCookies_base: Context.TagClass<EncryptedCookies, "EncryptedCookies", {
|
|
17
|
-
encrypt: (value: CookieValue) => Effect.Effect<string, EncryptedCookiesError>;
|
|
18
|
-
decrypt: (encryptedValue: string) => Effect.Effect<CookieValue, EncryptedCookiesError>;
|
|
19
|
-
encryptCookie: (cookie: Cookies.Cookie) => Effect.Effect<Cookies.Cookie, EncryptedCookiesError>;
|
|
20
|
-
decryptCookie: (cookie: Cookies.Cookie) => Effect.Effect<Cookies.Cookie, EncryptedCookiesError>;
|
|
21
|
-
}>;
|
|
22
|
-
export declare class EncryptedCookies extends EncryptedCookies_base {
|
|
23
|
-
}
|
|
24
|
-
export declare function layer(options: {
|
|
25
|
-
secret: string;
|
|
26
|
-
}): Layer.Layer<EncryptedCookies, EncryptedCookiesError, never>;
|
|
27
|
-
export declare function layerConfig(name?: string): Layer.Layer<EncryptedCookies, EncryptedCookiesError, never>;
|
|
28
|
-
export declare function encrypt(value: CookieValue, options: {
|
|
29
|
-
key: CryptoKey;
|
|
30
|
-
} | {
|
|
31
|
-
secret: string;
|
|
32
|
-
}): Effect.Effect<string, EncryptedCookiesError>;
|
|
33
|
-
export declare function encryptCookie(cookie: Cookies.Cookie, options: {
|
|
34
|
-
key: CryptoKey;
|
|
35
|
-
} | {
|
|
36
|
-
secret: string;
|
|
37
|
-
}): Effect.Effect<Cookies.Cookie, EncryptedCookiesError>;
|
|
38
|
-
export declare function decryptCookie(cookie: Cookies.Cookie, options: {
|
|
39
|
-
key: CryptoKey;
|
|
40
|
-
} | {
|
|
41
|
-
secret: string;
|
|
42
|
-
}): Effect.Effect<Cookies.Cookie, EncryptedCookiesError>;
|
|
43
|
-
export declare function decrypt(encryptedValue: string, options: {
|
|
44
|
-
key: CryptoKey;
|
|
45
|
-
} | {
|
|
46
|
-
secret: string;
|
|
47
|
-
}): Effect.Effect<CookieValue, EncryptedCookiesError>;
|
|
48
|
-
export {};
|
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
import * as Cookies from "../Cookies.js";
|
|
2
|
-
import * as Config from "effect/Config";
|
|
3
|
-
import * as Context from "effect/Context";
|
|
4
|
-
import * as Data from "effect/Data";
|
|
5
|
-
import * as Effect from "effect/Effect";
|
|
6
|
-
import * as Layer from "effect/Layer";
|
|
7
|
-
export class EncryptedCookiesError extends Data.TaggedError("EncryptedCookiesError") {
|
|
8
|
-
}
|
|
9
|
-
export class EncryptedCookies extends Context.Tag("EncryptedCookies")() {
|
|
10
|
-
}
|
|
11
|
-
export function layer(options) {
|
|
12
|
-
return Layer.effect(EncryptedCookies, Effect.gen(function* () {
|
|
13
|
-
const keyMaterial = yield* deriveKeyMaterial(options.secret);
|
|
14
|
-
// Pre-derive both keys once
|
|
15
|
-
const encryptKey = yield* deriveKey(keyMaterial, ["encrypt"]);
|
|
16
|
-
const decryptKey = yield* deriveKey(keyMaterial, ["decrypt"]);
|
|
17
|
-
return EncryptedCookies.of({
|
|
18
|
-
encrypt: (value) => encryptWithDerivedKey(value, encryptKey),
|
|
19
|
-
decrypt: (encryptedValue) => decryptWithDerivedKey(encryptedValue, decryptKey),
|
|
20
|
-
encryptCookie: (cookie) => encryptCookieWithDerivedKey(cookie, encryptKey),
|
|
21
|
-
decryptCookie: (cookie) => decryptCookieWithDerivedKey(cookie, decryptKey),
|
|
22
|
-
});
|
|
23
|
-
}));
|
|
24
|
-
}
|
|
25
|
-
export function layerConfig(name = "SECRET_KEY_BASE") {
|
|
26
|
-
return Effect.gen(function* () {
|
|
27
|
-
const secret = yield* Config.nonEmptyString(name).pipe(Effect.flatMap((value) => {
|
|
28
|
-
return value.length < 40 ? Effect.fail(new Error("ba")) : Effect.succeed(value);
|
|
29
|
-
}), Effect.catchAll((err) => {
|
|
30
|
-
return Effect.dieMessage("SECRET_KEY_BASE must be at least 40 characters");
|
|
31
|
-
}));
|
|
32
|
-
return layer({ secret });
|
|
33
|
-
}).pipe(Layer.unwrapEffect);
|
|
34
|
-
}
|
|
35
|
-
function encodeToBase64Segments(ciphertext, iv, authTag) {
|
|
36
|
-
return [base64urlEncode(ciphertext), base64urlEncode(iv), base64urlEncode(authTag)].join(".");
|
|
37
|
-
}
|
|
38
|
-
function base64urlEncode(data) {
|
|
39
|
-
const base64 = btoa(String.fromCharCode(...data));
|
|
40
|
-
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
41
|
-
}
|
|
42
|
-
function decodeFromBase64Segments(segments) {
|
|
43
|
-
return Effect.gen(function* () {
|
|
44
|
-
const [ciphertextB64, ivB64, authTagB64] = segments;
|
|
45
|
-
const ciphertext = yield* Effect.try({
|
|
46
|
-
try: () => base64urlDecode(ciphertextB64),
|
|
47
|
-
catch: (error) => new EncryptedCookiesError({ cause: error }),
|
|
48
|
-
});
|
|
49
|
-
const iv = yield* Effect.try({
|
|
50
|
-
try: () => base64urlDecode(ivB64),
|
|
51
|
-
catch: (error) => new EncryptedCookiesError({ cause: error }),
|
|
52
|
-
});
|
|
53
|
-
const authTag = yield* Effect.try({
|
|
54
|
-
try: () => base64urlDecode(authTagB64),
|
|
55
|
-
catch: (error) => new EncryptedCookiesError({ cause: error }),
|
|
56
|
-
});
|
|
57
|
-
return { ciphertext, iv, authTag };
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
function base64urlDecode(data) {
|
|
61
|
-
// Convert base64url back to standard base64
|
|
62
|
-
let base64 = data.replace(/-/g, "+").replace(/_/g, "/");
|
|
63
|
-
// Add padding if needed
|
|
64
|
-
while (base64.length % 4) {
|
|
65
|
-
base64 += "=";
|
|
66
|
-
}
|
|
67
|
-
return Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Encrypts cookie value using the SECRET_KEY_BASE.
|
|
71
|
-
*/
|
|
72
|
-
function encryptWithDerivedKey(value, derivedKey) {
|
|
73
|
-
return Effect.gen(function* () {
|
|
74
|
-
if (value === null || value === undefined) {
|
|
75
|
-
return yield* Effect.fail(new EncryptedCookiesError({
|
|
76
|
-
cause: "Cannot encrypt empty value",
|
|
77
|
-
}));
|
|
78
|
-
}
|
|
79
|
-
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
80
|
-
const data = new TextEncoder().encode(JSON.stringify(value));
|
|
81
|
-
const encrypted = yield* Effect.tryPromise({
|
|
82
|
-
try: () => crypto.subtle.encrypt({ name: "AES-GCM", iv }, derivedKey, data),
|
|
83
|
-
catch: (error) => new EncryptedCookiesError({ cause: error }),
|
|
84
|
-
});
|
|
85
|
-
const encryptedArray = new Uint8Array(encrypted);
|
|
86
|
-
const authTagLength = 16;
|
|
87
|
-
const ciphertext = encryptedArray.slice(0, -authTagLength);
|
|
88
|
-
const authTag = encryptedArray.slice(-authTagLength);
|
|
89
|
-
return encodeToBase64Segments(ciphertext, iv, authTag);
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
export function encrypt(value, options) {
|
|
93
|
-
return Effect.gen(function* () {
|
|
94
|
-
if ("key" in options) {
|
|
95
|
-
return yield* encryptWithDerivedKey(value, options.key);
|
|
96
|
-
}
|
|
97
|
-
const keyMaterial = yield* deriveKeyMaterial(options.secret);
|
|
98
|
-
const derivedKey = yield* deriveKey(keyMaterial, ["encrypt"]);
|
|
99
|
-
return yield* encryptWithDerivedKey(value, derivedKey);
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
function decryptWithDerivedKey(encryptedValue, derivedKey) {
|
|
103
|
-
return Effect.gen(function* () {
|
|
104
|
-
if (!encryptedValue || encryptedValue === null || encryptedValue === undefined) {
|
|
105
|
-
return yield* Effect.fail(new EncryptedCookiesError({
|
|
106
|
-
cause: "Cannot decrypt null, undefined, or empty value",
|
|
107
|
-
}));
|
|
108
|
-
}
|
|
109
|
-
const segments = encryptedValue.split(".");
|
|
110
|
-
if (segments.length !== 3) {
|
|
111
|
-
return yield* Effect.fail(new EncryptedCookiesError({
|
|
112
|
-
cause: "Invalid encrypted cookie format",
|
|
113
|
-
}));
|
|
114
|
-
}
|
|
115
|
-
const { ciphertext, iv, authTag } = yield* decodeFromBase64Segments(segments);
|
|
116
|
-
const encryptedData = new Uint8Array(ciphertext.length + authTag.length);
|
|
117
|
-
encryptedData.set(ciphertext);
|
|
118
|
-
encryptedData.set(authTag, ciphertext.length);
|
|
119
|
-
const decrypted = yield* Effect.tryPromise({
|
|
120
|
-
try: () => crypto.subtle.decrypt({ name: "AES-GCM", iv: iv.slice(0) }, derivedKey, encryptedData),
|
|
121
|
-
catch: (error) => new EncryptedCookiesError({ cause: error }),
|
|
122
|
-
});
|
|
123
|
-
const jsonString = new TextDecoder().decode(decrypted);
|
|
124
|
-
return yield* Effect.try({
|
|
125
|
-
try: () => JSON.parse(jsonString),
|
|
126
|
-
catch: (error) => new EncryptedCookiesError({ cause: error }),
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
function encryptCookieWithDerivedKey(cookie, derivedKey) {
|
|
131
|
-
return Effect.gen(function* () {
|
|
132
|
-
const encryptedValue = yield* encryptWithDerivedKey(cookie.value, derivedKey).pipe(Effect.mapError((error) => new EncryptedCookiesError({
|
|
133
|
-
cause: error.cause,
|
|
134
|
-
cookie,
|
|
135
|
-
})));
|
|
136
|
-
return Cookies.unsafeMakeCookie(cookie.name, encryptedValue, cookie.options);
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
function decryptCookieWithDerivedKey(cookie, derivedKey) {
|
|
140
|
-
return Effect.gen(function* () {
|
|
141
|
-
const decryptedValue = yield* decryptWithDerivedKey(cookie.value, derivedKey).pipe(Effect.mapError((error) => new EncryptedCookiesError({
|
|
142
|
-
cause: error.cause,
|
|
143
|
-
cookie,
|
|
144
|
-
})));
|
|
145
|
-
return Cookies.unsafeMakeCookie(cookie.name, JSON.stringify(decryptedValue), cookie.options);
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
export function encryptCookie(cookie, options) {
|
|
149
|
-
return Effect.gen(function* () {
|
|
150
|
-
if ("key" in options) {
|
|
151
|
-
return yield* encryptCookieWithDerivedKey(cookie, options.key);
|
|
152
|
-
}
|
|
153
|
-
const encryptedValue = yield* encrypt(cookie.value, {
|
|
154
|
-
secret: options.secret,
|
|
155
|
-
}).pipe(Effect.mapError((error) => new EncryptedCookiesError({
|
|
156
|
-
cause: error.cause,
|
|
157
|
-
cookie,
|
|
158
|
-
})));
|
|
159
|
-
return Cookies.unsafeMakeCookie(cookie.name, encryptedValue, cookie.options);
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
export function decryptCookie(cookie, options) {
|
|
163
|
-
return Effect.gen(function* () {
|
|
164
|
-
if ("key" in options) {
|
|
165
|
-
return yield* decryptCookieWithDerivedKey(cookie, options.key);
|
|
166
|
-
}
|
|
167
|
-
const decryptedValue = yield* decrypt(cookie.value, {
|
|
168
|
-
secret: options.secret,
|
|
169
|
-
}).pipe(Effect.mapError((error) => new EncryptedCookiesError({
|
|
170
|
-
cause: error.cause,
|
|
171
|
-
cookie,
|
|
172
|
-
})));
|
|
173
|
-
return Cookies.unsafeMakeCookie(cookie.name, JSON.stringify(decryptedValue), cookie.options);
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
export function decrypt(encryptedValue, options) {
|
|
177
|
-
return Effect.gen(function* () {
|
|
178
|
-
if ("key" in options) {
|
|
179
|
-
return yield* decryptWithDerivedKey(encryptedValue, options.key);
|
|
180
|
-
}
|
|
181
|
-
const keyMaterial = yield* deriveKeyMaterial(options.secret);
|
|
182
|
-
const derivedKey = yield* deriveKey(keyMaterial, ["decrypt"]);
|
|
183
|
-
return yield* decryptWithDerivedKey(encryptedValue, derivedKey);
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
function deriveKeyMaterial(secret) {
|
|
187
|
-
return Effect.gen(function* () {
|
|
188
|
-
const encoder = new TextEncoder();
|
|
189
|
-
const keyMaterial = yield* Effect.tryPromise({
|
|
190
|
-
try: () => crypto.subtle.importKey("raw", encoder.encode(secret), { name: "HKDF" }, false, [
|
|
191
|
-
"deriveKey",
|
|
192
|
-
]),
|
|
193
|
-
catch: (error) => new EncryptedCookiesError({ cause: error }),
|
|
194
|
-
});
|
|
195
|
-
return keyMaterial;
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
function deriveKey(keyMaterial, usage) {
|
|
199
|
-
return Effect.gen(function* () {
|
|
200
|
-
const encoder = new TextEncoder();
|
|
201
|
-
const key = yield* Effect.tryPromise({
|
|
202
|
-
try: () => crypto.subtle.deriveKey({
|
|
203
|
-
name: "HKDF",
|
|
204
|
-
salt: encoder.encode("cookie-encryption"),
|
|
205
|
-
info: encoder.encode("aes-256-gcm"),
|
|
206
|
-
hash: "SHA-256",
|
|
207
|
-
}, keyMaterial, { name: "AES-GCM", length: 256 }, false, usage),
|
|
208
|
-
catch: (error) => new EncryptedCookiesError({ cause: error }),
|
|
209
|
-
});
|
|
210
|
-
return key;
|
|
211
|
-
});
|
|
212
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import * as HttpServerResponse from "@effect/platform/HttpServerResponse";
|
|
2
|
-
import * as Duration from "effect/Duration";
|
|
3
|
-
import * as Effect from "effect/Effect";
|
|
4
|
-
import * as Stream from "effect/Stream";
|
|
5
|
-
export declare const make: <T = any>(stream: Stream.Stream<T, any>, options?: {
|
|
6
|
-
heartbeatInterval?: Duration.DurationInput;
|
|
7
|
-
}) => Effect.Effect<HttpServerResponse.HttpServerResponse, never, never>;
|