Saltar al contenido principal

Paquete de solución

Id del esquema: solution-package@1 Esquema legible por máquina: solution-package.schema.json

La representación canónica, en texto plano, de una solución exportada. Un paquete de solución es la unidad de promoción entre entornos: se genera al exportar una solución de un entorno de origen y se consume al importarla en un entorno de destino. El paquete es autodescriptivo: incluye tanto el manifiesto (qué componentes contiene la solución) como las definiciones canónicas incrustadas de cada componente basado en modelo, de modo que una importación vuelve a crear entidades, formularios, vistas y pasos de complemento reales, y no referencias sueltas.

La validación se aplica de forma idéntica sea cual sea el origen: un paquete generado por la herramienta de exportación, enviado mediante una llamada a la API o generado por un asistente de IA se valida con este mismo esquema antes de que la canalización de implementación toque el entorno de destino. Un archivo escrito a mano o generado que cumpla este esquema puede importarse con seguridad.

Forma​

Un paquete es un objeto JSON con estos miembros:

CampoTipoObligatorioNotas
formatVersionintegersíLa versión del formato del paquete. Actualmente 1.
publisherNamestringsíEl nombre para mostrar del editor propietario.
publisherPrefixstringsíEl prefijo corto en minúsculas del editor (p. ej., par). Se vuelve a crear al importar si no existe en el inquilino de destino.
solutionNamestringsíEl nombre de la solución.
versionstringsíVersión semántica major.minor.patch (p. ej., 1.0.0).
descriptionstring | nullnoDescripción opcional de la solución.
requiresarray | nullnoLas soluciones sobre las que se construye esta: { solutionName, minVersion? }. Se comprueban en el entorno de destino antes de escribir nada; una ausente o más antigua rechaza la importación.
componentsarraysíEl manifiesto: una entrada por componente (tipo + nombre lógico).
modelComponentsobjectsíLas definiciones canónicas incrustadas, agrupadas por tipo.
customAppsarray | nullnoManifiestos de aplicaciones personalizadas incrustados. Opcional para que los paquetes generados antes de que existieran las aplicaciones personalizadas sigan validándose; además, cada elemento se valida con custom-app-manifest@1 al materializarse.
webResourcesarray | nullnoRecursos web incrustados (sección 6.15): archivos de aplicación almacenados en la base de datos, cada uno con su content (texto UTF-8 para los tipos de texto, Base64 para los binarios). Opcional para que los paquetes antiguos sigan validándose; al materializarse, los metadatos de cada elemento se vuelven a validar con web-resource-manifest@1 y se comprueba el hash de su contenido.
customControlsarray | nullnoControles personalizados incrustados (§28), cada uno con su archivo comprimido de compilación completo codificado en Base64, de modo que el código de un control viaja con la solución en lugar de obtenerse de un host externo. Además, al materializarse, el manifiesto de cada elemento se valida con custom-control-manifest@1 y su archivo comprimido se comprueba frente al contentHash declarado: el momento en que se demuestra que el código que se revisó y el código que se ejecuta son el mismo.

Componente del manifiesto (components[])​

CampoTipoObligatorioNotas
componentTypestringsíUno de Entity, Form, View, App, CustomApp, CustomControl, Process, Report, WebResource, PolicyDefinition, SecurityRole, SavedQuery, Dashboard, BusinessRule, Script. (App es el mapa del sitio de una aplicación basada en modelo; CustomApp es una aplicación React escrita a mano).
logicalNamestringsíCon el prefijo del editor; en minúsculas, admitiendo _, ., / y - para los nombres de recursos web con forma de ruta (p. ej., par_invoice, par_/dashboard/app.js).
componentReferenceIdstring | nullnoEl id propio del componente en su subsistema, si lo tiene.

Definiciones incrustadas (modelComponents)​

Un objeto con matrices de entradas de definición de componentes: entities, forms, views, pluginSteps y el opcional apps (aplicaciones basadas en modelo). El orden refleja la intención de las dependencias: primero se materializan las entidades, después los formularios, las vistas y los pasos de complemento, y por último las aplicaciones (cuya navegación hace referencia a las entidades por nombre lógico). apps es opcional para que un paquete generado antes de que las aplicaciones viajaran siga validándose e importándose.

seedData (opcional) es la única lista cuyas entradas son filas y no definiciones: un documento seed-data@1 por tabla —con el nombre lógico de la tabla tanto en logicalName como en entity— que contiene las filas que devolvió la vista de datos iniciales de la tabla al exportar. Una importación lo materializa en último lugar e inserta o actualiza cada fila por su id a través de la ruta habitual de escritura de registros, escribiendo solo las columnas que contiene la fila y sin eliminar nunca nada; una fila que el destino rechaza se omite y se indica en el detalle del estado de la importación. Consulte Incluir datos iniciales en una solución.

CampoTipoObligatorioNotas
logicalNamestringsíEl nombre lógico del componente.
entitystringsíEl nombre lógico de la entidad propietaria (el propio nombre de la entidad, en el caso de una entidad).
jsonstringsíLa definición JSON canónica del componente (una definición de entidad, un formulario, una vista o un contenedor de paso de complemento, cada uno validado con su propio esquema al materializarse).
isDefaultbooleannoPara formularios y vistas: indica si es el predeterminado de la entidad.

Una única vía de validación. La carga json de cada componente incrustado no se vuelve a validar con este esquema de paquete; en su lugar, cada una se valida con su propio esquema publicado (por ejemplo, Definición de entidad basada en modelo, Formulario, Vista, Paso de complemento) al materializarse: la misma comprobación que realiza el guardado desde un diseñador.

Ejemplo​

{
"formatVersion": 1,
"publisherName": "Parsware",
"publisherPrefix": "par",
"solutionName": "Sales",
"version": "1.0.0",
"description": "Core sales entities.",
"components": [
{ "componentType": "Entity", "logicalName": "par_invoice" },
{ "componentType": "Form", "logicalName": "par_invoice_main" }
],
"modelComponents": {
"entities": [
{ "logicalName": "par_invoice", "entity": "par_invoice", "json": "{ ...entity definition... }" }
],
"forms": [
{ "logicalName": "par_invoice_main", "entity": "par_invoice", "json": "{ ...form definition... }", "isDefault": true }
],
"views": [],
"pluginSteps": []
}
}

Cómo se usa​

  • La exportación lee el manifiesto y las definiciones reales de un entorno de origen y genera un paquete en GET /solutions/{id}/export?sourceEnvironmentId=….
  • La importación valida el paquete con este esquema, resuelve las dependencias (cada formulario, vista o paso de complemento debe apuntar a una entidad incluida en el paquete), supera cualquier puerta de aprobación y después materializa los componentes en el esquema aislado del entorno de destino, en POST /solution-imports.

Control de versiones​

Las versiones anteriores del esquema se conservan junto a las nuevas para que las soluciones ya implementadas sigan validándose después de que el esquema evolucione. Un cambio incompatible se publica como una versión nueva (solution-package@2) en lugar de editar esta; un paquete incluye su propio formatVersion para que la canalización pueda rechazar una versión que no admite.