diff --git a/docs/i18n/01-dashboard-zh.png b/docs/i18n/01-dashboard-zh.png new file mode 100644 index 0000000..47572eb Binary files /dev/null and b/docs/i18n/01-dashboard-zh.png differ diff --git a/docs/i18n/02-bulk-bar-zh.png b/docs/i18n/02-bulk-bar-zh.png new file mode 100644 index 0000000..0aee0f8 Binary files /dev/null and b/docs/i18n/02-bulk-bar-zh.png differ diff --git a/docs/i18n/03-validation-refusal-zh.png b/docs/i18n/03-validation-refusal-zh.png new file mode 100644 index 0000000..a6312f1 Binary files /dev/null and b/docs/i18n/03-validation-refusal-zh.png differ diff --git a/package.json b/package.json index 4dc05fe..74c44af 100644 --- a/package.json +++ b/package.json @@ -17,22 +17,22 @@ "verify": "pnpm validate && pnpm typecheck && pnpm test" }, "dependencies": { - "@objectstack/spec": "^17.2.0", - "@objectstack/runtime": "^17.2.0", - "@objectstack/plugin-hono-server": "^17.2.0", - "@objectstack/connector-rest": "^17.2.0", - "@objectstack/connector-openapi": "^17.2.0", - "@objectstack/connector-mcp": "^17.2.0" + "@objectstack/spec": "^17.3.0", + "@objectstack/runtime": "^17.3.0", + "@objectstack/plugin-hono-server": "^17.3.0", + "@objectstack/connector-rest": "^17.3.0", + "@objectstack/connector-openapi": "^17.3.0", + "@objectstack/connector-mcp": "^17.3.0" }, "devDependencies": { - "@objectstack/cli": "^17.2.0", - "@objectstack/platform-objects": "^17.2.0", - "@objectstack/plugin-email": "^17.2.0", - "@objectstack/plugin-sharing": "^17.2.0", - "@objectstack/service-automation": "^17.2.0", - "@objectstack/service-job": "^17.2.0", - "@objectstack/service-messaging": "^17.2.0", - "@objectstack/trigger-schedule": "^17.2.0", + "@objectstack/cli": "^17.3.0", + "@objectstack/platform-objects": "^17.3.0", + "@objectstack/plugin-email": "^17.3.0", + "@objectstack/plugin-sharing": "^17.3.0", + "@objectstack/service-automation": "^17.3.0", + "@objectstack/service-job": "^17.3.0", + "@objectstack/service-messaging": "^17.3.0", + "@objectstack/trigger-schedule": "^17.3.0", "typescript": "^6.0.0", "vitest": "^4.1.10" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ac05eb1..b8dff31 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,48 +9,48 @@ importers: .: dependencies: '@objectstack/connector-mcp': - specifier: ^17.2.0 - version: 17.2.0(zod@4.5.4) + specifier: ^17.3.0 + version: 17.3.0(zod@4.5.4) '@objectstack/connector-openapi': - specifier: ^17.2.0 - version: 17.2.0 + specifier: ^17.3.0 + version: 17.3.0 '@objectstack/connector-rest': - specifier: ^17.2.0 - version: 17.2.0 + specifier: ^17.3.0 + version: 17.3.0 '@objectstack/plugin-hono-server': - specifier: ^17.2.0 - version: 17.2.0 + specifier: ^17.3.0 + version: 17.3.0 '@objectstack/runtime': - specifier: ^17.2.0 - version: 17.2.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + specifier: ^17.3.0 + version: 17.3.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) '@objectstack/spec': - specifier: ^17.2.0 - version: 17.2.0 + specifier: ^17.3.0 + version: 17.3.0 devDependencies: '@objectstack/cli': - specifier: ^17.2.0 - version: 17.2.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + specifier: ^17.3.0 + version: 17.3.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) '@objectstack/platform-objects': - specifier: ^17.2.0 - version: 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + specifier: ^17.3.0 + version: 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) '@objectstack/plugin-email': - specifier: ^17.2.0 - version: 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + specifier: ^17.3.0 + version: 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) '@objectstack/plugin-sharing': - specifier: ^17.2.0 - version: 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + specifier: ^17.3.0 + version: 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) '@objectstack/service-automation': - specifier: ^17.2.0 - version: 17.2.0 + specifier: ^17.3.0 + version: 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) '@objectstack/service-job': - specifier: ^17.2.0 - version: 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + specifier: ^17.3.0 + version: 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) '@objectstack/service-messaging': - specifier: ^17.2.0 - version: 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + specifier: ^17.3.0 + version: 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) '@objectstack/trigger-schedule': - specifier: ^17.2.0 - version: 17.2.0 + specifier: ^17.3.0 + version: 17.3.0 typescript: specifier: ^6.0.0 version: 6.0.3 @@ -139,13 +139,13 @@ packages: prisma: optional: true - '@better-auth/scim@1.7.0-rc.1': - resolution: {integrity: sha512-pcnliU2eewYq2SF4cRDn1XvQ2I7+WhufoDv5lx9yH7fmrfsU6mYQpZX3mu2Fj/AFCHauCI7Ld617pnz5+yTtOw==} + '@better-auth/scim@1.7.2': + resolution: {integrity: sha512-RBwVN189w37xwK0n+mRgARTmJFCriOsMVCbe7Bzeyak6esSg9kTGeCUmGtfgwOKJ3jJWQkeAQdWw7VRJ/HOG6w==} peerDependencies: - '@better-auth/core': ^1.7.0-rc.1 + '@better-auth/core': ^1.7.2 '@better-auth/utils': 0.4.2 - better-auth: ^1.7.0-rc.1 - better-call: 1.3.7 + better-auth: ^1.7.2 + better-call: 1.4.0 '@better-auth/sso@1.7.2': resolution: {integrity: sha512-8tmkAGdcVu8Tr/+LPfSRgs/5a8YE1uU8OeaN5mAzsSdMWR4iwZdwQlJJmU8f9qZyIpNL/B6mIfDc5vaVUy1ECQ==} @@ -397,54 +397,54 @@ packages: '@nodable/entities@3.0.0': resolution: {integrity: sha512-8L9xFeTYKhm49xfIypoe2W5wV1m/3Z58kT+7kR9A8OyFxcPduI4VmxaUMQyKYrRjUoLLSXv6EKKID5Tvj9cUVw==} - '@objectstack/account@17.2.0': - resolution: {integrity: sha512-2qzEoMhGF1z12udEMMQB8yDmYK4e1UUG+wSHf4uvejDILxv9kFAB0xpuOT53q6MG6jtbzEjZdu5NwuwoL04N9w==} + '@objectstack/account@17.3.0': + resolution: {integrity: sha512-m4t99EdHiIbVrKhVzNc7Q6o3vCk2QK7NWW0ugpGwbFrHl43L7WdPrYiTjfo1aWfbEcqW0yj2YouOQ3uW0G7C4w==} engines: {node: '>=22.0.0'} - '@objectstack/cli@17.2.0': - resolution: {integrity: sha512-rJFfvzmK7qV6qK26zR2V5jodFiyNpqLveRPNxmCic1B1o5EoF7g2habTgOrKkQzT3JDUyfhChbBFTB8yxGep5Q==} + '@objectstack/cli@17.3.0': + resolution: {integrity: sha512-I41b1A+0LUPBOwjAWe502GGELE/lVhzi9ERJZDnuvYjXSPm7Qflh14rdCzT0X+Wg8Z+KWQu4mp4NYFYNJ7Fhqw==} engines: {node: '>=22.0.0'} hasBin: true peerDependencies: - '@objectstack/driver-turso': ^17.2.0 + '@objectstack/driver-turso': ^17.3.0 peerDependenciesMeta: '@objectstack/driver-turso': optional: true - '@objectstack/client@17.2.0': - resolution: {integrity: sha512-bVRrWyqpn71U6HxQ2IuOuI5sg6b/xp0ZGaKms41+y1a/22bv1Q9cdTd3nY71jGvKmVZ/TJMEd8+D1poAPQQrKQ==} + '@objectstack/client@17.3.0': + resolution: {integrity: sha512-EoxDSZPxdqiInaEQ2eZlRAL0LES73sT2xVUqbUW84pXcB2f+s2uztOZmdkE/IDS65oBrMe8NnJ++q5RrwgI+wg==} engines: {node: '>=22.0.0'} - '@objectstack/cloud-connection@17.2.0': - resolution: {integrity: sha512-juLHj9gCZdF+mlp7iWR0LsfpsqB5ywo++MnndXmdqBKY8Nx7zHr5lSsxjKgD7Y3HR1npbKrt5NVPEly6Lq+elA==} + '@objectstack/cloud-connection@17.3.0': + resolution: {integrity: sha512-GftVHxdPNN/NKT7oOIlgRpYcKgkMVs/pBO8hXTAXiZXQJPUtCwAc27itysV+iga4S3SP8aR7R9h/+QeHz7WRsw==} engines: {node: '>=22.0.0'} - '@objectstack/connector-mcp@17.2.0': - resolution: {integrity: sha512-xXvOUXvavdOV2xnq+c+Rmme3oZTyTqkr89THa82R8hrUnhd613r/npCAFDkaTL2omuxO8tnVAlvHILuoVCMpWA==} + '@objectstack/connector-mcp@17.3.0': + resolution: {integrity: sha512-x+PFCIG7EPbq2wR/zIjGIvfeM8lRCePW0fyPLixpVY3ff3oTuQY7OduspbYHftahxf0K45As8zBTt79FR2/3VQ==} - '@objectstack/connector-openapi@17.2.0': - resolution: {integrity: sha512-k017Ix3s2iGK0n7BXDUHuAJT9eMbTg7cAE0QMbzowuZ+zZoWM/SYLjLXo16DwdnLIjq30k1hGmSydYh9yZ3KXQ==} + '@objectstack/connector-openapi@17.3.0': + resolution: {integrity: sha512-xPIbZ411b9408y6ejxv8xawPwOci4x2Vs601Iwt/Vjc8wTMpft+uM2G71kHtgaGkMaixlOygeW2sf1RxIzbJag==} - '@objectstack/connector-rest@17.2.0': - resolution: {integrity: sha512-oS/ixUuyc9xe02rxz/IvxMwlKMkLy33VUNDsEQwA99CkPnxbKTubxslBEJDIs3TTrDOt6Iq5M2sdFPMKN5sR3g==} + '@objectstack/connector-rest@17.3.0': + resolution: {integrity: sha512-0MybHbjfNi5GrBDVsQpNDQNGH7QeqP6Mo8qAnDaERB7jGuMISFdRacTs5249dnbc9zRyhvB5GIHNsgna3XlgDQ==} - '@objectstack/console@17.2.0': - resolution: {integrity: sha512-1vPuIageXISvpweoZLC9dsWjDPzkYJg9d15vxivlPAGxEhTU9IgK3wa41GiMNCDQhPE6CpDvq/+JPsVFX4514w==} + '@objectstack/console@17.3.0': + resolution: {integrity: sha512-R+ZdiQdulgELZh7sIiZFipmP3M02LZjtwq4b4yzlOB+bfzeWVqGppA53kBXkYolRT/T3kbQzlwyWojpbn5R5KQ==} - '@objectstack/core@17.2.0': - resolution: {integrity: sha512-82I4eL/qcuFKOBhXWEGjJPAS9mOfwGVd9jeRbhRGuUZTm282sCuVoR/QC1JkDVxsFE0kSAtE4ej0XsYxP/spZQ==} + '@objectstack/core@17.3.0': + resolution: {integrity: sha512-MgH+HYLEl7dCQJ9XW4Wi/mBX32+WMUSf5X65DplUvHvfOeLQHnDg/GoXjnNVFBI+82A0tgkBPpvsvn7haduY8A==} engines: {node: '>=22.0.0'} - '@objectstack/driver-memory@17.2.0': - resolution: {integrity: sha512-zS9N62LwODC47BpvEq4u8C5NXiu2Z1TqvNZorXReHLwDT2KjZSQ3Y26c71Jg3J3BU2v+Sy1s3/rA2pmsYvrGpw==} + '@objectstack/driver-memory@17.3.0': + resolution: {integrity: sha512-avmZF9+czDU4dDhHksEusRhax8C/k7K/z2dobR/ltS2euabtnitLVgbeUQc+kehsgcwkoX3xz6VoaFmDoC1qhg==} engines: {node: '>=22.0.0'} - '@objectstack/driver-mongodb@17.2.0': - resolution: {integrity: sha512-c+nr0wQtf5mW6nr0zYc7FMsK05rfyu8Oun8tuvHkyMpYjQNa2zsMgWx4ctxOgnI0y6VRroBnZSs9KjDZYvRDDw==} + '@objectstack/driver-mongodb@17.3.0': + resolution: {integrity: sha512-I2p9jmubA77CCoK1jCYQIocLUeQwC0ce9o+Eh1Wci9Xo4wrhSIAzTTHcOUBv/eGJ7Ad0x+xAWqeoXCeW6Zf0BA==} engines: {node: '>=22.0.0'} - '@objectstack/driver-sql@17.2.0': - resolution: {integrity: sha512-9yYEY2HOEfp2LuaTrVYdbYOBUnf08qSPF8+qsKRAMuPkIPqO3kVg7v+S/uAooUhqf/G/jthFk+hRk5fg+RIYBQ==} + '@objectstack/driver-sql@17.3.0': + resolution: {integrity: sha512-BYirrbnhAchvorwnBfw0obkdn1UhMXTzKLSPAi/1H52OnuQyJFoNjxAkAzal1XNp3dMWKC7JziT9J6bFTgz95g==} engines: {node: '>=22.0.0'} peerDependencies: mysql2: ^3.0.0 @@ -458,23 +458,23 @@ packages: tedious: optional: true - '@objectstack/driver-sqlite-wasm@17.2.0': - resolution: {integrity: sha512-sBn8SVz2pWpiEKms07zw7sgNSwX53jA1GDaoDa+e1Jwg9MslwixykrfZnpsTOh7wkNxsf5hjuhQXzcb2QvB2ww==} + '@objectstack/driver-sqlite-wasm@17.3.0': + resolution: {integrity: sha512-Fu71c5YCXL+SWfLGhkd3VlnkEtmQqeiU7c4zw85jnPjZn5kxTgCSywtzivCNyG7re/pfNwvomjy0hI0/fMZYdg==} engines: {node: '>=22.0.0'} - '@objectstack/formula@17.2.0': - resolution: {integrity: sha512-5p6gn92AwNj0e1tfT6mCjBkIUOPjjPr4C6K7GtOAfL20MRIILKgVtf94rZBpWr8+WBGRND050RpssgtN8CqQ/A==} + '@objectstack/formula@17.3.0': + resolution: {integrity: sha512-zLR5DdFshJOvNMX9G4CPBPbWeVrWa/b1GxcMFhyNldtJCb92YlGsgd7vw8OWUkoxE+k9AnbfbxbDaxSxY2Ecgw==} - '@objectstack/lint@17.2.0': - resolution: {integrity: sha512-PbyvKuiDdIQ61nVTy2y+19wl3bFJ3uTQk8u0l+OpNJsUYR1YxXCMnayC/h7h66kTPLs4IgjVTOedc3hV0CiSkg==} + '@objectstack/lint@17.3.0': + resolution: {integrity: sha512-pRFjIZ+sQmlPT2N24aM9szwHK50P3AjiwmHEFi6DUHJGtDq/Tt4HtZ+89nF7WP0MfT1AK8nlNadxsDrHPF8UCg==} engines: {node: '>=22.0.0'} - '@objectstack/mcp@17.2.0': - resolution: {integrity: sha512-91g2PkdRumlzg9bQQJPd1T1kc5JBTJkQgoVjS7H+UXB1THXhj8cLVdIKPV6Boy4Medy7/T2N9h2If9XxKLrwfA==} + '@objectstack/mcp@17.3.0': + resolution: {integrity: sha512-nBgpePUqDM0yHvPd8+qf7Csw0gvgcVkEQxMOoDjv+8T/NFGJwofK1s74f6oq5oPVpeGu3HbFLj4lay3OQKCb/Q==} engines: {node: '>=22.0.0'} - '@objectstack/metadata-core@17.2.0': - resolution: {integrity: sha512-lr8ireU2nglhDzFNxA3yHlmCs5oIPFVTbl7AAvZDcb/EhE+bFH2IMa2pggc5srETSgrQwIgtYP9I3VsnR4nYOw==} + '@objectstack/metadata-core@17.3.0': + resolution: {integrity: sha512-bB01VP7j6ZAnTvbl9Jwg3GoEknrmi43S7R1BxniUhOtnlszPNnPRdoNVLeE3kOLN/7wdqqrwNyCtXirYlES9Jg==} engines: {node: '>=22.0.0'} peerDependencies: vitest: ^4.0.0 @@ -482,126 +482,142 @@ packages: vitest: optional: true - '@objectstack/metadata-fs@17.2.0': - resolution: {integrity: sha512-xSCkwqAC9CA+eMeWVUeao5uUm/cNeTWjLegs9X76Lygj69NvS3YETgxVgXjqrfp677ILYq5y5Jn5WwIcfPRqPg==} + '@objectstack/metadata-fs@17.3.0': + resolution: {integrity: sha512-BGUOgffmiTMI1O5ca2ay1JbQUO0sPibkhWQukIjEFu4soaFG49FtH3PwPqQcV4WGzi1EC3HeV15s7gRy2LvG3g==} engines: {node: '>=22.0.0'} - '@objectstack/metadata-protocol@17.2.0': - resolution: {integrity: sha512-hQG8tlDBf/7y6XGEULbrY2OxKI4cDv+jvD18KhgJ1602+KfxVXjoAxLHVPZIiLKIIsldut75K409+HxeX8/zhw==} + '@objectstack/metadata-protocol@17.3.0': + resolution: {integrity: sha512-nXyHPYNydUj26gOLVn8/7/Gm1a2mBGPT9dSCl3T/IVsIhcgUEPOaIkatQOIhHKMQPn0lWVuXd37/QnZX+T8zMQ==} engines: {node: '>=22.0.0'} - '@objectstack/metadata@17.2.0': - resolution: {integrity: sha512-ZZ9LGyQHG+qA2sJGdPBdXj+8wOO6ZqwGhREFH+FgNfbE5xqq1h8gspyo7bcDVqWFSDS/UQ6vHuiOLF8yvsoY7Q==} + '@objectstack/metadata@17.3.0': + resolution: {integrity: sha512-zp9tMM7Vt/Dx5sZpvJ/LIOsUpGN36bo4V6daZJeIe8uQaYbRsdpIcq/JoLX/SQz1+4bE9rRqqkDHsAvmlxDIZQ==} engines: {node: '>=22.0.0'} - '@objectstack/objectql@17.2.0': - resolution: {integrity: sha512-2CC7hLvp7IwItb8XihYSLFYcRD1Yn7YDbgJWb9/3SqtEDMID9uNV7PxUIahPkyqb6x4jnFOZSIxuGXzadUtFeA==} + '@objectstack/objectql@17.3.0': + resolution: {integrity: sha512-/zhgxX0lmd8RCgAzDgocTY2mzcBQle9TVp1HAbVkMfCVPK87o9KRrR6MMZVa9RuTjZkLpab0JVHUvye/vB4UOQ==} engines: {node: '>=22.0.0'} - '@objectstack/observability@17.2.0': - resolution: {integrity: sha512-sohqkmsU18u4sILJrd6/p8BI08PvuU23wfs6XNDE3YBfIxHfgeiRQzUj9iiHNIgv8Lcsa+xlHM6UAku4RF1QAg==} + '@objectstack/observability@17.3.0': + resolution: {integrity: sha512-e7apFFPktKaSv1q8fEfYgEYsM7u8gnRHvRtWBTt4aJ4MXa9/RyX0cGILtyFegS9ou/VN/zs18c5feNLmqI6q0A==} engines: {node: '>=22.0.0'} - '@objectstack/platform-objects@17.2.0': - resolution: {integrity: sha512-DrTP3XJE3U9Juu97d5iA07H0XNeHTgjXoJLsxMH1G6hnWtdGoG/JQZYg7VQAFIjlE890x0nsZw+y8hRlIeQ+7A==} + '@objectstack/platform-objects@17.3.0': + resolution: {integrity: sha512-eQQ0NdPqss6QmWlgULVxW78WYj35wH4Pi9iwFKaw4tMxa3dqAoT7zkz4rPKo6jRe/iGtpuWQ/+tSsPUuPmeO2g==} engines: {node: '>=22.0.0'} - '@objectstack/plugin-approvals@17.2.0': - resolution: {integrity: sha512-5d1EtW2kZzznu3UlZvhtkDTxZkjt7FPecl+y/M3UtujoZdTJ/D5M1fqGopW2Srg/Xk4ZJRmqne4IC2I9EVZAlA==} + '@objectstack/plugin-approvals@17.3.0': + resolution: {integrity: sha512-5LnEN5OWZzY2HNa+8NuRSrLEiWOo3AFOYGEd5Cvgl7qs+qxA4QKAaO24sB/5i2GduNYnBtu8d02Llpuh5ndfyg==} - '@objectstack/plugin-audit@17.2.0': - resolution: {integrity: sha512-hyJqiMr4H7FTNpNCMgIUGjPqci2J8htBHcqfaw88iUyLyRm/+W+xLQFdvi9lkfc3v2iTkV65J2iq8mJy6fpbdA==} + '@objectstack/plugin-audit@17.3.0': + resolution: {integrity: sha512-+g4TodBpdPGOd0tKN0R0HyoFaoWBVrxE0ypEYEUPi8+KSj1th7s25N5B74+OlnnWtc3Pmd5+m3lC+zZQXI7Quw==} engines: {node: '>=22.0.0'} - '@objectstack/plugin-auth@17.2.0': - resolution: {integrity: sha512-4Pe7OIPZY2mBTlg7S0ORZUnZZwOkr3CCCbl/Na70cVmiEuYjnfic5YeTmuZhD5Ed5MuSwTGB9ZdsYedoDezMIg==} + '@objectstack/plugin-auth@17.3.0': + resolution: {integrity: sha512-euCoj8zQp6wZJgsx3edsVmLPss97/rXyR+CfwMSSD0IcDbErEVHRX0jfpqFxiCn/dukBxqpcrovHHeDWOIzeig==} engines: {node: '>=22.0.0'} - '@objectstack/plugin-email@17.2.0': - resolution: {integrity: sha512-25lPmH0OoXJJ4wyJqCR2qZcmQklfdhKNizrGnNmjZXrbGyNn5ZyWTIxBD3tdD7nUcy4uEHn3uYHgIA2KPJsGrQ==} + '@objectstack/plugin-email@17.3.0': + resolution: {integrity: sha512-aNnpSD9w1+KRDUVZrByUqFz9yd52iQEdKyeOhM/9QN3Xi+zYRGPNozyOl1j2+XmUNcTgy61dyn3q08hEZ9jLDQ==} - '@objectstack/plugin-hono-server@17.2.0': - resolution: {integrity: sha512-mK56rRh9zU0ExTD+4gLYV3g0B/sb/i2HGoh6XY4v/Oq87oWm5WDgcfczRyrpRoVAmHARUeTtZ28us+28L/WPfA==} + '@objectstack/plugin-hono-server@17.3.0': + resolution: {integrity: sha512-IhUPJzb8Xnm1kS0zmIjVHODWCt4vAH51q64tCQ7tOLDlj6W9P1mlPQ9Vt5SEp1aOwLl7ISCMA/VZtct9aYGMWQ==} engines: {node: '>=22.0.0'} - '@objectstack/plugin-pinyin-search@17.2.0': - resolution: {integrity: sha512-QULD+jRaWHJKyV2iHx9baEq7juU8vbeYpHsrcb1SbHdsM98MA53SfhxRtzl+XjIrmO4mT4dnbH3bG0pJcYnp5w==} + '@objectstack/plugin-pinyin-search@17.3.0': + resolution: {integrity: sha512-MneBViUNjZN6RWYlfD/Rs+yWuJS3Z0BxkhWtFNsq39nEy6IXQyTpvPFFkRYncg31ELiG1Ke0IiMKcaTd2IcRVA==} - '@objectstack/plugin-reports@17.2.0': - resolution: {integrity: sha512-EYd9ywY/esDB0PoOpjvnXrGN1V85qcbcmYn+cH9lxCRPnhW94OxGmyj1H/zDmRNwtZPFgzCeGN3sjI/0/zMOkw==} + '@objectstack/plugin-reports@17.3.0': + resolution: {integrity: sha512-nBcb1MDDU96HKOmPqaoHg5KqS/Yy0jdhmy0zLdUZTsuJYS2PjJ7qhKRk+ovcTzQHZRzVbDamC8RO4YE78H6Stw==} - '@objectstack/plugin-security@17.2.0': - resolution: {integrity: sha512-I4bNdTS7iz1xd1XURVsJUtSiOPbOliQJe+YllfUJ//Iks55KI4rblX4ZhZktZeeMv6LpliCLpgyZ7KpUItBZcQ==} + '@objectstack/plugin-security@17.3.0': + resolution: {integrity: sha512-oB1ErJiQ1MYel7t2NTxIDJDNDz5QsFN18bEJkq7efb/22hFHkvIDXZ43fHiw5d8xwqkC0nfkX1lgsej5BFDrWw==} engines: {node: '>=22.0.0'} - '@objectstack/plugin-sharing@17.2.0': - resolution: {integrity: sha512-8bHxsRn8gVDmNqrYLMWSdbt1xKwNuC2XvbzUwHNFWSGha96Qblk1jYDZ+9kBnEw1UhknwaoNyrNoodQv7016Dg==} + '@objectstack/plugin-sharing@17.3.0': + resolution: {integrity: sha512-ehn88zs9WJpoeL+T5LaqlXeC+xClGMU7NwJM/9n14Oy9aXjgCUXafhANy0vZbDsAIzzyElyhepLgl4YwcomqjQ==} - '@objectstack/plugin-webhooks@17.2.0': - resolution: {integrity: sha512-94WofgcuvipaqfoyktvOKCno25kxUD7KGCc1Pkr3+Z6kz21sazSFthX811M/cYzUavQMBjAYwQ5PsMoMns5u9g==} + '@objectstack/plugin-webhooks@17.3.0': + resolution: {integrity: sha512-RJpcC/058DzCuLgZXz7llujmLFdcOBW7owKMb68v3SPaPXUJ6q19FYTfiSdn7mRw89iSm2pvYMPcnBKiGSfwdA==} - '@objectstack/rest@17.2.0': - resolution: {integrity: sha512-8jj7VsBh/O+KNLz8As6s/k5POF/QFOh1HNePk4KxAewFwqKcDTi9Akqy4597AqUAPQZRgnv/jM4EL1iQCzP6mQ==} + '@objectstack/rest@17.3.0': + resolution: {integrity: sha512-CZS56TUV8XlE9L+pKzvTINdrLIr+0IJb7yj6vAUGdl325A6RS08JAP7xdYtP8hgGCBJuMWf+UxQIsQLkxCZBWA==} engines: {node: '>=22.0.0'} - '@objectstack/runtime@17.2.0': - resolution: {integrity: sha512-DfEISc+X1uJ+eIhP+B8+oPzY6xZPlirRe5mbeR9RuAGtytGnp6Fzh0OA4yqUrm/1S2ARvxtKQ3w05IL+ZmGBKA==} + '@objectstack/runtime@17.3.0': + resolution: {integrity: sha512-8RO3JDTa8N5UTxmCQbsfnb1aaSpyu+2qwpLa/7rgvbre11dg5VjGWeWL5z7frC8jL0Xob6ZMBtusKLgBUKmkHA==} engines: {node: '>=22.0.0'} + peerDependencies: + '@objectstack/driver-turso': ^17.3.0 + peerDependenciesMeta: + '@objectstack/driver-turso': + optional: true - '@objectstack/sdui-parser@17.2.0': - resolution: {integrity: sha512-ntkTsawiwCVx1wubBdLqfuM1KslPy+PwRTevX2YqBC567KVsRMyn2RbmcDXTAVLUDQNOl2yab7oI7vXZO82mag==} + '@objectstack/sdui-parser@17.3.0': + resolution: {integrity: sha512-LbzxlLBoDBd0yxoIYMhYuXJ+j3iEsqvvBtrB0JWWda8Iy6mhPqbpyjj11Y5bZ2A0yGf20z0b/vXLDi1ISNIwpA==} - '@objectstack/service-analytics@17.2.0': - resolution: {integrity: sha512-w8IfDDYZ9ts+yZ8SKLpSanbHRNpT6CBfuDRJ9yEAImUXytVwUiqRG6Ua9tzGcfFdcfrCM0lFs5qAIpOiiNbRmA==} + '@objectstack/service-analytics@17.3.0': + resolution: {integrity: sha512-eWUWzOiDb32SdvRpW+GtAqCVgciBGpIXaSh7FumIO9l+C4BiEzjtG40cTAd0XyyaIT4HwyBPWmG7h3YgbF0PZw==} engines: {node: '>=22.0.0'} - '@objectstack/service-automation@17.2.0': - resolution: {integrity: sha512-v5/psIXJv0kokRcFmsDGk4nvaE9EK0hWJ2HIxJIRY1fQ8/qJXGwo2JtEfloZYKHzsGR4+auasI4AKpIaAsx5QA==} + '@objectstack/service-automation@17.3.0': + resolution: {integrity: sha512-EI7NTwIOk9bFv7YgjmFmC/H060580dhyHGwENdETA4gV2NYIH0AHt0ULCl73GpV4XWBuA94LR2/eRdyQ0MjQDA==} engines: {node: '>=22.0.0'} - '@objectstack/service-cache@17.2.0': - resolution: {integrity: sha512-2ODRqiElpYZyjv0b06vfHpTNuphinlsVafiwvY+T79y1QrNEftiksy/Irs6ndP/3EPcX2qurIV4KQOpvS8FTjg==} + '@objectstack/service-cache@17.3.0': + resolution: {integrity: sha512-JHFh/wzIbTeWGLsgJTHWVJ7Vn3/GW/Brz17JzzgeuOMN2V0KO0XbPKe3HoJuKyJ3gbtNhldPhCRTWbFqZy2OLQ==} engines: {node: '>=22.0.0'} - '@objectstack/service-cluster@17.2.0': - resolution: {integrity: sha512-bSzHSn3eXwBRPHqfuTLhqkJVB9lD+4qUbZ4eTIZDjbgXhY10faAI71mc+TYtODEGuEP/7U6i/CXEqId9ZAafZw==} + '@objectstack/service-cluster@17.3.0': + resolution: {integrity: sha512-bykGAdswV0QcihBm4M/LLjJK49uAPIW1kuOes/Tg3ChcxoKsOBcDztGBfkkydwPXvJloeNwQTjNlLoigwcSPfA==} - '@objectstack/service-datasource@17.2.0': - resolution: {integrity: sha512-30LxQB4jP5H6W6cPlt+bVSRRQ8qrUoFFeI02eHgrUegagxEUYgS827in8LrihaIlmyXfih/0feSHWE3SPI+Lng==} + '@objectstack/service-datasource@17.3.0': + resolution: {integrity: sha512-sYNGmf23b6xtzeLgR11Oo3DIt/zyqaRnYiTLkM59udSkf3F+oCQERZc2giJO93PFv6g1W65vFUqJI0ee75SAoA==} + peerDependencies: + '@objectstack/driver-mongodb': ^17.3.0 + '@objectstack/driver-sqlite-wasm': ^17.3.0 + '@objectstack/driver-turso': ^17.3.0 + peerDependenciesMeta: + '@objectstack/driver-mongodb': + optional: true + '@objectstack/driver-sqlite-wasm': + optional: true + '@objectstack/driver-turso': + optional: true - '@objectstack/service-i18n@17.2.0': - resolution: {integrity: sha512-RpxssVWnDoQqTIKuXFsk7T0R7zBw89Y87rY4qT0vFNUB3nleu/Funjt3CRl5cPDPnhwc8iwuTb+Hm4Ho+I7vrw==} + '@objectstack/service-i18n@17.3.0': + resolution: {integrity: sha512-ZrsMKD1s0Glv1x9H7aV2VCdYGldlCs4SgTNfRb6XPAXT9dYTKQkvM5z5Yf26dO9vXFujMESB4jvduRC7BZLfAw==} engines: {node: '>=22.0.0'} - '@objectstack/service-job@17.2.0': - resolution: {integrity: sha512-FS2RmVed0KFMyROWGdMONAxRu5FHiVDjLq59AKXE8+ZujUbTDIHynAFOS+uYnqgwZdUE1AQNDqFJIU44kbTAdw==} + '@objectstack/service-job@17.3.0': + resolution: {integrity: sha512-vKYZdfpTiaaxMLqzYemwHEnBPD1b1IxPOrU9QF1N1LTA+os/SazWeFeddSLJLWzydy72cH/im0bRNfED+tAo/w==} engines: {node: '>=22.0.0'} - '@objectstack/service-messaging@17.2.0': - resolution: {integrity: sha512-27Kw2ZqSAhln83xQf5tcDZdq+lqX0KJ209o8AzVNu/NutwaNBic1ppgpQOxHIGHFOkiXoWPfqjn0IuJET2cTsw==} + '@objectstack/service-messaging@17.3.0': + resolution: {integrity: sha512-mNCba/QUJB4RdhwH2jLMTnPCOd9kR9ItTlAXiEOug9gW3df6Y2MSQ19x1dnp4dVf6NpLX6TZIbtrdLpOEyExrg==} engines: {node: '>=22.0.0'} - '@objectstack/service-package@17.2.0': - resolution: {integrity: sha512-X+WsgyWz5bAqnt1R5VDyJGKVK86BcEljzbQ6/xzJ3tG1ZNziAOl3j9pOjMc1Bl2Jdor7mZRPBLnsFsBNUI9FDg==} + '@objectstack/service-package@17.3.0': + resolution: {integrity: sha512-dOoGFgyn+T/ZtKu+85ApG2udQXPm5JaNP9qA2RflXxkf4GR1/6P2PwjTtovX/HddVoOQtDk+R5v0W51NxWw9wQ==} engines: {node: '>=22.0.0'} - '@objectstack/service-queue@17.2.0': - resolution: {integrity: sha512-KCuJud/ElTNs4jFmSTflPI12e1tM3scsxurXAdViaUW8hFivDIxRcvgKQyPI27TmSgrSi9tKr5BSMtvSTDJtUg==} + '@objectstack/service-queue@17.3.0': + resolution: {integrity: sha512-1C6PkIXxQNajqXG++VTXR2Y6H2Q7LhHd/GpX4NOPSoCiPUbMzE3F8GpMdQ03dWybbLnGbFQbq0BBTnHPe7H1Hg==} engines: {node: '>=22.0.0'} - '@objectstack/service-realtime@17.2.0': - resolution: {integrity: sha512-gK9VvfWaMKYR0NMAv56O8sUF8QDuDNVzkqeyiYT6FUj5nK2fzkwC7HoqTew7GL40vzeCEdq8JyRpuyp3sBMwFQ==} + '@objectstack/service-realtime@17.3.0': + resolution: {integrity: sha512-1wx3cLtO6Vqd2ILEiT8Db+PA1Cy6453KaM24Jx4EzGeUsnStJLpLFxZYmJMGhF+UdFkzZtnopiKYdkDaLpl1uw==} engines: {node: '>=22.0.0'} - '@objectstack/service-settings@17.2.0': - resolution: {integrity: sha512-BScPI/r5J3n94kYxGmb0Hvb9FG0CFBO0bSc9EU8RXO+5qjEHsNX9TIZHauCDQoIl02YKT5sEjYrvBxP5A8JEEQ==} + '@objectstack/service-settings@17.3.0': + resolution: {integrity: sha512-ujUb+47K7NdRcC9X85Q478VlPz4Y6SVG2d1QvaYqyZH5yY2o7glKKl/8rnUJsMKiY1aq8PMnhp0Q7oPyRezDgg==} engines: {node: '>=22.0.0'} - '@objectstack/service-sms@17.2.0': - resolution: {integrity: sha512-x6+5xG5CrkfvYgYavzfcIdB3DixiMKfVFESdllKwYxuBL+m97Bi/mI5hAVd4n+KfCkgbFHoUCf06xe0vdJTt/w==} + '@objectstack/service-sms@17.3.0': + resolution: {integrity: sha512-aWVv8FshItO+jwke3/soM/FV0e+xE2VruoGNNR7Yxuvcga58DnTYZZSKJIGIioByiitlTgl92vq3R/PisrZ/Zg==} - '@objectstack/service-storage@17.2.0': - resolution: {integrity: sha512-5awBRt/Ek65WuQM3OMldQdpBQ3p+766SbTdU6olu5GiDz8ZqsXTTVIc9oZJJWbJM0bY+fJ6MfgEEhdGY9kBzyw==} + '@objectstack/service-storage@17.3.0': + resolution: {integrity: sha512-uxU+DIURX4B8nMJaWZgpd7MVoQqxqhwi/HKvz2gYdxiFW0rlcdc9QP23PWzywSkuQy+QAOVkuciH7SMd5fbQ2A==} engines: {node: '>=22.0.0'} peerDependencies: '@aws-sdk/client-s3': ^3.0.0 @@ -612,12 +628,12 @@ packages: '@aws-sdk/s3-request-presigner': optional: true - '@objectstack/setup@17.2.0': - resolution: {integrity: sha512-DptaMARmZYZDS6cPGD7ZI5KSNdJqG4iM8zJXItc9oGS8+9VR4rb3ZXRZdJX2oTL48qYdbsrcXgW3pE4yLIQ+hw==} + '@objectstack/setup@17.3.0': + resolution: {integrity: sha512-+XVPjKJ+TR001OpfxqK9lnRk9f8sdK4ElL0atqvD4GNh45CYgpT7MhQLVH515GQaikG94IYrzc2mgCNe+itrSg==} engines: {node: '>=22.0.0'} - '@objectstack/spec@17.2.0': - resolution: {integrity: sha512-nQzyR9+9JQEtLzFastQbj0ETLLbOm4sSY+sNUEX2k0QgZThCsMB1rKPv100c6GQZYg1BaLfz5xc8tv9oH3cKqg==} + '@objectstack/spec@17.3.0': + resolution: {integrity: sha512-mceFp9swHHISMycZk8TjdqjBhi0GboQoapRSNeFyaI8GBIpw5cRc37GrWrIFVTZLaVCc7TF3XHSi1qqjaBNmzA==} engines: {node: '>=22.0.0'} peerDependencies: ai: ^7.0.0 @@ -625,23 +641,23 @@ packages: ai: optional: true - '@objectstack/trigger-api@17.2.0': - resolution: {integrity: sha512-0vZS+ZaJJ6cIC6kcb7QvEQ9XmKw6zGpxTlM7VRwFFo9YtLChpAxxFLLW7dQYIinl4HHqvlVVz53FxVdbwtrRyA==} + '@objectstack/trigger-api@17.3.0': + resolution: {integrity: sha512-+T6Gr17NjQgUsLU8Xm29RvvO5E+gmDtj0rpJHsZrnHBbKM3KDOk+nr3FoDROJI7xmgKo8ymocdcDqWhzvUm6BA==} - '@objectstack/trigger-record-change@17.2.0': - resolution: {integrity: sha512-+6ThNqPRF+B0hWbHj/fDM/z9nkZXANlePZrzUUpLWh89CBkUDBOEF3Djv/rZhqCUnKpO6TUsHN/al8hwMyfV+Q==} + '@objectstack/trigger-record-change@17.3.0': + resolution: {integrity: sha512-MRSHd7yRBRJxfWiCS0V2pgs6TYSrle3Oqy3Rc4sicpGXZG+mcZLqk4KR1MdJ2NxnqojtSoaf8HPyz1QHmUvLrA==} engines: {node: '>=22.0.0'} - '@objectstack/trigger-schedule@17.2.0': - resolution: {integrity: sha512-JOPEwt4lkBstmMlZhJjbbAC67n/KA2V/v8+RHGl+tSNYtMiwC34N/ZIN62yD/jaAseSI5v2s62pMN4hMHliqDw==} + '@objectstack/trigger-schedule@17.3.0': + resolution: {integrity: sha512-3Dz9ZmZj7xRh2gtOu01QKrWVJnxiOHjtiBwPsV/egoZYHhIKOjdtHvx58cEdWCg13klpZesq0EcvvI88NfCFLA==} engines: {node: '>=22.0.0'} - '@objectstack/types@17.2.0': - resolution: {integrity: sha512-bgeX9wzajlG+WFutsRKEIWPIxCR2u1kN8aEsFRcvtWV5jyuAuIA8tVTIhEs9yy2BwefeAWwouJrDZbv1Si8+bw==} + '@objectstack/types@17.3.0': + resolution: {integrity: sha512-G5c2+V0gzR5co5XcZ0Zs4uTOp42421Yj6fWEWVV6kEpKfIzaDYUzv1HfmwdOfLklrbtNiF3loBg6jB00BVge/g==} engines: {node: '>=22.0.0'} - '@objectstack/verify@17.2.0': - resolution: {integrity: sha512-qO0PfIO0fvFH/5I8uDnCbEQG1cFb6M72aSIwo3Y/979j5X7JIa2AY4GJ6JfDrUbOiUhx/yycWalY5rt0GU5yVw==} + '@objectstack/verify@17.3.0': + resolution: {integrity: sha512-mUh54oYSKSNnuoHKzieZCaRRJ5Oa6r5g/CMVwMssuKJN3aGY2fCy/CiUmF4mwNZUzWzCLtnhyNJZbsrrmpwqyw==} engines: {node: '>=22.0.0'} '@oclif/core@4.14.0': @@ -1122,8 +1138,8 @@ packages: resolution: {integrity: sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==} engines: {node: '>= 10'} - create-objectstack@17.2.0: - resolution: {integrity: sha512-n21CJalL8XEDlMWil7rmPs5GJ8nAAWVPgQYT/tzpTSzCfi2x5fqTTRc5Llh+CyTjfu1wXpw170jo+Lvw7QafGg==} + create-objectstack@17.3.0: + resolution: {integrity: sha512-5DxdEjsy9gHwCAWB8rJYFlYUy2mYl98CvlaE19xPO2bkPBMyTb1Y+C8Sz3assATqwFIOIbzbTgXH2PJJSDvCNA==} engines: {node: '>=22.0.0'} hasBin: true @@ -2365,10 +2381,11 @@ snapshots: '@better-auth/core': 1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.10)(kysely@0.29.5)(nanostores@1.5.2) '@better-auth/utils': 0.4.2 - '@better-auth/scim@1.7.0-rc.1(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.10)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)(better-auth@1.7.2(better-sqlite3@13.0.3)(mongodb@7.6.0)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))))(better-call@1.4.0(zod@4.5.4))': + '@better-auth/scim@1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.10)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)(better-auth@1.7.2(better-sqlite3@13.0.3)(mongodb@7.6.0)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))))(better-call@1.4.0(zod@4.5.4))': dependencies: '@better-auth/core': 1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.10)(kysely@0.29.5)(nanostores@1.5.2) '@better-auth/utils': 0.4.2 + '@noble/hashes': 2.4.0 better-auth: 1.7.2(better-sqlite3@13.0.3)(mongodb@7.6.0)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) better-call: 1.4.0(zod@4.5.4) zod: 4.5.4 @@ -2570,69 +2587,70 @@ snapshots: '@nodable/entities@3.0.0': {} - '@objectstack/account@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/account@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/platform-objects': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai - vitest - '@objectstack/cli@17.2.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': - dependencies: - '@objectstack/account': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/client': 17.2.0 - '@objectstack/cloud-connection': 17.2.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/console': 17.2.0 - '@objectstack/core': 17.2.0 - '@objectstack/driver-memory': 17.2.0 - '@objectstack/driver-mongodb': 17.2.0 - '@objectstack/driver-sql': 17.2.0 - '@objectstack/driver-sqlite-wasm': 17.2.0(better-sqlite3@13.0.3) - '@objectstack/formula': 17.2.0 - '@objectstack/lint': 17.2.0 - '@objectstack/mcp': 17.2.0 - '@objectstack/metadata': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/metadata-protocol': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/objectql': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/observability': 17.2.0 - '@objectstack/platform-objects': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/plugin-approvals': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/plugin-audit': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/plugin-auth': 17.2.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/plugin-email': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/plugin-hono-server': 17.2.0 - '@objectstack/plugin-pinyin-search': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/plugin-reports': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/plugin-security': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/plugin-sharing': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/plugin-webhooks': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/rest': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/runtime': 17.2.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/service-analytics': 17.2.0 - '@objectstack/service-automation': 17.2.0 - '@objectstack/service-cache': 17.2.0 - '@objectstack/service-datasource': 17.2.0 - '@objectstack/service-job': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/service-messaging': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/service-package': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/service-queue': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/service-realtime': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/service-settings': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/service-sms': 17.2.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/service-storage': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/setup': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 - '@objectstack/trigger-api': 17.2.0 - '@objectstack/trigger-record-change': 17.2.0 - '@objectstack/trigger-schedule': 17.2.0 - '@objectstack/types': 17.2.0 - '@objectstack/verify': 17.2.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/cli@17.3.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + dependencies: + '@objectstack/account': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/client': 17.3.0 + '@objectstack/cloud-connection': 17.3.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/console': 17.3.0 + '@objectstack/core': 17.3.0 + '@objectstack/driver-memory': 17.3.0 + '@objectstack/driver-mongodb': 17.3.0 + '@objectstack/driver-sql': 17.3.0 + '@objectstack/driver-sqlite-wasm': 17.3.0(better-sqlite3@13.0.3) + '@objectstack/formula': 17.3.0 + '@objectstack/lint': 17.3.0 + '@objectstack/mcp': 17.3.0 + '@objectstack/metadata': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/metadata-core': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/metadata-protocol': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/objectql': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/observability': 17.3.0 + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/plugin-approvals': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/plugin-audit': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/plugin-auth': 17.3.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/plugin-email': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/plugin-hono-server': 17.3.0 + '@objectstack/plugin-pinyin-search': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/plugin-reports': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/plugin-security': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/plugin-sharing': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/plugin-webhooks': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/rest': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/runtime': 17.3.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/service-analytics': 17.3.0 + '@objectstack/service-automation': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/service-cache': 17.3.0 + '@objectstack/service-datasource': 17.3.0(@objectstack/driver-mongodb@17.3.0)(@objectstack/driver-sqlite-wasm@17.3.0(better-sqlite3@13.0.3)) + '@objectstack/service-job': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/service-messaging': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/service-package': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/service-queue': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/service-realtime': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/service-settings': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/service-sms': 17.3.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/service-storage': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/setup': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 + '@objectstack/trigger-api': 17.3.0 + '@objectstack/trigger-record-change': 17.3.0 + '@objectstack/trigger-schedule': 17.3.0 + '@objectstack/types': 17.3.0 + '@objectstack/verify': 17.3.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@objectstack/driver-mongodb@17.3.0)(@objectstack/driver-sqlite-wasm@17.3.0(better-sqlite3@13.0.3))(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) '@oclif/core': 4.14.0 bundle-require: 5.1.0(esbuild@0.28.2) chalk: 6.0.0 chokidar: 5.0.0 - create-objectstack: 17.2.0 + create-objectstack: 17.3.0 dotenv-flow: 4.1.0 esbuild: 0.28.2 ts-morph: 28.0.0 @@ -2686,19 +2704,19 @@ snapshots: - vitest - vue - '@objectstack/client@17.2.0': + '@objectstack/client@17.3.0': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai - '@objectstack/cloud-connection@17.2.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/cloud-connection@17.3.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/runtime': 17.2.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/runtime': 17.3.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 transitivePeerDependencies: - '@aws-sdk/credential-providers' - '@better-auth/utils' @@ -2706,6 +2724,7 @@ snapshots: - '@cloudflare/workers-types' - '@lynx-js/react' - '@mongodb-js/zstd' + - '@objectstack/driver-turso' - '@opentelemetry/api' - '@prisma/client' - '@sveltejs/kit' @@ -2742,54 +2761,55 @@ snapshots: - vitest - vue - '@objectstack/connector-mcp@17.2.0(zod@4.5.4)': + '@objectstack/connector-mcp@17.3.0(zod@4.5.4)': dependencies: '@modelcontextprotocol/sdk': 1.30.0(zod@4.5.4) - '@objectstack/core': 17.2.0 - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - '@cfworker/json-schema' - ai - supports-color - zod - '@objectstack/connector-openapi@17.2.0': + '@objectstack/connector-openapi@17.3.0': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai - '@objectstack/connector-rest@17.2.0': + '@objectstack/connector-rest@17.3.0': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai - '@objectstack/console@17.2.0': {} + '@objectstack/console@17.3.0': {} - '@objectstack/core@17.2.0': + '@objectstack/core@17.3.0': dependencies: - '@objectstack/spec': 17.2.0 + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 zod: 4.5.4 transitivePeerDependencies: - ai - '@objectstack/driver-memory@17.2.0': + '@objectstack/driver-memory@17.3.0': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 mingo: 7.2.4 transitivePeerDependencies: - ai - '@objectstack/driver-mongodb@17.2.0': + '@objectstack/driver-mongodb@17.3.0': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 mongodb: 7.6.0 nanoid: 6.0.1 transitivePeerDependencies: @@ -2802,12 +2822,12 @@ snapshots: - snappy - socks - '@objectstack/driver-sql@17.2.0': + '@objectstack/driver-sql@17.3.0': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/observability': 17.2.0 - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/observability': 17.3.0 + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 knex: 3.3.0(better-sqlite3@13.0.3) nanoid: 6.0.1 optionalDependencies: @@ -2821,11 +2841,11 @@ snapshots: - sqlite3 - supports-color - '@objectstack/driver-sqlite-wasm@17.2.0(better-sqlite3@13.0.3)': + '@objectstack/driver-sqlite-wasm@17.3.0(better-sqlite3@13.0.3)': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/driver-sql': 17.2.0 - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/driver-sql': 17.3.0 + '@objectstack/spec': 17.3.0 knex: 3.3.0(better-sqlite3@13.0.3) nanoid: 6.0.1 sql.js: 1.14.2 @@ -2842,18 +2862,18 @@ snapshots: - supports-color - tedious - '@objectstack/formula@17.2.0': + '@objectstack/formula@17.3.0': dependencies: '@marcbachmann/cel-js': 8.0.0 - '@objectstack/spec': 17.2.0 + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai - '@objectstack/lint@17.2.0': + '@objectstack/lint@17.3.0': dependencies: - '@objectstack/formula': 17.2.0 - '@objectstack/sdui-parser': 17.2.0 - '@objectstack/spec': 17.2.0 + '@objectstack/formula': 17.3.0 + '@objectstack/sdui-parser': 17.3.0 + '@objectstack/spec': 17.3.0 ajv: 8.20.0 ajv-formats: 3.0.1(ajv@8.20.0) sucrase: 3.35.1 @@ -2861,58 +2881,58 @@ snapshots: transitivePeerDependencies: - ai - '@objectstack/mcp@17.2.0': + '@objectstack/mcp@17.3.0': dependencies: '@modelcontextprotocol/sdk': 1.30.0(zod@4.5.4) - '@objectstack/core': 17.2.0 - '@objectstack/formula': 17.2.0 - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/formula': 17.3.0 + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 zod: 4.5.4 transitivePeerDependencies: - '@cfworker/json-schema' - ai - supports-color - '@objectstack/metadata-core@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/metadata-core@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/spec': 17.2.0 + '@objectstack/spec': 17.3.0 zod: 4.5.4 optionalDependencies: vitest: 4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)) transitivePeerDependencies: - ai - '@objectstack/metadata-fs@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/metadata-fs@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/metadata-core': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/metadata-core': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) chokidar: 5.0.0 transitivePeerDependencies: - ai - vitest - '@objectstack/metadata-protocol@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/metadata-protocol@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/formula': 17.2.0 - '@objectstack/lint': 17.2.0 - '@objectstack/metadata': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/metadata-core': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/formula': 17.3.0 + '@objectstack/lint': 17.3.0 + '@objectstack/metadata': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/metadata-core': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 zod: 4.5.4 transitivePeerDependencies: - ai - vitest - '@objectstack/metadata@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/metadata@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/metadata-core': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/metadata-fs': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/platform-objects': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/metadata-core': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/metadata-fs': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 chokidar: 5.0.0 glob: 13.0.6 js-yaml: 5.4.1 @@ -2921,15 +2941,15 @@ snapshots: - ai - vitest - '@objectstack/objectql@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/objectql@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/formula': 17.2.0 - '@objectstack/metadata': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/metadata-core': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/metadata-protocol': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/formula': 17.3.0 + '@objectstack/metadata': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/metadata-core': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/metadata-protocol': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 ajv: 8.20.0 ajv-formats: 3.0.1(ajv@8.20.0) zod: 4.5.4 @@ -2937,54 +2957,56 @@ snapshots: - ai - vitest - '@objectstack/observability@17.2.0': + '@objectstack/observability@17.3.0': dependencies: - '@objectstack/spec': 17.2.0 + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai - '@objectstack/platform-objects@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/platform-objects@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/metadata-core': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 + '@objectstack/metadata-core': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai - vitest - '@objectstack/plugin-approvals@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/plugin-approvals@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/formula': 17.2.0 - '@objectstack/metadata-core': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/platform-objects': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/formula': 17.3.0 + '@objectstack/metadata-core': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 transitivePeerDependencies: - ai - vitest - '@objectstack/plugin-audit@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/plugin-audit@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/objectql': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/platform-objects': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/metadata-core': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/objectql': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai - vitest - '@objectstack/plugin-auth@17.2.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/plugin-auth@17.3.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: '@better-auth/core': 1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.10)(kysely@0.29.5)(nanostores@1.5.2) '@better-auth/oauth-provider': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.10)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-auth@1.7.2(better-sqlite3@13.0.3)(mongodb@7.6.0)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))))(better-call@1.4.0(zod@4.5.4)) - '@better-auth/scim': 1.7.0-rc.1(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.10)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)(better-auth@1.7.2(better-sqlite3@13.0.3)(mongodb@7.6.0)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))))(better-call@1.4.0(zod@4.5.4)) + '@better-auth/scim': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.10)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)(better-auth@1.7.2(better-sqlite3@13.0.3)(mongodb@7.6.0)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))))(better-call@1.4.0(zod@4.5.4)) '@better-auth/sso': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(jose@6.2.10)(kysely@0.29.5)(nanostores@1.5.2))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-auth@1.7.2(better-sqlite3@13.0.3)(mongodb@7.6.0)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))))(better-call@1.4.0(zod@4.5.4)) '@noble/hashes': 2.4.0 - '@objectstack/core': 17.2.0 - '@objectstack/platform-objects': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/rest': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/rest': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/service-messaging': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 better-auth: 1.7.2(better-sqlite3@13.0.3)(mongodb@7.6.0)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) jose: 6.2.10 transitivePeerDependencies: @@ -3016,120 +3038,122 @@ snapshots: - vitest - vue - '@objectstack/plugin-email@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/plugin-email@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/formula': 17.2.0 - '@objectstack/platform-objects': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/formula': 17.3.0 + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 nodemailer: 9.1.0 transitivePeerDependencies: - ai - vitest - '@objectstack/plugin-hono-server@17.2.0': + '@objectstack/plugin-hono-server@17.3.0': dependencies: '@hono/node-server': 2.1.1(hono@4.13.5) - '@objectstack/core': 17.2.0 - '@objectstack/observability': 17.2.0 - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/observability': 17.3.0 + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 hono: 4.13.5 transitivePeerDependencies: - ai - '@objectstack/plugin-pinyin-search@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/plugin-pinyin-search@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/objectql': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/objectql': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/types': 17.3.0 pinyin-pro: 3.29.3 transitivePeerDependencies: - ai - vitest - '@objectstack/plugin-reports@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/plugin-reports@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/platform-objects': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 croner: 10.0.1 transitivePeerDependencies: - ai - vitest - '@objectstack/plugin-security@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/plugin-security@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/formula': 17.2.0 - '@objectstack/metadata-core': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/platform-objects': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/formula': 17.3.0 + '@objectstack/metadata-core': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 transitivePeerDependencies: - ai - vitest - '@objectstack/plugin-sharing@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/plugin-sharing@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/formula': 17.2.0 - '@objectstack/metadata-core': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/objectql': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/platform-objects': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/formula': 17.3.0 + '@objectstack/metadata-core': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/objectql': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 transitivePeerDependencies: - ai - vitest - '@objectstack/plugin-webhooks@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/plugin-webhooks@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/service-messaging': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/service-messaging': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai - vitest - '@objectstack/rest@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/rest@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/metadata-core': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/observability': 17.2.0 - '@objectstack/platform-objects': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/service-package': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/metadata-core': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/observability': 17.3.0 + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/service-package': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 exceljs: 4.4.0 zod: 4.5.4 transitivePeerDependencies: - ai - vitest - '@objectstack/runtime@17.2.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': - dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/driver-memory': 17.2.0 - '@objectstack/driver-sql': 17.2.0 - '@objectstack/driver-sqlite-wasm': 17.2.0(better-sqlite3@13.0.3) - '@objectstack/formula': 17.2.0 - '@objectstack/metadata': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/metadata-core': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/metadata-protocol': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/objectql': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/observability': 17.2.0 - '@objectstack/plugin-auth': 17.2.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/plugin-security': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/rest': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/service-cluster': 17.2.0 - '@objectstack/service-datasource': 17.2.0 - '@objectstack/service-i18n': 17.2.0 - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/runtime@17.3.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + dependencies: + '@objectstack/core': 17.3.0 + '@objectstack/driver-memory': 17.3.0 + '@objectstack/driver-sql': 17.3.0 + '@objectstack/driver-sqlite-wasm': 17.3.0(better-sqlite3@13.0.3) + '@objectstack/formula': 17.3.0 + '@objectstack/metadata': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/metadata-core': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/metadata-protocol': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/objectql': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/observability': 17.3.0 + '@objectstack/plugin-auth': 17.3.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/plugin-security': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/rest': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/service-cluster': 17.3.0 + '@objectstack/service-datasource': 17.3.0(@objectstack/driver-mongodb@17.3.0)(@objectstack/driver-sqlite-wasm@17.3.0(better-sqlite3@13.0.3)) + '@objectstack/service-i18n': 17.3.0 + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 quickjs-emscripten: 0.32.0 zod: 4.5.4 optionalDependencies: - '@objectstack/driver-mongodb': 17.2.0 + '@objectstack/driver-mongodb': 17.3.0 transitivePeerDependencies: - '@aws-sdk/credential-providers' - '@better-auth/utils' @@ -3173,119 +3197,136 @@ snapshots: - vitest - vue - '@objectstack/sdui-parser@17.2.0': {} + '@objectstack/sdui-parser@17.3.0': {} - '@objectstack/service-analytics@17.2.0': + '@objectstack/service-analytics@17.3.0': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 transitivePeerDependencies: - ai - '@objectstack/service-automation@17.2.0': + '@objectstack/service-automation@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/formula': 17.2.0 - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/formula': 17.3.0 + '@objectstack/metadata-core': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai + - vitest - '@objectstack/service-cache@17.2.0': + '@objectstack/service-cache@17.3.0': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/observability': 17.2.0 - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/observability': 17.3.0 + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai - '@objectstack/service-cluster@17.2.0': + '@objectstack/service-cluster@17.3.0': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai - '@objectstack/service-datasource@17.2.0': + '@objectstack/service-datasource@17.3.0(@objectstack/driver-mongodb@17.3.0)(@objectstack/driver-sqlite-wasm@17.3.0(better-sqlite3@13.0.3))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/driver-memory': 17.3.0 + '@objectstack/driver-sql': 17.3.0 + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 pg-connection-string: 2.14.0 + optionalDependencies: + '@objectstack/driver-mongodb': 17.3.0 + '@objectstack/driver-sqlite-wasm': 17.3.0(better-sqlite3@13.0.3) transitivePeerDependencies: - ai + - mariadb + - mysql + - mysql2 + - pg + - pg-native + - pg-query-stream + - sqlite3 + - supports-color + - tedious - '@objectstack/service-i18n@17.2.0': + '@objectstack/service-i18n@17.3.0': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 transitivePeerDependencies: - ai - '@objectstack/service-job@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/service-job@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/platform-objects': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 croner: 10.0.1 transitivePeerDependencies: - ai - vitest - '@objectstack/service-messaging@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/service-messaging@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/platform-objects': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 transitivePeerDependencies: - ai - vitest - '@objectstack/service-package@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/service-package@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/metadata-core': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/metadata-core': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai - vitest - '@objectstack/service-queue@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/service-queue@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/platform-objects': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai - vitest - '@objectstack/service-realtime@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/service-realtime@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/platform-objects': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai - vitest - '@objectstack/service-settings@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/service-settings@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: '@noble/ciphers': 2.4.0 - '@objectstack/core': 17.2.0 - '@objectstack/platform-objects': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 transitivePeerDependencies: - ai - vitest - '@objectstack/service-sms@17.2.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/service-sms@17.3.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/plugin-auth': 17.2.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/plugin-auth': 17.3.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - '@better-auth/utils' - '@better-fetch/fetch' @@ -3315,74 +3356,74 @@ snapshots: - vitest - vue - '@objectstack/service-storage@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/service-storage@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/observability': 17.2.0 - '@objectstack/platform-objects': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/observability': 17.3.0 + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 transitivePeerDependencies: - ai - vitest - '@objectstack/setup@17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + '@objectstack/setup@17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': dependencies: - '@objectstack/platform-objects': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai - vitest - '@objectstack/spec@17.2.0': + '@objectstack/spec@17.3.0': dependencies: pg-connection-string: 2.14.0 zod: 4.5.4 - '@objectstack/trigger-api@17.2.0': + '@objectstack/trigger-api@17.3.0': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai - '@objectstack/trigger-record-change@17.2.0': + '@objectstack/trigger-record-change@17.3.0': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai - '@objectstack/trigger-schedule@17.2.0': + '@objectstack/trigger-schedule@17.3.0': dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/spec': 17.2.0 + '@objectstack/core': 17.3.0 + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai - '@objectstack/types@17.2.0': + '@objectstack/types@17.3.0': dependencies: - '@objectstack/spec': 17.2.0 + '@objectstack/spec': 17.3.0 transitivePeerDependencies: - ai - '@objectstack/verify@17.2.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': - dependencies: - '@objectstack/core': 17.2.0 - '@objectstack/objectql': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/platform-objects': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/plugin-auth': 17.2.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/plugin-hono-server': 17.2.0 - '@objectstack/plugin-security': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/plugin-sharing': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/rest': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/runtime': 17.2.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/service-analytics': 17.2.0 - '@objectstack/service-automation': 17.2.0 - '@objectstack/service-datasource': 17.2.0 - '@objectstack/service-settings': 17.2.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) - '@objectstack/spec': 17.2.0 - '@objectstack/types': 17.2.0 + '@objectstack/verify@17.3.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@objectstack/driver-mongodb@17.3.0)(@objectstack/driver-sqlite-wasm@17.3.0(better-sqlite3@13.0.3))(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0)))': + dependencies: + '@objectstack/core': 17.3.0 + '@objectstack/objectql': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/platform-objects': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/plugin-auth': 17.3.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/plugin-hono-server': 17.3.0 + '@objectstack/plugin-security': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/plugin-sharing': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/rest': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/runtime': 17.3.0(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-call@1.4.0(zod@4.5.4))(better-sqlite3@13.0.3)(kysely@0.29.5)(mongodb@7.6.0)(nanostores@1.5.2)(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/service-analytics': 17.3.0 + '@objectstack/service-automation': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/service-datasource': 17.3.0(@objectstack/driver-mongodb@17.3.0)(@objectstack/driver-sqlite-wasm@17.3.0(better-sqlite3@13.0.3)) + '@objectstack/service-settings': 17.3.0(vitest@4.1.11(vite@8.2.2(esbuild@0.28.2)(tsx@4.23.13)(yaml@2.9.0))) + '@objectstack/spec': 17.3.0 + '@objectstack/types': 17.3.0 transitivePeerDependencies: - '@aws-sdk/credential-providers' - '@better-auth/utils' @@ -3390,6 +3431,9 @@ snapshots: - '@cloudflare/workers-types' - '@lynx-js/react' - '@mongodb-js/zstd' + - '@objectstack/driver-mongodb' + - '@objectstack/driver-sqlite-wasm' + - '@objectstack/driver-turso' - '@opentelemetry/api' - '@prisma/client' - '@sveltejs/kit' @@ -3836,7 +3880,7 @@ snapshots: crc-32: 1.2.2 readable-stream: 3.6.2 - create-objectstack@17.2.0: + create-objectstack@17.3.0: dependencies: chalk: 6.0.0 commander: 15.0.0 diff --git a/src/hooks/task.hook.ts b/src/hooks/task.hook.ts index 51c6b43..caf3561 100644 --- a/src/hooks/task.hook.ts +++ b/src/hooks/task.hook.ts @@ -100,7 +100,12 @@ import type { Hook, HookContext } from '@objectstack/spec/data'; * - Only the stamping direction is guarded. A batch moving rows OUT of done * writes `completed_at = null`, and null is the correct value for every row * being moved out of done, including one that was never completed. That - * rewrite is genuinely row-invariant, so it is allowed. + * rewrite is genuinely row-invariant, so it is allowed — and it is written + * for EVERY matched row, not only the rows whose pre-image was done. That + * detail is load-bearing rather than tidy: keying it on the pre-image makes + * the hook emit a different key set per row, which 17.3.0 refuses outright + * with `MultiUpdateHookKeyDivergenceError`. The branch is therefore gated on + * the PAYLOAD's status, the one value every matched row shares. * - A batch in which EVERY row is already done is refused too, even though * nothing would leak. The hook cannot see the batch — `dispatch.index` is a * position, not a total — and a rule stated on the row is one a caller can @@ -360,7 +365,7 @@ const stampTaskLifecycle = (ctx: HookContext): void => { } input.completed_at = now; input.completed_late = late; - } else if (wasDone && !isDone) { + } else if ('status' in input && !isDone) { // Reopened, skipped or cancelled — the completion is undone, so the // timestamp goes with it, or the record keeps a completion that no longer // happened. The verdict goes with it for the same reason: a completion @@ -368,6 +373,34 @@ const stampTaskLifecycle = (ctx: HookContext): void => { // row-invariant — `null` is correct for every row being moved out of done, // including one that was never completed — so this direction stays // allowed on the shared-payload path. + // + // ── Why the test is on the PAYLOAD's status, not on `wasDone` ───────── + // The obvious spelling of this branch is `wasDone && !isDone`, and it is + // the one that breaks. `wasDone` reads THIS row's pre-image, so on a + // predicate write reopening a mixed batch the nulls are written for the + // rows that were done and not for the rows that were not — the hook + // produces a DIFFERENT KEY SET per row, which is precisely what a shared + // payload cannot express. The platform refuses the whole update: + // + // MultiUpdateHookKeyDivergenceError: Refusing a multi-record update on + // 'duly_task': its 'beforeUpdate' handlers wrote 'completed_at', + // 'completed_late' for some of the 2 matched records and not for others + // + // Measured on `@objectstack/objectql` 17.3.0, which added that guard; + // on 17.2.0 the same divergence went through unremarked. Writing the + // nulls for EVERY matched row fixes it at the cause rather than working + // around the guard: the row that was never done already holds null, so + // the write is a no-op on it, and the key set stops depending on the row. + // + // `'status' in input` is what makes that true. `isDone` falls back to the + // stored status when the payload carries none, so testing `!isDone` alone + // would re-open the same divergence one shape over — an administrative + // bulk write with no `status` (a re-owner, a business-unit backfill) would + // write the nulls on the not-done rows and skip the done ones. Gated on + // the payload, `isDone` is read off the ONE shared payload and is therefore + // identical for every matched row, which is the property the guard wants. + // A write that does not carry `status` is not a completion transition and + // still touches neither column, exactly as before. input.completed_at = null; input.completed_late = null; } diff --git a/src/translations/authored-text.ts b/src/translations/authored-text.ts index 9119663..2796cdb 100644 --- a/src/translations/authored-text.ts +++ b/src/translations/authored-text.ts @@ -39,14 +39,31 @@ import { TRANSLATABLE_METADATA_TYPES } from '@objectstack/spec/system'; * ── What is translatable is the PLATFORM's answer, not ours ────────────── * `TRANSLATABLE_METADATA_TYPES` is imported from `@objectstack/spec/system`, * where it is documented as "derived from the dispatch table — never restate - * it". Measured on 17.2.0 it is exactly - * `{ view, action, object, app, dashboard, page }`. Every other metadata type - * this app ships — dataset, flow, job, hook, permission set, position, + * it". Measured on 17.3.0 it is exactly + * `{ view, action, object, app, dashboard, dataset, page }`. Every other + * metadata type this app ships — flow, job, hook, permission set, position, * sharing rule — has no translator and no bundle group, so its display text is * `untranslatable` by the platform's own declaration rather than by our - * judgement. `test/i18n-coverage.test.ts` pins the set, so the day the - * platform makes datasets translatable the pin goes red and this walk gets - * extended instead of quietly staying behind. + * judgement. `test/i18n-coverage.test.ts` pins the set, so a platform change + * cannot pass silently. + * + * ── That pin did its job, which is why this file changed (#106) ────────── + * `dataset` is in the set above because objectstack#14381 put it there. The + * pin went red on the 17.3.0 bump — before any of this file was touched — and + * three exemptions that had been correct became stale in one release: + * + * dataset label / description / dimension / measure labels → the `datasets` + * group, resolved by the new `translateDataset`. + * a view's `bulkActionDefs` copy → `objects.._views..bulkActions`, + * resolved by `translateView`. + * a custom validation rule's `message` → `objects.._validations. + * .message`, resolved by `@objectstack/objectql` at THROW time. + * + * Each verdict below records where its key is resolved, because in two of the + * three cases it is NOT the document translator a reader would reach for + * first. The exemption list is now the designer- and operator-facing text + * only: flows, jobs, hooks, positions, permission sets, and the one + * `element:text` `content` slot the page face still has no key for. * * ── Measured behaviour the key builders below depend on ────────────────── * Run against `@objectstack/spec` 17.2.0's own resolvers, not assumed: @@ -316,15 +333,36 @@ const VERDICTS: Readonly> = { 'object.fields{}.defaultValue': machine('default value or token'), 'object.fields{}.defaultValue.dialect': machine('expression dialect'), 'object.fields{}.defaultValue.source': machine('CEL source'), - // No bundle slot exists for a custom validation rule's message. Measured on - // `@objectstack/objectql` 17.2.0: a rule's `message` is put on the error - // verbatim. `messages['validation.field.*']` overrides the platform's - // BUILT-IN field catalog (which already ships zh-CN), not an authored rule. - 'object.validations[].message': untranslatable( - 'a custom validation rule\'s message is emitted verbatim — the bundle has no ' - + '`_validations` group and `messages.validation.field.*` addresses only the ' - + 'platform\'s built-in field catalog. Filed upstream; see the PR body.', - ), + /** + * A custom validation rule's refusal sentence (#106, objectstack#14381). + * + * ── Where this key is resolved, and why it is not `translateObject` ─── + * Measured on 17.3.0, because the two halves disagree and only one of them + * reaches a person: + * + * `translateObject(obj, bundle, { locale })` does NOT rewrite + * `validations[].message`. Fed a bundle carrying + * `_validations..message` it returns the authored English untouched + * (the object's own `label` beside it does translate). + * + * `@objectstack/objectql` 17.3.0 resolves it at THROW time instead, which + * is the only moment the sentence is used. `authoredRuleMessage(rule, + * messages)` builds `objects.._validations..message` through + * the spec's own `objectValidationMessageKey` and asks the bridged i18n + * service for it in the CALLER's locale, falling back to `rule.message`. + * The bridge is real in this app: booting the stack logs + * `[ObjectQLPlugin] Bridging i18n service to ObjectQL for validation + * messages`. + * + * Resolving at throw time is what makes it correct — one stored rule serves + * every locale, and the refusal is spoken in the locale of whoever was + * stopped. So the key below is real, and a zh-CN session gets a Chinese + * refusal in the same envelope as the platform's own. + */ + 'object.validations[].message': translate((c) => { + const rule = str(c.parent.name); + return id(c) && rule ? ['objects', id(c)!, '_validations', rule, 'message'] : undefined; + }), 'object.validations[].name': machine('rule name'), 'object.validations[].type': machine('rule kind'), 'object.validations[].severity': machine('rule severity'), @@ -351,16 +389,32 @@ const VERDICTS: Readonly> = { }), 'view.type': machine('visualisation kind'), 'view.inlineEdit': machine('editing flag'), - // An authored `bulkActionDefs` entry is NOT an action document: it never - // reaches `translateAction`, and there is no `_bulkActions` group. The - // authored comment in `src/views/task.view.ts` said as much before this - // bundle existed; it is now measured rather than assumed. - 'view.bulkActionDefs[].label': untranslatable(BULK_WHY('the toolbar button caption')), - 'view.bulkActionDefs[].confirmText': untranslatable(BULK_WHY('the confirmation prompt')), - 'view.bulkActionDefs[].confirmLabel': untranslatable(BULK_WHY('the confirm button caption')), - 'view.bulkActionDefs[].params[].label': untranslatable(BULK_WHY('a parameter\'s field label')), - 'view.bulkActionDefs[].params[].placeholder': untranslatable(BULK_WHY('a parameter\'s placeholder')), - 'view.bulkActionDefs[].params[].help': untranslatable(BULK_WHY('a parameter\'s help text')), + /** + * The bulk toolbar's own copy (#106, objectstack#14381). + * + * A `bulkActionDefs` entry still is not an action DOCUMENT — it never + * reaches `translateAction` — but `_views..bulkActions` is now its own + * group, so it no longer needs to be one. Measured on `translateView` + * 17.3.0 rather than read off the schema: the resolver keys the group by the + * def's `name`, keys each param by the param's `name`, and addresses the + * view exactly as `view.label` above does — `viewTranslationKey` strips the + * `.` prefix, which is the same registry name `expandViewContainer` + * produces. So these six slots hang off the SAME `_views.` prefix + * the view's own label uses, one level down. + * + * One shape detail worth recording, because it looks like a mismatch and is + * not: `translateView` reads the array from `view.config.bulkActionDefs` + * (the registry document), while this walk reads it from the AUTHORED node, + * where it sits at the top level. The bundle key depends on neither — only + * on object, view key, def name and param name — so both halves address the + * same slot. + */ + 'view.bulkActionDefs[].label': translate((c) => bulkActionKey(c, 'label')), + 'view.bulkActionDefs[].confirmText': translate((c) => bulkActionKey(c, 'confirmText')), + 'view.bulkActionDefs[].confirmLabel': translate((c) => bulkActionKey(c, 'confirmLabel')), + 'view.bulkActionDefs[].params[].label': translate((c) => bulkActionParamKey(c, 'label')), + 'view.bulkActionDefs[].params[].placeholder': translate((c) => bulkActionParamKey(c, 'placeholder')), + 'view.bulkActionDefs[].params[].help': translate((c) => bulkActionParamKey(c, 'help')), 'view.bulkActionDefs[].name': machine('bulk action name'), 'view.bulkActionDefs[].icon': machine('icon name'), 'view.bulkActionDefs[].operation': machine('data-plane operation'), @@ -495,14 +549,31 @@ const VERDICTS: Readonly> = { 'action.visible.dialect': machine('expression dialect'), 'action.visible.source': machine('CEL source'), - // ── dataset — no translator, no bundle group ────────────────────────── + // ── dataset — a translator and a bundle group as of 17.3.0 ──────────── + // + // `METADATA_DOCUMENT_TRANSLATORS` gained `dataset` in objectstack#14381, so + // `TRANSLATABLE_METADATA_TYPES` now carries it and `translateDataset` + // rewrites all four slots below out of the `datasets` group. Measured, not + // read off the schema: fed `datasets.duly_duty_health.measures..label`, + // the resolver returns the Chinese for the measure, the dimension, the + // dataset label and its description. + // + // This is the group behind the dashboard: a measure label is what a metric + // tile prints under its number and what a pie legend names each slice, which + // is why a Chinese dashboard had English sub-labels before this landed. 'dataset.name': machine('dataset name'), 'dataset.object': machine('base object'), 'dataset.include[]': machine('join paths'), - 'dataset.label': untranslatable(DATASET_WHY()), - 'dataset.description': untranslatable(DATASET_WHY()), - 'dataset.dimensions[].label': untranslatable(DATASET_WHY()), - 'dataset.measures[].label': untranslatable(DATASET_WHY()), + 'dataset.label': translate((c) => (id(c) ? ['datasets', id(c)!, 'label'] : undefined)), + 'dataset.description': translate((c) => (id(c) ? ['datasets', id(c)!, 'description'] : undefined)), + 'dataset.dimensions[].label': translate((c) => { + const dimension = str(c.parent.name); + return id(c) && dimension ? ['datasets', id(c)!, 'dimensions', dimension, 'label'] : undefined; + }), + 'dataset.measures[].label': translate((c) => { + const measure = str(c.parent.name); + return id(c) && measure ? ['datasets', id(c)!, 'measures', measure, 'label'] : undefined; + }), 'dataset.dimensions[].name': machine('dimension name — bound by dashboards'), 'dataset.dimensions[].field': machine('field path'), 'dataset.dimensions[].type': machine('dimension kind'), @@ -591,23 +662,6 @@ const VERDICTS: Readonly> = { 'permissionSet.description': untranslatable(ADMIN_WHY('permission set')), }; -function BULK_WHY(what: string): string { - return `${what} of an authored \`bulkActionDefs\` entry. A bulk-action def is not an ` - + 'action DOCUMENT — it never reaches `translateAction`, and `TranslationDataSchema` ' - + 'has no group that addresses one — so this string renders in the source locale in ' - + 'every locale. The alternative shape (`bulkActions: [\'duly_task_complete\']`, ' - + 'promoting the row actions) is rejected in `src/views/task.view.ts` for a measured ' - + 'reason: N elevated action dispatches instead of one data-plane write. Filed ' - + 'upstream; see the PR body.'; -} - -function DATASET_WHY(): string { - return 'a dataset is not one of the platform\'s translatable metadata types ' - + '(`TRANSLATABLE_METADATA_TYPES`) and `TranslationDataSchema` has no `datasets` ' - + 'group, so a measure or dimension label reaches a chart axis in the source ' - + 'locale. Filed upstream; see the PR body.'; -} - function FLOW_WHY(): string { return 'a flow is not one of the platform\'s translatable metadata types and the ' + '`flows` bundle group addresses only `label` and SCREEN copy — this app declares ' @@ -619,6 +673,43 @@ function ADMIN_WHY(kind: string): string { + 'bundle group. Operator-facing text (Studio, the run log), not an end-user screen.'; } +/** + * The `_views..bulkActions.` prefix a bulk-action string hangs + * off, or `undefined` when the surface is not addressable. + * + * `ctx.parent` is the def itself for the three top-level slots, so its `name` + * is right there. A PARAM's parent is the param, and the def is one level up — + * reachable only through the concrete path, exactly as `pageComponentId` above + * reaches a page component. `viewNode` is on `ctx.ids` for that reason. + */ +const bulkActionDefAt = (ctx: KeyContext, index: string | undefined): string | undefined => { + const view = ctx.ids.viewNode; + if (!isRec(view) || !Array.isArray(view.bulkActionDefs)) return undefined; + const def = view.bulkActionDefs[Number(index)]; + return isRec(def) ? str(def.name) : undefined; +}; + +const bulkActionBase = (ctx: KeyContext, defName: string | undefined): readonly string[] | undefined => { + const object = str(ctx.ids.object); + const viewKey = str(ctx.ids.viewKey); + return object && viewKey && defName + ? ['objects', object, '_views', viewKey, 'bulkActions', defName] + : undefined; +}; + +function bulkActionKey(ctx: KeyContext, leaf: string): readonly string[] | undefined { + const base = bulkActionBase(ctx, str(ctx.parent.name)); + return base ? [...base, leaf] : undefined; +} + +function bulkActionParamKey(ctx: KeyContext, leaf: string): readonly string[] | undefined { + const [defsKey, defIndex, paramsKey] = ctx.path; + if (defsKey !== 'bulkActionDefs' || paramsKey !== 'params') return undefined; + const base = bulkActionBase(ctx, bulkActionDefAt(ctx, defIndex)); + const param = str(ctx.parent.name); + return base && param ? [...base, 'params', param, leaf] : undefined; +} + function actionKey(ctx: KeyContext, leaf: string): readonly string[] | undefined { const action = str(ctx.ids.name); if (!action) return undefined; @@ -772,7 +863,7 @@ const viewSurfaces = (views: readonly unknown[]): Surface[] => { kind: 'view', where: `view ${object} › listViews.${authored}`, node: view, - ids: { object, viewKey: namedKeys[at] ?? authored }, + ids: { object, viewKey: namedKeys[at] ?? authored, viewNode: view }, }); }); if (list) { @@ -780,7 +871,7 @@ const viewSurfaces = (views: readonly unknown[]): Surface[] => { kind: 'view', where: `view ${object} › list`, node: list, - ids: { object, viewKey: defaultKey }, + ids: { object, viewKey: defaultKey, viewNode: list }, }); } } diff --git a/src/translations/zh-CN.ts b/src/translations/zh-CN.ts index 6341120..6220da4 100644 --- a/src/translations/zh-CN.ts +++ b/src/translations/zh-CN.ts @@ -96,6 +96,35 @@ import { defineTranslationBundle } from '@objectstack/spec'; * literal compound carries nothing in Chinese. Its help text keeps the two * worked examples per anchor and is translated for sense, not structure. */ +/** + * 批量工具条的文案,`duly_task` 每个提供它的列表视图共用一份。 + * + * 平台按「视图」寻址这组键(`objects.duly_task._views.<视图>.bulkActions`), + * 所以同一个批量动作出现在五个视图里就是五份键。这里共用一个对象而不是抄 + * 五遍:抄五遍的那份迟早会有一处被改、四处没改,而这组文案在哪个视图里都 + * 必须读起来一样。 + * + * 与行内动作 `duly_task_skip` 的措辞刻意保持一致(跳过原因、同一句占位 + * 示例),只有说明文字不同——批量的那句要说清楚它落在所选的每一个任务上。 + */ +const TASK_BULK_ACTIONS = { + duly_task_bulk_complete: { + label: '完成', + confirmText: '把所选任务标记为已完成。', + confirmLabel: '完成', + }, + duly_task_bulk_skip: { + label: '跳过', + params: { + skip_reason: { + label: '跳过原因', + help: '会记录在所选的每一个任务上。', + placeholder: '当时装置停车,没有任何东西需要申报', + }, + }, + }, +}; + export const dulyChinese = defineTranslationBundle({ 'zh-CN': { objects: { @@ -217,6 +246,35 @@ export const dulyChinese = defineTranslationBundle({ catalog_tree: { label: '各团队应尽的职责' }, default: { label: '全部职责' }, }, + // 校验规则的拒绝语。由 objectql 在抛错当时按调用方的语言解析 + // (`objects.<对象>._validations.<规则>.message`),所以一条规则 + // 只存一句英文原文,中文会话看到的是这里的句子。 + // + // 写法上跟平台内建的拒绝语保持一致:先说清楚被拒的是什么,再说该 + // 怎么办。配置者是在填表当中被挡下来的,只被告知“不合法”没有用。 + _validations: { + recurring_needs_frequency: { + message: '周期性职责必须设置频率,否则没有任何东西能派发它。', + }, + standing_no_frequency: { + message: '常设职责从不派发任务,给它设频率没有意义。请清除频率。', + }, + non_recurring_no_due_timing: { + message: '“到期日锚定于”、偏移天数与提前天数用于算出每个周期的到期日,只有周期性职责才有周期。常设与一次性职责请清空这三项。', + }, + standing_no_grace_days: { + message: '宽限期是相对任务的到期日判定逾期的;常设职责从不产生任务,因此也谈不上宽限期。', + }, + review_status_transitions: { + message: '审定流程没有这一步。职责的流转是:待确认 → 待审定 → 已审定或已打回;已打回的职责修正之后重新回到待审定。', + }, + returned_needs_note: { + message: '请写明打回的原因——负责人需要据此知道该改什么。', + }, + effective_window_ordered: { + message: '生效日期不得晚于失效日期。', + }, + }, }, // ── duly_task — 任务:职责的一次派发 ──────────────────────────── @@ -316,9 +374,9 @@ export const dulyChinese = defineTranslationBundle({ history: { label: '历史' }, }, _views: { - my_week: { label: '我的本周' }, - late: { label: '逾期' }, - stalled: { label: '停滞' }, + my_week: { label: '我的本周', bulkActions: TASK_BULK_ACTIONS }, + late: { label: '逾期', bulkActions: TASK_BULK_ACTIONS }, + stalled: { label: '停滞', bulkActions: TASK_BULK_ACTIONS }, calendar: { label: '日历' }, board: { label: '看板' }, schedule: { label: '排期' }, @@ -326,8 +384,9 @@ export const dulyChinese = defineTranslationBundle({ by_unit: { label: '按部门', description: '仅包含待办与进行中的工作。分组计数是在已加载的这一页上算出来的——按部门的权威口径在仪表板,这个视图用于浏览。', + bulkActions: TASK_BULK_ACTIONS, }, - default: { label: '全部任务' }, + default: { label: '全部任务', bulkActions: TASK_BULK_ACTIONS }, }, _actions: { duly_task_complete: { @@ -353,6 +412,16 @@ export const dulyChinese = defineTranslationBundle({ }, }, }, + _validations: { + // 这一条挡的是「历史怎么写」那条路:完成时间是只读列,普通调用方 + // 建不出一个直接就是 done 的任务。中文照样要说清楚缺的是什么。 + completed_at_required_when_done: { + message: '已完成的任务必须带有完成时间。', + }, + skip_needs_reason: { + message: '请写明这个任务被跳过的原因。', + }, + }, }, // ── duly_catalog_item — 岗位职责库条目 ────────────────────────── @@ -434,6 +503,23 @@ export const dulyChinese = defineTranslationBundle({ }, }, }, + // 与 duly_duty 上的同名规则逐字一致,这是刻意的:职责库条目就是职责 + // 的模板,同一条约束在两处必须说同一句话。配置者常常先在职责库里被 + // 挡下、再到职责上被挡下一次,两句话不一样只会让人以为是两回事。 + _validations: { + recurring_needs_frequency: { + message: '周期性职责必须设置频率,否则没有任何东西能派发它。', + }, + standing_no_frequency: { + message: '常设职责从不派发任务,给它设频率没有意义。请清除频率。', + }, + non_recurring_no_due_timing: { + message: '“到期日锚定于”、偏移天数与提前天数用于算出每个周期的到期日,只有周期性职责才有周期。常设与一次性职责请清空这三项。', + }, + standing_no_grace_days: { + message: '宽限期是相对任务的到期日判定逾期的;常设职责从不产生任务,因此也谈不上宽限期。', + }, + }, }, // ── duly_assignment — 指派:一件工作分发给若干人 ───────────────── @@ -622,6 +708,81 @@ export const dulyChinese = defineTranslationBundle({ }, }, + // ── datasets — 仪表板数字底下的那一层文字 ───────────────────────── + // 17.3.0 (objectstack#14381) 之前这一组不存在:数据集不是可翻译的元数据 + // 类型,度量标签就是图表轴上、指标块数字下面那行英文。所以一个中文会话 + // 看到的是中文标题配英文小字——#106 关掉的正是这个。 + // + // 度量标签是「小字」,不是句子:它要在一个数字底下、在一条饼图图例里读 + // 得通,所以一律短词,口径写在数据集自己的 description 与仪表板部件的 + // description 里,不塞进标签。 + datasets: { + duly_duty_health: { + label: '职责健康度', + description: '组织认定职责的按期全貌(来自岗位职责库与主管指派)。自行申报的工作只在任务视图里呈现,这里从不为它打分。', + dimensions: { + business_unit: { label: '部门' }, + owner: { label: '负责人' }, + period_key: { label: '所属周期' }, + frequency: { label: '频率' }, + source: { label: '来源' }, + }, + measures: { + tasks_due: { label: '应完成任务' }, + tasks_done: { label: '已完成任务' }, + tasks_skipped: { label: '已跳过任务' }, + tasks_done_on_time: { label: '按期完成' }, + tasks_completed_late: { label: '逾期完成' }, + tasks_overdue: { label: '逾期未完成' }, + // 与仪表板部件 `on_time_rate` 的标题同词。同一个数在两处出现, + // 叫法不一样会被读成两个指标。 + on_time_rate: { label: '按期率' }, + }, + }, + duly_duty_register: { + label: '职责清单', + description: '组织认定的职责清单本身:其中有多少已确认、已审定,以及它由哪些形式的工作构成。这里数的是职责,不是它们派发出来的任务——所以常设职责只在这里露面。', + dimensions: { + // 与 duly_duty.form 的字段标签同词:饼图图例上的那一列就是这个 + // 字段的取值,标签跟着字段走才不会出现两个名字。 + form: { label: '形式' }, + }, + measures: { + duties_in_register: { label: '清单内职责' }, + duties_approved: { label: '已审定职责' }, + approved_rate: { label: '审定率' }, + }, + }, + duly_stagnation: { + label: '停滞', + description: '没有动静的组织认定待办工作,按已多久无人过问分档。刻意与到期日无关——一个还没到期、却始终没人碰的任务,同样是停滞。', + dimensions: { + business_unit: { label: '部门' }, + owner: { label: '负责人' }, + }, + measures: { + open_tasks: { label: '待办任务' }, + untouched_over_7d: { label: '超过 7 天无动静' }, + untouched_over_14d: { label: '超过 14 天无动静' }, + untouched_over_30d: { label: '超过 30 天无动静' }, + oldest_last_update_at: { label: '最久未动' }, + }, + }, + duly_workload: { + label: '工作量', + description: '组织认定任务的到期分布,按周与按月向前分档,让一个即将超载的周期在还来得及重新平衡的时候就能被看见。', + dimensions: { + business_unit: { label: '部门' }, + owner: { label: '负责人' }, + due_week: { label: '到期(周)' }, + due_month: { label: '到期(月)' }, + }, + measures: { + tasks_due: { label: '应完成任务' }, + }, + }, + }, + globalActions: { duly_catalog_apply: { label: '应用岗位职责库', diff --git a/test/i18n-coverage.test.ts b/test/i18n-coverage.test.ts index 1d4d01c..ad9ba62 100644 --- a/test/i18n-coverage.test.ts +++ b/test/i18n-coverage.test.ts @@ -16,6 +16,7 @@ import { } from '../src/translations/authored-text.js'; import type { TextStack } from '../src/translations/authored-text.js'; import { buildEnglishBundle, dulyTextStack, dulyEnglish } from '../src/translations/en.js'; +import { dulyTranslations } from '../src/translations/index.js'; import { dulyChinese } from '../src/translations/zh-CN.js'; /** @@ -50,31 +51,74 @@ import { dulyChinese } from '../src/translations/zh-CN.js'; type Rec = Record; const SOURCE_LOCALE = 'en'; -const TARGET_LOCALE = 'zh-CN'; const walk = collectAuthoredText(dulyTextStack); const derivedKeys = walk.translatable.map((entry) => keyPath(entry.key!)); const englishKeys = new Set(bundleKeys((dulyEnglish as Rec)[SOURCE_LOCALE])); -const chineseKeys = new Set(bundleKeys((dulyChinese as Rec)[TARGET_LOCALE])); + +/** + * Every locale the barrel ships except the source one (#102). + * + * This used to be the literal `'zh-CN'`, which made the two directional gates + * below check ONE named locale. The locale-set assertion further down would + * have caught a `ja-JP` that was declared and missing, but not a `ja-JP.ts` + * that existed and carried ten of the keys: nothing ran the coverage check + * against it. Read off `dulyTranslations` instead, so the third locale is + * gated by existing, not by somebody remembering to add a line here. + * + * `templateGaps()` at the bottom of this file already iterated + * `supportedLocales` generically — only the bundle half had the gap. + */ +const TRANSLATED_LOCALES: readonly string[] = (dulyTranslations as Rec[]) + .flatMap((bundle) => Object.keys(bundle)) + .filter((locale) => locale !== SOURCE_LOCALE) + .sort(); + +const keysForLocale = (locale: string): Set => { + const bundle = (dulyTranslations as Rec[]).find((b) => locale in b); + return new Set(bundleKeys(bundle?.[locale])); +}; + +const localeKeys = new Map(TRANSLATED_LOCALES.map((l) => [l, keysForLocale(l)] as const)); +const chineseKeys = keysForLocale('zh-CN'); // ─── The gate, over this app's real metadata ───────────────────────────── describe('i18n coverage — every authored label is translated, every key has a source', () => { - it('every declared label the walk can address is carried by zh-CN', () => { + it('gates every locale the app actually ships, so the per-locale checks below are not vacuous', () => { + // Non-vacuity guard for the generalisation (#102). `it.each` over an empty + // array reports success with zero cases, so a bug that emptied + // `TRANSLATED_LOCALES` would turn the two gates below into nothing at all + // and every one of them would still be green. + expect(TRANSLATED_LOCALES, 'the translations barrel ships no non-source locale') + .toContain('zh-CN'); + // And the keys read for `zh-CN` come from the hand-written bundle itself. + // The generalisation above swapped the source of those keys from the FILE + // to the BARREL; if the barrel ever carried a different object under that + // locale, every gate here would go on passing while measuring the wrong + // bundle. One identity check closes the gap the refactor opened. + expect( + (dulyTranslations as Rec[]).find((b) => 'zh-CN' in b), + 'the barrel\'s zh-CN entry is not the authored `dulyChinese` bundle', + ).toBe(dulyChinese); + }); + + it.each(TRANSLATED_LOCALES)('every declared label the walk can address is carried by %s', (locale) => { + const keys = localeKeys.get(locale)!; const missing = walk.translatable - .filter((entry) => !chineseKeys.has(keyPath(entry.key!))) + .filter((entry) => !keys.has(keyPath(entry.key!))) .map((entry) => `${keyPath(entry.key!)} ← ${entry.where} = ${JSON.stringify(entry.text)}`); expect( missing, - 'a declared label with no bundle key in zh-CN — it renders in English inside a ' - + 'Chinese deployment, beside labels that did translate', + `a declared label with no bundle key in ${locale} — it renders in English inside a ` + + `${locale} deployment, beside labels that did translate`, ).toEqual([]); }); - it('every zh-CN key still has a source in the metadata', () => { + it.each(TRANSLATED_LOCALES)('every %s key still has a source in the metadata', (locale) => { const sources = new Set(derivedKeys); expect( - [...chineseKeys].filter((key) => !sources.has(key)).sort(), + [...localeKeys.get(locale)!].filter((key) => !sources.has(key)).sort(), 'a bundle key that names nothing the metadata declares — a rename or a deletion ' + 'left it behind and it resolves nothing', ).toEqual([]); @@ -151,7 +195,14 @@ describe('i18n coverage — every authored label is translated, every key has a expected.add(`objects.${object}._views.${String(item.name).slice(object.length + 1)}.label`); } } - const derivedViewLabels = new Set(derivedKeys.filter((k) => k.endsWith('.label') && k.includes('._views.'))); + // Exactly `objects.._views..label` — the view's OWN label, + // five segments and no more. A substring test was enough until 17.3.0 put + // `bulkActions..label` and `bulkActions..params.

.label` + // underneath the same prefix (#106); it then swept 15 nested slots into a + // set that is supposed to hold one entry per LIST VIEW, and this assertion + // failed for a reason that had nothing to do with registry naming. + const VIEW_LABEL_KEY = /^objects\.[^.]+\._views\.[^.]+\.label$/; + const derivedViewLabels = new Set(derivedKeys.filter((k) => VIEW_LABEL_KEY.test(k))); expect([...expected].sort(), 'a view the walk did not key, or keyed under the wrong name') .toEqual([...derivedViewLabels].sort()); }); @@ -190,8 +241,8 @@ describe('the English bundle is derived from the metadata, never hand-written', expect(((second.en as Rec).objects as Rec).syn_thing).toMatchObject({ label: 'Gadget' }); }); - it('keys `en` and `zh-CN` identically', () => { - expect([...englishKeys].sort()).toEqual([...chineseKeys].sort()); + it.each(TRANSLATED_LOCALES)('keys `en` and `%s` identically', (locale) => { + expect([...englishKeys].sort()).toEqual([...localeKeys.get(locale)!].sort()); }); }); @@ -230,14 +281,23 @@ describe('the bundles reach the stack', () => { it('pins the metadata types the PLATFORM says are translatable', () => { // The anchor the walk's `untranslatable` verdicts rest on: a dataset - // measure label has no bundle key because the platform has no dataset + // measure label had no bundle key because the platform had no dataset // translator, not because we decided so. When this set grows, that // reasoning changes and the walk must be extended — so fail here. + // + // It did exactly that. `dataset` arrived in 17.3.0 (objectstack#14381) and + // this assertion went red on the bump, before anything else was touched — + // which is the whole point of pinning a set the platform owns. The verdict + // it was holding up has been RE-DERIVED rather than the pin widened: the + // four `dataset.*` paths are now `translate`, and `datasets` is a real + // group in the bundles. Widening this list without extending the walk + // would have turned the one assertion that noticed into the one that hid + // it (#106). expect( [...PLATFORM_TRANSLATABLE_TYPES].sort(), 'the platform\'s translatable metadata types changed — re-derive the ' + '`untranslatable` verdicts in src/translations/authored-text.ts against the new set', - ).toEqual(['action', 'app', 'dashboard', 'object', 'page', 'view']); + ).toEqual(['action', 'app', 'dashboard', 'dataset', 'object', 'page', 'view']); }); }); @@ -253,11 +313,14 @@ describe('untranslatable display text is declared rather than dropped', () => { paths, 'authored display text with no bundle key that this repo has not recorded — either ' + 'it has a key (add it to the walk) or it is a platform gap worth filing', + // + // Eleven paths left this list in one release (#106, objectstack#14381): + // the four `dataset.*`, the six `view.bulkActionDefs[].*` and + // `object.validations[].message`. What remains is designer- and + // operator-facing text plus the one page `content` slot — no END USER + // screen is on this list any more, which is the property the three counts + // below now pin at zero. ).toEqual([ - 'dataset.description', - 'dataset.dimensions[].label', - 'dataset.label', - 'dataset.measures[].label', 'flow.description', 'flow.edges[].label', 'flow.label', @@ -266,19 +329,12 @@ describe('untranslatable display text is declared rather than dropped', () => { 'hook.label', 'job.description', 'job.label', - 'object.validations[].message', 'page.regions[].components[].properties.content.en', 'page.regions[].components[].properties.content.zh-CN', 'permissionSet.description', 'permissionSet.label', 'position.description', 'position.label', - 'view.bulkActionDefs[].confirmLabel', - 'view.bulkActionDefs[].confirmText', - 'view.bulkActionDefs[].label', - 'view.bulkActionDefs[].params[].help', - 'view.bulkActionDefs[].params[].label', - 'view.bulkActionDefs[].params[].placeholder', ]); }); @@ -289,33 +345,33 @@ describe('untranslatable display text is declared rather than dropped', () => { }); it('counts the user-facing half, which is what a reader of the PR needs', () => { - // These three groups reach an END USER in English in a Chinese deployment. - // The rest (flow node labels, job/hook/position/permission-set text) is - // designer- or operator-facing. Asserted as counts so the PR body's - // numbers cannot drift from the code. + // These three groups USED to reach an END USER in English in a Chinese + // deployment. All three closed at once in 17.3.0 (objectstack#14381), so + // all three are pinned at ZERO — the same shape, and for the same reason, + // as the `flow.nodes[].config.` line below that #69 closed: a count that + // is merely deleted cannot notice the gap reopening, and the way each of + // these reopens is ordinary (a new bulk action, a new validation rule, a + // new measure, all of which the walk will key automatically — unless + // someone re-adds an `untranslatable` verdict to make a red gate green). + // + // The 84 strings they were holding are now authored in `zh-CN.ts`: + // 35 bulk-toolbar + 13 validation messages + 36 dataset labels. const count = (prefix: string): number => walk.untranslatable.filter((entry) => entry.path.startsWith(prefix)).length; - expect(count('view.bulkActionDefs'), 'bulk-action toolbar copy').toBe(35); - // Was 11 before #107 added `review_status_transitions` and - // `returned_needs_note`. Both messages are read by whoever is stopped by - // them — a reviewer taking a step the pipeline does not have, an owner - // returning a duty with no reason — so both enlarge the same declared gap - // (a custom rule message has no bundle key anywhere in the platform's - // schema) rather than opening a new kind of one. - expect(count('object.validations'), 'custom validation messages').toBe(13); - // Was 26 before #52 added the three on-time measures — `Done on time`, - // `Completed late` and the `On-time rate` derived from them. A measure - // label still has no bundle key anywhere in the platform's schema, so each - // new one enlarges the same declared gap rather than opening a new kind of - // one; the number moves with the code because that is what this pin is for. - // - // 29 -> 36 with the p20 dashboard set: `duly_duty_health.Overdue` (+1) and - // the whole of `duly_duty_register` — its label, its description, one - // dimension label and three measure labels (+6). Same declared gap, seven - // strings wider. It closes for all of them at once when the platform makes - // datasets translatable (duly#106 / objectstack#14253); nothing here works - // around it in the meantime. - expect(count('dataset.'), 'dataset labels behind chart axes').toBe(36); + expect(count('view.bulkActionDefs'), 'bulk-action toolbar copy — keyed since 17.3.0').toBe(0); + // Was 13. A custom rule's message is now resolved by + // `@objectstack/objectql` at THROW time out of + // `objects.._validations..message`, in the locale of whoever was + // stopped — so a Chinese session gets the refusal in Chinese, in the same + // envelope as the platform's own built-in ones. + expect(count('object.validations'), 'custom validation messages — keyed since 17.3.0').toBe(0); + // Was 36, and the comment here used to say it "closes for all of them at + // once when the platform makes datasets translatable (duly#106 / + // objectstack#14253)". That is what happened: `translateDataset` landed, + // `dataset` joined `TRANSLATABLE_METADATA_TYPES`, and all 36 became keys + // in the `datasets` group in one move. Nothing was worked around in the + // meantime, which is why the close was a re-derivation and not a rewrite. + expect(count('dataset.'), 'dataset labels behind chart axes — keyed since 17.3.0').toBe(0); // Was 6 before #99 (#69) landed: three `notify` nodes' inline title and // message. They now reference an email template, whose per-locale rows are // checked below — so this is a gap that CLOSED, pinned at zero so it @@ -485,7 +541,10 @@ describe('i18n coverage guard — the guard can fail (self-test on synthetic met const result = collectAuthoredText(emptyStack()); expect(result.staleExemptions.length, 'a stack with no authored text must make every exemption stale') .toBeGreaterThan(10); - expect(result.staleExemptions).toContain('object.validations[].message'); + // Was `object.validations[].message` until 17.3.0 gave it a key (#106). + // A job's label has no translator and no bundle group at all, so it is the + // stable pick for "an exemption that is still an exemption". + expect(result.staleExemptions).toContain('job.label'); }); it('detects a missing translation, and an orphan key', () => {