@entur/function-tools 0.0.7 → 0.0.9

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.
@@ -5,7 +5,7 @@ import { registerStart } from '../lib/commands/start.js';
5
5
  import { registerUnusedExports } from '../lib/commands/unusedExports.js';
6
6
 
7
7
  const program = new Command();
8
- program.name("entur-functions").description("A multi-tool for Firebase functions at Entur").version("0.0.7").option("-v, --verbose", "Enable verbose output");
8
+ program.name("entur-functions").description("A multi-tool for Firebase functions at Entur").version("0.0.9").option("-v, --verbose", "Enable verbose output");
9
9
  registerBuild(program);
10
10
  registerDeploy(program);
11
11
  registerStart(program);
@@ -1,34 +1,121 @@
1
- import { writeFile } from 'node:fs/promises';
1
+ import { copyFile } from 'node:fs/promises';
2
2
  import { builtinModules } from 'node:module';
3
- import { dirname } from 'node:path';
4
- import { stringify } from 'yaml';
3
+ import { dirname, relative } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { writePackageJSON, readPackageJSON, packageUp } from '../packageJSON/index.js';
6
+ import { filterMap } from '../utils/array.js';
5
7
  import { groupByAsync, asyncMap } from '../utils/async.js';
6
8
  import { spawnAsync } from '../utils/exec.js';
7
- import { writePackageJSON, readPackageJSON, packageUp } from '../utils/packageJSON.js';
9
+ import { readYAML, writeYAML } from '../utils/fs.js';
8
10
 
9
11
  const alwaysIncludePackageNames = [
10
12
  "@google-cloud/functions-framework",
11
13
  "firebase-functions",
12
14
  "firebase-admin"
13
15
  ];
