@microteia/console 2.28.1 → 2.29.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 +4 -0
- package/README.md +1 -1
- package/lib/console/exportCatalog.d.ts +16 -0
- package/lib/console/exportCatalog.js +51 -0
- 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,10 @@
|
|
|
22
22
|
- fix(command): what was broken, and what it did to whoever hit it.
|
|
23
23
|
-->
|
|
24
24
|
|
|
25
|
+
#### [2.29.0] — 2026-10-15
|
|
26
|
+
|
|
27
|
+
- feat(export-catalog): each installed extension now carries `navGroups` — the sidebar groups it declares, by key, with the name resolved in every language the package ships and its order. The authoring tools list them in `microteia://nav-groups`, so an extension joins an existing group instead of drawing a second one with the same title. Always written, even empty; a snapshot taken by an older Console is read as "groups unknown".
|
|
28
|
+
|
|
25
29
|
#### [2.28.1] — 2026-10-14
|
|
26
30
|
|
|
27
31
|
- fix(console/deploy): a function whose source declares `retry: true` is no longer refused on its first deploy. Without a terminal the Firebase CLI does not ask "Would you like to proceed with deployment?" — it aborts with "Pass the --force option to deploy functions with a failure policy", so `runAggregateBackfill` and `runRecordKeyAdoption` never went up through `microteia deploy` or `provision`. That one function is now redeployed with `--force`, and only when the project is known to hold no copy of it in another region: the same flag would delete that copy without asking, which stays a `--prune` decision. When a copy stands or the project could not be listed, the refusal is terminal and the hint points to `microteia deploy --prune`.
|
package/README.md
CHANGED
|
@@ -98,6 +98,20 @@ export interface CatalogExtensionExportedArtifact {
|
|
|
98
98
|
kind: 'workflow' | 'action' | 'script' | 'unknown';
|
|
99
99
|
name: string;
|
|
100
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Um grupo da barra lateral que a extensão declara (`ui.nav.group`). Viaja porque a CHAVE é contrato:
|
|
103
|
+
* é o que outra extensão escreve para entrar no grupo, e quem autora sem enxergá-la inventa outra — e
|
|
104
|
+
* o menu passa a mostrar dois grupos com o mesmo nome.
|
|
105
|
+
*
|
|
106
|
+
* O nome vai resolvido em cada idioma que o próprio pacote traz, porque é pelo nome que o autor
|
|
107
|
+
* reconhece o grupo; o rótulo literal vai como está, com `translations` vazio.
|
|
108
|
+
*/
|
|
109
|
+
export interface CatalogExtensionNavGroup {
|
|
110
|
+
key: string;
|
|
111
|
+
label: string;
|
|
112
|
+
translations: Record<string, string>;
|
|
113
|
+
order: number;
|
|
114
|
+
}
|
|
101
115
|
export interface CatalogExtensionExport {
|
|
102
116
|
id: string;
|
|
103
117
|
name: string;
|
|
@@ -108,6 +122,8 @@ export interface CatalogExtensionExport {
|
|
|
108
122
|
* a chave ausente é o silêncio de um Console anterior a este campo, e o kernel distingue as duas.
|
|
109
123
|
*/
|
|
110
124
|
exports: CatalogExtensionExportedArtifact[];
|
|
125
|
+
/** Sempre escrita, mesmo vazia, pela mesma razão de `exports`. */
|
|
126
|
+
navGroups: CatalogExtensionNavGroup[];
|
|
111
127
|
}
|
|
112
128
|
export interface CatalogExport {
|
|
113
129
|
version: number;
|
|
@@ -78,6 +78,54 @@ const exportedArtifacts = (extension) => {
|
|
|
78
78
|
.map((id) => named.get(id) ?? { id, kind: 'unknown', name: id })
|
|
79
79
|
.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
|
|
80
80
|
};
|
|
81
|
+
const NAV_GROUP_POINT = 'ui.nav.group';
|
|
82
|
+
const MESSAGES_POINT = 'i18n.messages';
|
|
83
|
+
const DEFAULT_LOCALE = 'en';
|
|
84
|
+
const MESSAGE_REFERENCE = /^@([a-z0-9.-]+)\/(.+)$/;
|
|
85
|
+
/**
|
|
86
|
+
* Os grupos da barra lateral de uma cópia instalada, com o nome resolvido pelos `i18n.messages` do
|
|
87
|
+
* próprio manifesto. É a mesma leitura que `declaredNavGroupsOf` faz no kernel, repetida porque o
|
|
88
|
+
* Console não alcança `src/` — e é o teste que atravessa a fronteira que confere as duas.
|
|
89
|
+
*/
|
|
90
|
+
const navGroupsOf = (extension) => {
|
|
91
|
+
const contributes = Array.isArray(extension.manifest?.contributes) ? extension.manifest.contributes : [];
|
|
92
|
+
const contributions = contributes.map(asRecord).filter((one) => one !== undefined);
|
|
93
|
+
const bundles = contributions
|
|
94
|
+
.filter((one) => one.point === MESSAGES_POINT)
|
|
95
|
+
.map((one) => asRecord(one.metadata))
|
|
96
|
+
.filter((one) => one !== undefined);
|
|
97
|
+
const translationsOf = (label) => {
|
|
98
|
+
const match = MESSAGE_REFERENCE.exec(label);
|
|
99
|
+
if (!match)
|
|
100
|
+
return {};
|
|
101
|
+
const found = {};
|
|
102
|
+
for (const bundle of bundles) {
|
|
103
|
+
const locale = text(bundle.locale);
|
|
104
|
+
const message = asRecord(bundle.messages)?.[match[2]];
|
|
105
|
+
if (bundle.namespace !== match[1] || locale === undefined || typeof message !== 'string' || message.trim() === '')
|
|
106
|
+
continue;
|
|
107
|
+
if (found[locale] === undefined)
|
|
108
|
+
found[locale] = message;
|
|
109
|
+
}
|
|
110
|
+
return found;
|
|
111
|
+
};
|
|
112
|
+
return contributions
|
|
113
|
+
.filter((one) => one.point === NAV_GROUP_POINT)
|
|
114
|
+
.flatMap((one) => {
|
|
115
|
+
const metadata = asRecord(one.metadata) ?? {};
|
|
116
|
+
const key = text(metadata.key)?.trim();
|
|
117
|
+
if (key === undefined)
|
|
118
|
+
return [];
|
|
119
|
+
const raw = text(metadata.label) ?? key;
|
|
120
|
+
const translations = translationsOf(raw);
|
|
121
|
+
return [{
|
|
122
|
+
key,
|
|
123
|
+
label: translations[DEFAULT_LOCALE] ?? Object.values(translations)[0] ?? raw,
|
|
124
|
+
translations,
|
|
125
|
+
order: typeof metadata.order === 'number' ? metadata.order : 0,
|
|
126
|
+
}];
|
|
127
|
+
});
|
|
128
|
+
};
|
|
81
129
|
/**
|
|
82
130
|
* A mesma dedução que a aplicação faz ao ler a tela (`screenDefinitionMapper.ts`): o `origin` gravado
|
|
83
131
|
* quando ele existe, senão `plugin` para quem tem dono e `design` para o que o escritório criou. Ela é
|
|
@@ -174,6 +222,7 @@ export const buildCatalogExport = (input) => ({
|
|
|
174
222
|
version: one.version,
|
|
175
223
|
active: one.active,
|
|
176
224
|
exports: exportedArtifacts(one),
|
|
225
|
+
navGroups: navGroupsOf(one),
|
|
177
226
|
}))
|
|
178
227
|
.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)),
|
|
179
228
|
screens: input.screens
|
|
@@ -293,6 +342,8 @@ export const exportCatalog = async (args) => {
|
|
|
293
342
|
+ `the rest the office built itself.`);
|
|
294
343
|
const exported = document.extensions.reduce((total, one) => total + one.exports.length, 0);
|
|
295
344
|
info(` ${exported} artifact(s) are declared for other extensions to reference as <extension-id>/<id>.`);
|
|
345
|
+
const groups = document.extensions.reduce((total, one) => total + one.navGroups.length, 0);
|
|
346
|
+
info(` ${groups} sidebar group(s) are declared, by key, for other extensions to join.`);
|
|
296
347
|
blank();
|
|
297
348
|
await checkIgnored(directory);
|
|
298
349
|
info('It is a SNAPSHOT, and it says so: the authoring tools report when it was taken and warn when it');
|
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.29.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.29.0';
|