@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/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]',
@@ -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;
@@ -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)
@@ -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.7.2";
90
+ export declare const CLI_VERSION = "2.10.0";
@@ -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.7.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) || specifier.includes('domain/')) {
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
- // The only difference from how it is written inside Microteia is the import path: there it reaches into
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:
@@ -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,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microteia/console",
3
- "version": "2.7.2",
3
+ "version": "2.10.0",
4
4
  "description": "Install and update Microteia in a Firebase project you own.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",