@aigne/aos 0.2.0-beta
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/CHANGELOG.md +49 -0
- package/LICENSE.md +26 -0
- package/dist/agent-dsl.cjs +116 -0
- package/dist/agent-dsl.d.cts +31 -0
- package/dist/agent-dsl.d.cts.map +1 -0
- package/dist/agent-dsl.d.mts +31 -0
- package/dist/agent-dsl.d.mts.map +1 -0
- package/dist/agent-dsl.mjs +115 -0
- package/dist/agent-dsl.mjs.map +1 -0
- package/dist/arc-compat.cjs +125 -0
- package/dist/arc-compat.d.cts +17 -0
- package/dist/arc-compat.d.cts.map +1 -0
- package/dist/arc-compat.d.mts +17 -0
- package/dist/arc-compat.d.mts.map +1 -0
- package/dist/arc-compat.mjs +123 -0
- package/dist/arc-compat.mjs.map +1 -0
- package/dist/auto-surface/compiler.cjs +36 -0
- package/dist/auto-surface/compiler.d.cts +7 -0
- package/dist/auto-surface/compiler.d.cts.map +1 -0
- package/dist/auto-surface/compiler.d.mts +7 -0
- package/dist/auto-surface/compiler.d.mts.map +1 -0
- package/dist/auto-surface/compiler.mjs +37 -0
- package/dist/auto-surface/compiler.mjs.map +1 -0
- package/dist/auto-surface/definition-dsl.cjs +333 -0
- package/dist/auto-surface/definition-dsl.d.cts +41 -0
- package/dist/auto-surface/definition-dsl.d.cts.map +1 -0
- package/dist/auto-surface/definition-dsl.d.mts +41 -0
- package/dist/auto-surface/definition-dsl.d.mts.map +1 -0
- package/dist/auto-surface/definition-dsl.mjs +332 -0
- package/dist/auto-surface/definition-dsl.mjs.map +1 -0
- package/dist/auto-surface/fragments.cjs +177 -0
- package/dist/auto-surface/fragments.d.cts +23 -0
- package/dist/auto-surface/fragments.d.cts.map +1 -0
- package/dist/auto-surface/fragments.d.mts +23 -0
- package/dist/auto-surface/fragments.d.mts.map +1 -0
- package/dist/auto-surface/fragments.mjs +175 -0
- package/dist/auto-surface/fragments.mjs.map +1 -0
- package/dist/auto-surface/index.d.mts +9 -0
- package/dist/auto-surface/layering.cjs +43 -0
- package/dist/auto-surface/layering.d.cts +7 -0
- package/dist/auto-surface/layering.d.cts.map +1 -0
- package/dist/auto-surface/layering.d.mts +7 -0
- package/dist/auto-surface/layering.d.mts.map +1 -0
- package/dist/auto-surface/layering.mjs +43 -0
- package/dist/auto-surface/layering.mjs.map +1 -0
- package/dist/auto-surface/projection.cjs +11 -0
- package/dist/auto-surface/projection.d.cts +11 -0
- package/dist/auto-surface/projection.d.cts.map +1 -0
- package/dist/auto-surface/projection.d.mts +11 -0
- package/dist/auto-surface/projection.d.mts.map +1 -0
- package/dist/auto-surface/projection.mjs +12 -0
- package/dist/auto-surface/projection.mjs.map +1 -0
- package/dist/auto-surface/projectors/settings-shell.cjs +114 -0
- package/dist/auto-surface/projectors/settings-shell.d.cts +10 -0
- package/dist/auto-surface/projectors/settings-shell.d.cts.map +1 -0
- package/dist/auto-surface/projectors/settings-shell.d.mts +10 -0
- package/dist/auto-surface/projectors/settings-shell.d.mts.map +1 -0
- package/dist/auto-surface/projectors/settings-shell.mjs +114 -0
- package/dist/auto-surface/projectors/settings-shell.mjs.map +1 -0
- package/dist/auto-surface/scenario.cjs +38 -0
- package/dist/auto-surface/scenario.d.cts +31 -0
- package/dist/auto-surface/scenario.d.cts.map +1 -0
- package/dist/auto-surface/scenario.d.mts +31 -0
- package/dist/auto-surface/scenario.d.mts.map +1 -0
- package/dist/auto-surface/scenario.mjs +37 -0
- package/dist/auto-surface/scenario.mjs.map +1 -0
- package/dist/auto-surface/types.cjs +9 -0
- package/dist/auto-surface/types.d.cts +153 -0
- package/dist/auto-surface/types.d.cts.map +1 -0
- package/dist/auto-surface/types.d.mts +153 -0
- package/dist/auto-surface/types.d.mts.map +1 -0
- package/dist/auto-surface/types.mjs +9 -0
- package/dist/auto-surface/types.mjs.map +1 -0
- package/dist/auto-surface/value-dsl.cjs +80 -0
- package/dist/auto-surface/value-dsl.d.cts +24 -0
- package/dist/auto-surface/value-dsl.d.cts.map +1 -0
- package/dist/auto-surface/value-dsl.d.mts +24 -0
- package/dist/auto-surface/value-dsl.d.mts.map +1 -0
- package/dist/auto-surface/value-dsl.mjs +79 -0
- package/dist/auto-surface/value-dsl.mjs.map +1 -0
- package/dist/blocklet/activation.cjs +94 -0
- package/dist/blocklet/activation.d.cts +30 -0
- package/dist/blocklet/activation.d.cts.map +1 -0
- package/dist/blocklet/activation.d.mts +30 -0
- package/dist/blocklet/activation.d.mts.map +1 -0
- package/dist/blocklet/activation.mjs +94 -0
- package/dist/blocklet/activation.mjs.map +1 -0
- package/dist/blocklet/did-space-registry.cjs +282 -0
- package/dist/blocklet/did-space-registry.d.cts +82 -0
- package/dist/blocklet/did-space-registry.d.cts.map +1 -0
- package/dist/blocklet/did-space-registry.d.mts +82 -0
- package/dist/blocklet/did-space-registry.d.mts.map +1 -0
- package/dist/blocklet/did-space-registry.mjs +281 -0
- package/dist/blocklet/did-space-registry.mjs.map +1 -0
- package/dist/blocklet/handlers.cjs +66 -0
- package/dist/blocklet/handlers.d.cts +16 -0
- package/dist/blocklet/handlers.d.cts.map +1 -0
- package/dist/blocklet/handlers.d.mts +16 -0
- package/dist/blocklet/handlers.d.mts.map +1 -0
- package/dist/blocklet/handlers.mjs +65 -0
- package/dist/blocklet/handlers.mjs.map +1 -0
- package/dist/blocklet/index.d.mts +7 -0
- package/dist/blocklet/manifest.d.cts +2 -0
- package/dist/blocklet/manifest.d.mts +2 -0
- package/dist/blocklet/manifest.mjs +3 -0
- package/dist/blocklet/registry.cjs +447 -0
- package/dist/blocklet/registry.d.cts +197 -0
- package/dist/blocklet/registry.d.cts.map +1 -0
- package/dist/blocklet/registry.d.mts +197 -0
- package/dist/blocklet/registry.d.mts.map +1 -0
- package/dist/blocklet/registry.mjs +441 -0
- package/dist/blocklet/registry.mjs.map +1 -0
- package/dist/blocklet/static-render.cjs +183 -0
- package/dist/blocklet/static-render.d.cts +55 -0
- package/dist/blocklet/static-render.d.cts.map +1 -0
- package/dist/blocklet/static-render.d.mts +55 -0
- package/dist/blocklet/static-render.d.mts.map +1 -0
- package/dist/blocklet/static-render.mjs +181 -0
- package/dist/blocklet/static-render.mjs.map +1 -0
- package/dist/blocklet/types.d.cts +70 -0
- package/dist/blocklet/types.d.cts.map +1 -0
- package/dist/blocklet/types.d.mts +70 -0
- package/dist/blocklet/types.d.mts.map +1 -0
- package/dist/devices/chain.cjs +127 -0
- package/dist/devices/chain.d.cts +48 -0
- package/dist/devices/chain.d.cts.map +1 -0
- package/dist/devices/chain.d.mts +48 -0
- package/dist/devices/chain.d.mts.map +1 -0
- package/dist/devices/chain.mjs +125 -0
- package/dist/devices/chain.mjs.map +1 -0
- package/dist/dsl-shared.cjs +290 -0
- package/dist/dsl-shared.d.cts +54 -0
- package/dist/dsl-shared.d.cts.map +1 -0
- package/dist/dsl-shared.d.mts +54 -0
- package/dist/dsl-shared.d.mts.map +1 -0
- package/dist/dsl-shared.mjs +287 -0
- package/dist/dsl-shared.mjs.map +1 -0
- package/dist/http/afs-mcp.cjs +85 -0
- package/dist/http/afs-mcp.d.cts +14 -0
- package/dist/http/afs-mcp.d.cts.map +1 -0
- package/dist/http/afs-mcp.d.mts +14 -0
- package/dist/http/afs-mcp.d.mts.map +1 -0
- package/dist/http/afs-mcp.mjs +86 -0
- package/dist/http/afs-mcp.mjs.map +1 -0
- package/dist/http/afs-raw.cjs +264 -0
- package/dist/http/afs-raw.d.cts +31 -0
- package/dist/http/afs-raw.d.cts.map +1 -0
- package/dist/http/afs-raw.d.mts +31 -0
- package/dist/http/afs-raw.d.mts.map +1 -0
- package/dist/http/afs-raw.mjs +264 -0
- package/dist/http/afs-raw.mjs.map +1 -0
- package/dist/http/afs-rest.cjs +30 -0
- package/dist/http/afs-rest.d.cts +21 -0
- package/dist/http/afs-rest.d.cts.map +1 -0
- package/dist/http/afs-rest.d.mts +21 -0
- package/dist/http/afs-rest.d.mts.map +1 -0
- package/dist/http/afs-rest.mjs +31 -0
- package/dist/http/afs-rest.mjs.map +1 -0
- package/dist/http/afs-rpc-wire.cjs +271 -0
- package/dist/http/afs-rpc-wire.d.cts +195 -0
- package/dist/http/afs-rpc-wire.d.cts.map +1 -0
- package/dist/http/afs-rpc-wire.d.mts +195 -0
- package/dist/http/afs-rpc-wire.d.mts.map +1 -0
- package/dist/http/afs-rpc-wire.mjs +262 -0
- package/dist/http/afs-rpc-wire.mjs.map +1 -0
- package/dist/http/afs-rpc.cjs +729 -0
- package/dist/http/afs-rpc.d.cts +103 -0
- package/dist/http/afs-rpc.d.cts.map +1 -0
- package/dist/http/afs-rpc.d.mts +103 -0
- package/dist/http/afs-rpc.d.mts.map +1 -0
- package/dist/http/afs-rpc.mjs +729 -0
- package/dist/http/afs-rpc.mjs.map +1 -0
- package/dist/http/afs-upload.cjs +116 -0
- package/dist/http/afs-upload.d.cts +40 -0
- package/dist/http/afs-upload.d.cts.map +1 -0
- package/dist/http/afs-upload.d.mts +40 -0
- package/dist/http/afs-upload.d.mts.map +1 -0
- package/dist/http/afs-upload.mjs +116 -0
- package/dist/http/afs-upload.mjs.map +1 -0
- package/dist/http/aup-client.cjs +60 -0
- package/dist/http/aup-client.d.cts +22 -0
- package/dist/http/aup-client.d.cts.map +1 -0
- package/dist/http/aup-client.d.mts +22 -0
- package/dist/http/aup-client.d.mts.map +1 -0
- package/dist/http/aup-client.mjs +59 -0
- package/dist/http/aup-client.mjs.map +1 -0
- package/dist/http/aup-event.cjs +100 -0
- package/dist/http/aup-event.d.cts +38 -0
- package/dist/http/aup-event.d.cts.map +1 -0
- package/dist/http/aup-event.d.mts +38 -0
- package/dist/http/aup-event.d.mts.map +1 -0
- package/dist/http/aup-event.mjs +101 -0
- package/dist/http/aup-event.mjs.map +1 -0
- package/dist/http/auth-context.cjs +66 -0
- package/dist/http/auth-context.d.cts +64 -0
- package/dist/http/auth-context.d.cts.map +1 -0
- package/dist/http/auth-context.d.mts +64 -0
- package/dist/http/auth-context.d.mts.map +1 -0
- package/dist/http/auth-context.mjs +66 -0
- package/dist/http/auth-context.mjs.map +1 -0
- package/dist/http/csrf.cjs +50 -0
- package/dist/http/csrf.d.cts +8 -0
- package/dist/http/csrf.d.cts.map +1 -0
- package/dist/http/csrf.d.mts +8 -0
- package/dist/http/csrf.d.mts.map +1 -0
- package/dist/http/csrf.mjs +49 -0
- package/dist/http/csrf.mjs.map +1 -0
- package/dist/http/handlers.cjs +106 -0
- package/dist/http/handlers.d.cts +39 -0
- package/dist/http/handlers.d.cts.map +1 -0
- package/dist/http/handlers.d.mts +39 -0
- package/dist/http/handlers.d.mts.map +1 -0
- package/dist/http/handlers.mjs +104 -0
- package/dist/http/handlers.mjs.map +1 -0
- package/dist/http/index.d.mts +1 -0
- package/dist/http/ingest-facade.cjs +315 -0
- package/dist/http/ingest-facade.mjs +314 -0
- package/dist/http/ingest-facade.mjs.map +1 -0
- package/dist/http/raw-url.cjs +136 -0
- package/dist/http/raw-url.d.cts +54 -0
- package/dist/http/raw-url.d.cts.map +1 -0
- package/dist/http/raw-url.d.mts +54 -0
- package/dist/http/raw-url.d.mts.map +1 -0
- package/dist/http/raw-url.mjs +136 -0
- package/dist/http/raw-url.mjs.map +1 -0
- package/dist/http/request-context.cjs +178 -0
- package/dist/http/request-context.d.cts +76 -0
- package/dist/http/request-context.d.cts.map +1 -0
- package/dist/http/request-context.d.mts +76 -0
- package/dist/http/request-context.d.mts.map +1 -0
- package/dist/http/request-context.mjs +179 -0
- package/dist/http/request-context.mjs.map +1 -0
- package/dist/index.cjs +197 -0
- package/dist/index.d.cts +63 -0
- package/dist/index.d.mts +68 -0
- package/dist/index.mjs +61 -0
- package/dist/mcp/index.cjs +9 -0
- package/dist/mcp/index.d.cts +5 -0
- package/dist/mcp/index.d.mts +5 -0
- package/dist/mcp/index.mjs +6 -0
- package/dist/mcp/prompts.cjs +17 -0
- package/dist/mcp/prompts.d.cts +8 -0
- package/dist/mcp/prompts.d.cts.map +1 -0
- package/dist/mcp/prompts.d.mts +8 -0
- package/dist/mcp/prompts.d.mts.map +1 -0
- package/dist/mcp/prompts.mjs +17 -0
- package/dist/mcp/prompts.mjs.map +1 -0
- package/dist/mcp/resources.cjs +22 -0
- package/dist/mcp/resources.d.cts +8 -0
- package/dist/mcp/resources.d.cts.map +1 -0
- package/dist/mcp/resources.d.mts +8 -0
- package/dist/mcp/resources.d.mts.map +1 -0
- package/dist/mcp/resources.mjs +22 -0
- package/dist/mcp/resources.mjs.map +1 -0
- package/dist/mcp/server.cjs +51 -0
- package/dist/mcp/server.d.cts +20 -0
- package/dist/mcp/server.d.cts.map +1 -0
- package/dist/mcp/server.d.mts +20 -0
- package/dist/mcp/server.d.mts.map +1 -0
- package/dist/mcp/server.mjs +52 -0
- package/dist/mcp/server.mjs.map +1 -0
- package/dist/mcp/tools.cjs +218 -0
- package/dist/mcp/tools.d.cts +8 -0
- package/dist/mcp/tools.d.cts.map +1 -0
- package/dist/mcp/tools.d.mts +8 -0
- package/dist/mcp/tools.d.mts.map +1 -0
- package/dist/mcp/tools.mjs +219 -0
- package/dist/mcp/tools.mjs.map +1 -0
- package/dist/mcp/utils.cjs +75 -0
- package/dist/mcp/utils.mjs +69 -0
- package/dist/mcp/utils.mjs.map +1 -0
- package/dist/mount/index.cjs +4 -0
- package/dist/mount/index.d.cts +3 -0
- package/dist/mount/index.d.mts +3 -0
- package/dist/mount/index.mjs +3 -0
- package/dist/mount/materializer.cjs +167 -0
- package/dist/mount/materializer.d.cts +97 -0
- package/dist/mount/materializer.d.cts.map +1 -0
- package/dist/mount/materializer.d.mts +97 -0
- package/dist/mount/materializer.d.mts.map +1 -0
- package/dist/mount/materializer.mjs +167 -0
- package/dist/mount/materializer.mjs.map +1 -0
- package/dist/mount/types.d.cts +90 -0
- package/dist/mount/types.d.cts.map +1 -0
- package/dist/mount/types.d.mts +90 -0
- package/dist/mount/types.d.mts.map +1 -0
- package/dist/mount-config.cjs +61 -0
- package/dist/mount-config.d.cts +19 -0
- package/dist/mount-config.d.cts.map +1 -0
- package/dist/mount-config.d.mts +19 -0
- package/dist/mount-config.d.mts.map +1 -0
- package/dist/mount-config.mjs +61 -0
- package/dist/mount-config.mjs.map +1 -0
- package/dist/projectors/aup-projector.cjs +190 -0
- package/dist/projectors/aup-projector.d.cts +59 -0
- package/dist/projectors/aup-projector.d.cts.map +1 -0
- package/dist/projectors/aup-projector.d.mts +59 -0
- package/dist/projectors/aup-projector.d.mts.map +1 -0
- package/dist/projectors/aup-projector.mjs +188 -0
- package/dist/projectors/aup-projector.mjs.map +1 -0
- package/dist/projectors/index.cjs +6 -0
- package/dist/projectors/index.d.cts +2 -0
- package/dist/projectors/index.d.mts +2 -0
- package/dist/projectors/index.mjs +3 -0
- package/dist/scaffold/afs.cjs +195 -0
- package/dist/scaffold/afs.d.cts +16 -0
- package/dist/scaffold/afs.d.cts.map +1 -0
- package/dist/scaffold/afs.d.mts +16 -0
- package/dist/scaffold/afs.d.mts.map +1 -0
- package/dist/scaffold/afs.mjs +195 -0
- package/dist/scaffold/afs.mjs.map +1 -0
- package/dist/scaffold/composition.cjs +92 -0
- package/dist/scaffold/composition.d.cts +10 -0
- package/dist/scaffold/composition.d.cts.map +1 -0
- package/dist/scaffold/composition.d.mts +10 -0
- package/dist/scaffold/composition.d.mts.map +1 -0
- package/dist/scaffold/composition.mjs +92 -0
- package/dist/scaffold/composition.mjs.map +1 -0
- package/dist/scaffold/dsl-error.cjs +21 -0
- package/dist/scaffold/dsl-error.d.cts +11 -0
- package/dist/scaffold/dsl-error.d.cts.map +1 -0
- package/dist/scaffold/dsl-error.d.mts +11 -0
- package/dist/scaffold/dsl-error.d.mts.map +1 -0
- package/dist/scaffold/dsl-error.mjs +20 -0
- package/dist/scaffold/dsl-error.mjs.map +1 -0
- package/dist/scaffold/index.d.mts +12 -0
- package/dist/scaffold/manifest-dsl.cjs +188 -0
- package/dist/scaffold/manifest-dsl.d.cts +8 -0
- package/dist/scaffold/manifest-dsl.d.cts.map +1 -0
- package/dist/scaffold/manifest-dsl.d.mts +8 -0
- package/dist/scaffold/manifest-dsl.d.mts.map +1 -0
- package/dist/scaffold/manifest-dsl.mjs +188 -0
- package/dist/scaffold/manifest-dsl.mjs.map +1 -0
- package/dist/scaffold/module-dsl.cjs +284 -0
- package/dist/scaffold/module-dsl.d.cts +8 -0
- package/dist/scaffold/module-dsl.d.cts.map +1 -0
- package/dist/scaffold/module-dsl.d.mts +8 -0
- package/dist/scaffold/module-dsl.d.mts.map +1 -0
- package/dist/scaffold/module-dsl.mjs +284 -0
- package/dist/scaffold/module-dsl.mjs.map +1 -0
- package/dist/scaffold/resolver.cjs +156 -0
- package/dist/scaffold/resolver.d.cts +7 -0
- package/dist/scaffold/resolver.d.cts.map +1 -0
- package/dist/scaffold/resolver.d.mts +7 -0
- package/dist/scaffold/resolver.d.mts.map +1 -0
- package/dist/scaffold/resolver.mjs +156 -0
- package/dist/scaffold/resolver.mjs.map +1 -0
- package/dist/scaffold/runtime.cjs +24 -0
- package/dist/scaffold/runtime.d.cts +19 -0
- package/dist/scaffold/runtime.d.cts.map +1 -0
- package/dist/scaffold/runtime.d.mts +19 -0
- package/dist/scaffold/runtime.d.mts.map +1 -0
- package/dist/scaffold/runtime.mjs +25 -0
- package/dist/scaffold/runtime.mjs.map +1 -0
- package/dist/scaffold/shell-dsl.cjs +279 -0
- package/dist/scaffold/shell-dsl.d.cts +8 -0
- package/dist/scaffold/shell-dsl.d.cts.map +1 -0
- package/dist/scaffold/shell-dsl.d.mts +8 -0
- package/dist/scaffold/shell-dsl.d.mts.map +1 -0
- package/dist/scaffold/shell-dsl.mjs +279 -0
- package/dist/scaffold/shell-dsl.mjs.map +1 -0
- package/dist/scaffold/surface-dsl.cjs +182 -0
- package/dist/scaffold/surface-dsl.d.cts +8 -0
- package/dist/scaffold/surface-dsl.d.cts.map +1 -0
- package/dist/scaffold/surface-dsl.d.mts +8 -0
- package/dist/scaffold/surface-dsl.d.mts.map +1 -0
- package/dist/scaffold/surface-dsl.mjs +182 -0
- package/dist/scaffold/surface-dsl.mjs.map +1 -0
- package/dist/scaffold/surfaces.cjs +84 -0
- package/dist/scaffold/surfaces.d.cts +23 -0
- package/dist/scaffold/surfaces.d.cts.map +1 -0
- package/dist/scaffold/surfaces.d.mts +24 -0
- package/dist/scaffold/surfaces.d.mts.map +1 -0
- package/dist/scaffold/surfaces.mjs +84 -0
- package/dist/scaffold/surfaces.mjs.map +1 -0
- package/dist/scaffold/types.d.cts +264 -0
- package/dist/scaffold/types.d.cts.map +1 -0
- package/dist/scaffold/types.d.mts +265 -0
- package/dist/scaffold/types.d.mts.map +1 -0
- package/dist/scaffold/workspace-dsl.cjs +339 -0
- package/dist/scaffold/workspace-dsl.d.cts +49 -0
- package/dist/scaffold/workspace-dsl.d.cts.map +1 -0
- package/dist/scaffold/workspace-dsl.d.mts +49 -0
- package/dist/scaffold/workspace-dsl.d.mts.map +1 -0
- package/dist/scaffold/workspace-dsl.mjs +337 -0
- package/dist/scaffold/workspace-dsl.mjs.map +1 -0
- package/dist/scope/index.d.mts +3 -0
- package/dist/scope/read-blocklet-scope.cjs +29 -0
- package/dist/scope/read-blocklet-scope.d.cts +8 -0
- package/dist/scope/read-blocklet-scope.d.cts.map +1 -0
- package/dist/scope/read-blocklet-scope.d.mts +8 -0
- package/dist/scope/read-blocklet-scope.d.mts.map +1 -0
- package/dist/scope/read-blocklet-scope.mjs +30 -0
- package/dist/scope/read-blocklet-scope.mjs.map +1 -0
- package/dist/scope/resolve-scoped-afs.cjs +87 -0
- package/dist/scope/resolve-scoped-afs.d.cts +7 -0
- package/dist/scope/resolve-scoped-afs.d.cts.map +1 -0
- package/dist/scope/resolve-scoped-afs.d.mts +7 -0
- package/dist/scope/resolve-scoped-afs.d.mts.map +1 -0
- package/dist/scope/resolve-scoped-afs.mjs +88 -0
- package/dist/scope/resolve-scoped-afs.mjs.map +1 -0
- package/dist/scope/types.d.cts +25 -0
- package/dist/scope/types.d.cts.map +1 -0
- package/dist/scope/types.d.mts +25 -0
- package/dist/scope/types.d.mts.map +1 -0
- package/dist/session/backends.cjs +90 -0
- package/dist/session/backends.d.cts +35 -0
- package/dist/session/backends.d.cts.map +1 -0
- package/dist/session/backends.d.mts +35 -0
- package/dist/session/backends.d.mts.map +1 -0
- package/dist/session/backends.mjs +89 -0
- package/dist/session/backends.mjs.map +1 -0
- package/dist/session/replication-resolver.cjs +323 -0
- package/dist/session/replication-resolver.d.cts +71 -0
- package/dist/session/replication-resolver.d.cts.map +1 -0
- package/dist/session/replication-resolver.d.mts +71 -0
- package/dist/session/replication-resolver.d.mts.map +1 -0
- package/dist/session/replication-resolver.mjs +323 -0
- package/dist/session/replication-resolver.mjs.map +1 -0
- package/dist/session/role-level.cjs +36 -0
- package/dist/session/role-level.d.cts +24 -0
- package/dist/session/role-level.d.cts.map +1 -0
- package/dist/session/role-level.d.mts +24 -0
- package/dist/session/role-level.d.mts.map +1 -0
- package/dist/session/role-level.mjs +35 -0
- package/dist/session/role-level.mjs.map +1 -0
- package/dist/session/session-dir-providers.cjs +254 -0
- package/dist/session/session-dir-providers.d.cts +32 -0
- package/dist/session/session-dir-providers.d.cts.map +1 -0
- package/dist/session/session-dir-providers.d.mts +32 -0
- package/dist/session/session-dir-providers.d.mts.map +1 -0
- package/dist/session/session-dir-providers.mjs +252 -0
- package/dist/session/session-dir-providers.mjs.map +1 -0
- package/dist/session/session-id.cjs +20 -0
- package/dist/session/session-id.d.cts +15 -0
- package/dist/session/session-id.d.cts.map +1 -0
- package/dist/session/session-id.d.mts +15 -0
- package/dist/session/session-id.d.mts.map +1 -0
- package/dist/session/session-id.mjs +20 -0
- package/dist/session/session-id.mjs.map +1 -0
- package/dist/session/session-user-afs.cjs +899 -0
- package/dist/session/session-user-afs.d.cts +296 -0
- package/dist/session/session-user-afs.d.cts.map +1 -0
- package/dist/session/session-user-afs.d.mts +296 -0
- package/dist/session/session-user-afs.d.mts.map +1 -0
- package/dist/session/session-user-afs.mjs +896 -0
- package/dist/session/session-user-afs.mjs.map +1 -0
- package/dist/session/settings-cascade.cjs +69 -0
- package/dist/session/settings-cascade.d.cts +81 -0
- package/dist/session/settings-cascade.d.cts.map +1 -0
- package/dist/session/settings-cascade.d.mts +81 -0
- package/dist/session/settings-cascade.d.mts.map +1 -0
- package/dist/session/settings-cascade.mjs +69 -0
- package/dist/session/settings-cascade.mjs.map +1 -0
- package/dist/session/settings-resolver.cjs +770 -0
- package/dist/session/settings-resolver.d.cts +177 -0
- package/dist/session/settings-resolver.d.cts.map +1 -0
- package/dist/session/settings-resolver.d.mts +177 -0
- package/dist/session/settings-resolver.d.mts.map +1 -0
- package/dist/session/settings-resolver.mjs +771 -0
- package/dist/session/settings-resolver.mjs.map +1 -0
- package/dist/session/settings-schema-store.cjs +0 -0
- package/dist/session/settings-schema-store.d.cts +72 -0
- package/dist/session/settings-schema-store.d.cts.map +1 -0
- package/dist/session/settings-schema-store.d.mts +72 -0
- package/dist/session/settings-schema-store.d.mts.map +1 -0
- package/dist/session/settings-schema-store.mjs +0 -0
- package/dist/session/settings-schema-store.mjs.map +1 -0
- package/dist/system-mounts/index.cjs +14 -0
- package/dist/system-mounts/index.d.cts +6 -0
- package/dist/system-mounts/index.d.mts +6 -0
- package/dist/system-mounts/index.mjs +6 -0
- package/dist/system-mounts/install.cjs +101 -0
- package/dist/system-mounts/install.d.cts +36 -0
- package/dist/system-mounts/install.d.cts.map +1 -0
- package/dist/system-mounts/install.d.mts +37 -0
- package/dist/system-mounts/install.d.mts.map +1 -0
- package/dist/system-mounts/install.mjs +102 -0
- package/dist/system-mounts/install.mjs.map +1 -0
- package/dist/system-mounts/installers.cjs +247 -0
- package/dist/system-mounts/installers.d.cts +13 -0
- package/dist/system-mounts/installers.d.cts.map +1 -0
- package/dist/system-mounts/installers.d.mts +14 -0
- package/dist/system-mounts/installers.d.mts.map +1 -0
- package/dist/system-mounts/installers.mjs +244 -0
- package/dist/system-mounts/installers.mjs.map +1 -0
- package/dist/system-mounts/lists.cjs +122 -0
- package/dist/system-mounts/lists.d.cts +34 -0
- package/dist/system-mounts/lists.d.cts.map +1 -0
- package/dist/system-mounts/lists.d.mts +34 -0
- package/dist/system-mounts/lists.d.mts.map +1 -0
- package/dist/system-mounts/lists.mjs +122 -0
- package/dist/system-mounts/lists.mjs.map +1 -0
- package/dist/system-mounts/types.d.cts +124 -0
- package/dist/system-mounts/types.d.cts.map +1 -0
- package/dist/system-mounts/types.d.mts +125 -0
- package/dist/system-mounts/types.d.mts.map +1 -0
- package/dist/system-mounts/validate.cjs +56 -0
- package/dist/system-mounts/validate.d.cts +34 -0
- package/dist/system-mounts/validate.d.cts.map +1 -0
- package/dist/system-mounts/validate.d.mts +34 -0
- package/dist/system-mounts/validate.d.mts.map +1 -0
- package/dist/system-mounts/validate.mjs +56 -0
- package/dist/system-mounts/validate.mjs.map +1 -0
- package/dist/terminal-llm.cjs +90 -0
- package/dist/terminal-llm.d.cts +50 -0
- package/dist/terminal-llm.d.cts.map +1 -0
- package/dist/terminal-llm.d.mts +50 -0
- package/dist/terminal-llm.d.mts.map +1 -0
- package/dist/terminal-llm.mjs +90 -0
- package/dist/terminal-llm.mjs.map +1 -0
- package/dist/terminal-repl.cjs +371 -0
- package/dist/terminal-repl.d.cts +69 -0
- package/dist/terminal-repl.d.cts.map +1 -0
- package/dist/terminal-repl.d.mts +69 -0
- package/dist/terminal-repl.d.mts.map +1 -0
- package/dist/terminal-repl.mjs +370 -0
- package/dist/terminal-repl.mjs.map +1 -0
- package/dist/transport/idle-timer.cjs +136 -0
- package/dist/transport/idle-timer.d.cts +92 -0
- package/dist/transport/idle-timer.d.cts.map +1 -0
- package/dist/transport/idle-timer.d.mts +92 -0
- package/dist/transport/idle-timer.d.mts.map +1 -0
- package/dist/transport/idle-timer.mjs +132 -0
- package/dist/transport/idle-timer.mjs.map +1 -0
- package/dist/web-component-dsl.cjs +153 -0
- package/dist/web-component-dsl.d.cts +27 -0
- package/dist/web-component-dsl.d.cts.map +1 -0
- package/dist/web-component-dsl.d.mts +27 -0
- package/dist/web-component-dsl.d.mts.map +1 -0
- package/dist/web-component-dsl.mjs +152 -0
- package/dist/web-component-dsl.mjs.map +1 -0
- package/package.json +81 -0
|
@@ -0,0 +1,770 @@
|
|
|
1
|
+
const require_settings_cascade = require('./settings-cascade.cjs');
|
|
2
|
+
let ufo = require("ufo");
|
|
3
|
+
let _aigne_afs = require("@aigne/afs");
|
|
4
|
+
|
|
5
|
+
//#region src/session/settings-resolver.ts
|
|
6
|
+
const log = (0, _aigne_afs.makeNsLog)("aos");
|
|
7
|
+
/** Root of the instance-layer schema tree on the Small World base. */
|
|
8
|
+
const INSTANCE_SETTINGS_ROOT = "/instance/settings";
|
|
9
|
+
/** Root of the per-user override store on the caller's `/user` backing. */
|
|
10
|
+
const USER_SETTINGS_ROOT = "/settings";
|
|
11
|
+
/** Keys that must never be copied out of a parsed wrapper (prototype-pollution + control fields). */
|
|
12
|
+
const DANGEROUS_KEYS = new Set([
|
|
13
|
+
"__proto__",
|
|
14
|
+
"constructor",
|
|
15
|
+
"prototype"
|
|
16
|
+
]);
|
|
17
|
+
const CONTROL_KEYS = new Set([
|
|
18
|
+
"value",
|
|
19
|
+
"scope",
|
|
20
|
+
"source",
|
|
21
|
+
"overridden",
|
|
22
|
+
"inheritedValue",
|
|
23
|
+
"visible",
|
|
24
|
+
"editable"
|
|
25
|
+
]);
|
|
26
|
+
/** Strip dangerous keys from a parsed object (prototype pollution defense). */
|
|
27
|
+
function sanitizeObject(obj) {
|
|
28
|
+
const out = {};
|
|
29
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
30
|
+
if (DANGEROUS_KEYS.has(k)) continue;
|
|
31
|
+
out[k] = v;
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Parse an instance-layer wrapper. Defensive: malformed JSON degrades to a
|
|
37
|
+
* bare `{ value: <raw> }` (scope absent → instance) rather than throwing — a
|
|
38
|
+
* broken file must not take down the whole settings page.
|
|
39
|
+
*/
|
|
40
|
+
function parseWrapper(raw) {
|
|
41
|
+
let obj = raw;
|
|
42
|
+
if (typeof raw === "string") try {
|
|
43
|
+
obj = JSON.parse(raw);
|
|
44
|
+
} catch {
|
|
45
|
+
return { value: raw };
|
|
46
|
+
}
|
|
47
|
+
if (obj === null || typeof obj !== "object") return { value: obj };
|
|
48
|
+
return sanitizeObject(obj);
|
|
49
|
+
}
|
|
50
|
+
function sanitizeScope(s) {
|
|
51
|
+
return s === "user" || s === "shared" ? s : "instance";
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Coerce a bare user-override value (read back from the per-user fs backing,
|
|
55
|
+
* which stringifies everything) to the type of the instance default. The schema
|
|
56
|
+
* default is the type oracle: a boolean field's "false" → false, a number
|
|
57
|
+
* field's "7" → 7. Strings and already-correct types pass through; an
|
|
58
|
+
* un-coercible value is returned as-is rather than fabricating a wrong type.
|
|
59
|
+
*/
|
|
60
|
+
function coerceToSchemaType(raw, schemaValue) {
|
|
61
|
+
if (typeof schemaValue === "boolean") {
|
|
62
|
+
if (raw === true || raw === false) return raw;
|
|
63
|
+
if (raw === "true") return true;
|
|
64
|
+
if (raw === "false") return false;
|
|
65
|
+
return raw;
|
|
66
|
+
}
|
|
67
|
+
if (typeof schemaValue === "number") {
|
|
68
|
+
if (typeof raw === "number") return raw;
|
|
69
|
+
if (typeof raw === "string" && raw.trim() !== "") {
|
|
70
|
+
const n = Number(raw);
|
|
71
|
+
if (Number.isFinite(n)) return n;
|
|
72
|
+
}
|
|
73
|
+
return raw;
|
|
74
|
+
}
|
|
75
|
+
return raw;
|
|
76
|
+
}
|
|
77
|
+
function isNotFound(e) {
|
|
78
|
+
return e instanceof _aigne_afs.AFSNotFoundError || typeof e === "object" && e !== null && e.code === "AFS_NOT_FOUND";
|
|
79
|
+
}
|
|
80
|
+
function lastSegment(path) {
|
|
81
|
+
return path.split("/").filter(Boolean).pop() ?? "";
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Split a resolver-relative path into the wrapper file part and an optional
|
|
85
|
+
* sub-key. Settings fields are always `<name>.json`; anything before the first
|
|
86
|
+
* `.json` segment is the wrapper, anything after is a key inside it
|
|
87
|
+
* (`value`, `label`, …). No `.json` segment → a structure directory.
|
|
88
|
+
*
|
|
89
|
+
* Segment-based, not raw string slicing (CLAUDE.md path rules).
|
|
90
|
+
*/
|
|
91
|
+
function splitWrapper(sub) {
|
|
92
|
+
const segs = sub.split("/").filter(Boolean);
|
|
93
|
+
const idx = segs.findIndex((s) => s.endsWith(".json"));
|
|
94
|
+
if (idx === -1) return { wrapperSub: null };
|
|
95
|
+
const wrapperSub = (0, ufo.joinURL)("/", ...segs.slice(0, idx + 1));
|
|
96
|
+
const rest = segs.slice(idx + 1);
|
|
97
|
+
return {
|
|
98
|
+
wrapperSub,
|
|
99
|
+
subKey: rest.length ? rest.join("/") : void 0
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Map a resolver-relative subscribe path to the two underlying layer paths a
|
|
104
|
+
* propBind subscription must watch (§3.6 dual-layer subscribe). Pure — exported
|
|
105
|
+
* for unit testing (T4.1).
|
|
106
|
+
*
|
|
107
|
+
* A field bind like `/cascade/theme.json/value` maps to:
|
|
108
|
+
* - instancePath: `/instance/settings/cascade/theme.json` (base WRAPPER FILE —
|
|
109
|
+
* instance-layer writes land on the whole wrapper, never the `/value`
|
|
110
|
+
* sub-path, so we must watch the file, not the sub-key)
|
|
111
|
+
* - userPath: `/settings/cascade/theme.json` (user bare-value file)
|
|
112
|
+
*
|
|
113
|
+
* A directory / path-less subscribe (`/cascade`, `/`) has no `.json` segment, so
|
|
114
|
+
* `wrapperSub` is null and we watch the directory itself on both layers. The
|
|
115
|
+
* re-emit path is then derived per-event from the underlying path (see
|
|
116
|
+
* `subscribe()`), not from a fixed field path.
|
|
117
|
+
*/
|
|
118
|
+
function mapSubscribePaths(relPath) {
|
|
119
|
+
const { wrapperSub } = splitWrapper(relPath);
|
|
120
|
+
const tail = wrapperSub ?? relPath;
|
|
121
|
+
return {
|
|
122
|
+
instancePath: (0, ufo.joinURL)(INSTANCE_SETTINGS_ROOT, tail),
|
|
123
|
+
userPath: (0, ufo.joinURL)(USER_SETTINGS_ROOT, tail),
|
|
124
|
+
isField: wrapperSub !== null
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* On-disk key holding EXPLICIT admin schema-text overrides in a converged
|
|
129
|
+
* (override-only) instance row: `{ value?, overrides?: { label: "...", … } }`.
|
|
130
|
+
* The nesting is the legacy/explicit discriminator (settings-layering §2.D):
|
|
131
|
+
* a LEGACY full wrapper carries its schema keys FLAT and is ignored on read
|
|
132
|
+
* (package schema wins — legacy-no-shadow); keys under `overrides` were
|
|
133
|
+
* deliberately written by an admin through `write()` and DO overlay the
|
|
134
|
+
* package schema.
|
|
135
|
+
*/
|
|
136
|
+
const OVERRIDES_KEY = "overrides";
|
|
137
|
+
var SettingsResolver = class {
|
|
138
|
+
name;
|
|
139
|
+
accessMode = "readwrite";
|
|
140
|
+
base;
|
|
141
|
+
userProvider;
|
|
142
|
+
role;
|
|
143
|
+
schema;
|
|
144
|
+
/** Memoized lazy ingest — at most one ensure() flight per session. */
|
|
145
|
+
schemaReady = null;
|
|
146
|
+
/**
|
|
147
|
+
* Outcome of the lazy ingest. `ready` = the package declares settings and
|
|
148
|
+
* the derived index is consumable (STORE MODE: existence/schema come from
|
|
149
|
+
* the package index). `empty` = package declares none; `failed` = store
|
|
150
|
+
* unavailable; `unwired` = no handle. All non-`ready` states resolve in
|
|
151
|
+
* LEGACY MODE (instance rows define existence + schema) — the pre-Phase-2
|
|
152
|
+
* behavior, so blocklets without package settings keep working.
|
|
153
|
+
*/
|
|
154
|
+
schemaState = "unwired";
|
|
155
|
+
/**
|
|
156
|
+
* Active render snapshots, insertion-ordered by `beginRender`. Ops resolve
|
|
157
|
+
* against the MOST RECENTLY begun snapshot (walks are sequential per
|
|
158
|
+
* render; concurrent renders each get their own immutable entry).
|
|
159
|
+
*/
|
|
160
|
+
snapshots = /* @__PURE__ */ new Map();
|
|
161
|
+
constructor(opts) {
|
|
162
|
+
this.base = opts.base;
|
|
163
|
+
this.userProvider = opts.userProvider;
|
|
164
|
+
this.role = opts.role;
|
|
165
|
+
this.schema = opts.schema ?? null;
|
|
166
|
+
this.name = `settings-resolver:${opts.sessionId}`;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Lazily materialize the package-schema scope (Phase 1c plumbing). Memoized
|
|
170
|
+
* per resolver (per session); the store's own single-flight + completion
|
|
171
|
+
* marker make cross-session work idempotent. BEST-EFFORT in Phase 1: a
|
|
172
|
+
* failed ingest logs and falls back to legacy resolution (Phase 2 will
|
|
173
|
+
* consume the scope for existence/schema and define the hard contract).
|
|
174
|
+
*/
|
|
175
|
+
ensureSchemaIngested() {
|
|
176
|
+
if (!this.schema) return Promise.resolve();
|
|
177
|
+
this.schemaReady ??= this.schema.ensure().then((result) => {
|
|
178
|
+
this.schemaState = result.fileCount > 0 ? "ready" : "empty";
|
|
179
|
+
}, (err) => {
|
|
180
|
+
this.schemaState = "failed";
|
|
181
|
+
log.warn(`[settings-resolver] schema ingest failed (legacy resolution continues): ${err instanceof Error ? err.message : err}`);
|
|
182
|
+
});
|
|
183
|
+
return this.schemaReady;
|
|
184
|
+
}
|
|
185
|
+
/** STORE MODE — existence/schema from the derived package index (§1.4). */
|
|
186
|
+
get storeMode() {
|
|
187
|
+
return this.schemaState === "ready";
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Begin a render-scoped snapshot. Called by the auto-surface walk entry
|
|
191
|
+
* point (via `SessionUserAFS.beginRender` proxy) with a fresh `renderId`
|
|
192
|
+
* before walking; the resolver builds the WHOLE settings snapshot once
|
|
193
|
+
* (1× derived-index listEntries + instance/user override list + sparse
|
|
194
|
+
* reads) and serves every list/read of that render from memory.
|
|
195
|
+
*
|
|
196
|
+
* Phase 0: contract only — no-op. Phase 2 implements the snapshot builder.
|
|
197
|
+
* Idempotency contract: repeated `beginRender` with the same renderId and
|
|
198
|
+
* `endRender` without a matching begin are both safe no-ops.
|
|
199
|
+
*/
|
|
200
|
+
async beginRender(renderId) {
|
|
201
|
+
if (this.snapshots.has(renderId)) return;
|
|
202
|
+
await this.ensureSchemaIngested();
|
|
203
|
+
const [schemas, instance, user] = await Promise.all([
|
|
204
|
+
this.storeMode ? this.loadSchemaMap() : Promise.resolve(null),
|
|
205
|
+
this.loadLayerRows(this.base, INSTANCE_SETTINGS_ROOT, true),
|
|
206
|
+
this.userProvider ? this.loadLayerRows(this.userProvider, USER_SETTINGS_ROOT, false) : Promise.resolve(/* @__PURE__ */ new Map())
|
|
207
|
+
]);
|
|
208
|
+
this.snapshots.set(renderId, {
|
|
209
|
+
schemas,
|
|
210
|
+
instance,
|
|
211
|
+
user
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
/** Discard the render snapshot for `renderId`. See {@link beginRender}. */
|
|
215
|
+
endRender(renderId) {
|
|
216
|
+
this.snapshots.delete(renderId);
|
|
217
|
+
}
|
|
218
|
+
/** The snapshot ops resolve against: the most recently begun, still active. */
|
|
219
|
+
get activeSnapshot() {
|
|
220
|
+
let last = null;
|
|
221
|
+
for (const snap of this.snapshots.values()) last = snap;
|
|
222
|
+
return last;
|
|
223
|
+
}
|
|
224
|
+
/** Bulk-read + parse the derived package schemas (1 store query). */
|
|
225
|
+
async loadSchemaMap() {
|
|
226
|
+
const map = /* @__PURE__ */ new Map();
|
|
227
|
+
if (!this.schema) return map;
|
|
228
|
+
try {
|
|
229
|
+
for (const { path, content } of await this.schema.listSchemas()) map.set((0, ufo.joinURL)("/", path), parseWrapper(content));
|
|
230
|
+
} catch (err) {
|
|
231
|
+
log.warn(`[settings-resolver] schema bulk read failed: ${err instanceof Error ? err.message : err}`);
|
|
232
|
+
}
|
|
233
|
+
return map;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Walk one override layer's tree and read every `.json` row. Sparse by
|
|
237
|
+
* design (converged rows: 0-5); legacy instances pay row-count reads ONCE
|
|
238
|
+
* per render — all in-process, replacing the per-field WS round-trips.
|
|
239
|
+
*/
|
|
240
|
+
async loadLayerRows(provider, root, parse) {
|
|
241
|
+
const map = /* @__PURE__ */ new Map();
|
|
242
|
+
if (!provider.list || !provider.read) return map;
|
|
243
|
+
const walk = async (dir) => {
|
|
244
|
+
let entries;
|
|
245
|
+
try {
|
|
246
|
+
entries = (await provider.list?.(dir))?.data ?? [];
|
|
247
|
+
} catch {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
for (const entry of entries) {
|
|
251
|
+
const name = entry.path.split("/").filter(Boolean).pop();
|
|
252
|
+
if (!name || name.startsWith(".")) continue;
|
|
253
|
+
const full = (0, ufo.joinURL)(dir, name);
|
|
254
|
+
if (name.endsWith(".json")) try {
|
|
255
|
+
const raw = (await provider.read?.(full))?.data?.content;
|
|
256
|
+
if (raw === void 0) continue;
|
|
257
|
+
map.set(full.slice(root.length), parse ? parseWrapper(raw) : raw);
|
|
258
|
+
} catch {}
|
|
259
|
+
else await walk(full);
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
await walk(root);
|
|
263
|
+
return map;
|
|
264
|
+
}
|
|
265
|
+
get isAuthed() {
|
|
266
|
+
return this.userProvider != null;
|
|
267
|
+
}
|
|
268
|
+
get isOwnerOrAdmin() {
|
|
269
|
+
return this.role === "owner" || this.role === "admin";
|
|
270
|
+
}
|
|
271
|
+
/** The physical layer this caller reads AND writes for the given scope. */
|
|
272
|
+
resolveWriteLayer(scope) {
|
|
273
|
+
if (scope === "instance") return "instance";
|
|
274
|
+
if (scope === "user") return "user";
|
|
275
|
+
return this.isOwnerOrAdmin ? "instance" : "user";
|
|
276
|
+
}
|
|
277
|
+
/** Presentation hint: should this caller's form render the field at all? */
|
|
278
|
+
visible(scope) {
|
|
279
|
+
if (scope === "instance") return this.isOwnerOrAdmin;
|
|
280
|
+
if (scope === "user") return this.isAuthed;
|
|
281
|
+
return true;
|
|
282
|
+
}
|
|
283
|
+
/** Capability hint + (P1) write-enforcement basis: may this caller edit it? */
|
|
284
|
+
editable(scope) {
|
|
285
|
+
if (scope === "instance") return this.isOwnerOrAdmin;
|
|
286
|
+
if (scope === "user") return this.isAuthed;
|
|
287
|
+
return this.isAuthed;
|
|
288
|
+
}
|
|
289
|
+
/** Normalize an incoming resolver-relative path; reject traversal outright. */
|
|
290
|
+
normalizeSub(path) {
|
|
291
|
+
const p = path.startsWith("/") ? path : `/${path}`;
|
|
292
|
+
if (p.split("/").some((seg) => seg === "..")) throw new _aigne_afs.AFSForbiddenError(path, "path traversal rejected");
|
|
293
|
+
return p;
|
|
294
|
+
}
|
|
295
|
+
/** Translate an underlying layer path back into the resolver-relative space. */
|
|
296
|
+
underlyingToRelative(fullPath, layer) {
|
|
297
|
+
const root = layer === "instance" ? INSTANCE_SETTINGS_ROOT : USER_SETTINGS_ROOT;
|
|
298
|
+
if (fullPath === root) return "/";
|
|
299
|
+
if (fullPath.startsWith(`${root}/`)) return fullPath.slice(root.length);
|
|
300
|
+
return fullPath;
|
|
301
|
+
}
|
|
302
|
+
baseRead(path, options) {
|
|
303
|
+
if (!this.base.read) throw new Error("base.read not supported");
|
|
304
|
+
return this.base.read(path, options);
|
|
305
|
+
}
|
|
306
|
+
baseStat(path, options) {
|
|
307
|
+
if (!this.base.stat) throw new Error("base.stat not supported");
|
|
308
|
+
return this.base.stat(path, options);
|
|
309
|
+
}
|
|
310
|
+
async loadInstanceWrapper(wrapperSub) {
|
|
311
|
+
const instancePath = (0, ufo.joinURL)(INSTANCE_SETTINGS_ROOT, wrapperSub);
|
|
312
|
+
let raw;
|
|
313
|
+
try {
|
|
314
|
+
raw = (await this.baseRead(instancePath)).data?.content;
|
|
315
|
+
} catch (e) {
|
|
316
|
+
if (isNotFound(e)) throw new _aigne_afs.AFSNotFoundError(wrapperSub);
|
|
317
|
+
throw e;
|
|
318
|
+
}
|
|
319
|
+
if (raw === void 0) throw new _aigne_afs.AFSNotFoundError(wrapperSub);
|
|
320
|
+
const inst = parseWrapper(raw);
|
|
321
|
+
return {
|
|
322
|
+
inst,
|
|
323
|
+
scope: sanitizeScope(inst.scope)
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
/** Read the caller's bare override value, or undefined when absent/anonymous. */
|
|
327
|
+
async readUserOverride(wrapperSub) {
|
|
328
|
+
const snap = this.activeSnapshot;
|
|
329
|
+
if (snap) return this.userProvider ? snap.user.get(wrapperSub) : void 0;
|
|
330
|
+
if (!this.userProvider?.read) return void 0;
|
|
331
|
+
try {
|
|
332
|
+
return (await this.userProvider.read((0, ufo.joinURL)(USER_SETTINGS_ROOT, wrapperSub))).data?.content;
|
|
333
|
+
} catch (e) {
|
|
334
|
+
if (isNotFound(e)) return void 0;
|
|
335
|
+
throw e;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
/** Parsed package schema for a field, or null (store mode only). */
|
|
339
|
+
async getSchemaWrapper(wrapperSub) {
|
|
340
|
+
const snap = this.activeSnapshot;
|
|
341
|
+
if (snap?.schemas) return snap.schemas.get(wrapperSub) ?? null;
|
|
342
|
+
if (!this.schema) return null;
|
|
343
|
+
const raw = await this.schema.getSchema(wrapperSub);
|
|
344
|
+
return raw === null ? null : parseWrapper(raw);
|
|
345
|
+
}
|
|
346
|
+
/** Parsed raw instance row, or null when absent (never throws not-found). */
|
|
347
|
+
async getInstanceRow(wrapperSub) {
|
|
348
|
+
const snap = this.activeSnapshot;
|
|
349
|
+
if (snap) return snap.instance.get(wrapperSub) ?? null;
|
|
350
|
+
try {
|
|
351
|
+
return (await this.loadInstanceWrapper(wrapperSub)).inst;
|
|
352
|
+
} catch (e) {
|
|
353
|
+
if (isNotFound(e)) return null;
|
|
354
|
+
throw e;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Reduce a raw instance row to its OVERRIDE-ONLY contribution (§2.D):
|
|
359
|
+
* `value` (when present) + keys explicitly written under `overrides`.
|
|
360
|
+
* A LEGACY full wrapper's flat schema keys are deliberately dropped —
|
|
361
|
+
* the package schema is authoritative (legacy-no-shadow).
|
|
362
|
+
*/
|
|
363
|
+
stripToOverrideOnly(row) {
|
|
364
|
+
const out = {};
|
|
365
|
+
if (!row) return out;
|
|
366
|
+
if (row.value !== void 0) out.value = row.value;
|
|
367
|
+
const ov = row[OVERRIDES_KEY];
|
|
368
|
+
if (ov && typeof ov === "object" && !Array.isArray(ov)) for (const [k, v] of Object.entries(ov)) {
|
|
369
|
+
if (DANGEROUS_KEYS.has(k) || CONTROL_KEYS.has(k) || k === OVERRIDES_KEY) continue;
|
|
370
|
+
out[k] = v;
|
|
371
|
+
}
|
|
372
|
+
return out;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Load one field through the cascade. Returns null when the field does not
|
|
376
|
+
* exist — store mode: not in the derived package index (orphan instance
|
|
377
|
+
* rows are IGNORED, §5.4.5); legacy mode: no instance row.
|
|
378
|
+
*/
|
|
379
|
+
async loadField(wrapperSub) {
|
|
380
|
+
let pkg;
|
|
381
|
+
let instOverride;
|
|
382
|
+
let instRow;
|
|
383
|
+
if (this.storeMode) {
|
|
384
|
+
const schemaWrapper = await this.getSchemaWrapper(wrapperSub);
|
|
385
|
+
if (!schemaWrapper) return null;
|
|
386
|
+
instRow = await this.getInstanceRow(wrapperSub);
|
|
387
|
+
pkg = schemaWrapper;
|
|
388
|
+
instOverride = this.stripToOverrideOnly(instRow);
|
|
389
|
+
} else {
|
|
390
|
+
instRow = await this.getInstanceRow(wrapperSub);
|
|
391
|
+
if (!instRow) return null;
|
|
392
|
+
pkg = instRow;
|
|
393
|
+
instOverride = {};
|
|
394
|
+
}
|
|
395
|
+
const scope = sanitizeScope(pkg.scope);
|
|
396
|
+
const rawUser = this.resolveWriteLayer(scope) === "user" ? await this.readUserOverride(wrapperSub) : void 0;
|
|
397
|
+
const inherited = instOverride.value !== void 0 ? instOverride.value : pkg.value;
|
|
398
|
+
const user = rawUser === void 0 ? void 0 : { value: coerceToSchemaType(rawUser, inherited) };
|
|
399
|
+
const eff = require_settings_cascade.cascade(pkg, instOverride, user);
|
|
400
|
+
const overridden = eff.source === "user";
|
|
401
|
+
const editable = this.editable(scope);
|
|
402
|
+
const visible = this.visible(scope);
|
|
403
|
+
const synth = {
|
|
404
|
+
...eff.synth,
|
|
405
|
+
source: overridden ? "user" : "instance",
|
|
406
|
+
editable,
|
|
407
|
+
visible
|
|
408
|
+
};
|
|
409
|
+
return {
|
|
410
|
+
scope,
|
|
411
|
+
visible,
|
|
412
|
+
editable,
|
|
413
|
+
overridden,
|
|
414
|
+
eff: eff.value,
|
|
415
|
+
synth,
|
|
416
|
+
instRow,
|
|
417
|
+
fromPackage: this.storeMode
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
/** Opaque version of the layer this caller would write — §3.7. */
|
|
421
|
+
async writeTargetVersion(scope, wrapperSub) {
|
|
422
|
+
const layer = this.resolveWriteLayer(scope);
|
|
423
|
+
try {
|
|
424
|
+
if (layer === "instance") return (await this.baseStat((0, ufo.joinURL)(INSTANCE_SETTINGS_ROOT, wrapperSub))).data?.meta?.version;
|
|
425
|
+
if (this.userProvider?.stat) return (await this.userProvider.stat((0, ufo.joinURL)(USER_SETTINGS_ROOT, wrapperSub))).data?.meta?.version;
|
|
426
|
+
} catch (e) {
|
|
427
|
+
if (!isNotFound(e)) throw e;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
async read(path, options) {
|
|
431
|
+
await this.ensureSchemaIngested();
|
|
432
|
+
const sub = this.normalizeSub(path);
|
|
433
|
+
const { wrapperSub, subKey } = splitWrapper(sub);
|
|
434
|
+
if (!wrapperSub) {
|
|
435
|
+
if (this.storeMode) {
|
|
436
|
+
if (!await this.dirExists(sub)) throw new _aigne_afs.AFSNotFoundError(sub);
|
|
437
|
+
return { data: {
|
|
438
|
+
id: lastSegment(sub) || "settings",
|
|
439
|
+
path: sub,
|
|
440
|
+
content: `Settings directory: ${sub}`,
|
|
441
|
+
meta: { kind: "directory" }
|
|
442
|
+
} };
|
|
443
|
+
}
|
|
444
|
+
const instancePath = (0, ufo.joinURL)(INSTANCE_SETTINGS_ROOT, sub);
|
|
445
|
+
let r;
|
|
446
|
+
try {
|
|
447
|
+
r = await this.baseRead(instancePath, options);
|
|
448
|
+
} catch (e) {
|
|
449
|
+
if (isNotFound(e)) throw new _aigne_afs.AFSNotFoundError(sub);
|
|
450
|
+
throw e;
|
|
451
|
+
}
|
|
452
|
+
if (!r.data) throw new _aigne_afs.AFSNotFoundError(sub);
|
|
453
|
+
return { data: {
|
|
454
|
+
...r.data,
|
|
455
|
+
path: sub,
|
|
456
|
+
meta: {
|
|
457
|
+
...r.data.meta,
|
|
458
|
+
kind: "directory"
|
|
459
|
+
}
|
|
460
|
+
} };
|
|
461
|
+
}
|
|
462
|
+
const field = await this.loadField(wrapperSub);
|
|
463
|
+
if (!field) throw new _aigne_afs.AFSNotFoundError(wrapperSub);
|
|
464
|
+
const version = this.activeSnapshot ? void 0 : await this.writeTargetVersion(field.scope, wrapperSub);
|
|
465
|
+
const meta = {
|
|
466
|
+
accessMode: field.editable ? "readwrite" : "readonly",
|
|
467
|
+
visible: field.visible,
|
|
468
|
+
editable: field.editable,
|
|
469
|
+
scope: field.scope,
|
|
470
|
+
version
|
|
471
|
+
};
|
|
472
|
+
if (subKey === void 0) return { data: {
|
|
473
|
+
id: lastSegment(wrapperSub),
|
|
474
|
+
path: wrapperSub,
|
|
475
|
+
content: JSON.stringify(field.synth),
|
|
476
|
+
meta
|
|
477
|
+
} };
|
|
478
|
+
const content = subKey === "value" ? field.eff : field.synth[subKey];
|
|
479
|
+
return { data: {
|
|
480
|
+
id: lastSegment(subKey),
|
|
481
|
+
path: (0, ufo.joinURL)(wrapperSub, subKey),
|
|
482
|
+
content,
|
|
483
|
+
meta
|
|
484
|
+
} };
|
|
485
|
+
}
|
|
486
|
+
/** Store-mode directory existence: any package field lives under `sub`. */
|
|
487
|
+
async dirExists(sub) {
|
|
488
|
+
if (sub === "/") return true;
|
|
489
|
+
const prefix = `${sub}/`;
|
|
490
|
+
for (const key of (await this.schemaMap()).keys()) if (key.startsWith(prefix)) return true;
|
|
491
|
+
return false;
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* The full schema map (store mode): from the active snapshot when present,
|
|
495
|
+
* else one bulk store query — replacing the legacy per-field N+1 scope peek.
|
|
496
|
+
*/
|
|
497
|
+
async schemaMap() {
|
|
498
|
+
const snap = this.activeSnapshot;
|
|
499
|
+
if (snap?.schemas) return snap.schemas;
|
|
500
|
+
return this.loadSchemaMap();
|
|
501
|
+
}
|
|
502
|
+
async list(path, options) {
|
|
503
|
+
await this.ensureSchemaIngested();
|
|
504
|
+
const sub = this.normalizeSub(path);
|
|
505
|
+
if (this.storeMode) {
|
|
506
|
+
const schemas = await this.schemaMap();
|
|
507
|
+
const prefix = sub === "/" ? "/" : `${sub}/`;
|
|
508
|
+
const children = /* @__PURE__ */ new Map();
|
|
509
|
+
for (const key of schemas.keys()) {
|
|
510
|
+
if (!key.startsWith(prefix)) continue;
|
|
511
|
+
const rest = key.slice(prefix.length);
|
|
512
|
+
const seg = rest.split("/")[0];
|
|
513
|
+
if (!seg) continue;
|
|
514
|
+
children.set(seg, children.get(seg) || rest.includes("/"));
|
|
515
|
+
}
|
|
516
|
+
if (children.size === 0 && sub !== "/") throw new _aigne_afs.AFSNotFoundError(sub);
|
|
517
|
+
const data$1 = [];
|
|
518
|
+
for (const [seg, isDir] of children) {
|
|
519
|
+
const childSub = (0, ufo.joinURL)(sub, seg);
|
|
520
|
+
if (isDir) {
|
|
521
|
+
data$1.push({
|
|
522
|
+
id: seg,
|
|
523
|
+
path: childSub,
|
|
524
|
+
meta: {
|
|
525
|
+
kind: "directory",
|
|
526
|
+
childrenCount: -1
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
continue;
|
|
530
|
+
}
|
|
531
|
+
const scope = sanitizeScope(schemas.get(childSub)?.scope);
|
|
532
|
+
const editable = this.editable(scope);
|
|
533
|
+
const visible = this.visible(scope);
|
|
534
|
+
data$1.push({
|
|
535
|
+
id: seg,
|
|
536
|
+
path: childSub,
|
|
537
|
+
meta: {
|
|
538
|
+
accessMode: editable ? "readwrite" : "readonly",
|
|
539
|
+
scope,
|
|
540
|
+
visible,
|
|
541
|
+
editable
|
|
542
|
+
}
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
return { data: data$1 };
|
|
546
|
+
}
|
|
547
|
+
const instanceDir = (0, ufo.joinURL)(INSTANCE_SETTINGS_ROOT, sub);
|
|
548
|
+
const result = await this.base.list(instanceDir, options);
|
|
549
|
+
const data = await Promise.all((result.data ?? []).map(async (e) => {
|
|
550
|
+
const relPath = this.underlyingToRelative(e.path, "instance");
|
|
551
|
+
if (!relPath.endsWith(".json")) return {
|
|
552
|
+
...e,
|
|
553
|
+
path: relPath,
|
|
554
|
+
meta: {
|
|
555
|
+
...e.meta,
|
|
556
|
+
kind: "directory",
|
|
557
|
+
childrenCount: e.meta?.childrenCount ?? -1
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
let scope = "instance";
|
|
561
|
+
try {
|
|
562
|
+
const row = await this.getInstanceRow(relPath);
|
|
563
|
+
if (row) scope = sanitizeScope(row.scope);
|
|
564
|
+
} catch {}
|
|
565
|
+
const editable = this.editable(scope);
|
|
566
|
+
const visible = this.visible(scope);
|
|
567
|
+
return {
|
|
568
|
+
...e,
|
|
569
|
+
path: relPath,
|
|
570
|
+
meta: {
|
|
571
|
+
...e.meta,
|
|
572
|
+
kind: void 0,
|
|
573
|
+
childrenCount: void 0,
|
|
574
|
+
accessMode: editable ? "readwrite" : "readonly",
|
|
575
|
+
scope,
|
|
576
|
+
visible,
|
|
577
|
+
editable
|
|
578
|
+
}
|
|
579
|
+
};
|
|
580
|
+
}));
|
|
581
|
+
return {
|
|
582
|
+
...result,
|
|
583
|
+
data
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
async stat(path, options) {
|
|
587
|
+
await this.ensureSchemaIngested();
|
|
588
|
+
const sub = this.normalizeSub(path);
|
|
589
|
+
const { wrapperSub, subKey } = splitWrapper(sub);
|
|
590
|
+
if (!wrapperSub) {
|
|
591
|
+
if (this.storeMode) {
|
|
592
|
+
if (!await this.dirExists(sub)) throw new _aigne_afs.AFSNotFoundError(sub);
|
|
593
|
+
return { data: {
|
|
594
|
+
id: lastSegment(sub) || "settings",
|
|
595
|
+
path: sub,
|
|
596
|
+
meta: {
|
|
597
|
+
kind: "directory",
|
|
598
|
+
childrenCount: -1
|
|
599
|
+
}
|
|
600
|
+
} };
|
|
601
|
+
}
|
|
602
|
+
const instancePath = (0, ufo.joinURL)(INSTANCE_SETTINGS_ROOT, sub);
|
|
603
|
+
let r;
|
|
604
|
+
try {
|
|
605
|
+
r = await this.baseStat(instancePath, options);
|
|
606
|
+
} catch (e) {
|
|
607
|
+
if (isNotFound(e)) throw new _aigne_afs.AFSNotFoundError(sub);
|
|
608
|
+
throw e;
|
|
609
|
+
}
|
|
610
|
+
if (!r.data) throw new _aigne_afs.AFSNotFoundError(sub);
|
|
611
|
+
return { data: {
|
|
612
|
+
...r.data,
|
|
613
|
+
path: sub,
|
|
614
|
+
meta: {
|
|
615
|
+
...r.data.meta,
|
|
616
|
+
kind: "directory"
|
|
617
|
+
}
|
|
618
|
+
} };
|
|
619
|
+
}
|
|
620
|
+
const field = await this.loadField(wrapperSub);
|
|
621
|
+
if (!field) throw new _aigne_afs.AFSNotFoundError(wrapperSub);
|
|
622
|
+
const version = await this.writeTargetVersion(field.scope, wrapperSub);
|
|
623
|
+
const statPath = subKey ? (0, ufo.joinURL)(wrapperSub, subKey) : wrapperSub;
|
|
624
|
+
return { data: {
|
|
625
|
+
id: lastSegment(statPath),
|
|
626
|
+
path: statPath,
|
|
627
|
+
meta: {
|
|
628
|
+
accessMode: field.editable ? "readwrite" : "readonly",
|
|
629
|
+
visible: field.visible,
|
|
630
|
+
editable: field.editable,
|
|
631
|
+
scope: field.scope,
|
|
632
|
+
version
|
|
633
|
+
}
|
|
634
|
+
} };
|
|
635
|
+
}
|
|
636
|
+
async write(path, content, options) {
|
|
637
|
+
await this.ensureSchemaIngested();
|
|
638
|
+
const { wrapperSub, subKey } = splitWrapper(this.normalizeSub(path));
|
|
639
|
+
if (!wrapperSub) throw new _aigne_afs.AFSForbiddenError(path, "settings writes must target a field, e.g. .../x.json/value");
|
|
640
|
+
if (subKey === void 0) throw new _aigne_afs.AFSForbiddenError(path, "settings writes must target a field sub-path (.../x.json/value)");
|
|
641
|
+
const field = await this.loadField(wrapperSub);
|
|
642
|
+
if (!field) throw new _aigne_afs.AFSNotFoundError(wrapperSub);
|
|
643
|
+
const ifMatch = options?.ifMatch;
|
|
644
|
+
const context = options?.context;
|
|
645
|
+
const instBase = this.storeMode ? this.overrideOnlyDiskShape(field.instRow) : field.instRow ?? {};
|
|
646
|
+
if (subKey !== "value") {
|
|
647
|
+
if (!this.isOwnerOrAdmin) throw new _aigne_afs.AFSForbiddenError(path, "editing settings schema requires owner/admin");
|
|
648
|
+
if (this.storeMode) {
|
|
649
|
+
const prior = instBase[OVERRIDES_KEY] ?? {};
|
|
650
|
+
return this.writeInstanceWrapper(wrapperSub, instBase, OVERRIDES_KEY, {
|
|
651
|
+
...prior,
|
|
652
|
+
[subKey]: content.content
|
|
653
|
+
}, {
|
|
654
|
+
ifMatch,
|
|
655
|
+
context
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
return this.writeInstanceWrapper(wrapperSub, instBase, subKey, content.content, {
|
|
659
|
+
ifMatch,
|
|
660
|
+
context
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
if (this.resolveWriteLayer(field.scope) === "instance") {
|
|
664
|
+
if (!this.isOwnerOrAdmin) throw new _aigne_afs.AFSForbiddenError(path, "instance-scope settings require owner/admin");
|
|
665
|
+
return this.writeInstanceWrapper(wrapperSub, instBase, "value", content.content, {
|
|
666
|
+
ifMatch,
|
|
667
|
+
context
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
if (!this.isAuthed || !this.userProvider?.write) throw new _aigne_afs.AFSForbiddenError(path, "sign in to personalize this setting");
|
|
671
|
+
return this.userProvider.write((0, ufo.joinURL)(USER_SETTINGS_ROOT, wrapperSub), { content: content.content }, this.writeOptions(ifMatch, context));
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* The ON-DISK override-only shape of an instance row: `{ value?, overrides? }`.
|
|
675
|
+
* Distinct from {@link stripToOverrideOnly} (the flattened READ-side
|
|
676
|
+
* contribution) — this preserves the nested `overrides` object so a write
|
|
677
|
+
* RMW keeps prior explicit schema-text edits.
|
|
678
|
+
*/
|
|
679
|
+
overrideOnlyDiskShape(row) {
|
|
680
|
+
const out = {};
|
|
681
|
+
if (!row) return out;
|
|
682
|
+
if (row.value !== void 0) out.value = row.value;
|
|
683
|
+
const ov = row[OVERRIDES_KEY];
|
|
684
|
+
if (ov && typeof ov === "object" && !Array.isArray(ov)) out[OVERRIDES_KEY] = ov;
|
|
685
|
+
return out;
|
|
686
|
+
}
|
|
687
|
+
/** Assemble write options, omitting empties so providers see a clean shape. */
|
|
688
|
+
writeOptions(ifMatch, context) {
|
|
689
|
+
const out = {};
|
|
690
|
+
if (ifMatch != null) out.ifMatch = ifMatch;
|
|
691
|
+
if (context != null) out.context = context;
|
|
692
|
+
return out;
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Read-modify-write the FULL instance wrapper so siblings
|
|
696
|
+
* (label/description/options/…) survive — the G0 regression guard. ifMatch
|
|
697
|
+
* (if supplied) is compared by the base provider against the wrapper version;
|
|
698
|
+
* context (if supplied) flows through so the emitted event carries origin.
|
|
699
|
+
*/
|
|
700
|
+
writeInstanceWrapper(wrapperSub, inst, key, value, opts) {
|
|
701
|
+
if (!this.base.write) throw new Error("base.write not supported");
|
|
702
|
+
const next = {
|
|
703
|
+
...inst,
|
|
704
|
+
[key]: value
|
|
705
|
+
};
|
|
706
|
+
return this.base.write((0, ufo.joinURL)(INSTANCE_SETTINGS_ROOT, wrapperSub), { content: JSON.stringify(next) }, this.writeOptions(opts.ifMatch, opts.context));
|
|
707
|
+
}
|
|
708
|
+
async delete(path, options) {
|
|
709
|
+
await this.ensureSchemaIngested();
|
|
710
|
+
const { wrapperSub, subKey } = splitWrapper(this.normalizeSub(path));
|
|
711
|
+
if (!wrapperSub) throw new _aigne_afs.AFSForbiddenError(path, "not a settings field path");
|
|
712
|
+
if (subKey !== void 0 && subKey !== "value") throw new _aigne_afs.AFSForbiddenError(path, "only a field's value can be reset");
|
|
713
|
+
const field = await this.loadField(wrapperSub);
|
|
714
|
+
if (!field) throw new _aigne_afs.AFSNotFoundError(wrapperSub);
|
|
715
|
+
if (this.resolveWriteLayer(field.scope) === "instance") throw new _aigne_afs.AFSForbiddenError(path, "instance settings cannot be deleted; admin edits via write");
|
|
716
|
+
if (!this.isAuthed || !this.userProvider?.delete) throw new _aigne_afs.AFSForbiddenError(path, "sign in to reset this setting");
|
|
717
|
+
return this.userProvider.delete((0, ufo.joinURL)(USER_SETTINGS_ROOT, wrapperSub), options);
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* Bridge instance-layer + user-layer change events into the
|
|
721
|
+
* `/instance/settings/...` namespace so propBind can react to a cascade write
|
|
722
|
+
* regardless of which physical layer it landed on.
|
|
723
|
+
*
|
|
724
|
+
* For a FIELD subscription (`/cascade/theme.json/value`):
|
|
725
|
+
* - watch the instance WRAPPER FILE on `base` and the bare-value file on
|
|
726
|
+
* `userProvider` (see `mapSubscribePaths`);
|
|
727
|
+
* - re-emit at the EXACT filter path so the bridged event matches what the
|
|
728
|
+
* subscriber (PropBindSubscriber) asked for — SessionUserAFS then
|
|
729
|
+
* re-prefixes the resolver-relative path back to `/instance/settings/...`.
|
|
730
|
+
*
|
|
731
|
+
* Two invariants make echo suppression + reset work:
|
|
732
|
+
* 1. ORIGIN PASSTHROUGH — `{ ...evt }` preserves `origin.sessionId`, so the
|
|
733
|
+
* writer's own session is filtered out by PropBindSubscriber and a
|
|
734
|
+
* different session still receives the patch. (The underlying write
|
|
735
|
+
* carries origin only because `write()` now forwards `options.context`.)
|
|
736
|
+
* 2. TYPE NORMALIZATION — a user-layer DELETE (reset, D-f) is re-emitted as
|
|
737
|
+
* `afs:write` because, from the cascade's point of view, the effective
|
|
738
|
+
* value changed (reverted to the instance default); subscribers re-read
|
|
739
|
+
* either way. We therefore drop the type filter on the underlying
|
|
740
|
+
* subscription so deletes are not missed.
|
|
741
|
+
*/
|
|
742
|
+
subscribe(filter, callback) {
|
|
743
|
+
const rawPath = typeof filter.path === "string" ? filter.path || "/" : "/";
|
|
744
|
+
const relPath = this.normalizeSub(rawPath);
|
|
745
|
+
const { instancePath, userPath, isField } = mapSubscribePaths(relPath);
|
|
746
|
+
const emit = (evt, layer) => {
|
|
747
|
+
const path = isField ? relPath : this.underlyingToRelative(evt.path, layer);
|
|
748
|
+
callback({
|
|
749
|
+
...evt,
|
|
750
|
+
type: "afs:write",
|
|
751
|
+
path
|
|
752
|
+
});
|
|
753
|
+
};
|
|
754
|
+
const unsubs = [];
|
|
755
|
+
if (this.base.subscribe) unsubs.push(this.base.subscribe({ path: instancePath }, (evt) => emit(evt, "instance")));
|
|
756
|
+
if (this.userProvider?.subscribe) unsubs.push(this.userProvider.subscribe({ path: userPath }, (evt) => emit(evt, "user")));
|
|
757
|
+
return () => {
|
|
758
|
+
for (const u of unsubs) try {
|
|
759
|
+
u();
|
|
760
|
+
} catch {}
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
setEventSink(sink) {
|
|
764
|
+
this.base.setEventSink?.(sink);
|
|
765
|
+
this.userProvider?.setEventSink?.(sink);
|
|
766
|
+
}
|
|
767
|
+
};
|
|
768
|
+
|
|
769
|
+
//#endregion
|
|
770
|
+
exports.SettingsResolver = SettingsResolver;
|