@microteia/console 2.19.0 → 2.20.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 +6 -0
- package/README.md +1 -1
- package/lib/console/exportCatalog.d.ts +22 -0
- package/lib/console/exportCatalog.js +44 -3
- package/lib/shared/paths.d.ts +1 -1
- package/lib/shared/paths.js +1 -1
- package/package.json +1 -1
package/CONSOLE-VERSIONS.md
CHANGED
|
@@ -22,6 +22,12 @@
|
|
|
22
22
|
- fix(command): what was broken, and what it did to whoever hit it.
|
|
23
23
|
-->
|
|
24
24
|
|
|
25
|
+
#### [2.20.0] — 2026-09-01
|
|
26
|
+
|
|
27
|
+
- feat(cli/export-catalog): the snapshot carries what each installed extension declares in `manifest.exports` — the artifacts another extension may reference as `<extension-id>/<source-id>`. Whoever authors outside the office knew an extension was installed and had no way to learn the name of anything inside it, so the reference could be written by hand and never discovered. Each entry carries the id, the artifact's name, and its `kind`, which is the part that decides where the reference fits: a script goes in `scriptId`, an automation in `targetWorkflowId`. What the artifact DOES still never travels — the steps and the code are behaviour, and the snapshot is shape.
|
|
28
|
+
- feat(cli/export-catalog): a declared export that matches no artifact in the package travels as `unknown` rather than being dropped. The install gate checks the LIST, so a reference to it would be accepted there and fail only on the step's first run; saying it is better than hiding it.
|
|
29
|
+
- feat(cli/export-catalog): `exports` is written for every extension, empty list included. A present-and-empty list is the answer "this extension exports nothing"; an absent key is the silence of a Console older than the field, and the kernel tells the two apart instead of reading absence as a claim.
|
|
30
|
+
|
|
25
31
|
#### [2.19.0] — 2026-08-28
|
|
26
32
|
|
|
27
33
|
- fix(cli/deploy): the installation gate is charged against the functions that are GOING UP, not against every source found on disk. It lived in `functionProblems` — the door that answers "can this set be assembled?" — and that door reads every `extensions/<x>/functions/` directory that exists, including one left behind by an extension that was uninstalled and removed. The result was `microteia deploy` refusing in full — hosting, rules and indexes with it — over a callable no command would have deployed. `gateProblems` now carries the function's name, and `gateProblemsFor` filters by what is being deployed.
|
package/README.md
CHANGED
|
@@ -76,11 +76,33 @@ export interface CatalogListExport {
|
|
|
76
76
|
label: string;
|
|
77
77
|
ownerPluginId?: string;
|
|
78
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Um artefato que a extensão declara em `manifest.exports` — a superfície que outra extensão pode
|
|
81
|
+
* referenciar como `<pluginId>/<sourceId>`.
|
|
82
|
+
*
|
|
83
|
+
* O `kind` viaja porque é ele que decide ONDE a referência cabe: script em `scriptId`, automação em
|
|
84
|
+
* `targetWorkflowId`. `unknown` é o export declarado que não casa com artefato nenhum do pacote —
|
|
85
|
+
* dizê-lo é melhor que omiti-lo, porque uma referência a ele passaria no portão da instalação, que
|
|
86
|
+
* confere a LISTA, e falharia só na primeira execução.
|
|
87
|
+
*
|
|
88
|
+
* O que NÃO viaja é o que o artefato faz: os passos e o código são comportamento, e o retrato é
|
|
89
|
+
* esquema. O nome e o tipo são contrato.
|
|
90
|
+
*/
|
|
91
|
+
export interface CatalogExtensionExportedArtifact {
|
|
92
|
+
id: string;
|
|
93
|
+
kind: 'workflow' | 'action' | 'script' | 'unknown';
|
|
94
|
+
name: string;
|
|
95
|
+
}
|
|
79
96
|
export interface CatalogExtensionExport {
|
|
80
97
|
id: string;
|
|
81
98
|
name: string;
|
|
82
99
|
version: string;
|
|
83
100
|
active: boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Sempre escrita, mesmo vazia. É a lista PRESENTE e vazia que diz "esta extensão não exporta nada";
|
|
103
|
+
* a chave ausente é o silêncio de um Console anterior a este campo, e o kernel distingue as duas.
|
|
104
|
+
*/
|
|
105
|
+
exports: CatalogExtensionExportedArtifact[];
|
|
84
106
|
}
|
|
85
107
|
export interface CatalogExport {
|
|
86
108
|
version: number;
|
|
@@ -46,6 +46,38 @@ const asRecord = (value) => (typeof value === 'object' && value !== null && !Arr
|
|
|
46
46
|
? value
|
|
47
47
|
: undefined);
|
|
48
48
|
const FIELD_ORIGINS = ['builtin', 'plugin', 'design'];
|
|
49
|
+
/**
|
|
50
|
+
* A superfície exportada de uma cópia instalada: os ids de `manifest.exports`, cada um casado com o
|
|
51
|
+
* artefato do pacote que o atende, para ganhar tipo e nome.
|
|
52
|
+
*
|
|
53
|
+
* O Console não alcança `src/` — logo não há `MarketplacePlugin` tipado aqui, e a leitura é do
|
|
54
|
+
* documento cru, como todo o resto deste arquivo. Um export que não casa com nada continua na lista
|
|
55
|
+
* como `unknown`: a extensão está declarando algo que não entrega, e esconder isso do autor apenas
|
|
56
|
+
* adia a descoberta para a primeira execução.
|
|
57
|
+
*/
|
|
58
|
+
const exportedArtifacts = (extension) => {
|
|
59
|
+
const declared = extension.manifest?.exports;
|
|
60
|
+
if (!Array.isArray(declared))
|
|
61
|
+
return [];
|
|
62
|
+
const pkg = asRecord(extension.data.package) ?? {};
|
|
63
|
+
const named = new Map();
|
|
64
|
+
const collect = (raw, kind) => {
|
|
65
|
+
for (const one of Array.isArray(raw) ? raw : []) {
|
|
66
|
+
const record = asRecord(one);
|
|
67
|
+
const id = text(record?.templateId);
|
|
68
|
+
if (id === undefined || named.has(id))
|
|
69
|
+
continue;
|
|
70
|
+
named.set(id, { id, kind, name: text(record?.name) ?? text(record?.title) ?? id });
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
collect(pkg.workflows, 'workflow');
|
|
74
|
+
collect(pkg.actions, 'action');
|
|
75
|
+
collect(pkg.scripts, 'script');
|
|
76
|
+
return declared
|
|
77
|
+
.filter((id) => typeof id === 'string' && id !== '')
|
|
78
|
+
.map((id) => named.get(id) ?? { id, kind: 'unknown', name: id })
|
|
79
|
+
.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
|
|
80
|
+
};
|
|
49
81
|
/**
|
|
50
82
|
* A mesma dedução que a aplicação faz ao ler a tela (`screenDefinitionMapper.ts`): o `origin` gravado
|
|
51
83
|
* quando ele existe, senão `plugin` para quem tem dono e `design` para o que o escritório criou. Ela é
|
|
@@ -135,7 +167,13 @@ export const buildCatalogExport = (input) => ({
|
|
|
135
167
|
kernelVersion: input.kernelVersion,
|
|
136
168
|
consoleVersion: CLI_VERSION,
|
|
137
169
|
extensions: input.extensions
|
|
138
|
-
.map((one) => ({
|
|
170
|
+
.map((one) => ({
|
|
171
|
+
id: one.id,
|
|
172
|
+
name: one.name,
|
|
173
|
+
version: one.version,
|
|
174
|
+
active: one.active,
|
|
175
|
+
exports: exportedArtifacts(one),
|
|
176
|
+
}))
|
|
139
177
|
.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)),
|
|
140
178
|
screens: input.screens
|
|
141
179
|
.filter((document) => document.data.enabled !== false)
|
|
@@ -252,13 +290,16 @@ export const exportCatalog = async (args) => {
|
|
|
252
290
|
+ `${document.lookups.length} list(s), ${document.tagLists.length} tag list(s)`);
|
|
253
291
|
info(` ${fromExtensions} screen(s) come from the ${document.extensions.length} installed extension(s); `
|
|
254
292
|
+ `the rest the office built itself.`);
|
|
293
|
+
const exported = document.extensions.reduce((total, one) => total + one.exports.length, 0);
|
|
294
|
+
info(` ${exported} artifact(s) are declared for other extensions to reference as <extension-id>/<id>.`);
|
|
255
295
|
blank();
|
|
256
296
|
await checkIgnored(directory);
|
|
257
297
|
info('It is a SNAPSHOT, and it says so: the authoring tools report when it was taken and warn when it');
|
|
258
298
|
info('is old. Nothing keeps it in step with the office — run this again after screens change there.');
|
|
259
299
|
blank();
|
|
260
300
|
info('What it deliberately leaves out: records, the values inside a list of options or a tag list,');
|
|
261
|
-
info('members and permissions,
|
|
262
|
-
info('the entities ARE, and nothing an office typed into them.');
|
|
301
|
+
info('members and permissions, what a workflow, script or action DOES, secrets and settings. It');
|
|
302
|
+
info('describes what the entities ARE, and nothing an office typed into them. What each extension');
|
|
303
|
+
info('declares in "exports" travels: that is the surface another extension may reference.');
|
|
263
304
|
blank();
|
|
264
305
|
};
|
package/lib/shared/paths.d.ts
CHANGED
|
@@ -87,4 +87,4 @@ export declare const consoleRoot: string;
|
|
|
87
87
|
* de código nunca chegou a quem instala. Este bloco fica sendo o que ele já era antes de crescer: a
|
|
88
88
|
* política de semver da ferramenta, mais o registro do que motivou as versões até a `2.5.0`.
|
|
89
89
|
*/
|
|
90
|
-
export declare const CLI_VERSION = "2.
|
|
90
|
+
export declare const CLI_VERSION = "2.20.0";
|
package/lib/shared/paths.js
CHANGED
|
@@ -94,4 +94,4 @@ export const consoleRoot = resolve(here, '..', '..');
|
|
|
94
94
|
* de código nunca chegou a quem instala. Este bloco fica sendo o que ele já era antes de crescer: a
|
|
95
95
|
* política de semver da ferramenta, mais o registro do que motivou as versões até a `2.5.0`.
|
|
96
96
|
*/
|
|
97
|
-
export const CLI_VERSION = '2.
|
|
97
|
+
export const CLI_VERSION = '2.20.0';
|