@microteia/console 2.7.2 → 2.10.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 +56 -0
- package/README.md +1 -1
- package/lib/console/deploy.js +43 -5
- package/lib/console/environment.d.ts +15 -0
- package/lib/console/environment.js +11 -0
- package/lib/console/exportCatalog.d.ts +124 -0
- package/lib/console/exportCatalog.js +264 -0
- package/lib/console/functionsUpToDate.d.ts +55 -0
- package/lib/console/functionsUpToDate.js +192 -0
- package/lib/console/init.js +1 -0
- package/lib/console/installedExtensions.d.ts +37 -0
- package/lib/console/installedExtensions.js +37 -0
- package/lib/console/loginExtensions.d.ts +29 -0
- package/lib/console/loginExtensions.js +101 -0
- package/lib/console/provision.d.ts +12 -0
- package/lib/console/provision.js +39 -19
- package/lib/console/regionOrphans.d.ts +22 -1
- package/lib/console/regionOrphans.js +15 -3
- package/lib/index.js +10 -2
- package/lib/kernel/manifest.d.ts +16 -0
- package/lib/kernel/manifest.js +16 -0
- package/lib/shared/paths.d.ts +1 -1
- package/lib/shared/paths.js +1 -1
- package/lib/vendor/exampleSources.js +7 -3
- package/lib/vendor/installationDocs.js +33 -2
- package/lib/vendor/pack.js +3 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import { connect } from './console/connect.js';
|
|
|
10
10
|
import { unpack } from './console/unpack.js';
|
|
11
11
|
import { deploy } from './console/deploy.js';
|
|
12
12
|
import { provision } from './console/provision.js';
|
|
13
|
+
import { exportCatalog } from './console/exportCatalog.js';
|
|
13
14
|
import { pluginInit } from './console/pluginWorkspace.js';
|
|
14
15
|
import { versionReport } from './console/versions.js';
|
|
15
16
|
import { newerThan } from './console/channel.js';
|
|
@@ -37,18 +38,25 @@ const COMMANDS = [
|
|
|
37
38
|
},
|
|
38
39
|
{
|
|
39
40
|
name: 'deploy',
|
|
40
|
-
usage: 'microteia deploy [--only rules,indexes,functions,hosting] [--delay <seconds>] [--prune]',
|
|
41
|
+
usage: 'microteia deploy [--only rules,indexes,functions,hosting] [--delay <seconds>] [--prune] [--all]',
|
|
41
42
|
summary: 'Publish the package that is in place to the connected Firebase project.',
|
|
42
43
|
audience: 'office',
|
|
43
44
|
execute: deploy,
|
|
44
45
|
},
|
|
45
46
|
{
|
|
46
47
|
name: 'provision',
|
|
47
|
-
usage: 'microteia provision [--prune] [--delay <seconds>]',
|
|
48
|
+
usage: 'microteia provision [--prune] [--delay <seconds>] [--all]',
|
|
48
49
|
summary: 'Give the installed extensions the Cloud Functions and indexes they ask for.',
|
|
49
50
|
audience: 'office',
|
|
50
51
|
execute: provision,
|
|
51
52
|
},
|
|
53
|
+
{
|
|
54
|
+
name: 'export-catalog',
|
|
55
|
+
usage: 'microteia export-catalog --tenant <tenantId> [--output <path>]',
|
|
56
|
+
summary: 'Write what an office has — screens, lists, extensions — for the authoring tools to read.',
|
|
57
|
+
audience: 'office',
|
|
58
|
+
execute: exportCatalog,
|
|
59
|
+
},
|
|
52
60
|
{
|
|
53
61
|
name: 'plugin-init',
|
|
54
62
|
usage: 'microteia plugin-init [--dir <path>] [--force]',
|
package/lib/kernel/manifest.d.ts
CHANGED
|
@@ -44,6 +44,16 @@ export interface KernelManifest {
|
|
|
44
44
|
baselineIndexes: FirestoreIndexSpec[];
|
|
45
45
|
/** Ausente nos pacotes anteriores a 7.51.0, que não conheciam a verificação de alcance. */
|
|
46
46
|
callables?: string[];
|
|
47
|
+
/**
|
|
48
|
+
* Os pontos de extensão que fazem efeito ANTES do login. É contra esta lista que o `deploy` decide
|
|
49
|
+
* se um pacote carimbado tem o que fazer no boot — carimbar um que não contribua para nenhum deles
|
|
50
|
+
* o carregaria sem efeito, e quem o carimbou acreditaria que está no ar.
|
|
51
|
+
*
|
|
52
|
+
* Ela é DERIVADA do kernel e viaja no manifesto justamente para o Console não a conhecer de cor: o
|
|
53
|
+
* Console é versionado separadamente, e uma cópia aqui passaria a descrever o contrato de outra
|
|
54
|
+
* versão em silêncio. Ausente nos pacotes anteriores às extensões carimbadas.
|
|
55
|
+
*/
|
|
56
|
+
preLoginPoints?: string[];
|
|
47
57
|
backendParameters: BackendParameter[];
|
|
48
58
|
manualPrerequisites: KernelPrerequisite[];
|
|
49
59
|
/**
|
|
@@ -135,4 +145,10 @@ export declare const callableFunctionNames: (source: string) => string[];
|
|
|
135
145
|
export declare const declaredParametersIn: (source: string) => BackendParameter[];
|
|
136
146
|
/** Comparação de versão suficiente para `minimumCliVersion`: três números, sem pré-lançamento. */
|
|
137
147
|
export declare const compareVersions: (left: string, right: string) => number;
|
|
148
|
+
/**
|
|
149
|
+
* Os pontos que valem antes do login, lidos de `domain/schema/plugin/preLoginPoints.ts`. Lista vazia é
|
|
150
|
+
* recusada em vez de aceita: um pacote sem nenhum ponto pré-login recusaria todo carimbo, e a causa
|
|
151
|
+
* (o parser não achou nada) não teria nada a ver com o sintoma.
|
|
152
|
+
*/
|
|
153
|
+
export declare const parsePreLoginPoints: (source: string) => string[];
|
|
138
154
|
export declare const parseKernelVersion: (source: string) => string;
|
package/lib/kernel/manifest.js
CHANGED
|
@@ -137,6 +137,22 @@ export const compareVersions = (left, right) => {
|
|
|
137
137
|
}
|
|
138
138
|
return 0;
|
|
139
139
|
};
|
|
140
|
+
/**
|
|
141
|
+
* Os pontos que valem antes do login, lidos de `domain/schema/plugin/preLoginPoints.ts`. Lista vazia é
|
|
142
|
+
* recusada em vez de aceita: um pacote sem nenhum ponto pré-login recusaria todo carimbo, e a causa
|
|
143
|
+
* (o parser não achou nada) não teria nada a ver com o sintoma.
|
|
144
|
+
*/
|
|
145
|
+
export const parsePreLoginPoints = (source) => {
|
|
146
|
+
const block = source.match(/PRE_LOGIN_POINTS[^=]*=\s*\[([^\]]*)\]/);
|
|
147
|
+
if (block === null) {
|
|
148
|
+
throw new Error('PRE_LOGIN_POINTS not found in domain/schema/plugin/preLoginPoints.ts');
|
|
149
|
+
}
|
|
150
|
+
const points = [...block[1].matchAll(/'([^']+)'/g)].map((match) => match[1]);
|
|
151
|
+
if (points.length === 0) {
|
|
152
|
+
throw new Error('PRE_LOGIN_POINTS is empty in domain/schema/plugin/preLoginPoints.ts');
|
|
153
|
+
}
|
|
154
|
+
return points;
|
|
155
|
+
};
|
|
140
156
|
export const parseKernelVersion = (source) => {
|
|
141
157
|
const match = source.match(/KERNEL_VERSION\s*=\s*'([^']+)'/);
|
|
142
158
|
if (match === null)
|
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.10.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.10.0';
|
|
@@ -31,7 +31,9 @@ export const EXAMPLE_SOURCES = {
|
|
|
31
31
|
* extensão tem a sua pasta — aqui elas moram num diretório comum, com um nível a mais.
|
|
32
32
|
*/
|
|
33
33
|
export const rewriteImports = (source) => source.replace(/from '(\.[^']*)'/g, (match, specifier) => {
|
|
34
|
-
if (/(^|\/)contributionBuilders$/.test(specifier)
|
|
34
|
+
if (/(^|\/)contributionBuilders$/.test(specifier)
|
|
35
|
+
|| specifier.includes('domain/')
|
|
36
|
+
|| specifier.includes('sdk/')) {
|
|
35
37
|
return "from '@microteia/sdk'";
|
|
36
38
|
}
|
|
37
39
|
// `./views/<plugin>/Nome.tsx?raw` -> `./views/Nome.tsx?raw`
|
|
@@ -44,8 +46,10 @@ const HEADER = (id) => `// Example: a Microteia first-party extension, as SOURCE
|
|
|
44
46
|
//
|
|
45
47
|
// npx microteia-plugin build ${id}/plugin.ts
|
|
46
48
|
//
|
|
47
|
-
//
|
|
48
|
-
// the kernel tree, here everything comes from '@microteia/sdk'.
|
|
49
|
+
// Two things differ from how you would write the same extension. The imports: inside Microteia they
|
|
50
|
+
// reach into the kernel tree, here everything comes from '@microteia/sdk'. And the view sources: these
|
|
51
|
+
// travel as TEXT and are merged by 'mergeViewSources', because the platform bundles them; you point at
|
|
52
|
+
// the files with 'sourceFile' and the compiler merges them for you. See AUTHORING.md, section 7.
|
|
49
53
|
|
|
50
54
|
`;
|
|
51
55
|
/**
|
|
@@ -90,10 +90,11 @@ const commandRows = () => [
|
|
|
90
90
|
'|---|---|',
|
|
91
91
|
'| `microteia unpack --version <latest\\|x.y.z>` | Downloads a platform version, verifies it, and puts it in place. Touches no Firebase — safe any time |',
|
|
92
92
|
'| `microteia unpack --kernel <pkg>.tgz` | The same, from a file you already have — for a machine with no access to the catalog |',
|
|
93
|
-
'| `microteia deploy [--only …] [--prune]` | Publishes what is in place: `rules`, `indexes`, `functions`, `hosting`. `--prune` also deletes functions left behind in a region this version no longer uses |',
|
|
94
|
-
'| `microteia provision [--prune]` | Gives installed extensions the functions and indexes they ask for |',
|
|
93
|
+
'| `microteia deploy [--only …] [--prune] [--all]` | Publishes what is in place: `rules`, `indexes`, `functions`, `hosting`. A Cloud Function the project already runs with this exact code is not deployed again; `--all` deploys every one of them anyway. `--prune` also deletes functions left behind in a region this version no longer uses |',
|
|
94
|
+
'| `microteia provision [--prune] [--all]` | Gives installed extensions the functions and indexes they ask for |',
|
|
95
95
|
'| `microteia connect --project <id>` | Binds this installation to a Firebase project you own |',
|
|
96
96
|
'| `microteia plugin-init` | Prepares `extensions/` for authoring in TypeScript |',
|
|
97
|
+
'| `microteia export-catalog --tenant <id>` | Writes what an office has — screens, lists, installed extensions — into `extensions/`, so the authoring tools can see it. Reads only; with no `--tenant` it lists the offices. The file is a snapshot and is git-ignored: it carries names the office typed |',
|
|
97
98
|
].join('\n');
|
|
98
99
|
/**
|
|
99
100
|
* O documento técnico. SOBREPOSTO a cada `unpack`, e por isso é onde o detalhe que acompanha a versão
|
|
@@ -145,6 +146,23 @@ it is what makes an upgrade trustworthy, and the reason your files are elsewhere
|
|
|
145
146
|
|
|
146
147
|
${commandRows()}
|
|
147
148
|
|
|
149
|
+
### Signing in before there is an organization
|
|
150
|
+
|
|
151
|
+
The sign-in screen runs above the organization: there is no tenant there, so nothing an organization
|
|
152
|
+
installed can reach it. That is why \`login.extensions\` in \`microteia.yaml\` exists — it lists compiled
|
|
153
|
+
extension packages that \`deploy\` stamps into the site itself, and it is how a corporate SSO, or your own
|
|
154
|
+
mark on the sign-in screen, gets there.
|
|
155
|
+
|
|
156
|
+
Two things follow, and both are deliberate:
|
|
157
|
+
|
|
158
|
+
- **Nothing stamped runs JavaScript.** The packages load untrusted, so only declarations apply. That is
|
|
159
|
+
what lets you put an SSO live without anyone reviewing code.
|
|
160
|
+
- **Stamping is not installing.** A stamped package applies before sign-in only; inside the organization
|
|
161
|
+
what applies is what the organization installed, from the Extensions screen. To have both, do both.
|
|
162
|
+
|
|
163
|
+
\`deploy\` refuses a package that contributes to nothing which works before sign-in, rather than stamping
|
|
164
|
+
it: it would load with no effect, and you would believe it was live.
|
|
165
|
+
|
|
148
166
|
\`unpack\` and \`deploy\` are separate so that taking a new version does not oblige you to publish
|
|
149
167
|
everything, and so that there is a moment between the two to fill in a setting the new version asks for.
|
|
150
168
|
|
|
@@ -179,6 +197,19 @@ carry that setting.
|
|
|
179
197
|
|
|
180
198
|
An empty line means "not configured". A feature that needs it stays off rather than failing halfway.
|
|
181
199
|
|
|
200
|
+
## 3.1 Why a deploy is usually much faster than the first one
|
|
201
|
+
|
|
202
|
+
Firebase stamps every Cloud Function with what it was built from — the whole source directory, the
|
|
203
|
+
resolved environment variables, and the secret versions. \`microteia deploy\` reads those stamps, deploys
|
|
204
|
+
one reference function, and compares: a function whose stamp comes back unchanged is byte-for-byte what
|
|
205
|
+
the project already runs, and is left alone. It is the same comparison \`firebase deploy\` makes when it
|
|
206
|
+
deploys in bulk, which is why a version that only changed the application's screens finishes in minutes
|
|
207
|
+
instead of publishing every function again.
|
|
208
|
+
|
|
209
|
+
What the stamp does not see is configuration changed **outside** this installation — memory, timeout,
|
|
210
|
+
concurrency or invoker policy edited in the Google console. \`microteia deploy --all\` deploys everything
|
|
211
|
+
regardless, and is the answer for that.
|
|
212
|
+
|
|
182
213
|
## 4. Your own Cloud Functions
|
|
183
214
|
|
|
184
215
|
Two places, answering two different questions:
|
package/lib/vendor/pack.js
CHANGED
|
@@ -4,7 +4,7 @@ import { flagValue, hasFlag } from '../shared/args.js';
|
|
|
4
4
|
import { repoRoot } from '../shared/paths.js';
|
|
5
5
|
import { run } from '../shared/run.js';
|
|
6
6
|
import { blank, bullets, heading, info, step, success } from '../shared/ui.js';
|
|
7
|
-
import { DEFAULT_FUNCTIONS_REGION, KERNEL_COMPONENTS, KERNEL_DISTRIBUTION_ID, MANUAL_PREREQUISITES, MINIMUM_CLI_VERSION, REQUIRED_NODE_VERSION, callableFunctionNames, declaredParametersIn, exportedFunctionNames, parseKernelVersion, } from '../kernel/manifest.js';
|
|
7
|
+
import { DEFAULT_FUNCTIONS_REGION, KERNEL_COMPONENTS, KERNEL_DISTRIBUTION_ID, MANUAL_PREREQUISITES, MINIMUM_CLI_VERSION, REQUIRED_NODE_VERSION, callableFunctionNames, declaredParametersIn, exportedFunctionNames, parseKernelVersion, parsePreLoginPoints, } from '../kernel/manifest.js';
|
|
8
8
|
import { digestOfFile } from '../shared/digest.js';
|
|
9
9
|
import { kernelTarballName } from '../kernel/channel.js';
|
|
10
10
|
import { baselineFunctionsOf, baselineIndexesOf, claimProblems, claimsFromTemplates, } from '../kernel/backendShape.js';
|
|
@@ -123,6 +123,7 @@ export const pack = async (args) => {
|
|
|
123
123
|
*/
|
|
124
124
|
const changelog = await readChangelog(root, KERNEL_CHANGELOG, version);
|
|
125
125
|
const kernelVersion = parseKernelVersion(await readFile(join(root, 'src/domain/schema/plugin/kernelVersion.ts'), 'utf8'));
|
|
126
|
+
const preLoginPoints = parsePreLoginPoints(await readFile(join(root, 'src/domain/schema/plugin/preLoginPoints.ts'), 'utf8'));
|
|
126
127
|
const functionNames = exportedFunctionNames(await readFile(join(root, 'functions/src/index.ts'), 'utf8'));
|
|
127
128
|
const scan = await scanBackendSources(join(root, 'functions/src'));
|
|
128
129
|
const backendParameters = scan.parameters;
|
|
@@ -225,6 +226,7 @@ export const pack = async (args) => {
|
|
|
225
226
|
baselineFunctions,
|
|
226
227
|
baselineIndexes,
|
|
227
228
|
callables,
|
|
229
|
+
preLoginPoints,
|
|
228
230
|
backendParameters,
|
|
229
231
|
manualPrerequisites: MANUAL_PREREQUISITES,
|
|
230
232
|
sdk,
|