@microteia/console 2.38.0 → 2.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONSOLE-VERSIONS.md +54 -0
- package/LICENSE +661 -0
- package/NOTICE +97 -0
- package/README.md +8 -1
- package/lib/console/backendApplied.d.ts +58 -0
- package/lib/console/backendApplied.js +81 -0
- package/lib/console/exportCatalog.d.ts +39 -210
- package/lib/console/exportCatalog.js +55 -310
- package/lib/console/firestoreRest.d.ts +2 -0
- package/lib/console/firestoreRest.js +13 -2
- package/lib/console/installedExtensions.d.ts +2 -0
- package/lib/console/installedExtensions.js +1 -0
- package/lib/console/provision.js +106 -21
- package/lib/index.js +1 -1
- package/lib/kernel/manifest.d.ts +17 -0
- package/lib/kernel/manifest.js +0 -14
- package/lib/shared/paths.d.ts +1 -1
- package/lib/shared/paths.js +1 -1
- package/lib/vendor/installationDocs.js +1 -1
- package/lib/vendor/pack.js +35 -1
- package/lib/vendor/packConsole.js +5 -0
- package/lib/vendor/packageTemplates.js +10 -2
- package/lib/vendor/publish.js +83 -0
- package/package.json +9 -3
package/NOTICE
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
Microteia — An AI-First Business Application Platform
|
|
2
|
+
Copyright (C) 2026 Alexnaldo Carvalho dos Santos and the Microteia contributors
|
|
3
|
+
Source code: https://github.com/microteia/microteia
|
|
4
|
+
|
|
5
|
+
This program is free software: you can redistribute it and/or modify it under the terms of the
|
|
6
|
+
GNU Affero General Public License as published by the Free Software Foundation, either version 3 of
|
|
7
|
+
the License, or (at your option) any later version.
|
|
8
|
+
|
|
9
|
+
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
|
10
|
+
even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
|
|
11
|
+
General Public License for more details.
|
|
12
|
+
|
|
13
|
+
You should have received a copy of the GNU Affero General Public License along with this program, in
|
|
14
|
+
the file LICENSE. If not, see <https://www.gnu.org/licenses/>.
|
|
15
|
+
|
|
16
|
+
The license is supplemented by the additional terms and the additional permission below, as allowed
|
|
17
|
+
by section 7 of the GNU Affero General Public License. Both apply to every copy of Microteia and to
|
|
18
|
+
every work based on it, and this file must be conveyed together with the LICENSE file.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
===================================================================================================
|
|
22
|
+
ADDITIONAL TERMS UNDER SECTION 7 OF THE GNU AFFERO GENERAL PUBLIC LICENSE
|
|
23
|
+
===================================================================================================
|
|
24
|
+
|
|
25
|
+
1. Attribution — section 7(b).
|
|
26
|
+
|
|
27
|
+
Every copy of Microteia, modified or not, that is conveyed or that users interact with remotely
|
|
28
|
+
over a computer network, must preserve the copyright notices and display the following
|
|
29
|
+
attribution, unaltered and legible:
|
|
30
|
+
|
|
31
|
+
Based on Microteia — https://github.com/microteia/microteia
|
|
32
|
+
Copyright (C) Alexnaldo Carvalho dos Santos and the Microteia contributors.
|
|
33
|
+
Licensed under the GNU Affero General Public License, version 3 or later.
|
|
34
|
+
|
|
35
|
+
The attribution must appear (a) in the Appropriate Legal Notices displayed by the interactive user
|
|
36
|
+
interface — in Microteia, the "Copyright and contact" section of the Terms of Use page, served at
|
|
37
|
+
the "/license" route, which is reachable before signing in — and (b) in the README, or equivalent
|
|
38
|
+
documentation, of every distribution. A translated interface may display the attribution in its
|
|
39
|
+
own language, provided the link and the names are kept.
|
|
40
|
+
|
|
41
|
+
2. Marking of modified versions — section 7(c).
|
|
42
|
+
|
|
43
|
+
A modified version must be marked in reasonable ways as different from the original version, and
|
|
44
|
+
must not misrepresent its origin: it must not be presented as the original Microteia, nor as made,
|
|
45
|
+
endorsed or supported by its author or contributors.
|
|
46
|
+
|
|
47
|
+
3. Trade names and trademarks — section 7(e).
|
|
48
|
+
|
|
49
|
+
This license grants no rights under trademark law to the name "Microteia", to its logos or to any
|
|
50
|
+
other brand identifier, beyond the use required to comply with the attribution in term 1 and to
|
|
51
|
+
state truthfully that a work is based on Microteia.
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
===================================================================================================
|
|
55
|
+
ADDITIONAL PERMISSION UNDER SECTION 7 — MICROTEIA EXTENSION EXCEPTION
|
|
56
|
+
===================================================================================================
|
|
57
|
+
|
|
58
|
+
Microteia is built to be extended without being modified. As a special exception, the copyright
|
|
59
|
+
holders of Microteia give you permission to create an Extension, and to use, convey, sell and offer
|
|
60
|
+
it to users over a computer network, under terms of your choice — proprietary, permissive or
|
|
61
|
+
copyleft — and to run it together with Microteia, without the Extension, or the combination of the
|
|
62
|
+
Extension with Microteia, being subject to the terms of the GNU Affero General Public License as to
|
|
63
|
+
the Extension, provided that the Extension interacts with Microteia only through the Published
|
|
64
|
+
Interfaces.
|
|
65
|
+
|
|
66
|
+
"Extension" means a plugin, extension package, module, theme, language package, view, startup
|
|
67
|
+
script, sandbox script, workflow, document template, or Cloud Function — together with its source
|
|
68
|
+
code and with every artifact compiled from it — that is not itself part of Microteia and that is
|
|
69
|
+
written to be installed in, or deployed beside, an installation of Microteia.
|
|
70
|
+
|
|
71
|
+
"Published Interfaces" means:
|
|
72
|
+
|
|
73
|
+
a. the extension package format — the manifest, its extension points and the artifact that the
|
|
74
|
+
platform validates and installs;
|
|
75
|
+
b. the authoring SDK, published as "@microteia/sdk", including its command-line tools and its type
|
|
76
|
+
definitions;
|
|
77
|
+
c. the curated host API offered to extension views and startup scripts (the "@microteia/*"
|
|
78
|
+
modules described by the SDK type definitions);
|
|
79
|
+
d. the API offered to sandbox scripts;
|
|
80
|
+
e. the office functions API (the "office" entry point of the platform's functions package), and the
|
|
81
|
+
directories in which an installation mounts its own Cloud Functions;
|
|
82
|
+
f. the Model Context Protocol server and the callable functions that the platform exposes to
|
|
83
|
+
external clients.
|
|
84
|
+
|
|
85
|
+
You may also copy code from the authoring examples that are distributed with the SDK (the
|
|
86
|
+
"examples" directory of the SDK package and the first-party extensions it is built from) into an
|
|
87
|
+
Extension, and convey that copied code as part of the Extension, under the Extension's terms.
|
|
88
|
+
|
|
89
|
+
This exception does not cover modifications of Microteia itself. A change to the kernel, to a
|
|
90
|
+
first-party plugin, to the SDK or to any other part of Microteia — including a change made in order
|
|
91
|
+
to support an Extension — is a modification of Microteia and remains subject to the GNU Affero
|
|
92
|
+
General Public License and to the additional terms above. The exception also grants no right to use
|
|
93
|
+
the Microteia name or trademarks for an Extension beyond stating truthfully that the Extension works
|
|
94
|
+
with Microteia.
|
|
95
|
+
|
|
96
|
+
If you modify Microteia, you may extend this exception to your version, but you are not obligated to
|
|
97
|
+
do so. If you do not wish to do so, delete this exception statement from your version.
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Microteia Console 2.
|
|
1
|
+
# Microteia Console 2.42.0
|
|
2
2
|
|
|
3
3
|
Installs and updates Microteia in a Firebase project you own. It has no npm dependencies of its own —
|
|
4
4
|
what it needs are command-line tools that are already on the machine, listed at the bottom.
|
|
@@ -64,3 +64,10 @@ the Microteia repository.
|
|
|
64
64
|
|
|
65
65
|
`CONSOLE-VERSIONS.md`, in this folder. `unpack` copies it into the installation it manages, beside the
|
|
66
66
|
platform's own `KERNEL-VERSIONS.md` — each history travels with the artifact it describes.
|
|
67
|
+
|
|
68
|
+
## License
|
|
69
|
+
|
|
70
|
+
Free software, licensed under the GNU Affero General Public License, version 3 or (at your option) any
|
|
71
|
+
later version — the full text is in `LICENSE`, and the additional terms in `NOTICE`, in this folder.
|
|
72
|
+
The source code of this Console and of the platform it installs is at
|
|
73
|
+
https://github.com/microteia/microteia.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { FirestoreTypedValue } from './firestoreRest.js';
|
|
2
|
+
/**
|
|
3
|
+
* O que o PROJETO tem aplicado, devolvido ao banco onde a aplicação pode ler.
|
|
4
|
+
*
|
|
5
|
+
* O carimbo mora em cada cópia instalada (`backendState`), e o `provision` o grava nas cópias que
|
|
6
|
+
* existem no momento em que roda. A cópia que chega DEPOIS — o segundo escritório que atualiza para a
|
|
7
|
+
* versão que o primeiro já pôs no ar — ficava "Backend pendente" até alguém rodar o comando de novo, e o
|
|
8
|
+
* comando não decidia nada: a aprovação por hash já é do projeto e as functions já estavam no ar. Ele
|
|
9
|
+
* só copiava um registro.
|
|
10
|
+
*
|
|
11
|
+
* Este documento é esse registro, uma vez por projeto: para cada extensão, o fingerprint que o projeto
|
|
12
|
+
* roda. A tela libera a cópia cujo fingerprint está aqui. Quem afirma continua sendo só o Console — a
|
|
13
|
+
* regra de `backend_state` nega escrita ao cliente.
|
|
14
|
+
*/
|
|
15
|
+
export declare const BACKEND_APPLIED_PATH = "/backend_state/applied";
|
|
16
|
+
export interface AppliedEntry {
|
|
17
|
+
pluginId: string;
|
|
18
|
+
fingerprint: string;
|
|
19
|
+
approvedHash?: string;
|
|
20
|
+
approvedBy?: string;
|
|
21
|
+
}
|
|
22
|
+
/** O que uma cópia exige, na forma mínima que as contas abaixo precisam. */
|
|
23
|
+
export interface FingerprintClaim {
|
|
24
|
+
pluginId: string;
|
|
25
|
+
fingerprint: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Os campos do documento, montados sem tocar na rede.
|
|
29
|
+
*
|
|
30
|
+
* Lista e não mapa por `pluginId` porque o id tem pontos, e ponto em chave de mapa vira caminho de
|
|
31
|
+
* campo no Firestore. A FORMA é contrato com o kernel, versionado à parte — é o que o teste confere.
|
|
32
|
+
*/
|
|
33
|
+
export declare const backendAppliedFields: (entries: readonly AppliedEntry[], writtenAt: Date) => Record<string, FirestoreTypedValue>;
|
|
34
|
+
/**
|
|
35
|
+
* O documento lido, defensivo pelo mesmo motivo do lado do kernel: pode ter sido escrito por um Console
|
|
36
|
+
* de outra versão. Entrada sem id ou sem fingerprint não libera nada, então é descartada.
|
|
37
|
+
*/
|
|
38
|
+
export declare const parseBackendApplied: (data: Record<string, unknown> | null) => AppliedEntry[];
|
|
39
|
+
export declare const appliedEntryOf: (entries: readonly AppliedEntry[], claim: FingerprintClaim) => AppliedEntry | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* O que continua verdadeiro aconteça o que acontecer nesta execução.
|
|
42
|
+
*
|
|
43
|
+
* Só fica a entrada de extensão ainda instalada E com o fingerprint da cópia mais nova — a que o
|
|
44
|
+
* deploy vai pôr no ar. A extensão que saiu de todo escritório pode ter a function apagada pelo
|
|
45
|
+
* `--prune`; a versão superada pode ter o código trocado pelo deploy. Nos dois casos a entrada
|
|
46
|
+
* anunciaria no ar o que talvez não esteja, e uma cópia nova nasceria liberada contra uma function que
|
|
47
|
+
* não existe — o defeito que parece CORS e que a pendência existe para impedir.
|
|
48
|
+
*
|
|
49
|
+
* Só REMOVE: acrescentar é do fim da execução, quando o deploy já respondeu.
|
|
50
|
+
*/
|
|
51
|
+
export declare const reduceBackendApplied: (entries: readonly AppliedEntry[], newest: readonly FingerprintClaim[]) => AppliedEntry[];
|
|
52
|
+
/**
|
|
53
|
+
* `[]` quando o documento não existe. Leitura recusada também vira `[]`, com aviso de quem chama: o
|
|
54
|
+
* que se perde é só o atalho — sem entradas, nada é materializado, e a redução grava a lista vazia,
|
|
55
|
+
* que é a resposta segura para "não sei o que o projeto tem".
|
|
56
|
+
*/
|
|
57
|
+
export declare const readBackendApplied: (projectId: string) => Promise<AppliedEntry[]>;
|
|
58
|
+
export declare const writeBackendApplied: (projectId: string, entries: readonly AppliedEntry[]) => Promise<void>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { asArray, asMap, asString, asTimestamp, getDocument, patchFields } from './firestoreRest.js';
|
|
2
|
+
import { CLI_VERSION } from '../shared/paths.js';
|
|
3
|
+
/**
|
|
4
|
+
* O que o PROJETO tem aplicado, devolvido ao banco onde a aplicação pode ler.
|
|
5
|
+
*
|
|
6
|
+
* O carimbo mora em cada cópia instalada (`backendState`), e o `provision` o grava nas cópias que
|
|
7
|
+
* existem no momento em que roda. A cópia que chega DEPOIS — o segundo escritório que atualiza para a
|
|
8
|
+
* versão que o primeiro já pôs no ar — ficava "Backend pendente" até alguém rodar o comando de novo, e o
|
|
9
|
+
* comando não decidia nada: a aprovação por hash já é do projeto e as functions já estavam no ar. Ele
|
|
10
|
+
* só copiava um registro.
|
|
11
|
+
*
|
|
12
|
+
* Este documento é esse registro, uma vez por projeto: para cada extensão, o fingerprint que o projeto
|
|
13
|
+
* roda. A tela libera a cópia cujo fingerprint está aqui. Quem afirma continua sendo só o Console — a
|
|
14
|
+
* regra de `backend_state` nega escrita ao cliente.
|
|
15
|
+
*/
|
|
16
|
+
export const BACKEND_APPLIED_PATH = '/backend_state/applied';
|
|
17
|
+
/**
|
|
18
|
+
* Os campos do documento, montados sem tocar na rede.
|
|
19
|
+
*
|
|
20
|
+
* Lista e não mapa por `pluginId` porque o id tem pontos, e ponto em chave de mapa vira caminho de
|
|
21
|
+
* campo no Firestore. A FORMA é contrato com o kernel, versionado à parte — é o que o teste confere.
|
|
22
|
+
*/
|
|
23
|
+
export const backendAppliedFields = (entries, writtenAt) => ({
|
|
24
|
+
writtenAt: asTimestamp(writtenAt),
|
|
25
|
+
consoleVersion: asString(CLI_VERSION),
|
|
26
|
+
extensions: asArray(entries.map((entry) => asMap({
|
|
27
|
+
pluginId: asString(entry.pluginId),
|
|
28
|
+
fingerprint: asString(entry.fingerprint),
|
|
29
|
+
...(entry.approvedHash !== undefined ? { approvedHash: asString(entry.approvedHash) } : {}),
|
|
30
|
+
...(entry.approvedBy !== undefined ? { approvedBy: asString(entry.approvedBy) } : {}),
|
|
31
|
+
}))),
|
|
32
|
+
});
|
|
33
|
+
/**
|
|
34
|
+
* O documento lido, defensivo pelo mesmo motivo do lado do kernel: pode ter sido escrito por um Console
|
|
35
|
+
* de outra versão. Entrada sem id ou sem fingerprint não libera nada, então é descartada.
|
|
36
|
+
*/
|
|
37
|
+
export const parseBackendApplied = (data) => {
|
|
38
|
+
const list = data?.extensions;
|
|
39
|
+
if (!Array.isArray(list))
|
|
40
|
+
return [];
|
|
41
|
+
return list.flatMap((item) => {
|
|
42
|
+
if (typeof item !== 'object' || item === null)
|
|
43
|
+
return [];
|
|
44
|
+
const fields = item;
|
|
45
|
+
if (typeof fields.pluginId !== 'string' || fields.pluginId === '')
|
|
46
|
+
return [];
|
|
47
|
+
if (typeof fields.fingerprint !== 'string' || fields.fingerprint === '')
|
|
48
|
+
return [];
|
|
49
|
+
return [{
|
|
50
|
+
pluginId: fields.pluginId,
|
|
51
|
+
fingerprint: fields.fingerprint,
|
|
52
|
+
...(typeof fields.approvedHash === 'string' ? { approvedHash: fields.approvedHash } : {}),
|
|
53
|
+
...(typeof fields.approvedBy === 'string' ? { approvedBy: fields.approvedBy } : {}),
|
|
54
|
+
}];
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
export const appliedEntryOf = (entries, claim) => entries.find((entry) => entry.pluginId === claim.pluginId && entry.fingerprint === claim.fingerprint);
|
|
58
|
+
/**
|
|
59
|
+
* O que continua verdadeiro aconteça o que acontecer nesta execução.
|
|
60
|
+
*
|
|
61
|
+
* Só fica a entrada de extensão ainda instalada E com o fingerprint da cópia mais nova — a que o
|
|
62
|
+
* deploy vai pôr no ar. A extensão que saiu de todo escritório pode ter a function apagada pelo
|
|
63
|
+
* `--prune`; a versão superada pode ter o código trocado pelo deploy. Nos dois casos a entrada
|
|
64
|
+
* anunciaria no ar o que talvez não esteja, e uma cópia nova nasceria liberada contra uma function que
|
|
65
|
+
* não existe — o defeito que parece CORS e que a pendência existe para impedir.
|
|
66
|
+
*
|
|
67
|
+
* Só REMOVE: acrescentar é do fim da execução, quando o deploy já respondeu.
|
|
68
|
+
*/
|
|
69
|
+
export const reduceBackendApplied = (entries, newest) => {
|
|
70
|
+
const standing = new Map(newest.map((claim) => [claim.pluginId, claim.fingerprint]));
|
|
71
|
+
return entries.filter((entry) => standing.get(entry.pluginId) === entry.fingerprint);
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* `[]` quando o documento não existe. Leitura recusada também vira `[]`, com aviso de quem chama: o
|
|
75
|
+
* que se perde é só o atalho — sem entradas, nada é materializado, e a redução grava a lista vazia,
|
|
76
|
+
* que é a resposta segura para "não sei o que o projeto tem".
|
|
77
|
+
*/
|
|
78
|
+
export const readBackendApplied = async (projectId) => parseBackendApplied(await getDocument(projectId, BACKEND_APPLIED_PATH));
|
|
79
|
+
export const writeBackendApplied = async (projectId, entries) => {
|
|
80
|
+
await patchFields(projectId, BACKEND_APPLIED_PATH, backendAppliedFields(entries, new Date()));
|
|
81
|
+
};
|
|
@@ -1,228 +1,57 @@
|
|
|
1
1
|
import type { ParsedArgs } from '../shared/args.js';
|
|
2
|
-
import type {
|
|
3
|
-
/**
|
|
4
|
-
|
|
5
|
-
*
|
|
6
|
-
* O servidor MCP do SDK monta o catálogo a partir dos `plugin.ts` do diretório mais o registro de
|
|
7
|
-
* entidades do kernel. Numa instalação real isso deixa de fora as duas coisas que mais importam: a
|
|
8
|
-
* tela que o escritório criou no Form Design e a extensão de terceiro já instalada. O detector de
|
|
9
|
-
* "campo que pertence a outra entidade conhecida" não podia disparar contra elas, porque para ele elas
|
|
10
|
-
* não existiam.
|
|
11
|
-
*
|
|
12
|
-
* A saída NÃO foi ligar o SDK ao Firestore. `microteia-plugin` é offline por desenho, e arrastar
|
|
13
|
-
* credencial para dentro da ferramenta de autoria trocaria uma cegueira por um problema pior. Quem já
|
|
14
|
-
* fala com o projeto do escritório é o Console — o token vem do `gcloud`, a cada execução, e nada é
|
|
15
|
-
* guardado. Então é o Console que lê e escreve o arquivo, e o SDK apenas o encontra ali.
|
|
16
|
-
*
|
|
17
|
-
* Três decisões que não são preferência:
|
|
18
|
-
*
|
|
19
|
-
* - **O arquivo NÃO mora em `.microteia/`.** Aquele diretório é apagado por inteiro a cada `unpack`,
|
|
20
|
-
* e um retrato que some na troca de kernel é um retrato que ninguém pode depender de ter. Ele fica
|
|
21
|
-
* em `extensions/`, ao lado do `microteia.yaml`, que é onde o autor trabalha.
|
|
22
|
-
* - **Ele é gitignorado**, pela conciliação que o SDK já faz do `.gitignore` daquele diretório. Ele
|
|
23
|
-
* carrega nome de tela e de campo que o escritório digitou: dado do tenant, não artefato do produto.
|
|
24
|
-
* - **`--tenant` é obrigatório.** Um projeto Firebase pode ter vários escritórios, e escolher um por
|
|
25
|
-
* adivinhação escreveria o vocabulário de um dentro do trabalho de outro. Sem a opção, o comando
|
|
26
|
-
* LISTA os que existem.
|
|
27
|
-
*/
|
|
28
|
-
/** O nome é contrato com o SDK, que o procura por este nome — ver `installedCatalog.ts` do kernel. */
|
|
29
|
-
export declare const CATALOG_FILE = "installed-catalog.json";
|
|
30
|
-
/**
|
|
31
|
-
* A versão do FORMATO. Ela existe para que um Console de outra época não seja lido como se falasse a
|
|
32
|
-
* mesma língua: o SDK recusa o que não for exatamente esta, e diz o comando que refaz o arquivo.
|
|
33
|
-
*/
|
|
34
|
-
export declare const CATALOG_FORMAT_VERSION = 1;
|
|
35
|
-
/**
|
|
36
|
-
* O que viaja de cada campo, e nada além.
|
|
37
|
-
*
|
|
38
|
-
* A linha é ESQUEMA versus CONTEÚDO. Nome, tipo, obrigatoriedade, referência, agregado e expressão
|
|
39
|
-
* descrevem o que a entidade É, e é disso que o catálogo e os detectores precisam. Opção de lista,
|
|
40
|
-
* máscara, texto de ajuda, valor padrão e regra de formulário são conteúdo e apresentação: o catálogo
|
|
41
|
-
* nunca os lê, e cada um deles é mais vocabulário do escritório saindo do banco sem precisar.
|
|
42
|
-
*/
|
|
43
|
-
export interface CatalogFieldExport {
|
|
44
|
-
key: string;
|
|
45
|
-
label: string;
|
|
46
|
-
type: string;
|
|
47
|
-
required: boolean;
|
|
48
|
-
order: number;
|
|
49
|
-
multi?: boolean;
|
|
50
|
-
refEntity?: string;
|
|
51
|
-
refDenormKey?: string;
|
|
52
|
-
lookupCollection?: string;
|
|
53
|
-
section?: string;
|
|
54
|
-
origin: string;
|
|
55
|
-
ownerPluginId?: string;
|
|
56
|
-
aggregation?: Record<string, unknown>;
|
|
57
|
-
compute?: string;
|
|
58
|
-
/** O atalho de chave de um campo só — o kernel o desaçucara em `field:<key>`. */
|
|
59
|
-
unique?: true;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Uma chave da coleção (`ScreenDefinition.keys`): o que não pode se repetir. É esquema, como o campo:
|
|
63
|
-
* quem modela precisa saber que ela existe antes de propor outra, e o plano a propunha como nova a
|
|
64
|
-
* cada execução quando ela só existia na instalação.
|
|
65
|
-
*
|
|
66
|
-
* A mensagem do conflito NÃO viaja — é apresentação, e não muda qual reserva um registro recebe. O
|
|
67
|
-
* `status` também não: ele é ignorado pelo kernel desde que a adoção passou a ser estado dele.
|
|
68
|
-
*/
|
|
69
|
-
export interface CatalogKeyExport {
|
|
70
|
-
name: string;
|
|
71
|
-
kind: string;
|
|
72
|
-
fields: string[];
|
|
73
|
-
scope?: string;
|
|
74
|
-
normalize?: {
|
|
75
|
-
trim?: boolean;
|
|
76
|
-
caseInsensitive?: boolean;
|
|
77
|
-
formatPreset?: string;
|
|
78
|
-
};
|
|
79
|
-
sparse?: boolean;
|
|
80
|
-
ownerPluginId?: string;
|
|
81
|
-
}
|
|
82
|
-
export interface CatalogScreenExport {
|
|
83
|
-
key: string;
|
|
84
|
-
/**
|
|
85
|
-
* O id UNIVERSAL da tela. A chave acima é a instalada, que pode ter sido desambiguada; é pelo
|
|
86
|
-
* `sourceId` que uma extensão endereça a tela de outra (`record:<sourceId>`).
|
|
87
|
-
*/
|
|
88
|
-
sourceId?: string;
|
|
89
|
-
collection?: string;
|
|
90
|
-
titleSingular: string;
|
|
91
|
-
titlePlural?: string;
|
|
92
|
-
titleFieldKey: string;
|
|
93
|
-
origin: string;
|
|
94
|
-
ownerPluginId?: string;
|
|
95
|
-
parentEntity?: string;
|
|
96
|
-
parentFieldKey?: string;
|
|
97
|
-
parentRelation?: string;
|
|
98
|
-
tagCollection?: string;
|
|
99
|
-
eventPrefix?: string;
|
|
100
|
-
/**
|
|
101
|
-
* Sempre escrita, mesmo vazia, pela mesma razão de `CatalogExtensionExport.exports`: a lista vazia diz
|
|
102
|
-
* "esta tela não tem chave"; a chave ausente é o silêncio de um Console anterior a este campo.
|
|
103
|
-
*/
|
|
104
|
-
keys: CatalogKeyExport[];
|
|
105
|
-
fields: CatalogFieldExport[];
|
|
106
|
-
}
|
|
107
|
-
export interface CatalogListExport {
|
|
108
|
-
collection: string;
|
|
109
|
-
label: string;
|
|
110
|
-
ownerPluginId?: string;
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Um artefato que a extensão declara em `manifest.exports` — a superfície que outra extensão pode
|
|
114
|
-
* referenciar como `<pluginId>/<sourceId>`.
|
|
115
|
-
*
|
|
116
|
-
* O `kind` viaja porque é ele que decide ONDE a referência cabe: script em `scriptId`, automação em
|
|
117
|
-
* `targetWorkflowId`. `unknown` é o export declarado que não casa com artefato nenhum do pacote —
|
|
118
|
-
* dizê-lo é melhor que omiti-lo, porque uma referência a ele passaria no portão da instalação, que
|
|
119
|
-
* confere a LISTA, e falharia só na primeira execução.
|
|
120
|
-
*
|
|
121
|
-
* O que NÃO viaja é o que o artefato faz: os passos e o código são comportamento, e o retrato é
|
|
122
|
-
* esquema. O nome e o tipo são contrato.
|
|
123
|
-
*/
|
|
124
|
-
export interface CatalogExtensionExportedArtifact {
|
|
2
|
+
import type { TenantSummary } from './installedExtensions.js';
|
|
3
|
+
/** Um documento já decodificado, com o id que a coleção lhe deu — a entrada que o escritor do SDK pede. */
|
|
4
|
+
export interface CatalogSourceDocument {
|
|
125
5
|
id: string;
|
|
126
|
-
|
|
127
|
-
name: string;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Um grupo da barra lateral que a extensão declara (`ui.nav.group`). Viaja porque a CHAVE é contrato:
|
|
131
|
-
* é o que outra extensão escreve para entrar no grupo, e quem autora sem enxergá-la inventa outra — e
|
|
132
|
-
* o menu passa a mostrar dois grupos com o mesmo nome.
|
|
133
|
-
*
|
|
134
|
-
* O nome vai resolvido em cada idioma que o próprio pacote traz, porque é pelo nome que o autor
|
|
135
|
-
* reconhece o grupo; o rótulo literal vai como está, com `translations` vazio.
|
|
136
|
-
*/
|
|
137
|
-
export interface CatalogExtensionNavGroup {
|
|
138
|
-
key: string;
|
|
139
|
-
label: string;
|
|
140
|
-
translations: Record<string, string>;
|
|
141
|
-
order: number;
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Um modelo de documento que a extensão declara (`document.template`), como CONTRATO: a chave, a origem
|
|
145
|
-
* e a forma de cada parâmetro. Viaja porque outra extensão GERA esse modelo pelo passo
|
|
146
|
-
* `render-document`, com `param.<chave>` e `belongsTo`, e um nome trocado ali só aparece na geração —
|
|
147
|
-
* com o campo em branco, ou com a recusa no clique.
|
|
148
|
-
*
|
|
149
|
-
* O que NÃO viaja é o texto do modelo, o rótulo, a regra e a amostra: é conteúdo, e o passo não os lê.
|
|
150
|
-
*/
|
|
151
|
-
export interface CatalogExtensionDocumentParameter {
|
|
152
|
-
key: string;
|
|
153
|
-
type: string;
|
|
154
|
-
required?: boolean;
|
|
155
|
-
list?: boolean;
|
|
156
|
-
entityType?: string;
|
|
157
|
-
}
|
|
158
|
-
export interface CatalogExtensionDocumentTemplate {
|
|
159
|
-
key: string;
|
|
160
|
-
source: 'record' | 'payload';
|
|
161
|
-
parameters: CatalogExtensionDocumentParameter[];
|
|
6
|
+
data: Record<string, unknown>;
|
|
162
7
|
}
|
|
163
8
|
/**
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
* `mask: 'cpf-cnpj'` contra o `cpfCnpj` da Brasil instalava, e o campo ficava sem máscara.
|
|
9
|
+
* O pedaço do retrato que o Console ainda lê, para o resumo no terminal. A forma inteira é do SDK — o
|
|
10
|
+
* Console não a conhece, e é exatamente isso que o impede de escrever um formato que o kernel não lê.
|
|
167
11
|
*/
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
12
|
+
interface WrittenCatalog {
|
|
13
|
+
screens: {
|
|
14
|
+
origin: string;
|
|
15
|
+
}[];
|
|
16
|
+
lookups: unknown[];
|
|
17
|
+
tagLists: unknown[];
|
|
18
|
+
extensions: {
|
|
19
|
+
exports: unknown[];
|
|
20
|
+
navGroups: unknown[];
|
|
21
|
+
documentTemplates: unknown[];
|
|
22
|
+
}[];
|
|
171
23
|
}
|
|
172
|
-
|
|
173
|
-
id: string;
|
|
174
|
-
name: string;
|
|
175
|
-
version: string;
|
|
176
|
-
active: boolean;
|
|
177
|
-
/**
|
|
178
|
-
* Sempre escrita, mesmo vazia. É a lista PRESENTE e vazia que diz "esta extensão não exporta nada";
|
|
179
|
-
* a chave ausente é o silêncio de um Console anterior a este campo, e o kernel distingue as duas.
|
|
180
|
-
*/
|
|
181
|
-
exports: CatalogExtensionExportedArtifact[];
|
|
182
|
-
/** Sempre escrita, mesmo vazia, pela mesma razão de `exports`. */
|
|
183
|
-
navGroups: CatalogExtensionNavGroup[];
|
|
184
|
-
/** Sempre escrita, mesmo vazia, pela mesma razão de `exports`. */
|
|
185
|
-
documentTemplates: CatalogExtensionDocumentTemplate[];
|
|
186
|
-
/** Sempre escrita, mesmo vazia, pela mesma razão de `exports`. */
|
|
187
|
-
fieldPresets: CatalogExtensionFieldPreset[];
|
|
188
|
-
}
|
|
189
|
-
export interface CatalogExport {
|
|
190
|
-
version: number;
|
|
191
|
-
projectId: string;
|
|
192
|
-
tenantId: string;
|
|
193
|
-
tenantName: string;
|
|
194
|
-
exportedAt: string;
|
|
195
|
-
kernelVersion: string;
|
|
196
|
-
consoleVersion: string;
|
|
197
|
-
extensions: CatalogExtensionExport[];
|
|
198
|
-
screens: CatalogScreenExport[];
|
|
199
|
-
lookups: CatalogListExport[];
|
|
200
|
-
tagLists: CatalogListExport[];
|
|
201
|
-
}
|
|
202
|
-
/** Um documento já decodificado, com o id que a coleção lhe deu. */
|
|
203
|
-
export interface CatalogSourceDocument {
|
|
204
|
-
id: string;
|
|
205
|
-
data: Record<string, unknown>;
|
|
206
|
-
}
|
|
207
|
-
export interface CatalogExportInput {
|
|
24
|
+
interface CatalogWriterInput {
|
|
208
25
|
projectId: string;
|
|
209
26
|
tenant: TenantSummary;
|
|
210
27
|
kernelVersion: string;
|
|
211
28
|
exportedAt: Date;
|
|
29
|
+
exporter: {
|
|
30
|
+
tool: 'console';
|
|
31
|
+
version: string;
|
|
32
|
+
};
|
|
212
33
|
screens: CatalogSourceDocument[];
|
|
213
34
|
lookups: CatalogSourceDocument[];
|
|
214
35
|
tagLists: CatalogSourceDocument[];
|
|
215
|
-
extensions:
|
|
36
|
+
extensions: CatalogSourceDocument[];
|
|
37
|
+
}
|
|
38
|
+
/** O que o Console usa do barril do `@microteia/sdk` instalado em `extensions/`. */
|
|
39
|
+
export interface CatalogWriter {
|
|
40
|
+
file: string;
|
|
41
|
+
build: (input: CatalogWriterInput) => WrittenCatalog;
|
|
42
|
+
serialize: (snapshot: WrittenCatalog) => string;
|
|
216
43
|
}
|
|
217
44
|
/**
|
|
218
|
-
* O
|
|
219
|
-
*
|
|
220
|
-
*
|
|
45
|
+
* O escritor do retrato, carregado do SDK que o escritório tem em `extensions/`.
|
|
46
|
+
*
|
|
47
|
+
* O Console trazia uma CÓPIA do escritor, e o leitor morava no SDK: os dois lados eram compilados
|
|
48
|
+
* separadamente e casados só por teste, e o Console é distribuído à parte do kernel. Carregar o
|
|
49
|
+
* escritor de onde mora o leitor faz o formato ter um dono só — e é a mesma função que a aplicação usa
|
|
50
|
+
* no botão Exportar catálogo da tela de Extensões.
|
|
221
51
|
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
* extensão DESATIVADA continua: o documento dela segue gravado, e é ele que explica um campo que o
|
|
225
|
-
* autor vai encontrar.
|
|
52
|
+
* O SDK de um kernel anterior a esse escritor não o tem, e aí o comando RECUSA dizendo como trazê-lo,
|
|
53
|
+
* em vez de escrever com uma cópia que já não é conferida contra nada.
|
|
226
54
|
*/
|
|
227
|
-
export declare const
|
|
55
|
+
export declare const loadCatalogWriter: (directory: string) => CatalogWriter;
|
|
228
56
|
export declare const exportCatalog: (args: ParsedArgs) => Promise<void>;
|
|
57
|
+
export {};
|