@fireemu/darwin-arm64 0.19.0 → 0.21.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/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # @fireemu/darwin-arm64
2
2
 
3
3
  The [fireemu](https://www.npmjs.com/package/fireemu) daemon built for `darwin-arm64`
4
- (Rust target `aarch64-apple-darwin`), version 0.19.0.
4
+ (Rust target `aarch64-apple-darwin`), version 0.21.0.
5
5
 
6
6
  macOS 13 or newer on Apple silicon.
7
7
 
package/bin/fireemu CHANGED
Binary file
@@ -28,6 +28,7 @@ import { invocationFailure } from "./invocation-error.mjs";
28
28
  import { InvocationBudget, readFrames } from "./protocol.mjs";
29
29
  import { deliverSchedule, v1ScheduleContext } from "./schedule-delivery.mjs";
30
30
  import { collectFunctions, exportNamespace } from "./discovery.mjs";
31
+ import { resolveDeclaredParams, resolveWhenDeclared } from "./params.mjs";
31
32
  import { FrameWriter } from "./output.mjs";
32
33
  import { installDiagnosticOutput } from "./diagnostic-output.mjs";
33
34
  import { trackHttpResponse } from "./http-lifecycle.mjs";
@@ -1539,6 +1540,25 @@ async function invoke(functions, manifest, msg) {
1539
1540
  }
1540
1541
 
1541
1542
 
1543
+ // Applies the declared defaults of `defineString`/`defineInt`/... to the environment and reports
1544
+ // the parameters that have no value and no default, which the daemon refuses to start with. A
1545
+ // codebase that does not use `firebase-functions/params` declares none.
1546
+ function declaredParamsOfCodebase() {
1547
+ try {
1548
+ const require = createRequire(join(sourceDir, "package.json"));
1549
+ return require("firebase-functions/params").declaredParams;
1550
+ } catch {
1551
+ return undefined;
1552
+ }
1553
+ }
1554
+
1555
+ function resolveCodebaseParams() {
1556
+ const declared = declaredParamsOfCodebase();
1557
+ return declared
1558
+ ? resolveDeclaredParams(declared, process.env)
1559
+ : { missing: [], defaulted: [] };
1560
+ }
1561
+
1542
1562
  async function main() {
1543
1563
  const clockOptions = JSON.parse(process.env.FIREEMU_CLOCK_JSON ?? '{}');
1544
1564
  const runtimeClock = createRuntimeClock(clockOptions);
@@ -1619,6 +1639,7 @@ async function main() {
1619
1639
  // Before any user code loads: the callable options are only observable as a callable is
1620
1640
  // declared (spec 13.4).
1621
1641
  const instrumentation = instrumentCallables(sourceDir);
1642
+ resolveWhenDeclared(declaredParamsOfCodebase(), process.env);
1622
1643
  let ns;
1623
1644
  try {
1624
1645
  ns = await loadCodebase();
@@ -1626,6 +1647,8 @@ async function main() {
1626
1647
  log("error", `cannot load functions from ${sourceDir}: ${invocationFailure(e).diagnostic}`);
1627
1648
  process.exit(1);
1628
1649
  }
1650
+ // Parameters are resolved before any endpoint option that references one is evaluated.
1651
+ const paramReport = resolveCodebaseParams();
1629
1652
  try {
1630
1653
  const require = createRequire(join(sourceDir, "package.json"));
1631
1654
  const cjsOptions = require("firebase-functions/v2/options").getGlobalOptions();
@@ -1717,6 +1740,7 @@ async function main() {
1717
1740
  inspectorPort: activeInspectorPort,
1718
1741
  httpPort,
1719
1742
  manifest,
1743
+ params: paramReport,
1720
1744
  appCheck: {
1721
1745
  firebaseFunctionsVersion: instrumentation.version,
1722
1746
  instrumentation: instrumentation.supported ? "ok" : instrumentation.reason,
@@ -0,0 +1,82 @@
1
+ // Parameters declared with `defineString`, `defineInt`, `defineBoolean`, `defineFloat` and
2
+ // `defineList` are resolved by `firebase deploy` before any function runs: a value from the
3
+ // dotenv files wins, a declared `default` fills the gap, and a parameter with neither stops the
4
+ // deploy (a non-interactive deploy cannot prompt for it). The deployed runtime therefore never
5
+ // sees an unresolved parameter. The SDK only reads `process.env[name]` at runtime, so the same
6
+ // resolution has to happen here, after the codebase has declared its parameters and before any
7
+ // endpoint option that references one is evaluated.
8
+ //
9
+ // Secrets (`defineSecret`, `defineJsonSecret`) are not resolved here: their values come from
10
+ // `.secret.local`, bound per function by the daemon.
11
+
12
+ const SECRET_TYPE = 'secret';
13
+
14
+ function typeOf(param) {
15
+ const type = param?.constructor?.type;
16
+ return typeof type === 'string' ? type : 'string';
17
+ }
18
+
19
+ // A declared default is a literal or another parameter / expression. Expressions are evaluated
20
+ // with the environment as resolved so far, in declaration order.
21
+ function defaultOf(param) {
22
+ const value = param?.options?.default;
23
+ if (value === undefined) return undefined;
24
+ if (value !== null && typeof value === 'object' && typeof value.runtimeValue === 'function') {
25
+ return value.runtimeValue();
26
+ }
27
+ return value;
28
+ }
29
+
30
+ // The environment spelling of a resolved value, as the Firebase CLI writes it.
31
+ export function serializeDefault(value) {
32
+ if (Array.isArray(value)) return JSON.stringify(value);
33
+ if (typeof value === 'string') return value;
34
+ if (typeof value === 'number' || typeof value === 'boolean') return String(value);
35
+ return undefined;
36
+ }
37
+
38
+ // Applies each declared default to `env` and reports what stayed unresolved.
39
+ //
40
+ // A variable that is present, even empty, is a value (`NAME=` in a dotenv file is the empty
41
+ // string, which is a legitimate string value). Only an absent variable falls back to the
42
+ // default, and only an absent variable with no default is missing.
43
+ export function resolveDeclaredParams(declared, env = process.env) {
44
+ const missing = [];
45
+ const defaulted = [];
46
+ for (const param of declared ?? []) {
47
+ const name = param?.name;
48
+ const type = typeOf(param);
49
+ if (typeof name !== 'string' || name === '' || type === SECRET_TYPE) continue;
50
+ if (env[name] !== undefined) continue;
51
+ let text;
52
+ try {
53
+ text = serializeDefault(defaultOf(param));
54
+ } catch {
55
+ text = undefined;
56
+ }
57
+ if (text === undefined) {
58
+ missing.push({ name, type });
59
+ continue;
60
+ }
61
+ env[name] = text;
62
+ defaulted.push({ name, type });
63
+ }
64
+ return { missing, defaulted };
65
+ }
66
+
67
+ // A parameter's default has to be in the environment from the moment the parameter is declared,
68
+ // not only after the codebase has loaded: `.value()` at the top level of a module reads the
69
+ // environment right then, and a deployed function sees the default there. The SDK registers each
70
+ // declaration with `declaredParams.push`, so wrapping that one method resolves each parameter as
71
+ // it is declared. `resolveDeclaredParams` after the load stays the authority for what is missing.
72
+ export function resolveWhenDeclared(declared, env = process.env) {
73
+ if (!Array.isArray(declared) || Object.prototype.hasOwnProperty.call(declared, 'push')) {
74
+ return false;
75
+ }
76
+ const push = declared.push;
77
+ declared.push = function pushAndResolve(...items) {
78
+ resolveDeclaredParams(items, env);
79
+ return push.apply(this, items);
80
+ };
81
+ return true;
82
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fireemu/darwin-arm64",
3
- "version": "0.19.0",
3
+ "version": "0.21.0",
4
4
  "description": "The fireemu daemon for darwin-arm64",
5
5
  "homepage": "https://github.com/t-k/fireemu#readme",
6
6
  "repository": {