@walkeros/server-source-gcp 0.4.1 → 0.5.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 +49 -8
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -9,6 +9,25 @@ runtime adapters for GCP services.
|
|
|
9
9
|
npm install @walkeros/server-source-gcp @google-cloud/functions-framework
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
import {
|
|
16
|
+
sourceCloudFunction,
|
|
17
|
+
type SourceCloudFunction,
|
|
18
|
+
} from '@walkeros/server-source-gcp';
|
|
19
|
+
import { startFlow } from '@walkeros/collector';
|
|
20
|
+
import { http } from '@google-cloud/functions-framework';
|
|
21
|
+
|
|
22
|
+
const { elb } = await startFlow<SourceCloudFunction.Push>({
|
|
23
|
+
sources: { api: { code: sourceCloudFunction } },
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
http('walkerHandler', elb);
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
12
31
|
## Cloud Functions Source
|
|
13
32
|
|
|
14
33
|
The Cloud Functions source provides an HTTP handler that receives walker events
|
|
@@ -17,17 +36,39 @@ and forwards them to the walkerOS collector.
|
|
|
17
36
|
### Basic Usage
|
|
18
37
|
|
|
19
38
|
```typescript
|
|
20
|
-
import {
|
|
39
|
+
import {
|
|
40
|
+
sourceCloudFunction,
|
|
41
|
+
type SourceCloudFunction,
|
|
42
|
+
} from '@walkeros/server-source-gcp';
|
|
43
|
+
import { startFlow } from '@walkeros/collector';
|
|
21
44
|
import { http } from '@google-cloud/functions-framework';
|
|
22
45
|
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
);
|
|
46
|
+
// Handler singleton - reused across warm invocations
|
|
47
|
+
let handler: SourceCloudFunction.Push;
|
|
48
|
+
|
|
49
|
+
async function setup() {
|
|
50
|
+
if (handler) return handler;
|
|
51
|
+
|
|
52
|
+
const { elb } = await startFlow<SourceCloudFunction.Push>({
|
|
53
|
+
sources: {
|
|
54
|
+
api: {
|
|
55
|
+
code: sourceCloudFunction,
|
|
56
|
+
config: {
|
|
57
|
+
settings: { cors: true },
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
destinations: {
|
|
62
|
+
// Your destinations
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
handler = elb;
|
|
67
|
+
return handler;
|
|
68
|
+
}
|
|
28
69
|
|
|
29
|
-
//
|
|
30
|
-
http('walkerHandler',
|
|
70
|
+
// Register with Cloud Functions framework
|
|
71
|
+
setup().then((h) => http('walkerHandler', h));
|
|
31
72
|
```
|
|
32
73
|
|
|
33
74
|
## Bundler Integration
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e,o=Object.defineProperty,r=Object.getOwnPropertyDescriptor,t=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,n=(e,r)=>{for(var t in r)o(e,t,{get:r[t],enumerable:!0})},i={};n(i,{SourceCloudFunction:()=>a,examples:()=>
|
|
1
|
+
"use strict";var e,o=Object.defineProperty,r=Object.getOwnPropertyDescriptor,t=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,n=(e,r)=>{for(var t in r)o(e,t,{get:r[t],enumerable:!0})},i={};n(i,{SourceCloudFunction:()=>a,examples:()=>b,schemas:()=>c,sourceCloudFunction:()=>C}),module.exports=(e=i,((e,n,i,a)=>{if(n&&"object"==typeof n||"function"==typeof n)for(let c of t(n))s.call(e,c)||c===i||o(e,c,{get:()=>n[c],enumerable:!(a=r(n,c))||a.enumerable});return e})(o({},"__esModule",{value:!0}),e));var a={},c={};n(c,{CorsOptionsSchema:()=>f,CorsOrigin:()=>m,HttpMethod:()=>g,SettingsSchema:()=>h,settings:()=>p});var l=require("@walkeros/core/dev"),u=require("@walkeros/core/dev"),d=require("@walkeros/core/dev"),g=d.z.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),m=d.z.union([d.z.string(),d.z.array(d.z.string()),d.z.literal("*")]),f=d.z.object({origin:m.describe("Allowed origins (* for all, URL string, or array of URLs)").optional(),methods:d.z.array(g).describe("Allowed HTTP methods").optional(),headers:d.z.array(d.z.string()).describe("Allowed request headers").optional(),credentials:d.z.boolean().describe("Allow credentials (cookies, authorization headers)").optional(),maxAge:d.z.number().int().positive().describe("Preflight cache duration in seconds").optional()}),h=u.z.object({cors:u.z.union([u.z.boolean(),f]).describe("CORS configuration: false = disabled, true = allow all origins, object = custom configuration").optional(),timeout:u.z.number().int().positive().max(54e4).describe("Request timeout in milliseconds (max: 540000 for GCP)").optional()}),p=(0,l.zodToSchema)(h),b={};n(b,{env:()=>A});var A={};n(A,{push:()=>O});var v=()=>()=>Promise.resolve({ok:!0,successful:[],queued:[],failed:[]}),w=()=>{},y={error:w,info:w,debug:w,throw:e=>{throw"string"==typeof e?new Error(e):e},scope:()=>y},O={get push(){return v()},get command(){return v()},get elb(){return v()},logger:y},z={cors:!0,timeout:3e4},j=async(e={},o)=>{const{push:r}=o,t={...z,...e.settings||{}};return{type:"cloudfunction",config:{...e,settings:t},push:async(e,o)=>{try{if(function(e,o){if(o)if(!0===o)e.set("Access-Control-Allow-Origin","*"),e.set("Access-Control-Allow-Methods","POST, OPTIONS"),e.set("Access-Control-Allow-Headers","Content-Type, Authorization"),e.set("Access-Control-Max-Age","3600");else{if(o.origin){const r=Array.isArray(o.origin)?o.origin.join(", "):o.origin;e.set("Access-Control-Allow-Origin",r)}o.methods&&e.set("Access-Control-Allow-Methods",o.methods.join(", ")),o.headers&&e.set("Access-Control-Allow-Headers",o.headers.join(", ")),o.credentials&&e.set("Access-Control-Allow-Credentials","true"),void 0!==o.maxAge&&e.set("Access-Control-Max-Age",o.maxAge.toString())}}(o,t.cors||!1),"OPTIONS"===e.method)return void o.status(204).send();if("POST"!==e.method)return void o.status(405).json({success:!1,error:"Method not allowed. Use POST."});if(!e.body)return void o.status(400).json({success:!1,error:"Request body is required"});const s=e.body;if(function(e){return"event"in e&&"string"==typeof e.event}(s)){const e=await async function(e,o){var r;try{const t=await o({name:e.event,data:e.data||{},context:e.context,user:e.user,globals:e.globals,consent:e.consent});return{id:null==(r=null==t?void 0:t.event)?void 0:r.id}}catch(e){return{error:e instanceof Error?e.message:"Unknown error"}}}(s,r);e.error?o.status(400).json({success:!1,error:e.error}):o.status(200).json({success:!0,id:e.id})}else o.status(400).json({success:!1,error:"Invalid request format. Expected event object."})}catch(e){o.status(500).json({success:!1,error:e instanceof Error?e.message:"Internal server error"})}}}},C=j;//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/cloudfunction/utils.ts","../src/cloudfunction/push.ts","../src/cloudfunction/types.ts","../src/cloudfunction/schemas/index.ts","../src/cloudfunction/schemas/settings.ts","../src/cloudfunction/schemas/primitives.ts","../src/cloudfunction/examples/index.ts","../src/cloudfunction/examples/env.ts","../src/cloudfunction/index.ts"],"sourcesContent":["export * from './cloudfunction';\nexport { default as sourceCloudFunction } from './cloudfunction';\n","import type { RequestBody, EventRequest, CorsOptions, Response } from './types';\n\nexport function isEventRequest(body: RequestBody): body is EventRequest {\n return 'event' in body && typeof body.event === 'string';\n}\n\nexport function setCorsHeaders(\n res: Response,\n corsOptions: boolean | CorsOptions,\n): void {\n if (!corsOptions) return;\n\n if (corsOptions === true) {\n res.set('Access-Control-Allow-Origin', '*');\n res.set('Access-Control-Allow-Methods', 'POST, OPTIONS');\n res.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');\n res.set('Access-Control-Max-Age', '3600');\n } else {\n if (corsOptions.origin) {\n const origin = Array.isArray(corsOptions.origin)\n ? corsOptions.origin.join(', ')\n : corsOptions.origin;\n res.set('Access-Control-Allow-Origin', origin);\n }\n if (corsOptions.methods) {\n res.set('Access-Control-Allow-Methods', corsOptions.methods.join(', '));\n }\n if (corsOptions.headers) {\n res.set('Access-Control-Allow-Headers', corsOptions.headers.join(', '));\n }\n if (corsOptions.credentials) {\n res.set('Access-Control-Allow-Credentials', 'true');\n }\n if (corsOptions.maxAge !== undefined) {\n res.set('Access-Control-Max-Age', corsOptions.maxAge.toString());\n }\n }\n}\n","import type { Collector, WalkerOS } from '@walkeros/core';\nimport type { EventRequest } from './types';\n\nexport async function processEvent(\n eventReq: EventRequest,\n push: Collector.PushFn,\n): Promise<{ id?: string; error?: string }> {\n try {\n const result = await push({\n name: eventReq.event,\n data: (eventReq.data || {}) as WalkerOS.Properties,\n context: eventReq.context as WalkerOS.OrderedProperties | undefined,\n user: eventReq.user as WalkerOS.User | undefined,\n globals: eventReq.globals as WalkerOS.Properties | undefined,\n consent: eventReq.consent as WalkerOS.Consent | undefined,\n });\n\n return { id: result?.event?.id };\n } catch (error) {\n return { error: error instanceof Error ? error.message : 'Unknown error' };\n }\n}\n","import type { WalkerOS, Source as CoreSource } from '@walkeros/core';\nimport type { SettingsSchema, CorsOptionsSchema } from './schemas';\nimport { z } from '@walkeros/core/dev';\n\n// Minimal request/response interfaces\nexport interface Request {\n method: string;\n body?: unknown;\n headers: Record<string, string | string[]>;\n get(name: string): string | undefined;\n}\n\nexport interface Response {\n status(code: number): Response;\n json(body: unknown): Response;\n send(body?: unknown): Response;\n set(key: string, value: string): Response;\n}\n\n// Types inferred from Zod schemas\nexport type Settings = z.infer<typeof SettingsSchema>;\nexport type CorsOptions = z.infer<typeof CorsOptionsSchema>;\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n // Custom source event mapping properties\n}\n\n// CloudFunction-specific push type\nexport type Push = (req: Request, res: Response) => Promise<void>;\n\nexport interface Env extends CoreSource.Env {\n req?: Request;\n res?: Response;\n}\n\n// Type bundle (must be after Settings, Mapping, Push, Env are defined)\nexport type Types = CoreSource.Types<\n Settings,\n Mapping,\n Push,\n Env,\n InitSettings\n>;\n\nexport interface CloudFunctionSource\n extends Omit<CoreSource.Instance<Types>, 'push'> {\n push: Push;\n}\n\n// Convenience Config type\nexport type Config = CoreSource.Config<Types>;\nexport type PartialConfig = CoreSource.PartialConfig<Types>;\n\n// Cloud function source doesn't follow standard Source.Init pattern due to HTTP handler interface\n\nexport interface EventRequest {\n event: string;\n data?: WalkerOS.AnyObject;\n context?: WalkerOS.AnyObject;\n user?: WalkerOS.AnyObject;\n globals?: WalkerOS.AnyObject;\n consent?: WalkerOS.AnyObject;\n}\n\nexport interface EventResponse {\n success: boolean;\n id?: string;\n error?: string;\n}\n\nexport type RequestBody = EventRequest;\nexport type ResponseBody = EventResponse;\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export primitives\nexport * from './primitives';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\n","import { z } from '@walkeros/core/dev';\nimport { CorsOptionsSchema } from './primitives';\n\n/**\n * GCP CloudFunction source settings schema\n */\nexport const SettingsSchema = z.object({\n cors: z\n .union([z.boolean(), CorsOptionsSchema])\n .describe(\n 'CORS configuration: false = disabled, true = allow all origins, object = custom configuration',\n )\n .optional(),\n\n timeout: z\n .number()\n .int()\n .positive()\n .max(540000) // GCP Cloud Functions max timeout: 9 minutes\n .describe('Request timeout in milliseconds (max: 540000 for GCP)')\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * HTTP methods enum\n */\nexport const HttpMethod = z.enum([\n 'GET',\n 'POST',\n 'PUT',\n 'PATCH',\n 'DELETE',\n 'OPTIONS',\n 'HEAD',\n]);\n\n/**\n * CORS origin configuration\n * Accepts:\n * - '*' for all origins\n * - Single URL string\n * - Array of URL strings\n */\nexport const CorsOrigin = z.union([\n z.string(),\n z.array(z.string()),\n z.literal('*'),\n]);\n\n/**\n * CORS options schema\n * Configuration for Cross-Origin Resource Sharing\n */\nexport const CorsOptionsSchema = z.object({\n origin: CorsOrigin.describe(\n 'Allowed origins (* for all, URL string, or array of URLs)',\n ).optional(),\n\n methods: z.array(HttpMethod).describe('Allowed HTTP methods').optional(),\n\n headers: z.array(z.string()).describe('Allowed request headers').optional(),\n\n credentials: z\n .boolean()\n .describe('Allow credentials (cookies, authorization headers)')\n .optional(),\n\n maxAge: z\n .number()\n .int()\n .positive()\n .describe('Preflight cache duration in seconds')\n .optional(),\n});\n\nexport type CorsOptions = z.infer<typeof CorsOptionsSchema>;\n","export * as env from './env';\n","import type { Env } from '../types';\nimport type { Elb } from '@walkeros/core';\n\n/**\n * Example environment configurations for GCP Cloud Function source\n *\n * These environments provide standardized mock structures for testing\n * HTTP request handling without requiring actual cloud function deployment.\n */\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n successful: [],\n queued: [],\n failed: [],\n })) as Elb.Fn;\n return fn;\n};\n\n/**\n * Standard mock environment for testing cloud function source\n *\n * Use this for testing HTTP event ingestion and request/response handling\n * without requiring a real GCP Cloud Function environment.\n */\nexport const push: Env = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n};\n","import type {\n Env,\n CloudFunctionSource,\n Settings,\n EventResponse,\n RequestBody,\n Request,\n Response,\n Mapping,\n Types,\n} from './types';\nimport type { Source } from '@walkeros/core';\nimport { isEventRequest, setCorsHeaders } from './utils';\nimport { processEvent } from './push';\n\nexport * as SourceCloudFunction from './types';\nexport * as schemas from './schemas';\n\n// Export examples\nexport * as examples from './examples';\n\nconst DEFAULT_SETTINGS: Settings = {\n cors: true,\n timeout: 30000,\n};\n\nexport const sourceCloudFunction = async (\n config: Partial<Source.Config<Types>> = {},\n env: Env,\n): Promise<CloudFunctionSource> => {\n const { push: envPush } = env;\n\n const settings: Settings = {\n ...DEFAULT_SETTINGS,\n ...(config.settings || {}),\n };\n\n const fullConfig: Source.Config<Types> = {\n ...config,\n settings,\n };\n\n const push = async (req: Request, res: Response): Promise<void> => {\n try {\n setCorsHeaders(res, settings.cors || false);\n\n if (req.method === 'OPTIONS') {\n res.status(204).send();\n return;\n }\n\n if (req.method !== 'POST') {\n res.status(405).json({\n success: false,\n error: 'Method not allowed. Use POST.',\n });\n return;\n }\n\n if (!req.body) {\n res.status(400).json({\n success: false,\n error: 'Request body is required',\n });\n return;\n }\n\n const body = req.body as RequestBody;\n\n if (isEventRequest(body)) {\n const result = await processEvent(body, envPush);\n\n if (result.error) {\n res.status(400).json({\n success: false,\n error: result.error,\n } as EventResponse);\n } else {\n res.status(200).json({\n success: true,\n id: result.id,\n } as EventResponse);\n }\n } else {\n res.status(400).json({\n success: false,\n error: 'Invalid request format. Expected event object.',\n });\n }\n } catch (error) {\n res.status(500).json({\n success: false,\n error: error instanceof Error ? error.message : 'Internal server error',\n });\n }\n };\n\n return {\n type: 'cloudfunction',\n config: fullConfig,\n push,\n };\n};\n\nexport default sourceCloudFunction;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,SAAS,eAAe,MAAyC;AACtE,SAAO,WAAW,QAAQ,OAAO,KAAK,UAAU;AAClD;AAEO,SAAS,eACd,KACA,aACM;AACN,MAAI,CAAC,YAAa;AAElB,MAAI,gBAAgB,MAAM;AACxB,QAAI,IAAI,+BAA+B,GAAG;AAC1C,QAAI,IAAI,gCAAgC,eAAe;AACvD,QAAI,IAAI,gCAAgC,6BAA6B;AACrE,QAAI,IAAI,0BAA0B,MAAM;AAAA,EAC1C,OAAO;AACL,QAAI,YAAY,QAAQ;AACtB,YAAM,SAAS,MAAM,QAAQ,YAAY,MAAM,IAC3C,YAAY,OAAO,KAAK,IAAI,IAC5B,YAAY;AAChB,UAAI,IAAI,+BAA+B,MAAM;AAAA,IAC/C;AACA,QAAI,YAAY,SAAS;AACvB,UAAI,IAAI,gCAAgC,YAAY,QAAQ,KAAK,IAAI,CAAC;AAAA,IACxE;AACA,QAAI,YAAY,SAAS;AACvB,UAAI,IAAI,gCAAgC,YAAY,QAAQ,KAAK,IAAI,CAAC;AAAA,IACxE;AACA,QAAI,YAAY,aAAa;AAC3B,UAAI,IAAI,oCAAoC,MAAM;AAAA,IACpD;AACA,QAAI,YAAY,WAAW,QAAW;AACpC,UAAI,IAAI,0BAA0B,YAAY,OAAO,SAAS,CAAC;AAAA,IACjE;AAAA,EACF;AACF;;;AClCA,eAAsB,aACpB,UACAA,OAC0C;AAN5C;AAOE,MAAI;AACF,UAAM,SAAS,MAAMA,MAAK;AAAA,MACxB,MAAM,SAAS;AAAA,MACf,MAAO,SAAS,QAAQ,CAAC;AAAA,MACzB,SAAS,SAAS;AAAA,MAClB,MAAM,SAAS;AAAA,MACf,SAAS,SAAS;AAAA,MAClB,SAAS,SAAS;AAAA,IACpB,CAAC;AAED,WAAO,EAAE,KAAI,sCAAQ,UAAR,mBAAe,GAAG;AAAA,EACjC,SAAS,OAAO;AACd,WAAO,EAAE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,gBAAgB;AAAA,EAC3E;AACF;;;ACrBA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAAC,cAA4B;;;ACA5B,IAAAC,cAAkB;;;ACAlB,iBAAkB;AAKX,IAAM,aAAa,aAAE,KAAK;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AASM,IAAM,aAAa,aAAE,MAAM;AAAA,EAChC,aAAE,OAAO;AAAA,EACT,aAAE,MAAM,aAAE,OAAO,CAAC;AAAA,EAClB,aAAE,QAAQ,GAAG;AACf,CAAC;AAMM,IAAM,oBAAoB,aAAE,OAAO;AAAA,EACxC,QAAQ,WAAW;AAAA,IACjB;AAAA,EACF,EAAE,SAAS;AAAA,EAEX,SAAS,aAAE,MAAM,UAAU,EAAE,SAAS,sBAAsB,EAAE,SAAS;AAAA,EAEvE,SAAS,aAAE,MAAM,aAAE,OAAO,CAAC,EAAE,SAAS,yBAAyB,EAAE,SAAS;AAAA,EAE1E,aAAa,aACV,QAAQ,EACR,SAAS,oDAAoD,EAC7D,SAAS;AAAA,EAEZ,QAAQ,aACL,OAAO,EACP,IAAI,EACJ,SAAS,EACT,SAAS,qCAAqC,EAC9C,SAAS;AACd,CAAC;;;AD9CM,IAAM,iBAAiB,cAAE,OAAO;AAAA,EACrC,MAAM,cACH,MAAM,CAAC,cAAE,QAAQ,GAAG,iBAAiB,CAAC,EACtC;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EAEZ,SAAS,cACN,OAAO,EACP,IAAI,EACJ,SAAS,EACT,IAAI,IAAM,EACV,SAAS,uDAAuD,EAChE,SAAS;AACd,CAAC;;;ADXM,IAAM,eAAW,yBAAY,cAAc;;;AGVlD;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAWA,IAAM,kBAAkB,MAAc;AACpC,QAAM,MAAM,MACV,QAAQ,QAAQ;AAAA,IACd,IAAI;AAAA,IACJ,YAAY,CAAC;AAAA,IACb,QAAQ,CAAC;AAAA,IACT,QAAQ,CAAC;AAAA,EACX,CAAC;AACH,SAAO;AACT;AAQO,IAAM,OAAY;AAAA,EACvB,IAAI,OAAO;AACT,WAAO,gBAAgB;AAAA,EACzB;AAAA,EACA,IAAI,UAAU;AACZ,WAAO,gBAAgB;AAAA,EACzB;AAAA,EACA,IAAI,MAAM;AACR,WAAO,gBAAgB;AAAA,EACzB;AACF;;;ACjBA,IAAM,mBAA6B;AAAA,EACjC,MAAM;AAAA,EACN,SAAS;AACX;AAEO,IAAM,sBAAsB,OACjC,SAAwC,CAAC,GACzC,QACiC;AACjC,QAAM,EAAE,MAAM,QAAQ,IAAI;AAE1B,QAAMC,YAAqB;AAAA,IACzB,GAAG;AAAA,IACH,GAAI,OAAO,YAAY,CAAC;AAAA,EAC1B;AAEA,QAAM,aAAmC;AAAA,IACvC,GAAG;AAAA,IACH,UAAAA;AAAA,EACF;AAEA,QAAMC,QAAO,OAAO,KAAc,QAAiC;AACjE,QAAI;AACF,qBAAe,KAAKD,UAAS,QAAQ,KAAK;AAE1C,UAAI,IAAI,WAAW,WAAW;AAC5B,YAAI,OAAO,GAAG,EAAE,KAAK;AACrB;AAAA,MACF;AAEA,UAAI,IAAI,WAAW,QAAQ;AACzB,YAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UACnB,SAAS;AAAA,UACT,OAAO;AAAA,QACT,CAAC;AACD;AAAA,MACF;AAEA,UAAI,CAAC,IAAI,MAAM;AACb,YAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UACnB,SAAS;AAAA,UACT,OAAO;AAAA,QACT,CAAC;AACD;AAAA,MACF;AAEA,YAAM,OAAO,IAAI;AAEjB,UAAI,eAAe,IAAI,GAAG;AACxB,cAAM,SAAS,MAAM,aAAa,MAAM,OAAO;AAE/C,YAAI,OAAO,OAAO;AAChB,cAAI,OAAO,GAAG,EAAE,KAAK;AAAA,YACnB,SAAS;AAAA,YACT,OAAO,OAAO;AAAA,UAChB,CAAkB;AAAA,QACpB,OAAO;AACL,cAAI,OAAO,GAAG,EAAE,KAAK;AAAA,YACnB,SAAS;AAAA,YACT,IAAI,OAAO;AAAA,UACb,CAAkB;AAAA,QACpB;AAAA,MACF,OAAO;AACL,YAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UACnB,SAAS;AAAA,UACT,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA,IACF,SAAS,OAAO;AACd,UAAI,OAAO,GAAG,EAAE,KAAK;AAAA,QACnB,SAAS;AAAA,QACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAClD,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,MAAAC;AAAA,EACF;AACF;AAEA,IAAO,wBAAQ;","names":["push","import_dev","import_dev","settings","push"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/cloudfunction/utils.ts","../src/cloudfunction/push.ts","../src/cloudfunction/types.ts","../src/cloudfunction/schemas/index.ts","../src/cloudfunction/schemas/settings.ts","../src/cloudfunction/schemas/primitives.ts","../src/cloudfunction/examples/index.ts","../src/cloudfunction/examples/env.ts","../src/cloudfunction/index.ts"],"sourcesContent":["export * from './cloudfunction';\nexport { default as sourceCloudFunction } from './cloudfunction';\n","import type { RequestBody, EventRequest, CorsOptions, Response } from './types';\n\nexport function isEventRequest(body: RequestBody): body is EventRequest {\n return 'event' in body && typeof body.event === 'string';\n}\n\nexport function setCorsHeaders(\n res: Response,\n corsOptions: boolean | CorsOptions,\n): void {\n if (!corsOptions) return;\n\n if (corsOptions === true) {\n res.set('Access-Control-Allow-Origin', '*');\n res.set('Access-Control-Allow-Methods', 'POST, OPTIONS');\n res.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');\n res.set('Access-Control-Max-Age', '3600');\n } else {\n if (corsOptions.origin) {\n const origin = Array.isArray(corsOptions.origin)\n ? corsOptions.origin.join(', ')\n : corsOptions.origin;\n res.set('Access-Control-Allow-Origin', origin);\n }\n if (corsOptions.methods) {\n res.set('Access-Control-Allow-Methods', corsOptions.methods.join(', '));\n }\n if (corsOptions.headers) {\n res.set('Access-Control-Allow-Headers', corsOptions.headers.join(', '));\n }\n if (corsOptions.credentials) {\n res.set('Access-Control-Allow-Credentials', 'true');\n }\n if (corsOptions.maxAge !== undefined) {\n res.set('Access-Control-Max-Age', corsOptions.maxAge.toString());\n }\n }\n}\n","import type { Collector, WalkerOS } from '@walkeros/core';\nimport type { EventRequest } from './types';\n\nexport async function processEvent(\n eventReq: EventRequest,\n push: Collector.PushFn,\n): Promise<{ id?: string; error?: string }> {\n try {\n const result = await push({\n name: eventReq.event,\n data: (eventReq.data || {}) as WalkerOS.Properties,\n context: eventReq.context as WalkerOS.OrderedProperties | undefined,\n user: eventReq.user as WalkerOS.User | undefined,\n globals: eventReq.globals as WalkerOS.Properties | undefined,\n consent: eventReq.consent as WalkerOS.Consent | undefined,\n });\n\n return { id: result?.event?.id };\n } catch (error) {\n return { error: error instanceof Error ? error.message : 'Unknown error' };\n }\n}\n","import type { WalkerOS, Source as CoreSource } from '@walkeros/core';\nimport type { SettingsSchema, CorsOptionsSchema } from './schemas';\nimport { z } from '@walkeros/core/dev';\n\n// Minimal request/response interfaces\nexport interface Request {\n method: string;\n body?: unknown;\n headers: Record<string, string | string[]>;\n get(name: string): string | undefined;\n}\n\nexport interface Response {\n status(code: number): Response;\n json(body: unknown): Response;\n send(body?: unknown): Response;\n set(key: string, value: string): Response;\n}\n\n// Types inferred from Zod schemas\nexport type Settings = z.infer<typeof SettingsSchema>;\nexport type CorsOptions = z.infer<typeof CorsOptionsSchema>;\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n // Custom source event mapping properties\n}\n\n// CloudFunction-specific push type\nexport type Push = (req: Request, res: Response) => Promise<void>;\n\nexport interface Env extends CoreSource.Env {\n req?: Request;\n res?: Response;\n}\n\n// Type bundle (must be after Settings, Mapping, Push, Env are defined)\nexport type Types = CoreSource.Types<\n Settings,\n Mapping,\n Push,\n Env,\n InitSettings\n>;\n\nexport interface CloudFunctionSource\n extends Omit<CoreSource.Instance<Types>, 'push'> {\n push: Push;\n}\n\n// Convenience Config type\nexport type Config = CoreSource.Config<Types>;\nexport type PartialConfig = CoreSource.PartialConfig<Types>;\n\n// Cloud function source doesn't follow standard Source.Init pattern due to HTTP handler interface\n\nexport interface EventRequest {\n event: string;\n data?: WalkerOS.AnyObject;\n context?: WalkerOS.AnyObject;\n user?: WalkerOS.AnyObject;\n globals?: WalkerOS.AnyObject;\n consent?: WalkerOS.AnyObject;\n}\n\nexport interface EventResponse {\n success: boolean;\n id?: string;\n error?: string;\n}\n\nexport type RequestBody = EventRequest;\nexport type ResponseBody = EventResponse;\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export primitives\nexport * from './primitives';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\n","import { z } from '@walkeros/core/dev';\nimport { CorsOptionsSchema } from './primitives';\n\n/**\n * GCP CloudFunction source settings schema\n */\nexport const SettingsSchema = z.object({\n cors: z\n .union([z.boolean(), CorsOptionsSchema])\n .describe(\n 'CORS configuration: false = disabled, true = allow all origins, object = custom configuration',\n )\n .optional(),\n\n timeout: z\n .number()\n .int()\n .positive()\n .max(540000) // GCP Cloud Functions max timeout: 9 minutes\n .describe('Request timeout in milliseconds (max: 540000 for GCP)')\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * HTTP methods enum\n */\nexport const HttpMethod = z.enum([\n 'GET',\n 'POST',\n 'PUT',\n 'PATCH',\n 'DELETE',\n 'OPTIONS',\n 'HEAD',\n]);\n\n/**\n * CORS origin configuration\n * Accepts:\n * - '*' for all origins\n * - Single URL string\n * - Array of URL strings\n */\nexport const CorsOrigin = z.union([\n z.string(),\n z.array(z.string()),\n z.literal('*'),\n]);\n\n/**\n * CORS options schema\n * Configuration for Cross-Origin Resource Sharing\n */\nexport const CorsOptionsSchema = z.object({\n origin: CorsOrigin.describe(\n 'Allowed origins (* for all, URL string, or array of URLs)',\n ).optional(),\n\n methods: z.array(HttpMethod).describe('Allowed HTTP methods').optional(),\n\n headers: z.array(z.string()).describe('Allowed request headers').optional(),\n\n credentials: z\n .boolean()\n .describe('Allow credentials (cookies, authorization headers)')\n .optional(),\n\n maxAge: z\n .number()\n .int()\n .positive()\n .describe('Preflight cache duration in seconds')\n .optional(),\n});\n\nexport type CorsOptions = z.infer<typeof CorsOptionsSchema>;\n","export * as env from './env';\n","import type { Env } from '../types';\nimport type { Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for GCP Cloud Function source\n *\n * These environments provide standardized mock structures for testing\n * HTTP request handling without requiring actual cloud function deployment.\n */\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n successful: [],\n queued: [],\n failed: [],\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopFn = () => {};\nconst noopLogger: Logger.Instance = {\n error: noopFn,\n info: noopFn,\n debug: noopFn,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n scope: () => noopLogger,\n};\n\n/**\n * Standard mock environment for testing cloud function source\n *\n * Use this for testing HTTP event ingestion and request/response handling\n * without requiring a real GCP Cloud Function environment.\n */\nexport const push: Env = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n logger: noopLogger,\n};\n","import type {\n Env,\n CloudFunctionSource,\n Settings,\n EventResponse,\n RequestBody,\n Request,\n Response,\n Mapping,\n Types,\n} from './types';\nimport type { Source } from '@walkeros/core';\nimport { isEventRequest, setCorsHeaders } from './utils';\nimport { processEvent } from './push';\n\nexport * as SourceCloudFunction from './types';\nexport * as schemas from './schemas';\n\n// Export examples\nexport * as examples from './examples';\n\nconst DEFAULT_SETTINGS: Settings = {\n cors: true,\n timeout: 30000,\n};\n\nexport const sourceCloudFunction = async (\n config: Partial<Source.Config<Types>> = {},\n env: Env,\n): Promise<CloudFunctionSource> => {\n const { push: envPush } = env;\n\n const settings: Settings = {\n ...DEFAULT_SETTINGS,\n ...(config.settings || {}),\n };\n\n const fullConfig: Source.Config<Types> = {\n ...config,\n settings,\n };\n\n const push = async (req: Request, res: Response): Promise<void> => {\n try {\n setCorsHeaders(res, settings.cors || false);\n\n if (req.method === 'OPTIONS') {\n res.status(204).send();\n return;\n }\n\n if (req.method !== 'POST') {\n res.status(405).json({\n success: false,\n error: 'Method not allowed. Use POST.',\n });\n return;\n }\n\n if (!req.body) {\n res.status(400).json({\n success: false,\n error: 'Request body is required',\n });\n return;\n }\n\n const body = req.body as RequestBody;\n\n if (isEventRequest(body)) {\n const result = await processEvent(body, envPush);\n\n if (result.error) {\n res.status(400).json({\n success: false,\n error: result.error,\n } as EventResponse);\n } else {\n res.status(200).json({\n success: true,\n id: result.id,\n } as EventResponse);\n }\n } else {\n res.status(400).json({\n success: false,\n error: 'Invalid request format. Expected event object.',\n });\n }\n } catch (error) {\n res.status(500).json({\n success: false,\n error: error instanceof Error ? error.message : 'Internal server error',\n });\n }\n };\n\n return {\n type: 'cloudfunction',\n config: fullConfig,\n push,\n };\n};\n\nexport default sourceCloudFunction;\n"],"mappings":"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","names":["push","import_dev","import_dev","settings","push"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=Object.defineProperty,o=(o,
|
|
1
|
+
var e=Object.defineProperty,o=(o,r)=>{for(var s in r)e(o,s,{get:r[s],enumerable:!0})};var r={},s={};o(s,{CorsOptionsSchema:()=>l,CorsOrigin:()=>c,HttpMethod:()=>a,SettingsSchema:()=>u,settings:()=>d});import{zodToSchema as t}from"@walkeros/core/dev";import{z as n}from"@walkeros/core/dev";import{z as i}from"@walkeros/core/dev";var a=i.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),c=i.union([i.string(),i.array(i.string()),i.literal("*")]),l=i.object({origin:c.describe("Allowed origins (* for all, URL string, or array of URLs)").optional(),methods:i.array(a).describe("Allowed HTTP methods").optional(),headers:i.array(i.string()).describe("Allowed request headers").optional(),credentials:i.boolean().describe("Allow credentials (cookies, authorization headers)").optional(),maxAge:i.number().int().positive().describe("Preflight cache duration in seconds").optional()}),u=n.object({cors:n.union([n.boolean(),l]).describe("CORS configuration: false = disabled, true = allow all origins, object = custom configuration").optional(),timeout:n.number().int().positive().max(54e4).describe("Request timeout in milliseconds (max: 540000 for GCP)").optional()}),d=t(u),g={};o(g,{env:()=>m});var m={};o(m,{push:()=>p});var f=()=>()=>Promise.resolve({ok:!0,successful:[],queued:[],failed:[]}),h=()=>{},A={error:h,info:h,debug:h,throw:e=>{throw"string"==typeof e?new Error(e):e},scope:()=>A},p={get push(){return f()},get command(){return f()},get elb(){return f()},logger:A},v={cors:!0,timeout:3e4},b=async(e={},o)=>{const{push:r}=o,s={...v,...e.settings||{}};return{type:"cloudfunction",config:{...e,settings:s},push:async(e,o)=>{try{if(function(e,o){if(o)if(!0===o)e.set("Access-Control-Allow-Origin","*"),e.set("Access-Control-Allow-Methods","POST, OPTIONS"),e.set("Access-Control-Allow-Headers","Content-Type, Authorization"),e.set("Access-Control-Max-Age","3600");else{if(o.origin){const r=Array.isArray(o.origin)?o.origin.join(", "):o.origin;e.set("Access-Control-Allow-Origin",r)}o.methods&&e.set("Access-Control-Allow-Methods",o.methods.join(", ")),o.headers&&e.set("Access-Control-Allow-Headers",o.headers.join(", ")),o.credentials&&e.set("Access-Control-Allow-Credentials","true"),void 0!==o.maxAge&&e.set("Access-Control-Max-Age",o.maxAge.toString())}}(o,s.cors||!1),"OPTIONS"===e.method)return void o.status(204).send();if("POST"!==e.method)return void o.status(405).json({success:!1,error:"Method not allowed. Use POST."});if(!e.body)return void o.status(400).json({success:!1,error:"Request body is required"});const t=e.body;if(function(e){return"event"in e&&"string"==typeof e.event}(t)){const e=await async function(e,o){var r;try{const s=await o({name:e.event,data:e.data||{},context:e.context,user:e.user,globals:e.globals,consent:e.consent});return{id:null==(r=null==s?void 0:s.event)?void 0:r.id}}catch(e){return{error:e instanceof Error?e.message:"Unknown error"}}}(t,r);e.error?o.status(400).json({success:!1,error:e.error}):o.status(200).json({success:!0,id:e.id})}else o.status(400).json({success:!1,error:"Invalid request format. Expected event object."})}catch(e){o.status(500).json({success:!1,error:e instanceof Error?e.message:"Internal server error"})}}}};export{r as SourceCloudFunction,g as examples,s as schemas,b as sourceCloudFunction};//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cloudfunction/utils.ts","../src/cloudfunction/push.ts","../src/cloudfunction/types.ts","../src/cloudfunction/schemas/index.ts","../src/cloudfunction/schemas/settings.ts","../src/cloudfunction/schemas/primitives.ts","../src/cloudfunction/examples/index.ts","../src/cloudfunction/examples/env.ts","../src/cloudfunction/index.ts"],"sourcesContent":["import type { RequestBody, EventRequest, CorsOptions, Response } from './types';\n\nexport function isEventRequest(body: RequestBody): body is EventRequest {\n return 'event' in body && typeof body.event === 'string';\n}\n\nexport function setCorsHeaders(\n res: Response,\n corsOptions: boolean | CorsOptions,\n): void {\n if (!corsOptions) return;\n\n if (corsOptions === true) {\n res.set('Access-Control-Allow-Origin', '*');\n res.set('Access-Control-Allow-Methods', 'POST, OPTIONS');\n res.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');\n res.set('Access-Control-Max-Age', '3600');\n } else {\n if (corsOptions.origin) {\n const origin = Array.isArray(corsOptions.origin)\n ? corsOptions.origin.join(', ')\n : corsOptions.origin;\n res.set('Access-Control-Allow-Origin', origin);\n }\n if (corsOptions.methods) {\n res.set('Access-Control-Allow-Methods', corsOptions.methods.join(', '));\n }\n if (corsOptions.headers) {\n res.set('Access-Control-Allow-Headers', corsOptions.headers.join(', '));\n }\n if (corsOptions.credentials) {\n res.set('Access-Control-Allow-Credentials', 'true');\n }\n if (corsOptions.maxAge !== undefined) {\n res.set('Access-Control-Max-Age', corsOptions.maxAge.toString());\n }\n }\n}\n","import type { Collector, WalkerOS } from '@walkeros/core';\nimport type { EventRequest } from './types';\n\nexport async function processEvent(\n eventReq: EventRequest,\n push: Collector.PushFn,\n): Promise<{ id?: string; error?: string }> {\n try {\n const result = await push({\n name: eventReq.event,\n data: (eventReq.data || {}) as WalkerOS.Properties,\n context: eventReq.context as WalkerOS.OrderedProperties | undefined,\n user: eventReq.user as WalkerOS.User | undefined,\n globals: eventReq.globals as WalkerOS.Properties | undefined,\n consent: eventReq.consent as WalkerOS.Consent | undefined,\n });\n\n return { id: result?.event?.id };\n } catch (error) {\n return { error: error instanceof Error ? error.message : 'Unknown error' };\n }\n}\n","import type { WalkerOS, Source as CoreSource } from '@walkeros/core';\nimport type { SettingsSchema, CorsOptionsSchema } from './schemas';\nimport { z } from '@walkeros/core/dev';\n\n// Minimal request/response interfaces\nexport interface Request {\n method: string;\n body?: unknown;\n headers: Record<string, string | string[]>;\n get(name: string): string | undefined;\n}\n\nexport interface Response {\n status(code: number): Response;\n json(body: unknown): Response;\n send(body?: unknown): Response;\n set(key: string, value: string): Response;\n}\n\n// Types inferred from Zod schemas\nexport type Settings = z.infer<typeof SettingsSchema>;\nexport type CorsOptions = z.infer<typeof CorsOptionsSchema>;\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n // Custom source event mapping properties\n}\n\n// CloudFunction-specific push type\nexport type Push = (req: Request, res: Response) => Promise<void>;\n\nexport interface Env extends CoreSource.Env {\n req?: Request;\n res?: Response;\n}\n\n// Type bundle (must be after Settings, Mapping, Push, Env are defined)\nexport type Types = CoreSource.Types<\n Settings,\n Mapping,\n Push,\n Env,\n InitSettings\n>;\n\nexport interface CloudFunctionSource\n extends Omit<CoreSource.Instance<Types>, 'push'> {\n push: Push;\n}\n\n// Convenience Config type\nexport type Config = CoreSource.Config<Types>;\nexport type PartialConfig = CoreSource.PartialConfig<Types>;\n\n// Cloud function source doesn't follow standard Source.Init pattern due to HTTP handler interface\n\nexport interface EventRequest {\n event: string;\n data?: WalkerOS.AnyObject;\n context?: WalkerOS.AnyObject;\n user?: WalkerOS.AnyObject;\n globals?: WalkerOS.AnyObject;\n consent?: WalkerOS.AnyObject;\n}\n\nexport interface EventResponse {\n success: boolean;\n id?: string;\n error?: string;\n}\n\nexport type RequestBody = EventRequest;\nexport type ResponseBody = EventResponse;\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export primitives\nexport * from './primitives';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\n","import { z } from '@walkeros/core/dev';\nimport { CorsOptionsSchema } from './primitives';\n\n/**\n * GCP CloudFunction source settings schema\n */\nexport const SettingsSchema = z.object({\n cors: z\n .union([z.boolean(), CorsOptionsSchema])\n .describe(\n 'CORS configuration: false = disabled, true = allow all origins, object = custom configuration',\n )\n .optional(),\n\n timeout: z\n .number()\n .int()\n .positive()\n .max(540000) // GCP Cloud Functions max timeout: 9 minutes\n .describe('Request timeout in milliseconds (max: 540000 for GCP)')\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * HTTP methods enum\n */\nexport const HttpMethod = z.enum([\n 'GET',\n 'POST',\n 'PUT',\n 'PATCH',\n 'DELETE',\n 'OPTIONS',\n 'HEAD',\n]);\n\n/**\n * CORS origin configuration\n * Accepts:\n * - '*' for all origins\n * - Single URL string\n * - Array of URL strings\n */\nexport const CorsOrigin = z.union([\n z.string(),\n z.array(z.string()),\n z.literal('*'),\n]);\n\n/**\n * CORS options schema\n * Configuration for Cross-Origin Resource Sharing\n */\nexport const CorsOptionsSchema = z.object({\n origin: CorsOrigin.describe(\n 'Allowed origins (* for all, URL string, or array of URLs)',\n ).optional(),\n\n methods: z.array(HttpMethod).describe('Allowed HTTP methods').optional(),\n\n headers: z.array(z.string()).describe('Allowed request headers').optional(),\n\n credentials: z\n .boolean()\n .describe('Allow credentials (cookies, authorization headers)')\n .optional(),\n\n maxAge: z\n .number()\n .int()\n .positive()\n .describe('Preflight cache duration in seconds')\n .optional(),\n});\n\nexport type CorsOptions = z.infer<typeof CorsOptionsSchema>;\n","export * as env from './env';\n","import type { Env } from '../types';\nimport type { Elb } from '@walkeros/core';\n\n/**\n * Example environment configurations for GCP Cloud Function source\n *\n * These environments provide standardized mock structures for testing\n * HTTP request handling without requiring actual cloud function deployment.\n */\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n successful: [],\n queued: [],\n failed: [],\n })) as Elb.Fn;\n return fn;\n};\n\n/**\n * Standard mock environment for testing cloud function source\n *\n * Use this for testing HTTP event ingestion and request/response handling\n * without requiring a real GCP Cloud Function environment.\n */\nexport const push: Env = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n};\n","import type {\n Env,\n CloudFunctionSource,\n Settings,\n EventResponse,\n RequestBody,\n Request,\n Response,\n Mapping,\n Types,\n} from './types';\nimport type { Source } from '@walkeros/core';\nimport { isEventRequest, setCorsHeaders } from './utils';\nimport { processEvent } from './push';\n\nexport * as SourceCloudFunction from './types';\nexport * as schemas from './schemas';\n\n// Export examples\nexport * as examples from './examples';\n\nconst DEFAULT_SETTINGS: Settings = {\n cors: true,\n timeout: 30000,\n};\n\nexport const sourceCloudFunction = async (\n config: Partial<Source.Config<Types>> = {},\n env: Env,\n): Promise<CloudFunctionSource> => {\n const { push: envPush } = env;\n\n const settings: Settings = {\n ...DEFAULT_SETTINGS,\n ...(config.settings || {}),\n };\n\n const fullConfig: Source.Config<Types> = {\n ...config,\n settings,\n };\n\n const push = async (req: Request, res: Response): Promise<void> => {\n try {\n setCorsHeaders(res, settings.cors || false);\n\n if (req.method === 'OPTIONS') {\n res.status(204).send();\n return;\n }\n\n if (req.method !== 'POST') {\n res.status(405).json({\n success: false,\n error: 'Method not allowed. Use POST.',\n });\n return;\n }\n\n if (!req.body) {\n res.status(400).json({\n success: false,\n error: 'Request body is required',\n });\n return;\n }\n\n const body = req.body as RequestBody;\n\n if (isEventRequest(body)) {\n const result = await processEvent(body, envPush);\n\n if (result.error) {\n res.status(400).json({\n success: false,\n error: result.error,\n } as EventResponse);\n } else {\n res.status(200).json({\n success: true,\n id: result.id,\n } as EventResponse);\n }\n } else {\n res.status(400).json({\n success: false,\n error: 'Invalid request format. Expected event object.',\n });\n }\n } catch (error) {\n res.status(500).json({\n success: false,\n error: error instanceof Error ? error.message : 'Internal server error',\n });\n }\n };\n\n return {\n type: 'cloudfunction',\n config: fullConfig,\n push,\n };\n};\n\nexport default sourceCloudFunction;\n"],"mappings":"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","names":["push","z","z","settings","push"]}
|
|
1
|
+
{"version":3,"sources":["../src/cloudfunction/utils.ts","../src/cloudfunction/push.ts","../src/cloudfunction/types.ts","../src/cloudfunction/schemas/index.ts","../src/cloudfunction/schemas/settings.ts","../src/cloudfunction/schemas/primitives.ts","../src/cloudfunction/examples/index.ts","../src/cloudfunction/examples/env.ts","../src/cloudfunction/index.ts"],"sourcesContent":["import type { RequestBody, EventRequest, CorsOptions, Response } from './types';\n\nexport function isEventRequest(body: RequestBody): body is EventRequest {\n return 'event' in body && typeof body.event === 'string';\n}\n\nexport function setCorsHeaders(\n res: Response,\n corsOptions: boolean | CorsOptions,\n): void {\n if (!corsOptions) return;\n\n if (corsOptions === true) {\n res.set('Access-Control-Allow-Origin', '*');\n res.set('Access-Control-Allow-Methods', 'POST, OPTIONS');\n res.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');\n res.set('Access-Control-Max-Age', '3600');\n } else {\n if (corsOptions.origin) {\n const origin = Array.isArray(corsOptions.origin)\n ? corsOptions.origin.join(', ')\n : corsOptions.origin;\n res.set('Access-Control-Allow-Origin', origin);\n }\n if (corsOptions.methods) {\n res.set('Access-Control-Allow-Methods', corsOptions.methods.join(', '));\n }\n if (corsOptions.headers) {\n res.set('Access-Control-Allow-Headers', corsOptions.headers.join(', '));\n }\n if (corsOptions.credentials) {\n res.set('Access-Control-Allow-Credentials', 'true');\n }\n if (corsOptions.maxAge !== undefined) {\n res.set('Access-Control-Max-Age', corsOptions.maxAge.toString());\n }\n }\n}\n","import type { Collector, WalkerOS } from '@walkeros/core';\nimport type { EventRequest } from './types';\n\nexport async function processEvent(\n eventReq: EventRequest,\n push: Collector.PushFn,\n): Promise<{ id?: string; error?: string }> {\n try {\n const result = await push({\n name: eventReq.event,\n data: (eventReq.data || {}) as WalkerOS.Properties,\n context: eventReq.context as WalkerOS.OrderedProperties | undefined,\n user: eventReq.user as WalkerOS.User | undefined,\n globals: eventReq.globals as WalkerOS.Properties | undefined,\n consent: eventReq.consent as WalkerOS.Consent | undefined,\n });\n\n return { id: result?.event?.id };\n } catch (error) {\n return { error: error instanceof Error ? error.message : 'Unknown error' };\n }\n}\n","import type { WalkerOS, Source as CoreSource } from '@walkeros/core';\nimport type { SettingsSchema, CorsOptionsSchema } from './schemas';\nimport { z } from '@walkeros/core/dev';\n\n// Minimal request/response interfaces\nexport interface Request {\n method: string;\n body?: unknown;\n headers: Record<string, string | string[]>;\n get(name: string): string | undefined;\n}\n\nexport interface Response {\n status(code: number): Response;\n json(body: unknown): Response;\n send(body?: unknown): Response;\n set(key: string, value: string): Response;\n}\n\n// Types inferred from Zod schemas\nexport type Settings = z.infer<typeof SettingsSchema>;\nexport type CorsOptions = z.infer<typeof CorsOptionsSchema>;\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n // Custom source event mapping properties\n}\n\n// CloudFunction-specific push type\nexport type Push = (req: Request, res: Response) => Promise<void>;\n\nexport interface Env extends CoreSource.Env {\n req?: Request;\n res?: Response;\n}\n\n// Type bundle (must be after Settings, Mapping, Push, Env are defined)\nexport type Types = CoreSource.Types<\n Settings,\n Mapping,\n Push,\n Env,\n InitSettings\n>;\n\nexport interface CloudFunctionSource\n extends Omit<CoreSource.Instance<Types>, 'push'> {\n push: Push;\n}\n\n// Convenience Config type\nexport type Config = CoreSource.Config<Types>;\nexport type PartialConfig = CoreSource.PartialConfig<Types>;\n\n// Cloud function source doesn't follow standard Source.Init pattern due to HTTP handler interface\n\nexport interface EventRequest {\n event: string;\n data?: WalkerOS.AnyObject;\n context?: WalkerOS.AnyObject;\n user?: WalkerOS.AnyObject;\n globals?: WalkerOS.AnyObject;\n consent?: WalkerOS.AnyObject;\n}\n\nexport interface EventResponse {\n success: boolean;\n id?: string;\n error?: string;\n}\n\nexport type RequestBody = EventRequest;\nexport type ResponseBody = EventResponse;\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export primitives\nexport * from './primitives';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\n","import { z } from '@walkeros/core/dev';\nimport { CorsOptionsSchema } from './primitives';\n\n/**\n * GCP CloudFunction source settings schema\n */\nexport const SettingsSchema = z.object({\n cors: z\n .union([z.boolean(), CorsOptionsSchema])\n .describe(\n 'CORS configuration: false = disabled, true = allow all origins, object = custom configuration',\n )\n .optional(),\n\n timeout: z\n .number()\n .int()\n .positive()\n .max(540000) // GCP Cloud Functions max timeout: 9 minutes\n .describe('Request timeout in milliseconds (max: 540000 for GCP)')\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * HTTP methods enum\n */\nexport const HttpMethod = z.enum([\n 'GET',\n 'POST',\n 'PUT',\n 'PATCH',\n 'DELETE',\n 'OPTIONS',\n 'HEAD',\n]);\n\n/**\n * CORS origin configuration\n * Accepts:\n * - '*' for all origins\n * - Single URL string\n * - Array of URL strings\n */\nexport const CorsOrigin = z.union([\n z.string(),\n z.array(z.string()),\n z.literal('*'),\n]);\n\n/**\n * CORS options schema\n * Configuration for Cross-Origin Resource Sharing\n */\nexport const CorsOptionsSchema = z.object({\n origin: CorsOrigin.describe(\n 'Allowed origins (* for all, URL string, or array of URLs)',\n ).optional(),\n\n methods: z.array(HttpMethod).describe('Allowed HTTP methods').optional(),\n\n headers: z.array(z.string()).describe('Allowed request headers').optional(),\n\n credentials: z\n .boolean()\n .describe('Allow credentials (cookies, authorization headers)')\n .optional(),\n\n maxAge: z\n .number()\n .int()\n .positive()\n .describe('Preflight cache duration in seconds')\n .optional(),\n});\n\nexport type CorsOptions = z.infer<typeof CorsOptionsSchema>;\n","export * as env from './env';\n","import type { Env } from '../types';\nimport type { Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for GCP Cloud Function source\n *\n * These environments provide standardized mock structures for testing\n * HTTP request handling without requiring actual cloud function deployment.\n */\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n successful: [],\n queued: [],\n failed: [],\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopFn = () => {};\nconst noopLogger: Logger.Instance = {\n error: noopFn,\n info: noopFn,\n debug: noopFn,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n scope: () => noopLogger,\n};\n\n/**\n * Standard mock environment for testing cloud function source\n *\n * Use this for testing HTTP event ingestion and request/response handling\n * without requiring a real GCP Cloud Function environment.\n */\nexport const push: Env = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n logger: noopLogger,\n};\n","import type {\n Env,\n CloudFunctionSource,\n Settings,\n EventResponse,\n RequestBody,\n Request,\n Response,\n Mapping,\n Types,\n} from './types';\nimport type { Source } from '@walkeros/core';\nimport { isEventRequest, setCorsHeaders } from './utils';\nimport { processEvent } from './push';\n\nexport * as SourceCloudFunction from './types';\nexport * as schemas from './schemas';\n\n// Export examples\nexport * as examples from './examples';\n\nconst DEFAULT_SETTINGS: Settings = {\n cors: true,\n timeout: 30000,\n};\n\nexport const sourceCloudFunction = async (\n config: Partial<Source.Config<Types>> = {},\n env: Env,\n): Promise<CloudFunctionSource> => {\n const { push: envPush } = env;\n\n const settings: Settings = {\n ...DEFAULT_SETTINGS,\n ...(config.settings || {}),\n };\n\n const fullConfig: Source.Config<Types> = {\n ...config,\n settings,\n };\n\n const push = async (req: Request, res: Response): Promise<void> => {\n try {\n setCorsHeaders(res, settings.cors || false);\n\n if (req.method === 'OPTIONS') {\n res.status(204).send();\n return;\n }\n\n if (req.method !== 'POST') {\n res.status(405).json({\n success: false,\n error: 'Method not allowed. Use POST.',\n });\n return;\n }\n\n if (!req.body) {\n res.status(400).json({\n success: false,\n error: 'Request body is required',\n });\n return;\n }\n\n const body = req.body as RequestBody;\n\n if (isEventRequest(body)) {\n const result = await processEvent(body, envPush);\n\n if (result.error) {\n res.status(400).json({\n success: false,\n error: result.error,\n } as EventResponse);\n } else {\n res.status(200).json({\n success: true,\n id: result.id,\n } as EventResponse);\n }\n } else {\n res.status(400).json({\n success: false,\n error: 'Invalid request format. Expected event object.',\n });\n }\n } catch (error) {\n res.status(500).json({\n success: false,\n error: error instanceof Error ? error.message : 'Internal server error',\n });\n }\n };\n\n return {\n type: 'cloudfunction',\n config: fullConfig,\n push,\n };\n};\n\nexport default sourceCloudFunction;\n"],"mappings":";;;;;;;AAEO,SAAS,eAAe,MAAyC;AACtE,SAAO,WAAW,QAAQ,OAAO,KAAK,UAAU;AAClD;AAEO,SAAS,eACd,KACA,aACM;AACN,MAAI,CAAC,YAAa;AAElB,MAAI,gBAAgB,MAAM;AACxB,QAAI,IAAI,+BAA+B,GAAG;AAC1C,QAAI,IAAI,gCAAgC,eAAe;AACvD,QAAI,IAAI,gCAAgC,6BAA6B;AACrE,QAAI,IAAI,0BAA0B,MAAM;AAAA,EAC1C,OAAO;AACL,QAAI,YAAY,QAAQ;AACtB,YAAM,SAAS,MAAM,QAAQ,YAAY,MAAM,IAC3C,YAAY,OAAO,KAAK,IAAI,IAC5B,YAAY;AAChB,UAAI,IAAI,+BAA+B,MAAM;AAAA,IAC/C;AACA,QAAI,YAAY,SAAS;AACvB,UAAI,IAAI,gCAAgC,YAAY,QAAQ,KAAK,IAAI,CAAC;AAAA,IACxE;AACA,QAAI,YAAY,SAAS;AACvB,UAAI,IAAI,gCAAgC,YAAY,QAAQ,KAAK,IAAI,CAAC;AAAA,IACxE;AACA,QAAI,YAAY,aAAa;AAC3B,UAAI,IAAI,oCAAoC,MAAM;AAAA,IACpD;AACA,QAAI,YAAY,WAAW,QAAW;AACpC,UAAI,IAAI,0BAA0B,YAAY,OAAO,SAAS,CAAC;AAAA,IACjE;AAAA,EACF;AACF;;;AClCA,eAAsB,aACpB,UACAA,OAC0C;AAN5C;AAOE,MAAI;AACF,UAAM,SAAS,MAAMA,MAAK;AAAA,MACxB,MAAM,SAAS;AAAA,MACf,MAAO,SAAS,QAAQ,CAAC;AAAA,MACzB,SAAS,SAAS;AAAA,MAClB,MAAM,SAAS;AAAA,MACf,SAAS,SAAS;AAAA,MAClB,SAAS,SAAS;AAAA,IACpB,CAAC;AAED,WAAO,EAAE,KAAI,sCAAQ,UAAR,mBAAe,GAAG;AAAA,EACjC,SAAS,OAAO;AACd,WAAO,EAAE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,gBAAgB;AAAA,EAC3E;AACF;;;ACrBA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAS,mBAAmB;;;ACA5B,SAAS,KAAAC,UAAS;;;ACAlB,SAAS,SAAS;AAKX,IAAM,aAAa,EAAE,KAAK;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AASM,IAAM,aAAa,EAAE,MAAM;AAAA,EAChC,EAAE,OAAO;AAAA,EACT,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,EAClB,EAAE,QAAQ,GAAG;AACf,CAAC;AAMM,IAAM,oBAAoB,EAAE,OAAO;AAAA,EACxC,QAAQ,WAAW;AAAA,IACjB;AAAA,EACF,EAAE,SAAS;AAAA,EAEX,SAAS,EAAE,MAAM,UAAU,EAAE,SAAS,sBAAsB,EAAE,SAAS;AAAA,EAEvE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,yBAAyB,EAAE,SAAS;AAAA,EAE1E,aAAa,EACV,QAAQ,EACR,SAAS,oDAAoD,EAC7D,SAAS;AAAA,EAEZ,QAAQ,EACL,OAAO,EACP,IAAI,EACJ,SAAS,EACT,SAAS,qCAAqC,EAC9C,SAAS;AACd,CAAC;;;AD9CM,IAAM,iBAAiBC,GAAE,OAAO;AAAA,EACrC,MAAMA,GACH,MAAM,CAACA,GAAE,QAAQ,GAAG,iBAAiB,CAAC,EACtC;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EAEZ,SAASA,GACN,OAAO,EACP,IAAI,EACJ,SAAS,EACT,IAAI,IAAM,EACV,SAAS,uDAAuD,EAChE,SAAS;AACd,CAAC;;;ADXM,IAAM,WAAW,YAAY,cAAc;;;AGVlD;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAWA,IAAM,kBAAkB,MAAc;AACpC,QAAM,MAAM,MACV,QAAQ,QAAQ;AAAA,IACd,IAAI;AAAA,IACJ,YAAY,CAAC;AAAA,IACb,QAAQ,CAAC;AAAA,IACT,QAAQ,CAAC;AAAA,EACX,CAAC;AACH,SAAO;AACT;AAGA,IAAM,SAAS,MAAM;AAAC;AACtB,IAAM,aAA8B;AAAA,EAClC,OAAO;AAAA,EACP,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO,CAAC,YAA4B;AAClC,UAAM,OAAO,YAAY,WAAW,IAAI,MAAM,OAAO,IAAI;AAAA,EAC3D;AAAA,EACA,OAAO,MAAM;AACf;AAQO,IAAM,OAAY;AAAA,EACvB,IAAI,OAAO;AACT,WAAO,gBAAgB;AAAA,EACzB;AAAA,EACA,IAAI,UAAU;AACZ,WAAO,gBAAgB;AAAA,EACzB;AAAA,EACA,IAAI,MAAM;AACR,WAAO,gBAAgB;AAAA,EACzB;AAAA,EACA,QAAQ;AACV;;;AC9BA,IAAM,mBAA6B;AAAA,EACjC,MAAM;AAAA,EACN,SAAS;AACX;AAEO,IAAM,sBAAsB,OACjC,SAAwC,CAAC,GACzC,QACiC;AACjC,QAAM,EAAE,MAAM,QAAQ,IAAI;AAE1B,QAAMC,YAAqB;AAAA,IACzB,GAAG;AAAA,IACH,GAAI,OAAO,YAAY,CAAC;AAAA,EAC1B;AAEA,QAAM,aAAmC;AAAA,IACvC,GAAG;AAAA,IACH,UAAAA;AAAA,EACF;AAEA,QAAMC,QAAO,OAAO,KAAc,QAAiC;AACjE,QAAI;AACF,qBAAe,KAAKD,UAAS,QAAQ,KAAK;AAE1C,UAAI,IAAI,WAAW,WAAW;AAC5B,YAAI,OAAO,GAAG,EAAE,KAAK;AACrB;AAAA,MACF;AAEA,UAAI,IAAI,WAAW,QAAQ;AACzB,YAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UACnB,SAAS;AAAA,UACT,OAAO;AAAA,QACT,CAAC;AACD;AAAA,MACF;AAEA,UAAI,CAAC,IAAI,MAAM;AACb,YAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UACnB,SAAS;AAAA,UACT,OAAO;AAAA,QACT,CAAC;AACD;AAAA,MACF;AAEA,YAAM,OAAO,IAAI;AAEjB,UAAI,eAAe,IAAI,GAAG;AACxB,cAAM,SAAS,MAAM,aAAa,MAAM,OAAO;AAE/C,YAAI,OAAO,OAAO;AAChB,cAAI,OAAO,GAAG,EAAE,KAAK;AAAA,YACnB,SAAS;AAAA,YACT,OAAO,OAAO;AAAA,UAChB,CAAkB;AAAA,QACpB,OAAO;AACL,cAAI,OAAO,GAAG,EAAE,KAAK;AAAA,YACnB,SAAS;AAAA,YACT,IAAI,OAAO;AAAA,UACb,CAAkB;AAAA,QACpB;AAAA,MACF,OAAO;AACL,YAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UACnB,SAAS;AAAA,UACT,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA,IACF,SAAS,OAAO;AACd,UAAI,OAAO,GAAG,EAAE,KAAK;AAAA,QACnB,SAAS;AAAA,QACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAClD,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,MAAAC;AAAA,EACF;AACF;AAEA,IAAO,wBAAQ;","names":["push","z","z","settings","push"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walkeros/server-source-gcp",
|
|
3
3
|
"description": "Google Cloud Platform server sources for walkerOS (Cloud Functions)",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"module": "./dist/index.mjs",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"update": "npx npm-check-updates -u && npm update"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@walkeros/core": "0.
|
|
21
|
+
"@walkeros/core": "0.5.0"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
24
24
|
"@google-cloud/functions-framework": "^3.0.0"
|