TenantAtlas/apps/platform/.pnpm-store/v10/files/c9/6c991d18274b87952f1a54a7fa4f2dece78507bd222f4020a063352ce4d99f3701e93a6b920192afa3c7b84df2eba3dcef9fdf3cab22c3fef87372431e3ac7
ahmido 1fec9c6f9d
Some checks failed
Main Confidence / confidence (push) Failing after 45s
feat: compress governance operator outcomes (#253)
## Summary
- introduce surface-aware compressed governance outcomes and reuse the shared truth/explanation seams for operator-first summaries
- apply the compressed outcome hierarchy across baseline, evidence, review, review-pack, canonical review/evidence, and artifact-oriented operation-run surfaces
- expand spec 214 fixtures and Pest coverage, and fix tenant-panel route assertions by generating explicit tenant-panel URLs in the affected Filament tests

## Validation
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- focused governance compression suite from `specs/214-governance-outcome-compression/quickstart.md` passed (`68` tests, `445` assertions)
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/InventoryItemResourceTest.php tests/Feature/Filament/BackupSetUiEnforcementTest.php tests/Feature/Filament/RestoreRunUiEnforcementTest.php` passed (`18` tests, `81` assertions)

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #253
2026-04-19 12:30:36 +00:00

96 lines
2.1 KiB
Plaintext

'use strict';
import utils from '../utils.js';
/**
* It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z']
*
* @param {string} name - The name of the property to get.
*
* @returns An array of strings.
*/
function parsePropPath(name) {
// foo[x][y][z]
// foo.x.y.z
// foo-x-y-z
// foo x y z
return utils.matchAll(/\w+|\[(\w*)]/g, name).map((match) => {
return match[0] === '[]' ? '' : match[1] || match[0];
});
}
/**
* Convert an array to an object.
*
* @param {Array<any>} arr - The array to convert to an object.
*
* @returns An object with the same keys and values as the array.
*/
function arrayToObject(arr) {
const obj = {};
const keys = Object.keys(arr);
let i;
const len = keys.length;
let key;
for (i = 0; i < len; i++) {
key = keys[i];
obj[key] = arr[key];
}
return obj;
}
/**
* It takes a FormData object and returns a JavaScript object
*
* @param {string} formData The FormData object to convert to JSON.
*
* @returns {Object<string, any> | null} The converted object.
*/
function formDataToJSON(formData) {
function buildPath(path, value, target, index) {
let name = path[index++];
if (name === '__proto__') return true;
const isNumericKey = Number.isFinite(+name);
const isLast = index >= path.length;
name = !name && utils.isArray(target) ? target.length : name;
if (isLast) {
if (utils.hasOwnProp(target, name)) {
target[name] = [target[name], value];
} else {
target[name] = value;
}
return !isNumericKey;
}
if (!target[name] || !utils.isObject(target[name])) {
target[name] = [];
}
const result = buildPath(path, value, target[name], index);
if (result && utils.isArray(target[name])) {
target[name] = arrayToObject(target[name]);
}
return !isNumericKey;
}
if (utils.isFormData(formData) && utils.isFunction(formData.entries)) {
const obj = {};
utils.forEachEntry(formData, (name, value) => {
buildPath(parsePropPath(name), value, obj, 0);
});
return obj;
}
return null;
}
export default formDataToJSON;