14
- async function writeDependencies(outputs, getOutputFilePath, outputDir) {
15
- const packages = [];
16
- for (const [packageJSONPath, packageJSON] of (await calculateDependencies(outputs))){
16
+ async function writeDependencies(outputs, getOutputFilePath, projectRoot, outputDir) {
17
+ const pnpmLockSourceURL = new URL("./pnpm-lock.yaml", projectRoot);
18
+ const pnpmLockOutputURL = new URL("./pnpm-lock.yaml", outputDir);
19
+ const pnpmWorkspaceSourceURL = new URL("./pnpm-workspace.yaml", projectRoot);
20
+ const pnpmWorkspaceOutputURL = new URL("./pnpm-workspace.yaml", outputDir);
21
+ await Promise.all([
22
+ copyFile(pnpmLockSourceURL, pnpmLockOutputURL),
23
+ copyFile(pnpmWorkspaceSourceURL, pnpmWorkspaceOutputURL)
24
+ ]);
25
+ const dependencies = await calculateDependencies(outputs);
26
+ await Promise.all([
27
+ writePackageJSONs(dependencies, getOutputFilePath, outputDir),
28
+ updateWorkspace(dependencies, getOutputFilePath, pnpmWorkspaceOutputURL),
29
+ updatePNPMLock(dependencies, getOutputFilePath, pnpmLockOutputURL, projectRoot)
30
+ ]);
31
+ }
32
+ async function writePackageJSONs(packageJSONMap, getOutputFilePath, outputDir) {
33
+ for (const [packageJSONPath, packageJSON] of packageJSONMap){
17
34
  const newPackageJSONPath = getOutputFilePath(packageJSONPath);
18
- const directory = dirname(newPackageJSONPath);
19
- if (directory === ".") {
20
- await writePackageJSON(new URL(`./${newPackageJSONPath}`, outputDir), {
21
- ...packageJSON,
22
- main: `./${outputs[0].fileName}`
23
- });
24
- } else {
25
- await writePackageJSON(new URL(`./${newPackageJSONPath}`, outputDir), packageJSON);
26
- packages.push(directory);
27
- }
35
+ await writePackageJSON(new URL(`./${newPackageJSONPath}`, outputDir), packageJSON);
28
36
  }
29
- await writeFile(new URL("./pnpm-workspace.yaml", outputDir), stringify({
37
+ }
38
+ async function updateWorkspace(packageJSONMap, getOutputFilePath, pnpmWorkspaceURL) {
39
+ const packages = filterMap([
40
+ ...packageJSONMap.keys()
41
+ ], (filePath)=>{
42
+ const outputFileName = dirname(getOutputFilePath(filePath));
43
+ return outputFileName !== "." ? outputFileName : undefined;
44
+ });
45
+ const workspace = await readYAML(pnpmWorkspaceURL);
46
+ await writeYAML(pnpmWorkspaceURL, {
47
+ ...workspace,
30
48
  packages
31
- }));
49
+ });
50
+ }
51
+ async function updatePNPMLock(packageJSONMap, getOutputFilePath, pnpmLockURL, projectRoot) {
52
+ const projectRootPath = fileURLToPath(projectRoot);
53
+ const lockfile = await readYAML(pnpmLockURL);
54
+ const updateDependencies = (dependencies, packageJSONDependencies)=>{
55
+ if (!dependencies || !packageJSONDependencies) {
56
+ return;
57
+ }
58
+ const entries = filterMap(Object.entries(dependencies), ([packageName, versionOrDependency])=>{
59
+ const specifier = packageJSONDependencies[packageName];
60
+ if (!specifier) return;
61
+ return typeof versionOrDependency === "string" ? [
62
+ packageName,
63
+ {
64
+ specifier,
65
+ version: versionOrDependency
66
+ }
67
+ ] : [
68
+ packageName,
69
+ versionOrDependency
70
+ ];
71
+ });
72
+ if (entries.length === 0) {
73
+ return;
74
+ }
75
+ return Object.fromEntries(entries);
76
+ };
77
+ const findSnapshot = (packageName)=>{
78
+ for (const { dependencies, devDependencies } of Object.values(lockfile.importers)){
79
+ const found = dependencies?.[packageName] || devDependencies?.[packageName];
80
+ if (found) {
81
+ const key = `${packageName}@${found.version}`;
82
+ const snapshot = lockfile.snapshots[key];
83
+ if (snapshot) return snapshot;
84
+ }
85
+ }
86
+ };
87
+ const entries = [
88
+ ...packageJSONMap
89
+ ].map(([packageJSONPath, packageJSON])=>{
90
+ const packageRootPath = dirname(packageJSONPath);
91
+ const key = relative(projectRootPath, packageRootPath);
92
+ const importer = lockfile.importers[key];
93
+ const updatedKey = getOutputFilePath(packageRootPath) || ".";
94
+ if (importer) {
95
+ return [
96
+ updatedKey,
97
+ {
98
+ dependencies: updateDependencies(importer.dependencies, packageJSON.dependencies),
99
+ devDependencies: updateDependencies(importer.devDependencies, packageJSON.devDependencies)
100
+ }
101
+ ];
102
+ }
103
+ const snapshot = findSnapshot(packageJSON.name);
104
+ if (snapshot) {
105
+ return [
106
+ updatedKey,
107
+ {
108
+ dependencies: updateDependencies(snapshot.dependencies, packageJSON.dependencies),
109
+ devDependencies: updateDependencies(snapshot.devDependencies, packageJSON.devDependencies)
110
+ }
111
+ ];
112
+ }
113
+ throw new Error(`Unable to create importer for ${packageJSON.name}`);
114
+ });
115
+ await writeYAML(pnpmLockURL, {
116
+ ...lockfile,
117
+ importers: Object.fromEntries(entries)
118
+ });
32
119
  }
33
120
  async function calculateDependencies(outputs) {
34
121
  const outputGroupedByPackage = await groupByAsync(outputs.filter((it)=>Boolean(it.type === "chunk" && it.facadeModuleId && it.imports.length > 0)), async (output)=>{
@@ -45,6 +132,7 @@ async function calculateDependencies(outputs) {
45
132
  const entries = Object.entries(dependencies).filter(([key])=>lookup.has(key));
46
133
  return entries.length > 0 ? Object.fromEntries(entries) : undefined;
47
134
  };
135
+ const entryFile = outputs[0];
48
136
  const entries = await asyncMap([
49
137
  ...outputGroupedByPackage
50
138
  ], async ([packageJSONPath, outputs])=>{
@@ -59,6 +147,7 @@ async function calculateDependencies(outputs) {
59
147
  name,
60
148
  type,
61
149
  version,
150
+ main: outputs.includes(entryFile) ? `./${entryFile.fileName}` : undefined,
62
151
  dependencies: filterDependencies(importedPackageNames, packageJSON.dependencies),
63
152
  devDependencies: filterDependencies(importedPackageNames, packageJSON.devDependencies),
64
153
  optionalDependencies: filterDependencies(importedPackageNames, packageJSON.optionalDependencies)
@@ -79,7 +168,7 @@ function isBuiltinImport(specifier) {
79
168
  async function linkDependencies(workingDir) {
80
169
  await spawnAsync("pnpm", [
81
170
  "install",
82
- "--prefer-offline"
171
+ "--fix-lockfile"
83
172
  ], {
84
173
  cwd: workingDir
85
174
  });
@@ -2,15 +2,13 @@ import { fileURLToPath } from 'node:url';
2
2
  import { nodeResolve } from '@rollup/plugin-node-resolve';
3
3
  import swc from '@rollup/plugin-swc';
4
4
  import { rollup, watch } from 'rollup';
5
- import { createOutputFileName } from './utils.js';
6
5
 
7
- async function bundle(entryFile, { outputDir, packageRoot, projectRoot, packagesToInline }) {
6
+ async function bundle(entryFile, { outputDir, outputFileName, shouldInlinePackage }) {
8
7
  const bundle = await rollup({
9
8
  input: fileURLToPath(entryFile),
10
- plugins: plugins(packagesToInline),
9
+ plugins: plugins(shouldInlinePackage),
11
10
  treeshake: "smallest"
12
11
  });
13
- const outputFileName = createOutputFileName(packageRoot, projectRoot);
14
12
  return bundle.write({
15
13
  preserveModules: true,
16
14
  format: "esm",
@@ -18,8 +16,7 @@ async function bundle(entryFile, { outputDir, packageRoot, projectRoot, packages
18
16
  entryFileNames: ({ facadeModuleId })=>outputFileName(facadeModuleId)
19
17
  });
20
18
  }
21
- async function bundleAndWatch(entryFile, { outputDir, packageRoot, projectRoot, packagesToInline, onBundleEnd }) {
22
- const outputFileName = createOutputFileName(packageRoot, projectRoot);
19
+ async function bundleAndWatch(entryFile, { outputDir, outputFileName, shouldInlinePackage, onBundleEnd }) {
23
20
  const output = {
24
21
  preserveModules: true,
25
22
  format: "esm",
@@ -27,7 +24,7 @@ async function bundleAndWatch(entryFile, { outputDir, packageRoot, projectRoot,
27
24
  entryFileNames: ({ facadeModuleId })=>outputFileName(facadeModuleId)
28
25
  };
29
26
  const watchOptions = {
30
- plugins: plugins(packagesToInline),
27
+ plugins: plugins(shouldInlinePackage),
31
28
  input: fileURLToPath(entryFile),
32
29
  treeshake: "smallest",
33
30
  output,
@@ -61,7 +58,7 @@ async function bundleAndWatch(entryFile, { outputDir, packageRoot, projectRoot,
61
58
  }
62
59
  });
63
60
  }
64
- const plugins = (workspacePackages)=>[
61
+ const plugins = (resolveOnly)=>[
65
62
  swc({
66
63
  swc: {
67
64
  jsc: {
@@ -70,7 +67,7 @@ const plugins = (workspacePackages)=>[
70
67
  }
71
68
  }),
72
69
  nodeResolve({
73
- resolveOnly: (moduleId)=>moduleId.startsWith(".") || workspacePackages?.some((it)=>moduleId.startsWith(it)) || moduleId.startsWith("@entur-private/") || false
70
+ resolveOnly
74
71
  })
75
72
  ];
76
73
 
@@ -5,19 +5,25 @@ function createOutputFileName(packageRootURL, projectRootURL) {
5
5
  const projectRoot = fileURLToPath(projectRootURL);
6
6
  const packageRoot = fileURLToPath(packageRootURL);
7
7
  return (facadeModuleId)=>{
8
- const index = facadeModuleId?.lastIndexOf(nodeModulesPartPath);
9
- if (facadeModuleId && index && index > -1) {
8
+ if (!facadeModuleId) {
9
+ throw new Error(`file path is null`);
10
+ }
11
+ const index = facadeModuleId.lastIndexOf(nodeModulesPartPath);
12
+ if (facadeModuleId && index > -1) {
10
13
  return `bundled_modules/${facadeModuleId.slice(index + nodeModulesPartPath.length)}`;
11
14
  }
12
- const filePath = facadeModuleId?.replace(".ts", ".js").replaceAll("/src/", "/lib/");
13
- if (filePath?.startsWith(packageRoot)) {
15
+ const filePath = facadeModuleId.replace(".ts", ".js").replaceAll("/src/", "/lib/");
16
+ if (filePath.startsWith(packageRoot) || packageRoot.slice(0, -1) === filePath) {
14
17
  return filePath.slice(packageRoot.length);
15
18
  }
16
- if (filePath?.startsWith(projectRoot)) {
19
+ if (filePath.startsWith(projectRoot)) {
17
20
  return `local_modules/${filePath.slice(projectRoot.length)}`;
18
21
  }
19
22
  throw new Error(`Unable to determine correct placement for file ${facadeModuleId}`);
20
23
  };
21
24
  }
25
+ function createShouldInlinePackage(packagesToInline) {
26
+ return (moduleId)=>moduleId.startsWith(".") || packagesToInline?.some((it)=>moduleId.startsWith(it)) || moduleId.startsWith("@entur-private/") || false;
27
+ }
22
28
 
23
- export { createOutputFileName };
29
+ export { createOutputFileName, createShouldInlinePackage };
@@ -1,37 +1,40 @@
1
- import { writeDependencies } from '../bundle/dependencies.js';
1
+ import { writeDependencies, linkDependencies } from '../bundle/dependencies.js';
2
2
  import { bundle } from '../bundle/index.js';
3
- import { createOutputFileName } from '../bundle/utils.js';
3
+ import { createOutputFileName, createShouldInlinePackage } from '../bundle/utils.js';
4
+ import { readPackageJSON } from '../packageJSON/index.js';
4
5
  import { cleanDir } from '../utils/fs.js';
5
- import { readPackageJSON } from '../utils/packageJSON.js';
6
6
  import { getWorkspacePackageNames } from '../utils/workspace.js';
7
7
  import { resolveProjectConfig } from './utils.js';
8
8
 
9
9
  function registerBuild(program) {
10
- program.command("build").description("Build the project").option("-o, --output-dir <dir>", "Output directory").action(async (options)=>{
10
+ program.command("build").description("Build the project").option("-o, --output-dir <dir>", "Output directory").action(async ({ outputDir })=>{
11
11
  try {
12
- const projectConfig = await resolveProjectConfig(options);
13
- const { packageRoot, packageJSON, outputDir, pnpmWorkspaceYAML } = projectConfig;
14
- const { name, exports: exports$1 } = await readPackageJSON(packageJSON);
15
- console.log("🧹 Cleaning dist folder");
16
- await cleanDir(outputDir);
17
- console.log(`🔨 Building ${name}`);
18
- const workspacePackages = await getWorkspacePackageNames(pnpmWorkspaceYAML);
19
- const entryFile = new URL(exports$1?.["."] ?? "./index.js", packageRoot);
20
- await build(entryFile, workspacePackages, projectConfig);
12
+ const projectConfig = await resolveProjectConfig({
13
+ outputDir
14
+ });
15
+ await build(projectConfig);
21
16
  } catch (error) {
22
17
  console.error(error);
23
18
  process.exit(1);
24
19
  }
25
20
  });
26
21
  }
27
- async function build(entryFile, packagesToInline, { outputDir, packageRoot, projectRoot }) {
22
+ async function build(projectConfig) {
23
+ const { packageRoot, projectRoot, packageJSON, outputDir, pnpmWorkspaceYAML } = projectConfig;
24
+ const { name, exports: exports$1 } = await readPackageJSON(packageJSON);
25
+ console.log("🧹 Cleaning dist folder");
26
+ await cleanDir(outputDir);
27
+ console.log(`🔨 Building ${name}`);
28
+ const entryFile = new URL(exports$1?.["."] ?? "./index.js", packageRoot);
29
+ const outputFileName = createOutputFileName(packageRoot, projectRoot);
30
+ const shouldInlinePackage = createShouldInlinePackage(await getWorkspacePackageNames(pnpmWorkspaceYAML));
28
31
  const { output } = await bundle(entryFile, {
29
32
  outputDir,
30
- packageRoot,
31
- projectRoot,
32
- packagesToInline
33
+ outputFileName,
34
+ shouldInlinePackage
33
35
  });
34
- await writeDependencies(output, createOutputFileName(packageRoot, projectRoot), outputDir);
36
+ await writeDependencies(output, outputFileName, projectRoot, outputDir);
37
+ await linkDependencies(outputDir);
35
38
  }
36
39
 
37
40
  export { registerBuild };
@@ -1,33 +1,35 @@
1
1
  import { writeDependencies, linkDependencies } from '../bundle/dependencies.js';
2
2
  import { bundle } from '../bundle/index.js';
3
- import { createOutputFileName } from '../bundle/utils.js';
3
+ import { createOutputFileName, createShouldInlinePackage } from '../bundle/utils.js';
4
4
  import { deploy as deploy$1 } from '../firebase/index.js';
5
- import { getFirebaseJSON, writeFirebaseJSON } from '../utils/firebase.js';
5
+ import { getFirebaseJSON, writeFirebaseJSON } from '../firebase/utils.js';
6
+ import { readPackageJSON, getPackageName } from '../packageJSON/index.js';
6
7
  import { cleanDir, writeJSON } from '../utils/fs.js';
7
- import { readPackageJSON, getPackageName } from '../utils/packageJSON.js';
8
8
  import { getWorkspacePackageNames } from '../utils/workspace.js';
9
9
  import { resolveProjectConfig, copyEnvFiles } from './utils.js';
10
10
 
11
11
  function registerDeploy(program) {
12
- program.command("deploy").description("Deploy the project").option("-o, --output-dir <dir>", "Output directory").option("-P, --project <project id or alias>", "Project id or alias").option("--debug", "print verbose debug output and keep a debug log file", false).action(async (options)=>{
12
+ program.command("deploy").description("Deploy the project").option("-o, --output-dir <dir>", "Output directory").option("-P, --project <project id or alias>", "Project id or alias").option("--debug", "print verbose debug output and keep a debug log file", false).option("--force", "delete missing Cloud Functions and bypass interactive prompts", false).action(async ({ outputDir, project, ...options })=>{
13
13
  try {
14
- const projectConfig = await resolveProjectConfig(options);
15
- await deploy(options.debug, projectConfig);
14
+ const projectConfig = await resolveProjectConfig({
15
+ outputDir,
16
+ project
17
+ });
18
+ await deploy(options, projectConfig);
16
19
  } catch (error) {
17
20
  console.error(error);
18
21
  process.exit(1);
19
22
  }
20
23
  });
21
24
  }
22
- async function deploy(debug, projectConfig) {
23
- const { projectAlias, projectId, packageJSON, packageRoot, pnpmWorkspaceYAML, projectRoot, outputDir } = projectConfig;
25
+ async function deploy(options, projectConfig) {
26
+ const { projectAlias, projectId, packageJSON, packageRoot, projectRoot, outputDir } = projectConfig;
24
27
  const { name, exports: exports$1 } = await readPackageJSON(packageJSON);
25
- const workspacePackages = await getWorkspacePackageNames(pnpmWorkspaceYAML);
26
28
  const entryFile = new URL(exports$1?.["."] ?? "./index.js", packageRoot);
27
29
  console.log("🧹 Cleaning dist folder");
28
30
  await cleanDir(outputDir);
29
31
  console.log(`🔨 Building ${name}`);
30
- await build(entryFile, workspacePackages, projectConfig);
32
+ await build(entryFile, projectConfig);
31
33
  console.log("⛷️ Prepare deploy");
32
34
  const firebaseJSON = await getFirebaseJSON(new URL("firebase.json", projectRoot));
33
35
  await prepareDeploy(getPackageName(name), firebaseJSON, projectConfig);
@@ -35,17 +37,19 @@ async function deploy(debug, projectConfig) {
35
37
  await deploy$1({
36
38
  projectId,
37
39
  cwd: outputDir,
38
- debug
40
+ ...options
39
41
  });
40
42
  }
41
- async function build(entryFile, packagesToInline, { outputDir, packageRoot, projectRoot }) {
43
+ async function build(entryFile, { outputDir, packageRoot, projectRoot, pnpmWorkspaceYAML }) {
44
+ const outputFileName = createOutputFileName(packageRoot, projectRoot);
45
+ const shouldInlinePackage = createShouldInlinePackage(await getWorkspacePackageNames(pnpmWorkspaceYAML));
42
46
  const { output } = await bundle(entryFile, {
43
- packageRoot,
44
- projectRoot,
45
47
  outputDir,
46
- packagesToInline
48
+ outputFileName,
49
+ shouldInlinePackage
47
50
  });
48
- await writeDependencies(output, createOutputFileName(packageRoot, projectRoot), outputDir);
51
+ await writeDependencies(output, outputFileName, projectRoot, outputDir);
52
+ await linkDependencies(outputDir);
49
53
  }
50
54
  async function prepareDeploy(codebase, firebaseJSON, { projectAlias, projectId, outputDir, envFiles }) {
51
55
  const envPrefix = `FUNCTION_CODEBASE='${codebase}'\nENTUR_PROJECT_ALIAS='${projectAlias}'`;
@@ -1,39 +1,42 @@
1
1
  import { writeDependencies, linkDependencies } from '../bundle/dependencies.js';
2
2
  import { bundleAndWatch } from '../bundle/index.js';
3
- import { createOutputFileName } from '../bundle/utils.js';
3
+ import { createOutputFileName, createShouldInlinePackage } from '../bundle/utils.js';
4
4
  import { startEmulator } from '../firebase/index.js';
5
- import { getFirebaseJSON, writeFirebaseJSON } from '../utils/firebase.js';
5
+ import { getFirebaseJSON, writeFirebaseJSON } from '../firebase/utils.js';
6
+ import { readPackageJSON, getPackageName } from '../packageJSON/index.js';
6
7
  import { cleanDir, writeJSON } from '../utils/fs.js';
7
- import { readPackageJSON, getPackageName } from '../utils/packageJSON.js';
8
8
  import { getWorkspacePackageNames } from '../utils/workspace.js';
9
9
  import { resolveProjectConfig, copyEnvFiles } from './utils.js';
10
10
 
11
11
  function registerStart(program) {
12
- program.command("start").description("Start function emulator").option("-o, --output-dir <dir>", "Output directory").option("-P, --project <project id or alias>", "Project id or alias").option("--inspect-functions [port]", "emulate Cloud Functions in debug mode with the node inspector on the given port (9229 if not specified)", false).option("--debug", "print verbose debug output and keep a debug log file", false).action(async (options)=>{
12
+ program.command("start").description("Start function emulator").option("-o, --output-dir <dir>", "Output directory").option("-P, --project <project id or alias>", "Project id or alias").option("--inspect-functions [port]", "emulate Cloud Functions in debug mode with the node inspector on the given port (9229 if not specified)", false).option("--debug", "print verbose debug output and keep a debug log file", false).action(async ({ outputDir, project, ...options })=>{
13
13
  try {
14
14
  const projectConfig = await resolveProjectConfig({
15
- ...options,
15
+ outputDir,
16
+ project,
16
17
  isEmulator: true
17
18
  });
18
- await start(options.debug, options.inspectFunctions, projectConfig);
19
+ await start(options, projectConfig);
19
20
  } catch (error) {
20
21
  console.error(error);
21
22
  process.exit(1);
22
23
  }
23
24
  });
24
25
  }
25
- async function start(debug, inspectFunctions, projectConfig) {
26
+ async function start(options, projectConfig) {
26
27
  const { packageRoot, packageJSON, projectId, projectRoot, pnpmWorkspaceYAML, outputDir } = projectConfig;
27
28
  const { name, exports: exports$1 } = await readPackageJSON(packageJSON);
28
29
  const codebase = getPackageName(name);
29
- const packagesToInline = await getWorkspacePackageNames(pnpmWorkspaceYAML);
30
30
  const entryFile = new URL(exports$1?.["."] ?? "./index.js", packageRoot);
31
31
  console.log("🧹 Cleaning dist folder");
32
32
  await cleanDir(outputDir);
33
33
  console.log(`🔨 Building ${name}`);
34
+ const outputFileName = createOutputFileName(packageRoot, projectRoot);
35
+ const shouldInlinePackage = createShouldInlinePackage(await getWorkspacePackageNames(pnpmWorkspaceYAML));
34
36
  let firstRun = true;
35
37
  const onBundleEnd = async ({ output })=>{
36
- await writeDependencies(output, createOutputFileName(packageRoot, projectRoot), outputDir);
38
+ await writeDependencies(output, outputFileName, projectRoot, outputDir);
39
+ await linkDependencies(outputDir);
37
40
  const firebaseJSON = await getFirebaseJSON(new URL("firebase.json", projectRoot));
38
41
  await prepareStart(codebase, firebaseJSON, projectConfig);
39
42
  if (firstRun) {
@@ -41,8 +44,7 @@ async function start(debug, inspectFunctions, projectConfig) {
41
44
  startEmulator({
42
45
  projectId,
43
46
  cwd: outputDir,
44
- debug,
45
- inspectFunctions
47
+ ...options
46
48
  }).catch((error)=>{
47
49
  console.error(error);
48
50
  });
@@ -50,9 +52,8 @@ async function start(debug, inspectFunctions, projectConfig) {
50
52
  };
51
53
  await bundleAndWatch(entryFile, {
52
54
  outputDir,
53
- projectRoot,
54
- packageRoot,
55
- packagesToInline,
55
+ outputFileName,
56
+ shouldInlinePackage,
56
57
  onBundleEnd
57
58
  });
58
59
  }
@@ -1,12 +1,14 @@
1
1
  import { spawnAsync } from '../utils/exec.js';
2
2
 
3
3
  const FUNCTIONS_DISCOVERY_TIMEOUT = "30";
4
- function deploy({ projectId, cwd, debug }) {
4
+ function deploy({ projectId, cwd, debug, force }) {
5
5
  const extraArgs = [];
6
6
  if (debug) {
7
- console.log("Environment variables:", process.env);
8
7
  extraArgs.push("--debug");
9
8
  }
9
+ if (force) {
10
+ extraArgs.push("--force");
11
+ }
10
12
  return spawnAsync("firebase", [
11
13
  "deploy",
12
14
  "--only",
@@ -1,5 +1,5 @@
1
1
  import { writeFile } from 'node:fs/promises';
2
- import { readJSON } from './fs.js';
2
+ import { readJSON } from '../utils/fs.js';
3
3
 
4
4
  function getFirebaseJSON(file) {
5
5
  return readJSON(file);
@@ -1,6 +1,6 @@
1
1
  import process from 'node:process';
2
2
  import { findUp } from 'find-up-simple';
3
- import { readJSON, writeJSON } from './fs.js';
3
+ import { readJSON, writeJSON } from '../utils/fs.js';
4
4
 
5
5
  function readPackageJSON(file) {
6
6
  return readJSON(file);
package/lib/utils/fs.js CHANGED
@@ -1,4 +1,5 @@
1
- import { rm, mkdir, readFile, writeFile, access } from 'node:fs/promises';
1
+ import { readFile, rm, mkdir, writeFile, access } from 'node:fs/promises';
2
+ import { parse, stringify } from 'yaml';
2
3
 
3
4
  async function cleanDir(dir) {
4
5
  await rm(dir, {
@@ -24,5 +25,12 @@ async function readJSON(file) {
24
25
  async function writeJSON(file, data) {
25
26
  await writeFile(file, JSON.stringify(data, undefined, 4));
26
27
  }
28
+ async function readYAML(file) {
29
+ const fileContent = await readFile(file, "utf-8");
30
+ return parse(fileContent);
31
+ }
32
+ async function writeYAML(file, data) {
33
+ await writeFile(file, stringify(data, undefined, 4));
34
+ }
27
35
 
28
- export { cleanDir, exists, readJSON, writeJSON };
36
+ export { cleanDir, exists, readJSON, readYAML, writeJSON, writeYAML };
@@ -1,6 +1,6 @@
1
1
  import { readFile, glob } from 'node:fs/promises';
2
2
  import { parse } from 'yaml';
3
- import { readPackageJSON } from './packageJSON.js';
3
+ import { readPackageJSON } from '../packageJSON/index.js';
4
4
 
5
5
  async function getWorkspacePackageNames(pnpmWorkspaceYAML) {
6
6
  const pnpmWorkspaceContent = await readFile(pnpmWorkspaceYAML, "utf-8");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@entur/function-tools",
3
3
  "type": "module",
4
- "version": "0.0.7",
4
+ "version": "0.0.9",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },