pi-proactive 0.2.0-beta.2 → 0.2.0-beta.3
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 +29 -0
- package/README.md +32 -28
- package/build/cli.mjs +121 -0
- package/build/extensions/proactive.js +47 -6
- package/build/src/commands.js +78 -2
- package/build/src/config.js +511 -4
- package/build/src/daemon-config.js +221 -0
- package/build/src/daemon-contact.js +103 -0
- package/build/src/daemon-host.js +84 -0
- package/build/src/daemon.js +193 -3
- package/build/src/health.js +84 -0
- package/build/src/lineage.js +41 -2
- package/build/src/notify.js +183 -0
- package/build/src/progress-eta.js +134 -0
- package/build/src/trigger.js +43 -0
- package/build/src/trust-loop.js +321 -0
- package/build/src/trust-metrics.js +236 -0
- package/build/src/trust-notify.js +73 -0
- package/build/src/trust-policy.js +58 -0
- package/build/src/trust-registry.js +323 -0
- package/daemon/launchd.plist +48 -0
- package/daemon/pi-proactive-daemon.service +29 -0
- package/daemon/run-daemon.sh +84 -0
- package/node_modules/typebox/build/compile/code.mjs +2 -1
- package/node_modules/typebox/build/compile/validator.mjs +1 -5
- package/node_modules/typebox/build/format/date_time.d.mts +1 -2
- package/node_modules/typebox/build/format/date_time.mjs +3 -12
- package/node_modules/typebox/build/format/duration.d.mts +2 -2
- package/node_modules/typebox/build/format/duration.mjs +2 -2
- package/node_modules/typebox/build/format/idn_email.d.mts +0 -1
- package/node_modules/typebox/build/format/idn_email.mjs +0 -1
- package/node_modules/typebox/build/format/idn_hostname.d.mts +1 -1
- package/node_modules/typebox/build/format/idn_hostname.mjs +1 -1
- package/node_modules/typebox/build/format/ipv4.d.mts +2 -2
- package/node_modules/typebox/build/format/ipv4.mjs +2 -2
- package/node_modules/typebox/build/format/ipv6.d.mts +1 -1
- package/node_modules/typebox/build/format/ipv6.mjs +1 -1
- package/node_modules/typebox/build/format/iri.mjs +9 -16
- package/node_modules/typebox/build/format/relative_json_pointer.d.mts +2 -2
- package/node_modules/typebox/build/format/relative_json_pointer.mjs +2 -2
- package/node_modules/typebox/build/guard/emit.mjs +2 -2
- package/node_modules/typebox/build/guard/guard.d.mts +5 -7
- package/node_modules/typebox/build/guard/guard.mjs +9 -14
- package/node_modules/typebox/build/guard/index.mjs +0 -6
- package/node_modules/typebox/build/guard/{unicode/unicode_segment.mjs → string.mjs} +19 -16
- package/node_modules/typebox/build/schema/build.mjs +5 -5
- package/node_modules/typebox/build/schema/check.mjs +1 -1
- package/node_modules/typebox/build/schema/engine/_context.d.mts +1 -5
- package/node_modules/typebox/build/schema/engine/_context.mjs +3 -16
- package/node_modules/typebox/build/schema/engine/_functions.d.mts +2 -2
- package/node_modules/typebox/build/schema/engine/_functions.mjs +1 -1
- package/node_modules/typebox/build/schema/engine/_reducer.d.mts +3 -3
- package/node_modules/typebox/build/schema/engine/_refine.d.mts +5 -5
- package/node_modules/typebox/build/schema/engine/_refine.mjs +9 -14
- package/node_modules/typebox/build/schema/engine/_stack.d.mts +20 -34
- package/node_modules/typebox/build/schema/engine/_stack.mjs +202 -143
- package/node_modules/typebox/build/schema/engine/_unique.d.mts +2 -4
- package/node_modules/typebox/build/schema/engine/_unique.mjs +3 -7
- package/node_modules/typebox/build/schema/engine/additionalItems.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/additionalItems.mjs +3 -3
- package/node_modules/typebox/build/schema/engine/additionalProperties.d.mts +8 -5
- package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +32 -27
- package/node_modules/typebox/build/schema/engine/allOf.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/allOf.mjs +1 -1
- package/node_modules/typebox/build/schema/engine/anyOf.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/anyOf.mjs +9 -4
- package/node_modules/typebox/build/schema/engine/boolean.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/boolean.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/const.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/const.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/contains.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/contains.mjs +9 -5
- package/node_modules/typebox/build/schema/engine/dependencies.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/dependencies.mjs +7 -5
- package/node_modules/typebox/build/schema/engine/dependentRequired.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/dependentRequired.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/dependentSchemas.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/dependentSchemas.mjs +1 -2
- package/node_modules/typebox/build/schema/engine/dynamicRef.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/dynamicRef.mjs +8 -12
- package/node_modules/typebox/build/schema/engine/enum.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/enum.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/exclusiveMaximum.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/exclusiveMaximum.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/exclusiveMinimum.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/exclusiveMinimum.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/format.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/format.mjs +8 -11
- package/node_modules/typebox/build/schema/engine/if.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/if.mjs +13 -5
- package/node_modules/typebox/build/schema/engine/index.d.mts +0 -1
- package/node_modules/typebox/build/schema/engine/index.mjs +0 -1
- package/node_modules/typebox/build/schema/engine/items.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/items.mjs +5 -8
- package/node_modules/typebox/build/schema/engine/maxContains.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/maxContains.mjs +8 -4
- package/node_modules/typebox/build/schema/engine/maxItems.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/maxItems.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/maxLength.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/maxLength.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/maxProperties.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/maxProperties.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/maximum.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/maximum.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/minContains.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/minContains.mjs +9 -5
- package/node_modules/typebox/build/schema/engine/minItems.d.mts +5 -5
- package/node_modules/typebox/build/schema/engine/minItems.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/minLength.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/minLength.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/minProperties.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/minProperties.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/minimum.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/minimum.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/multipleOf.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/multipleOf.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/not.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/not.mjs +8 -4
- package/node_modules/typebox/build/schema/engine/oneOf.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/oneOf.mjs +11 -6
- package/node_modules/typebox/build/schema/engine/pattern.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/pattern.mjs +7 -3
- package/node_modules/typebox/build/schema/engine/patternProperties.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/patternProperties.mjs +5 -6
- package/node_modules/typebox/build/schema/engine/prefixItems.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/prefixItems.mjs +1 -1
- package/node_modules/typebox/build/schema/engine/properties.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/properties.mjs +3 -4
- package/node_modules/typebox/build/schema/engine/propertyNames.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/propertyNames.mjs +10 -7
- package/node_modules/typebox/build/schema/engine/recursiveRef.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/recursiveRef.mjs +8 -12
- package/node_modules/typebox/build/schema/engine/ref.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/ref.mjs +14 -18
- package/node_modules/typebox/build/schema/engine/required.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/required.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/schema.d.mts +7 -7
- package/node_modules/typebox/build/schema/engine/schema.mjs +138 -136
- package/node_modules/typebox/build/schema/engine/type.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/type.mjs +6 -2
- package/node_modules/typebox/build/schema/engine/unevaluatedItems.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/unevaluatedItems.mjs +9 -5
- package/node_modules/typebox/build/schema/engine/unevaluatedProperties.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/unevaluatedProperties.mjs +9 -5
- package/node_modules/typebox/build/schema/engine/uniqueItems.d.mts +4 -4
- package/node_modules/typebox/build/schema/engine/uniqueItems.mjs +6 -2
- package/node_modules/typebox/build/schema/errors.mjs +1 -1
- package/node_modules/typebox/build/schema/intern/intern.d.mts +9 -6
- package/node_modules/typebox/build/schema/intern/intern.mjs +56 -90
- package/node_modules/typebox/build/schema/parse.mjs +0 -3
- package/node_modules/typebox/build/schema/pointer/pointer.d.mts +6 -1
- package/node_modules/typebox/build/schema/pointer/pointer.mjs +64 -47
- package/node_modules/typebox/build/schema/resolve/resolve.d.mts +32 -6
- package/node_modules/typebox/build/schema/resolve/resolve.mjs +227 -231
- package/node_modules/typebox/build/schema/schema.d.mts +0 -1
- package/node_modules/typebox/build/schema/schema.mjs +0 -1
- package/node_modules/typebox/build/system/hashing/hash.mjs +34 -63
- package/node_modules/typebox/build/system/locale/en_US.mjs +1 -2
- package/node_modules/typebox/build/system/memory/assign.d.mts +8 -2
- package/node_modules/typebox/build/system/memory/assign.mjs +6 -13
- package/node_modules/typebox/build/system/memory/clone.d.mts +5 -4
- package/node_modules/typebox/build/system/memory/clone.mjs +96 -8
- package/node_modules/typebox/build/system/memory/create.d.mts +5 -1
- package/node_modules/typebox/build/system/memory/create.mjs +13 -18
- package/node_modules/typebox/build/system/memory/discard.d.mts +1 -1
- package/node_modules/typebox/build/system/memory/discard.mjs +8 -9
- package/node_modules/typebox/build/system/memory/freeze.d.mts +4 -0
- package/node_modules/typebox/build/system/memory/freeze.mjs +6 -0
- package/node_modules/typebox/build/system/memory/update.d.mts +4 -1
- package/node_modules/typebox/build/system/memory/update.mjs +16 -43
- package/node_modules/typebox/build/system/settings/settings.d.mts +0 -11
- package/node_modules/typebox/build/system/settings/settings.mjs +0 -14
- package/node_modules/typebox/build/type/engine/evaluate/composite.d.mts +24 -2
- package/node_modules/typebox/build/type/engine/evaluate/composite.mjs +29 -2
- package/node_modules/typebox/build/type/engine/evaluate/index.d.mts +0 -1
- package/node_modules/typebox/build/type/engine/evaluate/index.mjs +0 -1
- package/node_modules/typebox/build/type/engine/evaluate/narrow.d.mts +1 -5
- package/node_modules/typebox/build/type/engine/evaluate/narrow.mjs +1 -6
- package/node_modules/typebox/build/type/engine/immutable/instantiate_add.d.mts +3 -1
- package/node_modules/typebox/build/type/engine/immutable/instantiate_add.mjs +4 -1
- package/node_modules/typebox/build/type/engine/object/from_intersect.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/object/from_intersect.mjs +2 -2
- package/node_modules/typebox/build/type/engine/object/from_union.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/object/from_union.mjs +2 -2
- package/node_modules/typebox/build/type/engine/optional/instantiate_add.d.mts +3 -1
- package/node_modules/typebox/build/type/engine/optional/instantiate_add.mjs +4 -1
- package/node_modules/typebox/build/type/engine/readonly/instantiate_add.d.mts +3 -1
- package/node_modules/typebox/build/type/engine/readonly/instantiate_add.mjs +4 -1
- package/node_modules/typebox/build/type/extends/inference.d.mts +1 -1
- package/node_modules/typebox/build/type/extends/inference.mjs +2 -15
- package/node_modules/typebox/build/type/extends/tuple.d.mts +1 -2
- package/node_modules/typebox/build/type/extends/tuple.mjs +1 -21
- package/node_modules/typebox/build/value/clean/from_object.mjs +1 -1
- package/node_modules/typebox/build/value/clone/clone.d.mts +3 -4
- package/node_modules/typebox/build/value/clone/clone.mjs +7 -5
- package/node_modules/typebox/build/value/parse/parse.mjs +4 -10
- package/node_modules/typebox/build/value/shared/union_priority_sort.mjs +14 -25
- package/node_modules/typebox/package.json +1 -1
- package/node_modules/typebox/readme.md +84 -52
- package/package.json +11 -3
- package/skills/pi-proactive/SKILL.md +27 -24
- package/tools/cli.mjs +121 -0
- package/tools/daemon-install.sh +397 -0
- package/tools/daemon-uninstall.sh +226 -0
- package/node_modules/typebox/build/guard/unicode/unicode.d.mts +0 -6
- package/node_modules/typebox/build/guard/unicode/unicode.mjs +0 -35
- package/node_modules/typebox/build/schema/engine/_pathing.d.mts +0 -1
- package/node_modules/typebox/build/schema/engine/_pathing.mjs +0 -11
- package/node_modules/typebox/build/schema/meta/draft_2019_09.d.mts +0 -2
- package/node_modules/typebox/build/schema/meta/draft_2019_09.mjs +0 -288
- package/node_modules/typebox/build/schema/meta/draft_2020_12.d.mts +0 -2
- package/node_modules/typebox/build/schema/meta/draft_2020_12.mjs +0 -300
- package/node_modules/typebox/build/schema/meta/draft_3.d.mts +0 -2
- package/node_modules/typebox/build/schema/meta/draft_3.mjs +0 -143
- package/node_modules/typebox/build/schema/meta/draft_4.d.mts +0 -2
- package/node_modules/typebox/build/schema/meta/draft_4.mjs +0 -149
- package/node_modules/typebox/build/schema/meta/draft_6.d.mts +0 -2
- package/node_modules/typebox/build/schema/meta/draft_6.mjs +0 -155
- package/node_modules/typebox/build/schema/meta/draft_7.d.mts +0 -2
- package/node_modules/typebox/build/schema/meta/draft_7.mjs +0 -172
- package/node_modules/typebox/build/schema/meta/index.d.mts +0 -2
- package/node_modules/typebox/build/schema/meta/index.mjs +0 -2
- package/node_modules/typebox/build/schema/meta/meta.d.mts +0 -9
- package/node_modules/typebox/build/schema/meta/meta.mjs +0 -15
- package/node_modules/typebox/build/schema/meta/schema.d.mts +0 -6
- package/node_modules/typebox/build/schema/meta/schema.mjs +0 -1
- package/node_modules/typebox/build/system/memory/deep.d.mts +0 -2
- package/node_modules/typebox/build/system/memory/deep.mjs +0 -108
- package/node_modules/typebox/build/system/memory/finalize.d.mts +0 -4
- package/node_modules/typebox/build/system/memory/finalize.mjs +0 -30
- package/node_modules/typebox/build/system/memory/keys.d.mts +0 -2
- package/node_modules/typebox/build/system/memory/keys.mjs +0 -8
- package/node_modules/typebox/build/system/settings/internal.d.mts +0 -2
- package/node_modules/typebox/build/system/settings/internal.mjs +0 -20
- package/node_modules/typebox/build/type/engine/call/index.d.mts +0 -1
- package/node_modules/typebox/build/type/engine/call/index.mjs +0 -1
- package/node_modules/typebox/build/type/engine/evaluate/property.d.mts +0 -30
- package/node_modules/typebox/build/type/engine/evaluate/property.mjs +0 -29
- package/node_modules/typebox/build/type/engine/this/index.d.mts +0 -1
- package/node_modules/typebox/build/type/engine/this/index.mjs +0 -1
- package/node_modules/typebox/build/value/repair/from_cyclic.d.mts +0 -2
- package/node_modules/typebox/build/value/repair/from_cyclic.mjs +0 -6
- /package/node_modules/typebox/build/guard/{unicode/unicode_segment.d.mts → string.d.mts} +0 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<!--
|
|
4
|
+
pi-proactive 常驻值班进程(macOS launchd LaunchAgent)。
|
|
5
|
+
|
|
6
|
+
**模板文件**:双下划线包裹的大写占位符由 `pi-proactive/tools/daemon-install.sh` 渲染
|
|
7
|
+
(节点路径 / 值班脚本路径 / agentDir / 稳定身份 / 日志目录)。
|
|
8
|
+
|
|
9
|
+
为什么用 launchd 而不是 cron(任务卡 §2①):
|
|
10
|
+
- cron 的最小粒度是 1 分钟,且**没有崩溃自愈**;launchd 有 `KeepAlive`(进程退出即拉起)→ 崩溃重启是内建的;
|
|
11
|
+
- cron 不带环境变量语义(要绕 shell 脚本传身份);launchd 的 `EnvironmentVariables` 是结构化的;
|
|
12
|
+
- 日志由 `StandardOutPath` / `StandardErrorPath` 落盘 → 可被巡检读。
|
|
13
|
+
|
|
14
|
+
成本硬约束:这里的 `PI_PROACTIVE_DAEMON_DRY_RUN=1` 与配置里的 `enabled=false`(默认)
|
|
15
|
+
一起保证**装上不等于花钱**。
|
|
16
|
+
-->
|
|
17
|
+
<plist version="1.0">
|
|
18
|
+
<dict>
|
|
19
|
+
<key>Label</key>
|
|
20
|
+
<string>__LABEL__</string>
|
|
21
|
+
<key>ProgramArguments</key>
|
|
22
|
+
<array>
|
|
23
|
+
<string>/bin/bash</string>
|
|
24
|
+
<string>__RUNNER__</string>
|
|
25
|
+
</array>
|
|
26
|
+
<key>RunAtLoad</key>
|
|
27
|
+
<true/>
|
|
28
|
+
<key>KeepAlive</key>
|
|
29
|
+
<true/>
|
|
30
|
+
<key>ThrottleInterval</key>
|
|
31
|
+
<integer>10</integer>
|
|
32
|
+
<key>ProcessType</key>
|
|
33
|
+
<string>Background</string>
|
|
34
|
+
<key>WorkingDirectory</key>
|
|
35
|
+
<string>__PKG_ROOT__</string>
|
|
36
|
+
<key>EnvironmentVariables</key>
|
|
37
|
+
<dict>
|
|
38
|
+
<key>PI_PROACTIVE_AGENT_ID</key>
|
|
39
|
+
<string>__AGENT_ID__</string>
|
|
40
|
+
<key>PI_PROACTIVE_DAEMON_DRY_RUN</key>
|
|
41
|
+
<string>1</string>
|
|
42
|
+
</dict>
|
|
43
|
+
<key>StandardOutPath</key>
|
|
44
|
+
<string>__LOG_DIR__/daemon.out.log</string>
|
|
45
|
+
<key>StandardErrorPath</key>
|
|
46
|
+
<string>__LOG_DIR__/daemon.err.log</string>
|
|
47
|
+
</dict>
|
|
48
|
+
</plist>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# pi-proactive 常驻值班进程(Linux systemd --user 单元)
|
|
2
|
+
#
|
|
3
|
+
# **模板文件**:双下划线包裹的大写占位符由 `pi-proactive/tools/daemon-install.sh` 渲染
|
|
4
|
+
# (节点路径 / 值班脚本路径 / agentDir / 稳定身份)。
|
|
5
|
+
#
|
|
6
|
+
# 为什么用 systemd --user 而不是 cron(任务卡 §2①):
|
|
7
|
+
# - `Restart=always` → 崩溃自启是内建的(cron 没有);
|
|
8
|
+
# - `Environment=` → 稳定身份(`PI_PROACTIVE_AGENT_ID`)跨重启连续;
|
|
9
|
+
# - `KillSignal=SIGTERM` + `TimeoutStopSec` → 停止时给值班进程时间写交班摘要再退出。
|
|
10
|
+
#
|
|
11
|
+
# 成本硬约束:`PI_PROACTIVE_DAEMON_DRY_RUN=1` + 配置里的 `enabled=false`(默认)
|
|
12
|
+
# 一起保证**装上不等于花钱**。
|
|
13
|
+
[Unit]
|
|
14
|
+
Description=pi-proactive 常驻值班进程(7x24 数字员工)
|
|
15
|
+
After=default.target
|
|
16
|
+
|
|
17
|
+
[Service]
|
|
18
|
+
Type=simple
|
|
19
|
+
ExecStart=/bin/bash __RUNNER__
|
|
20
|
+
WorkingDirectory=__PKG_ROOT__
|
|
21
|
+
Environment=PI_PROACTIVE_AGENT_ID=__AGENT_ID__
|
|
22
|
+
Environment=PI_PROACTIVE_DAEMON_DRY_RUN=1
|
|
23
|
+
Restart=always
|
|
24
|
+
RestartSec=5
|
|
25
|
+
KillSignal=SIGTERM
|
|
26
|
+
TimeoutStopSec=20
|
|
27
|
+
|
|
28
|
+
[Install]
|
|
29
|
+
WantedBy=default.target
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# pi-proactive 常驻助理的**保活监督器**(supervisor)。
|
|
5
|
+
#
|
|
6
|
+
# 角色:**同时**充当两个宿主里的「保活容器」——
|
|
7
|
+
# ① herdr 宿主:助理跑在 herdr pane 里(纯 headless:无 TUI、不抢 stdin);
|
|
8
|
+
# ② 系统宿主:launchd / systemd --user 单元跑的就是这个脚本。
|
|
9
|
+
# 两者**跑的是同一个脚本** → 谁先拿到「值班锁」谁当值班进程,另一个转为待命。
|
|
10
|
+
#
|
|
11
|
+
# 为什么必须这样(形态选型 §2.5):
|
|
12
|
+
# - 「用 herdr 工具」≠「有常驻」:herdr server 挂了 / pane 被回收 → 助理就没了;
|
|
13
|
+
# - 所以:**任何一边的宿主没了,另一边立刻接管**(助理不会随宿主一起消失);
|
|
14
|
+
# - 这就是 §2.5 要求的「server 挂 → 助理可判定的降级」——降级目标 = 自带 daemon。
|
|
15
|
+
#
|
|
16
|
+
# 判定(**可判定**,不猜):
|
|
17
|
+
# - 心跳新鲜(< STALE_MS)→ 已有实例在值班 → **不重复拉起**(避免双开 → 避免重复打扰);
|
|
18
|
+
# - 心跳陈旧/缺失 → 抢 `daemon.lock`(mkdir 原子锁)→ 拿到锁的成为值班进程。
|
|
19
|
+
#
|
|
20
|
+
# 模板文件:双下划线包裹的大写占位符由 `pi-proactive/tools/daemon-install.sh` 渲染。
|
|
21
|
+
set -uo pipefail
|
|
22
|
+
|
|
23
|
+
NODE_BIN="__NODE__"
|
|
24
|
+
DAEMON_TS="__DAEMON_TS__"
|
|
25
|
+
AGENT_DIR="__AGENT_DIR__"
|
|
26
|
+
AGENT_ID="__AGENT_ID__"
|
|
27
|
+
LOG_DIR="__LOG_DIR__"
|
|
28
|
+
|
|
29
|
+
export PI_PROACTIVE_AGENT_ID="${AGENT_ID}"
|
|
30
|
+
|
|
31
|
+
DAEMON_DIR="${AGENT_DIR}/proactive/daemon"
|
|
32
|
+
HEARTBEAT_FILE="${DAEMON_DIR}/heartbeat.json"
|
|
33
|
+
LOCK_DIR="${DAEMON_DIR}/daemon.lock"
|
|
34
|
+
# 心跳周期 5s(src/daemon.ts 的 HEARTBEAT_INTERVAL_MS)→ 20s 还没更新即判定「没在跑」。
|
|
35
|
+
STALE_MS=20000
|
|
36
|
+
|
|
37
|
+
mkdir -p "${LOG_DIR}" 2>/dev/null || true
|
|
38
|
+
|
|
39
|
+
# 心跳是否新鲜(= 已经有实例在值班)。
|
|
40
|
+
heartbeat_fresh() {
|
|
41
|
+
[ -f "${HEARTBEAT_FILE}" ] || return 1
|
|
42
|
+
local ts now
|
|
43
|
+
ts="$("${NODE_BIN}" -e '
|
|
44
|
+
const fs=require("fs");
|
|
45
|
+
try{const j=JSON.parse(fs.readFileSync(process.argv[1],"utf8"));console.log(String(j.ts??""))}catch{console.log("")}' "${HEARTBEAT_FILE}" 2>/dev/null)"
|
|
46
|
+
[ -n "${ts}" ] || return 1
|
|
47
|
+
now="$(date +%s000)"
|
|
48
|
+
[ $(( now - ts )) -lt ${STALE_MS} ]
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# 抢值班锁(mkdir 是原子的 → 两个监督器同时启动也只有一个能当值班进程)。
|
|
52
|
+
acquire_lock() {
|
|
53
|
+
if mkdir "${LOCK_DIR}" 2>/dev/null; then
|
|
54
|
+
printf '%s' "$$" >"${LOCK_DIR}/pid" 2>/dev/null || true
|
|
55
|
+
return 0
|
|
56
|
+
fi
|
|
57
|
+
# 锁可能是上次崩溃留下的 → 锁里的 pid 不在了就清掉重抢。
|
|
58
|
+
local owner=""
|
|
59
|
+
owner="$(cat "${LOCK_DIR}/pid" 2>/dev/null || true)"
|
|
60
|
+
if [ -n "${owner}" ] && kill -0 "${owner}" 2>/dev/null; then
|
|
61
|
+
return 1
|
|
62
|
+
fi
|
|
63
|
+
rm -rf "${LOCK_DIR}" 2>/dev/null || true
|
|
64
|
+
if mkdir "${LOCK_DIR}" 2>/dev/null; then
|
|
65
|
+
printf '%s' "$$" >"${LOCK_DIR}/pid" 2>/dev/null || true
|
|
66
|
+
return 0
|
|
67
|
+
fi
|
|
68
|
+
return 1
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
while true; do
|
|
72
|
+
if heartbeat_fresh; then
|
|
73
|
+
# 已有实例在值班(多半是另一个宿主里的那个)→ 待命,不重复拉起。
|
|
74
|
+
sleep 3
|
|
75
|
+
continue
|
|
76
|
+
fi
|
|
77
|
+
if acquire_lock; then
|
|
78
|
+
"${NODE_BIN}" --experimental-strip-types "${DAEMON_TS}" --agent-dir "${AGENT_DIR}" \
|
|
79
|
+
>>"${LOG_DIR}/daemon.out.log" 2>>"${LOG_DIR}/daemon.err.log"
|
|
80
|
+
# 值班进程退出 → 释放锁,稍后重试(崩溃自愈)。
|
|
81
|
+
rm -rf "${LOCK_DIR}" 2>/dev/null || true
|
|
82
|
+
fi
|
|
83
|
+
sleep 3
|
|
84
|
+
done
|
|
@@ -16,8 +16,9 @@ function Separator() {
|
|
|
16
16
|
function ImportSection(build) {
|
|
17
17
|
const context = build.UseUnevaluated() ? [`import { CheckContext } from "typebox/schema"`] : [];
|
|
18
18
|
const hashing = `import { Hashing } from "typebox/system"`;
|
|
19
|
+
const format = `import { Format } from "typebox/format"`;
|
|
19
20
|
const guard = `import { Guard } from "typebox/guard"`;
|
|
20
|
-
return [...context, hashing, guard];
|
|
21
|
+
return [...context, hashing, format, guard];
|
|
21
22
|
}
|
|
22
23
|
// ------------------------------------------------------------------
|
|
23
24
|
// ExternalSection
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// deno-fmt-ignore-file
|
|
2
|
-
import { EnableParseErrors, DisableParseErrors } from '../system/settings/internal.mjs';
|
|
3
2
|
import { Settings } from '../system/settings/index.mjs';
|
|
4
3
|
import { Errors, Clean, Convert, Create, Default, Decode, Encode, HasCodec, Parser, ParseError } from '../value/index.mjs';
|
|
5
4
|
import { Build } from '../schema/index.mjs';
|
|
@@ -52,10 +51,7 @@ export class Validator {
|
|
|
52
51
|
return value;
|
|
53
52
|
if (Settings.Get().correctiveParse)
|
|
54
53
|
return Parser(this.Context(), this.Type(), value);
|
|
55
|
-
|
|
56
|
-
const errors = this.Errors(value);
|
|
57
|
-
DisableParseErrors();
|
|
58
|
-
throw new ParseError(value, errors);
|
|
54
|
+
throw new ParseError(value, this.Errors(value));
|
|
59
55
|
}
|
|
60
56
|
/** Returns an array of validation errors for the given value. */
|
|
61
57
|
Errors(value) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Returns true if the
|
|
2
|
+
* Returns true if the value is a ISO8601 DateTime string
|
|
3
3
|
* @specification https://datatracker.ietf.org/doc/html/rfc3339
|
|
4
|
-
* @specification https://datatracker.ietf.org/doc/html/rfc9557
|
|
5
4
|
* @example `2020-12-12T20:20:40+00:00`
|
|
6
5
|
*/
|
|
7
6
|
export declare function IsDateTime(value: string): boolean;
|
|
@@ -1,20 +1,11 @@
|
|
|
1
1
|
import { IsDate } from './date.mjs';
|
|
2
2
|
import { IsTime } from './time.mjs';
|
|
3
|
-
// ------------------------------------------------------------------
|
|
4
|
-
// RFC 9557 DATE_TIME_SUFFIX
|
|
5
|
-
// ------------------------------------------------------------------
|
|
6
|
-
const DATE_TIME_SUFFIX = /^(?:\[!?(?:(?!\.{1,2}[/\]])[A-Za-z._][A-Za-z._0-9+-]{0,13}(?:\/(?!\.{1,2}[/\]])[A-Za-z._][A-Za-z._0-9+-]{0,13})*|[+-](?:[01][0-9]|2[0-3]):[0-5][0-9])\](?:\[!?[a-z_][a-z_0-9-]*=[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*\])*|(?:\[!?[a-z_][a-z_0-9-]*=[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*\])*)$/;
|
|
7
3
|
/**
|
|
8
|
-
* Returns true if the
|
|
4
|
+
* Returns true if the value is a ISO8601 DateTime string
|
|
9
5
|
* @specification https://datatracker.ietf.org/doc/html/rfc3339
|
|
10
|
-
* @specification https://datatracker.ietf.org/doc/html/rfc9557
|
|
11
6
|
* @example `2020-12-12T20:20:40+00:00`
|
|
12
7
|
*/
|
|
13
8
|
export function IsDateTime(value) {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
if (index !== -1 && !DATE_TIME_SUFFIX.test(value.slice(index)))
|
|
17
|
-
return false;
|
|
18
|
-
const split = datetime.split(/T/i);
|
|
19
|
-
return split.length === 2 && IsDate(split[0]) && IsTime(split[1]);
|
|
9
|
+
const dateTime = value.split(/T/i);
|
|
10
|
+
return dateTime.length === 2 && IsDate(dateTime[0]) && IsTime(dateTime[1]);
|
|
20
11
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Returns true if the value is a valid duration.
|
|
3
|
-
* @specification https://
|
|
2
|
+
* Returns true if the value is a valid ISO-8601 duration.
|
|
3
|
+
* @specification https://tools.ietf.org/html/rfc3339
|
|
4
4
|
*/
|
|
5
5
|
export declare function IsDuration(value: string): boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const Duration = /^P((\d+Y(\d+M(\d+D)?)?|\d+M(\d+D)?|\d+D)(T(\d+H(\d+M(\d+S)?)?|\d+M(\d+S)?|\d+S))?|T(\d+H(\d+M(\d+S)?)?|\d+M(\d+S)?|\d+S)|\d+W)$/;
|
|
2
2
|
/**
|
|
3
|
-
* Returns true if the value is a valid duration.
|
|
4
|
-
* @specification https://
|
|
3
|
+
* Returns true if the value is a valid ISO-8601 duration.
|
|
4
|
+
* @specification https://tools.ietf.org/html/rfc3339
|
|
5
5
|
*/
|
|
6
6
|
export function IsDuration(value) {
|
|
7
7
|
return Duration.test(value);
|
|
@@ -2,7 +2,6 @@ const IdnEmail = /^(?:[A-Za-z0-9!#$%&'*+\/=?^_`{|}~\u{0080}-\u{10FFFF}-]+(?:\.[A
|
|
|
2
2
|
/**
|
|
3
3
|
* Returns true if the value is an IdnEmail
|
|
4
4
|
* @specification https://datatracker.ietf.org/doc/html/rfc4952
|
|
5
|
-
* @specification https://datatracker.ietf.org/doc/html/rfc6531
|
|
6
5
|
*/
|
|
7
6
|
export function IsIdnEmail(value) {
|
|
8
7
|
return IdnEmail.test(value.normalize('NFC'));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Returns true if the value is a valid internationalized (IDN) hostname.
|
|
3
|
-
* @specification https://
|
|
3
|
+
* @specification https://tools.ietf.org/html/rfc3490
|
|
4
4
|
* @specification https://tools.ietf.org/html/rfc5891
|
|
5
5
|
* @specification https://tools.ietf.org/html/rfc5892
|
|
6
6
|
* @specification https://tools.ietf.org/html/rfc5893
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as Idna from './idna/index.mjs';
|
|
2
2
|
/**
|
|
3
3
|
* Returns true if the value is a valid internationalized (IDN) hostname.
|
|
4
|
-
* @specification https://
|
|
4
|
+
* @specification https://tools.ietf.org/html/rfc3490
|
|
5
5
|
* @specification https://tools.ietf.org/html/rfc5891
|
|
6
6
|
* @specification https://tools.ietf.org/html/rfc5892
|
|
7
7
|
* @specification https://tools.ietf.org/html/rfc5893
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Returns true if the value is
|
|
3
|
-
* @specification
|
|
2
|
+
* Returns true if the value is a IPV4 address
|
|
3
|
+
* @specification http://tools.ietf.org/html/rfc2673#section-3.2
|
|
4
4
|
*/
|
|
5
5
|
export declare function IsIPv4(value: string): boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const IPv4 = /^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/;
|
|
2
2
|
/**
|
|
3
|
-
* Returns true if the value is
|
|
4
|
-
* @specification
|
|
3
|
+
* Returns true if the value is a IPV4 address
|
|
4
|
+
* @specification http://tools.ietf.org/html/rfc2673#section-3.2
|
|
5
5
|
*/
|
|
6
6
|
export function IsIPv4(value) {
|
|
7
7
|
return IPv4.test(value);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const IPv6 = /^(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:)?[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)$/i;
|
|
2
2
|
/**
|
|
3
3
|
* Returns true if the value is an IPv6 address
|
|
4
|
-
* @specification
|
|
4
|
+
* @specification http://tools.ietf.org/html/rfc2373#section-2.2
|
|
5
5
|
*/
|
|
6
6
|
export function IsIPv6(value) {
|
|
7
7
|
return IPv6.test(value);
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
// deno-lint-ignore-file no-control-regex
|
|
2
|
+
const IpvFutureMatchMaxLength = 2048;
|
|
3
|
+
const IpvFutureMatch = /\[[vV][0-9a-fA-F]+\.[^\]]+\]/; // Guarded By IpvFutureMatchMaxLength
|
|
4
|
+
const InvalidIriChars = /[\x00-\x20<>\^`{|}\\]/;
|
|
5
|
+
const InvalidPercentEncoding = /%(?![0-9a-fA-F]{2})/;
|
|
2
6
|
// ------------------------------------------------------------------
|
|
3
|
-
//
|
|
4
|
-
// Removed by the following PR
|
|
5
|
-
//
|
|
6
|
-
// https://github.com/json-schema-org/JSON-Schema-Test-Suite/pull/1176
|
|
7
|
-
//
|
|
8
7
|
// NarrowIpvFuture
|
|
9
8
|
//
|
|
10
9
|
// Substitutes an IPvFuture address with a standard IPv6 loopback
|
|
@@ -14,18 +13,12 @@
|
|
|
14
13
|
// be expensive on large strings, this operation is strictly
|
|
15
14
|
// limited to inputs under a defined length threshold.
|
|
16
15
|
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
// const IpvFutureMatchMaxLength = 2048
|
|
20
|
-
// const IpvFutureMatch = /\[[vV][0-9a-fA-F]+\.[^\]]+\]/ // Guarded By IpvFutureMatchMaxLength
|
|
21
|
-
//
|
|
22
|
-
// function NarrowIpvFuture(value: string): string {
|
|
23
|
-
// return value.length < IpvFutureMatchMaxLength ? value.replace(IpvFutureMatch, '[::1]') : value
|
|
24
|
-
// }
|
|
16
|
+
// (review-optimization)
|
|
25
17
|
//
|
|
26
18
|
// ------------------------------------------------------------------
|
|
27
|
-
|
|
28
|
-
|
|
19
|
+
function NarrowIpvFuture(value) {
|
|
20
|
+
return value.length < IpvFutureMatchMaxLength ? value.replace(IpvFutureMatch, '[::1]') : value;
|
|
21
|
+
}
|
|
29
22
|
/**
|
|
30
23
|
* Returns true if the value is a valid Internationalized Resource Identifier.
|
|
31
24
|
* @specification https://datatracker.ietf.org/doc/html/rfc3987
|
|
@@ -38,5 +31,5 @@ export function IsIri(value) {
|
|
|
38
31
|
if (InvalidPercentEncoding.test(value))
|
|
39
32
|
return false;
|
|
40
33
|
// 3. Delegate to the native URL parser, patching the IPvFuture edge case beforehand.
|
|
41
|
-
return URL.canParse(value);
|
|
34
|
+
return URL.canParse(NarrowIpvFuture(value));
|
|
42
35
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Returns true if the value is a relative
|
|
3
|
-
* @specification https://datatracker.ietf.org/doc/html/
|
|
2
|
+
* Returns true if the value is a relative json pointer
|
|
3
|
+
* @specification https://datatracker.ietf.org/doc/html/rfc6901
|
|
4
4
|
* @source https://github.com/ajv-validator/ajv-formats
|
|
5
5
|
*/
|
|
6
6
|
export declare function IsRelativeJsonPointer(value: string): boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const RelativeJsonPointer = /^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/;
|
|
2
2
|
/**
|
|
3
|
-
* Returns true if the value is a relative
|
|
4
|
-
* @specification https://datatracker.ietf.org/doc/html/
|
|
3
|
+
* Returns true if the value is a relative json pointer
|
|
4
|
+
* @specification https://datatracker.ietf.org/doc/html/rfc6901
|
|
5
5
|
* @source https://github.com/ajv-validator/ajv-formats
|
|
6
6
|
*/
|
|
7
7
|
export function IsRelativeJsonPointer(value) {
|
|
@@ -97,10 +97,10 @@ export function IsGreaterEqualThan(left, right) {
|
|
|
97
97
|
// String
|
|
98
98
|
// --------------------------------------------------------------------------
|
|
99
99
|
export function IsMinLength(value, length) {
|
|
100
|
-
return `
|
|
100
|
+
return `Guard.IsMinLength(${value}, ${length})`;
|
|
101
101
|
}
|
|
102
102
|
export function IsMaxLength(value, length) {
|
|
103
|
-
return `
|
|
103
|
+
return `Guard.IsMaxLength(${value}, ${length})`;
|
|
104
104
|
}
|
|
105
105
|
// --------------------------------------------------------------------------
|
|
106
106
|
// Array
|
|
@@ -33,14 +33,12 @@ export declare function IsMultipleOf(dividend: bigint | number, divisor: bigint
|
|
|
33
33
|
/** Returns true if the value appears to be an instance of a class. */
|
|
34
34
|
export declare function IsClassInstance(value: unknown): boolean;
|
|
35
35
|
export declare function IsValueLike(value: unknown): value is bigint | boolean | null | number | string | undefined;
|
|
36
|
-
/** Returns the
|
|
36
|
+
/** Returns the number of grapheme clusters in the string */
|
|
37
37
|
export declare function GraphemeCount(value: string): number;
|
|
38
|
-
/** Returns the
|
|
39
|
-
export declare function
|
|
40
|
-
/** Returns true if the string
|
|
41
|
-
export declare function
|
|
42
|
-
/** Returns true if the string length in Unicode code points is at least minLength */
|
|
43
|
-
export declare function IsMinLength(value: string, minLength: number): boolean;
|
|
38
|
+
/** Returns true if the string has at most the given number of graphemes */
|
|
39
|
+
export declare function IsMaxLength(value: string, length: number): boolean;
|
|
40
|
+
/** Returns true if the string has at least the given number of graphemes */
|
|
41
|
+
export declare function IsMinLength(value: string, length: number): boolean;
|
|
44
42
|
/** Returns true if every element from offset satisfies the callback, short-circuiting on the first failure */
|
|
45
43
|
export declare function Every<T>(value: T[], offset: number, callback: (value: T, index: number) => boolean): boolean;
|
|
46
44
|
/** Returns true if every element from offset satisfies the callback, using exhaustive enumeration */
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// deno-fmt-ignore-file
|
|
2
|
-
import * as
|
|
3
|
-
import * as UnicodeGuard from './unicode/unicode.mjs';
|
|
2
|
+
import * as String from './string.mjs';
|
|
4
3
|
// --------------------------------------------------------------------------
|
|
5
4
|
// Guards
|
|
6
5
|
// --------------------------------------------------------------------------
|
|
@@ -124,21 +123,17 @@ export function IsValueLike(value) {
|
|
|
124
123
|
// --------------------------------------------------------------------------
|
|
125
124
|
// String
|
|
126
125
|
// --------------------------------------------------------------------------
|
|
127
|
-
/** Returns the
|
|
126
|
+
/** Returns the number of grapheme clusters in the string */
|
|
128
127
|
export function GraphemeCount(value) {
|
|
129
|
-
return
|
|
128
|
+
return String.GraphemeCount(value);
|
|
130
129
|
}
|
|
131
|
-
/** Returns the
|
|
132
|
-
export function
|
|
133
|
-
return
|
|
130
|
+
/** Returns true if the string has at most the given number of graphemes */
|
|
131
|
+
export function IsMaxLength(value, length) {
|
|
132
|
+
return String.IsMaxLength(value, length);
|
|
134
133
|
}
|
|
135
|
-
/** Returns true if the string
|
|
136
|
-
export function
|
|
137
|
-
return
|
|
138
|
-
}
|
|
139
|
-
/** Returns true if the string length in Unicode code points is at least minLength */
|
|
140
|
-
export function IsMinLength(value, minLength) {
|
|
141
|
-
return UnicodeGuard.IsMinLength(value, minLength);
|
|
134
|
+
/** Returns true if the string has at least the given number of graphemes */
|
|
135
|
+
export function IsMinLength(value, length) {
|
|
136
|
+
return String.IsMinLength(value, length);
|
|
142
137
|
}
|
|
143
138
|
// --------------------------------------------------------------------------
|
|
144
139
|
// Array
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
// ------------------------------------------------------------------
|
|
2
|
-
// Guards
|
|
3
|
-
// ------------------------------------------------------------------
|
|
4
1
|
export * as EmitGuard from './emit.mjs';
|
|
5
2
|
export * as GlobalsGuard from './globals.mjs';
|
|
6
3
|
export * as NativeGuard from './native.mjs';
|
|
7
|
-
// ------------------------------------------------------------------
|
|
8
|
-
// Default
|
|
9
|
-
// ------------------------------------------------------------------
|
|
10
4
|
import * as Guard from './guard.mjs';
|
|
11
5
|
export * as Guard from './guard.mjs';
|
|
12
6
|
export default Guard;
|
|
@@ -91,12 +91,26 @@ function IsGraphemeCodePoint(value) {
|
|
|
91
91
|
IsZeroWidthJoiner(value)));
|
|
92
92
|
}
|
|
93
93
|
// --------------------------------------------------------------------------
|
|
94
|
+
// GraphemeCount
|
|
95
|
+
// --------------------------------------------------------------------------
|
|
96
|
+
/** Returns the number of grapheme clusters in a string */
|
|
97
|
+
export function GraphemeCount(value) {
|
|
98
|
+
let count = 0;
|
|
99
|
+
let index = 0;
|
|
100
|
+
while (index < value.length) {
|
|
101
|
+
index = NextGraphemeClusterIndex(value, index);
|
|
102
|
+
count++;
|
|
103
|
+
}
|
|
104
|
+
return count;
|
|
105
|
+
}
|
|
106
|
+
// --------------------------------------------------------------------------
|
|
94
107
|
// IsMinLengthSegmented
|
|
95
108
|
// --------------------------------------------------------------------------
|
|
96
109
|
/** Checks if a string has at least a minimum number of grapheme clusters */
|
|
97
110
|
function IsMinLengthSegmented(value, minLength) {
|
|
98
111
|
// if (minLength === 0) return true // 0-length (unreachable)
|
|
99
|
-
let count = 0
|
|
112
|
+
let count = 0;
|
|
113
|
+
let index = 0;
|
|
100
114
|
while (index < value.length) {
|
|
101
115
|
index = NextGraphemeClusterIndex(value, index);
|
|
102
116
|
if ((++count) >= minLength)
|
|
@@ -109,7 +123,8 @@ function IsMinLengthSegmented(value, minLength) {
|
|
|
109
123
|
// --------------------------------------------------------------------------
|
|
110
124
|
/** Checks if a string has at most a maximum number of grapheme clusters */
|
|
111
125
|
function IsMaxLengthSegmented(value, maxLength) {
|
|
112
|
-
let count = 0
|
|
126
|
+
let count = 0;
|
|
127
|
+
let index = 0;
|
|
113
128
|
while (index < value.length) {
|
|
114
129
|
index = NextGraphemeClusterIndex(value, index);
|
|
115
130
|
if ((++count) > maxLength)
|
|
@@ -118,19 +133,7 @@ function IsMaxLengthSegmented(value, maxLength) {
|
|
|
118
133
|
return true;
|
|
119
134
|
}
|
|
120
135
|
// --------------------------------------------------------------------------
|
|
121
|
-
//
|
|
122
|
-
// --------------------------------------------------------------------------
|
|
123
|
-
/** Returns the number of grapheme clusters in a string */
|
|
124
|
-
export function GraphemeCount(value) {
|
|
125
|
-
let count = 0, index = 0;
|
|
126
|
-
while (index < value.length) {
|
|
127
|
-
index = NextGraphemeClusterIndex(value, index);
|
|
128
|
-
count++;
|
|
129
|
-
}
|
|
130
|
-
return count;
|
|
131
|
-
}
|
|
132
|
-
// --------------------------------------------------------------------------
|
|
133
|
-
// IsMinLength
|
|
136
|
+
// IsMinLengthFast
|
|
134
137
|
// --------------------------------------------------------------------------
|
|
135
138
|
/** Fast check for minimum grapheme length, falls back to full check if needed */
|
|
136
139
|
export function IsMinLength(value, minLength) {
|
|
@@ -148,7 +151,7 @@ export function IsMinLength(value, minLength) {
|
|
|
148
151
|
}
|
|
149
152
|
}
|
|
150
153
|
// --------------------------------------------------------------------------
|
|
151
|
-
//
|
|
154
|
+
// IsMaxLengthFast
|
|
152
155
|
// --------------------------------------------------------------------------
|
|
153
156
|
/** Fast check for maximum grapheme length, falls back to full check if needed */
|
|
154
157
|
export function IsMaxLength(value, maxLength) {
|
|
@@ -4,6 +4,7 @@ import { Arguments } from '../system/arguments/index.mjs';
|
|
|
4
4
|
import { Environment } from '../system/environment/index.mjs';
|
|
5
5
|
import { Hashing } from '../system/hashing/index.mjs';
|
|
6
6
|
import { Guard } from '../guard/index.mjs';
|
|
7
|
+
import { Format } from '../format/index.mjs';
|
|
7
8
|
import * as Engine from './engine/index.mjs';
|
|
8
9
|
// ------------------------------------------------------------------
|
|
9
10
|
// CreateCode
|
|
@@ -19,14 +20,14 @@ function CreateCode(build) {
|
|
|
19
20
|
// CreateEvaluatedCheck
|
|
20
21
|
// ------------------------------------------------------------------
|
|
21
22
|
function CreateEvaluatedCheck(build, code) {
|
|
22
|
-
const factory = Environment.Evaluate('CheckContext', 'Guard', 'Hashing', build.External().identifier, code);
|
|
23
|
-
return factory(Engine.CheckContext, Guard, Hashing, build.External().variables);
|
|
23
|
+
const factory = Environment.Evaluate('CheckContext', 'Guard', 'Format', 'Hashing', build.External().identifier, code);
|
|
24
|
+
return factory(Engine.CheckContext, Guard, Format, Hashing, build.External().variables);
|
|
24
25
|
}
|
|
25
26
|
// ------------------------------------------------------------------
|
|
26
27
|
// CreateDynamicCheck
|
|
27
28
|
// ------------------------------------------------------------------
|
|
28
29
|
function CreateDynamicCheck(build) {
|
|
29
|
-
const stack = Engine.Stack(build.Context(), build.Schema());
|
|
30
|
+
const stack = new Engine.Stack(build.Context(), build.Schema());
|
|
30
31
|
const context = new Engine.CheckContext();
|
|
31
32
|
return (value) => Engine.CheckSchema(stack, context, build.Schema(), value);
|
|
32
33
|
}
|
|
@@ -106,10 +107,9 @@ export function Build(...args) {
|
|
|
106
107
|
2: (context, schema) => [context, schema],
|
|
107
108
|
1: (schema) => [{}, schema]
|
|
108
109
|
});
|
|
109
|
-
Engine.ResetUnique();
|
|
110
110
|
Engine.ResetExternal();
|
|
111
111
|
Engine.ResetFunctions();
|
|
112
|
-
const stack = Engine.Stack(context, schema);
|
|
112
|
+
const stack = new Engine.Stack(context, schema);
|
|
113
113
|
const build = new Engine.BuildContext(Engine.HasUnevaluated(context, schema));
|
|
114
114
|
const call = Engine.CreateFunction(stack, build, schema, 'value');
|
|
115
115
|
const functions = Engine.GetFunctions();
|
|
@@ -8,7 +8,7 @@ export function Check(...args) {
|
|
|
8
8
|
3: (context, schema, value) => [context, schema, value],
|
|
9
9
|
2: (schema, value) => [{}, schema, value]
|
|
10
10
|
});
|
|
11
|
-
const stack = Engine.Stack(context, schema);
|
|
11
|
+
const stack = new Engine.Stack(context, schema);
|
|
12
12
|
const checkContext = new Engine.CheckContext();
|
|
13
13
|
return Engine.CheckSchema(stack, checkContext, schema, value);
|
|
14
14
|
}
|
|
@@ -25,10 +25,6 @@ export declare class ErrorContext extends CheckContext {
|
|
|
25
25
|
private readonly errors;
|
|
26
26
|
constructor();
|
|
27
27
|
AtCapacity(): boolean;
|
|
28
|
-
AddError
|
|
29
|
-
keyword: Keyword;
|
|
30
|
-
}>['params']): false;
|
|
31
|
-
AddErrors(error: TValidationError[]): false;
|
|
28
|
+
AddError(error: TValidationError): false;
|
|
32
29
|
GetErrors(): TValidationError[];
|
|
33
|
-
private AddErrorObject;
|
|
34
30
|
}
|