cloud-run-functions 0.1.2 → 0.1.4

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.
@@ -0,0 +1,82 @@
1
+ // node_modules/.pnpm/radashi@12.4.0/node_modules/radashi/dist/radashi.js
2
+ function objectify(array, getKey, getValue = (item) => item) {
3
+ return array.reduce(
4
+ (acc, item) => {
5
+ acc[getKey(item)] = getValue(item);
6
+ return acc;
7
+ },
8
+ {}
9
+ );
10
+ }
11
+ var TimeoutError = class extends Error {
12
+ constructor(message) {
13
+ super(message ?? "Operation timed out");
14
+ this.name = "TimeoutError";
15
+ }
16
+ };
17
+ function timeout(ms, error) {
18
+ return new Promise(
19
+ (_, reject) => setTimeout(
20
+ () => reject(isFunction(error) ? error() : new TimeoutError(error)),
21
+ ms
22
+ )
23
+ );
24
+ }
25
+ async function toResult(promise) {
26
+ try {
27
+ const result = await promise;
28
+ return [void 0, result];
29
+ } catch (error) {
30
+ if (isError(error)) {
31
+ return [error, void 0];
32
+ }
33
+ throw error;
34
+ }
35
+ }
36
+ function dedent(text, ...values) {
37
+ var _a;
38
+ if (isArray(text)) {
39
+ if (values.length > 0) {
40
+ return dedent(
41
+ text.reduce((acc, input, i) => {
42
+ var _a2;
43
+ let value = String(values[i] ?? "");
44
+ const indent2 = value.includes("\n") && ((_a2 = input.match(/[ \t]*(?=[^\n]*$)/)) == null ? void 0 : _a2[0]);
45
+ if (indent2) {
46
+ value = value.replace(/\n(?=[^\n]*?\S)/g, "\n" + indent2);
47
+ }
48
+ return acc + input + value;
49
+ }, "")
50
+ );
51
+ }
52
+ text = text[0];
53
+ }
54
+ const indent = values[0] ?? ((_a = text.match(/^[ \t]*(?=\S)/m)) == null ? void 0 : _a[0]);
55
+ const output = indent ? text.replace(new RegExp(`^${indent}`, "gm"), "") : text;
56
+ return output.replace(/^[ \t]*\n|\n[ \t]*$/g, "");
57
+ }
58
+ var isArray = /* @__PURE__ */ (() => Array.isArray)();
59
+ var asyncIteratorSymbol = (
60
+ /* c8 ignore next */
61
+ Symbol.asyncIterator || Symbol.for("Symbol.asyncIterator")
62
+ );
63
+ function isError(value) {
64
+ return isTagged(value, "[object Error]");
65
+ }
66
+ function isFunction(value) {
67
+ return typeof value === "function";
68
+ }
69
+ function isNumber(value) {
70
+ return typeof value === "number" && !Number.isNaN(value);
71
+ }
72
+ function isTagged(value, tag) {
73
+ return Object.prototype.toString.call(value) === tag;
74
+ }
75
+
76
+ export {
77
+ objectify,
78
+ timeout,
79
+ toResult,
80
+ dedent,
81
+ isNumber
82
+ };
package/dist/main.js CHANGED
@@ -1,29 +1,72 @@
1
+ import {
2
+ objectify
3
+ } from "./chunk-SPF3AMMV.js";
4
+
1
5
  // src/main.ts
