Spaces:
Running
Running
Create packs.mjs
Browse files- core/packs.mjs +48 -0
core/packs.mjs
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export const APPacks = {
|
| 2 |
+
registry: [],
|
| 3 |
+
migrations: [],
|
| 4 |
+
async load(){
|
| 5 |
+
const idx = await fetch('packs/index.json');
|
| 6 |
+
if(!idx.ok)throw Error('No se pudo cargar packs/index.json');
|
| 7 |
+
const reg = await idx.json();
|
| 8 |
+
if(!reg||!Array.isArray(reg.countries))throw Error('Registro de packs inv谩lido');
|
| 9 |
+
const plan = await fetch('data/migrations/index.json');
|
| 10 |
+
APPacks.migrations = plan.ok ? ((await plan.json()).migrations || []) : [];
|
| 11 |
+
APPacks.registry = [];
|
| 12 |
+
for(const entry of reg.countries)APPacks.register(entry);
|
| 13 |
+
return APPacks.registry;
|
| 14 |
+
},
|
| 15 |
+
register(entry){
|
| 16 |
+
const e = entry || {};
|
| 17 |
+
if(!/^[A-Z]{2}$/.test(e.code||''))throw Error('C贸digo de pack inv谩lido');
|
| 18 |
+
if(typeof e.name!=='string'||!e.name.trim())throw Error('Pack sin nombre: '+e.code);
|
| 19 |
+
if(!['borrador','en_revision','validado'].includes(e.status))throw Error('Estado de pack inv谩lido: '+e.code);
|
| 20 |
+
if(typeof e.runtime_enabled!=='boolean')throw Error('runtime_enabled inv谩lido: '+e.code);
|
| 21 |
+
const files = e.files || {};
|
| 22 |
+
const list = (v) => Array.isArray(v) ? v.filter((x) => typeof x === 'string') : [];
|
| 23 |
+
const rec = {
|
| 24 |
+
code: e.code, name: e.name, status: e.status, runtime_enabled: e.runtime_enabled,
|
| 25 |
+
maintainer: typeof e.maintainer === 'string' ? e.maintainer : '',
|
| 26 |
+
scope: list(e.scope), data: list(files.data), locale: list(files.locale), tests: list(files.tests),
|
| 27 |
+
};
|
| 28 |
+
const at = APPacks.registry.findIndex((p) => p.code === rec.code);
|
| 29 |
+
if(at < 0)APPacks.registry.push(rec); else APPacks.registry[at] = rec;
|
| 30 |
+
return rec;
|
| 31 |
+
},
|
| 32 |
+
migrationOf(code){
|
| 33 |
+
return APPacks.migrations.find((m) => typeof m.file === 'string' && m.file.endsWith('_pack_' + code + '.sql')) || null;
|
| 34 |
+
},
|
| 35 |
+
gate(code){
|
| 36 |
+
const pack = APPacks.registry.find((p) => p.code === code);
|
| 37 |
+
if(!pack)return { code, registered: false, eligible: false, reasons: ['pack no registrado en el kernel'] };
|
| 38 |
+
const reasons = [];
|
| 39 |
+
if(pack.status !== 'validado')reasons.push('estado ' + pack.status + ': falta revisi贸n humana');
|
| 40 |
+
if(!pack.tests.length)reasons.push('sin pruebas adjuntas');
|
| 41 |
+
const mig = APPacks.migrationOf(pack.code);
|
| 42 |
+
if(!mig)reasons.push('sin migraci贸n asociada _pack_' + pack.code + '.sql');
|
| 43 |
+
if(!pack.data.length)reasons.push('sin datos declarados');
|
| 44 |
+
if(!pack.runtime_enabled)reasons.push('runtime_enabled=false');
|
| 45 |
+
return { code: pack.code, registered: true, eligible: reasons.length === 0, reasons, migration: mig && mig.file, status: pack.status };
|
| 46 |
+
},
|
| 47 |
+
};
|
| 48 |
+
globalThis.APPacks = APPacks;
|