2
- import * as ordana from "ordana";
3
- var command = ordana.parse(process.argv.slice(2), {
6
+ import {
7
+ array,
8
+ command,
9
+ multioption,
10
+ option,
11
+ optional,
12
+ positional,
13
+ run,
14
+ string,
15
+ subcommands
16
+ } from "cmd-ts";
17
+ var dev = command({
18
+ name: "dev",
19
+ description: "Start the development server",
20
+ args: {
21
+ root: positional({
22
+ type: optional(string),
23
+ displayName: "root",
24
+ description: "Directory to search for function entrypoints"
25
+ }),
26
+ port: option({
27
+ type: optional(string),
28
+ long: "port",
29
+ short: "p",
30
+ description: "The port to use for the development server"
31
+ }),
32
+ define: multioption({
33
+ type: optional(array(string)),
34
+ long: "define",
35
+ short: "d",
36
+ description: "Statically replace specific variables in the source code"
37
+ })
38
+ },
39
+ async handler({ root, port, define }) {
40
+ const { dev: dev2 } = await import("./tools/dev.js");
41
+ await dev2(root, {
42
+ port,
43
+ define: define && objectify(
44
+ define.map((d) => d.split(":")),
45
+ ([key]) => key,
46
+ ([, value]) => value ? isNaN(parseFloat(value)) ? JSON.stringify(value) : value : ""
47
+ )
48
+ });
49
+ }
50
+ });
51
+ var build = command({
52
+ name: "build",
53
+ description: "Generate a bundle for each function",
54
+ args: {
55
+ root: positional({
56
+ type: optional(string),
57
+ displayName: "root",
58
+ description: "Directory to search for function entrypoints"
59
+ })
60
+ },
61
+ async handler() {
62
+ throw new Error("Not implemented");
63
+ }
64
+ });
65
+ var cli = subcommands({
4
66
  name: "cloud-run-functions",
5
- subcommands: {
6
- dev: {
7
- description: "Start the development server",
8
- positionals: { maximum: 1 }
9
- },
10
- build: {
11
- description: "Generate a bundle for each function",
12
- positionals: { maximum: 1 }
13
- }
67
+ cmds: {
68
+ dev,
69
+ build
14
70
  }
15
71
  });
16
- if (command.type === "help") {
17
- console.log(ordana.generateHelpMessage(command));
18
- } else {
19
- const subcommands = {
20
- async dev() {
21
- const { dev } = await import("./tools/dev.js");
22
- await dev(command.positionals[0]);
23
- },
24
- async build() {
25
- throw new Error("Not implemented");
26
- }
27
- };
28
- await subcommands[command.subcommand]();
29
- }
72
+ await run(cli, process.argv.slice(2));
@@ -1,3 +1,10 @@
1
+ import {
2
+ dedent,
3
+ isNumber,
4
+ timeout,
5
+ toResult
6
+ } from "../chunk-SPF3AMMV.js";
7
+
1
8
  // src/targets/dev.ts
2
9
  import "source-map-support/register.js";
3
10
  import functions from "@google-cloud/functions-framework";
@@ -6,78 +13,56 @@ import { findUpSync } from "find-up-simple";
6
13
  import fs2 from "node:fs";
7
14
  import { Module } from "node:module";
8
15
  import os from "node:os";
9
- import path2 from "node:path";
16
+ import path3 from "node:path";
10
17
 
11
- // node_modules/.pnpm/radashi@12.4.0/node_modules/radashi/dist/radashi.js
12
- var TimeoutError = class extends Error {
13
- constructor(message) {
14
- super(message ?? "Operation timed out");
15
- this.name = "TimeoutError";
16
- }
17
- };
18
- function timeout(ms, error) {
19
- return new Promise(
20
- (_, reject) => setTimeout(
21
- () => reject(isFunction(error) ? error() : new TimeoutError(error)),
22
- ms
23
- )
24
- );
25
- }
26
- async function toResult(promise) {
27
- try {
28
- const result = await promise;
29
- return [void 0, result];
30
- } catch (error) {
31
- if (isError(error)) {
32
- return [error, void 0];
33
- }
34
- throw error;
35
- }
18
+ // src/common/emptyDir.ts
19
+ import fs from "node:fs";
20
+ function emptyDir(dir) {
21
+ fs.rmSync(dir, { recursive: true, force: true });
22
+ fs.mkdirSync(dir, { recursive: true });
23
+ return dir;
36
24
  }
37
- function dedent(text, ...values) {
38
- var _a;
39
- if (isArray(text)) {
40
- if (values.length > 0) {
41
- return dedent(
42
- text.reduce((acc, input, i) => {
43
- var _a2;
44
- let value = String(values[i] ?? "");
45
- const indent2 = value.includes("\n") && ((_a2 = input.match(/[ \t]*(?=[^\n]*$)/)) == null ? void 0 : _a2[0]);
46
- if (indent2) {
47
- value = value.replace(/\n(?=[^\n]*?\S)/g, "\n" + indent2);
48
- }
49
- return acc + input + value;
50
- }, "")
25
+
26
+ // src/common/functionFilter.ts
27
+ import path from "node:path";
28
+ function getFunctionFilter(options) {
29
+ const functionGlobs = [];
30
+ const functionSuffixes = /* @__PURE__ */ new Set();
31
+ const requiredSuffix = options.entrySuffix?.replace(/^\.?/, ".") ?? "";
32
+ for (const glob of options.globs ?? ["**/*"]) {
33
+ let ext = path.extname(glob);
34
+ if (ext) {
35
+ functionSuffixes.add(requiredSuffix + ext);
36
+ functionGlobs.push(
37
+ requiredSuffix ? glob.replace(ext, requiredSuffix + ext) : glob
51
38
  );
39
+ continue;
40
+ }
41
+ for (ext of options.extensions ?? [".ts", ".js"]) {
42
+ ext = requiredSuffix + ext;
43
+ functionSuffixes.add(ext);
44
+ functionGlobs.push(glob + ext);
52
45
  }
53
- text = text[0];
54
46
  }
55
- const indent = values[0] ?? ((_a = text.match(/^[ \t]*(?=\S)/m)) == null ? void 0 : _a[0]);
56
- const output = indent ? text.replace(new RegExp(`^${indent}`, "gm"), "") : text;
57
- return output.replace(/^[ \t]*\n|\n[ \t]*$/g, "");
58
- }
59
- var isArray = /* @__PURE__ */ (() => Array.isArray)();
60
- var asyncIteratorSymbol = (
61
- /* c8 ignore next */
62
- Symbol.asyncIterator || Symbol.for("Symbol.asyncIterator")
63
- );
64
- function isError(value) {
65
- return isTagged(value, "[object Error]");
66
- }
67
- function isFunction(value) {
68
- return typeof value === "function";
69
- }
70
- function isNumber(value) {
71
- return typeof value === "number" && !Number.isNaN(value);
47
+ const suffixPattern = new RegExp(
48
+ `(${Array.from(functionSuffixes, (e) => e.replace(/\./g, "\\.")).sort((a, b) => b.length - a.length).join("|")})$`
49
+ );
50
+ return {
51
+ globs: functionGlobs,
52
+ suffixPattern
53
+ };
72
54
  }
73
- function isTagged(value, tag) {
74
- return Object.prototype.toString.call(value) === tag;
55
+
56
+ // src/common/hash.ts
57
+ import crypto from "node:crypto";
58
+ function hash(data, len) {
59
+ return crypto.createHash("sha256").update(data).digest("hex").slice(0, len);
75
60
  }
76
61
 
77
62
  // src/config/index.ts
78
63
  import * as z2 from "@zod/mini";
79
64
  import Joycon from "joycon";
80
- import path from "node:path";
65
+ import path2 from "node:path";
81
66
 
82
67
  // src/config/schema.ts
83
68
  import * as z from "@zod/mini";
@@ -141,53 +126,19 @@ function loadConfig(cwd) {
141
126
  }
142
127
  return {
143
128
  ...z2.parse(configSchema, result.data),
144
- configDir: path.dirname(result.path)
129
+ configDir: path2.dirname(result.path)
145
130
  };
146
131
  }
147
132
 
148
- // src/utils/emptyDir.ts
149
- import fs from "node:fs";
150
- function emptyDir(dir) {
151
- fs.rmSync(dir, { recursive: true, force: true });
152
- fs.mkdirSync(dir, { recursive: true });
153
- return dir;
154
- }
155
-
156
- // src/utils/hash.ts
157
- import crypto from "node:crypto";
158
- function hash(data, len) {
159
- return crypto.createHash("sha256").update(data).digest("hex").slice(0, len);
160
- }
161
-
162
133
  // src/targets/dev.ts
163
134
  async function createBuild() {
164
135
  const options = JSON.parse(process.env.CRF_OPTIONS);
165
- const searchDir = path2.resolve(options.workingDir, options.searchDir ?? "");
136
+ const searchDir = path3.resolve(options.workingDir, options.searchDir ?? "");
166
137
  const config = loadConfig(searchDir);
167
- const root = config.configDir ? path2.resolve(config.configDir, config.root ?? "") : searchDir;
168
- const entryPoints = [];
169
- const requiredSuffix = config.entrySuffix?.replace(/^\.?/, ".") ?? "";
170
- const knownSuffixes = /* @__PURE__ */ new Set();
171
- for (const glob of config.globs ?? ["**/*"]) {
172
- let ext = path2.extname(glob);
173
- if (ext) {
174
- knownSuffixes.add(requiredSuffix + ext);
175
- entryPoints.push(
176
- requiredSuffix ? glob.replace(ext, requiredSuffix + ext) : glob
177
- );
178
- continue;
179
- }
180
- for (ext of config.extensions ?? [".ts", ".js"]) {
181
- ext = requiredSuffix + ext;
182
- knownSuffixes.add(ext);
183
- entryPoints.push(glob + ext);
184
- }
185
- }
186
- const knownSuffixesRE = new RegExp(
187
- `(${Array.from(knownSuffixes, (e) => e.replace(/\./g, "\\.")).sort((a, b) => b.length - a.length).join("|")})$`
188
- );
138
+ const root = config.configDir ? path3.resolve(config.configDir, config.root ?? "") : searchDir;
139
+ const functionFilter = getFunctionFilter(config);
189
140
  const cacheDir = emptyDir(
190
- path2.join(
141
+ path3.join(
191
142
  fs2.realpathSync(os.tmpdir()),
192
143
  "cloud-run-functions-" + hash(root, 8)
193
144
  )
@@ -195,7 +146,7 @@ async function createBuild() {
195
146
  let pendingBuild;
196
147
  let finishedBuild;
197
148
  const context = await esbuild.context({
198
- entryPoints,
149
+ entryPoints: functionFilter.globs,
199
150
  absWorkingDir: root,
200
151
  outdir: cacheDir,
201
152
  define: options.define,
@@ -213,14 +164,26 @@ async function createBuild() {
213
164
  {
214
165
  name: "build-status",
215
166
  setup(build) {
167
+ let startTime;
216
168
  pendingBuild = Promise.withResolvers();
217
169
  build.onStart(() => {
218
170
  pendingBuild ??= Promise.withResolvers();
171
+ startTime = Date.now();
219
172
  });
220
173
  build.onEnd((result) => {
221
174
  if (pendingBuild) {
222
175
  pendingBuild.resolve(result);
223
176
  pendingBuild = void 0;
177
+ console.log(
178
+ `[%s] %s your Cloud Run functions in %sms.`,
179
+ (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", {
180
+ hour: "2-digit",
181
+ minute: "2-digit",
182
+ hour12: false
183
+ }),
184
+ finishedBuild ? "Rebuilt" : "Built",
185
+ Date.now() - startTime
186
+ );
224
187
  }
225
188
  finishedBuild = result;
226
189
  });
@@ -252,7 +215,10 @@ async function createBuild() {
252
215
  if (!output.entryPoint) {
253
216
  continue;
254
217
  }
255
- const taskName = output.entryPoint.replace(knownSuffixesRE, "");
218
+ const taskName = output.entryPoint.replace(
219
+ functionFilter.suffixPattern,
220
+ ""
221
+ );
256
222
  if (url.pathname === "/" + taskName) {
257
223
  const taskState = taskStates.get(taskName) ?? {
258
224
  running: 0,
@@ -274,7 +240,7 @@ async function createBuild() {
274
240
  taskState.running++;
275
241
  taskStates.set(taskName, taskState);
276
242
  const require2 = Module.createRequire(import.meta.filename);
277
- let taskHandler = require2(path2.join(root, file));
243
+ let taskHandler = require2(path3.join(root, file));
278
244
  while (taskHandler && typeof taskHandler !== "function") {
279
245
  taskHandler = taskHandler.default;
280
246
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "cloud-run-functions",
3
3
  "type": "module",
4
- "version": "0.1.2",
4
+ "version": "0.1.4",
5
5
  "bin": "./dist/main.js",
6
6
  "exports": {
7
7
  "types": "./dist/index.d.ts",
@@ -35,10 +35,10 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@zod/mini": "4.0.0-beta.0",
38
+ "cmd-ts": "^0.14.3",
38
39
  "esbuild": "^0.25.4",
39
40
  "find-up-simple": "^1.0.1",
40
41
  "joycon": "^3.1.1",
41
- "ordana": "^0.4.0",
42
42
  "picospawn": "^0.3.2",
43
43
  "source-map-support": "^0.5.21",
44
44
  "tinyglobby": "^0.2.13"