feat: big-suite terraform example + provider nodejs zip fix

- examples/big-suite: E-Commerce 10 functions, 6 layers, real depends_on
- provider: nodejs packages now wrapped in ESM zip (buildJSDeployZip)
- provider: loadPackageLiteral reads raw file, nodejs zip via source_dir
- all 10 functions verified working: python/node/ruby/go runtimes
This commit is contained in:
Naeel
2026-04-20 11:38:45 +03:00
parent 4837d42ba1
commit 01df1498d6
22 changed files with 1033 additions and 5 deletions
@@ -6,6 +6,7 @@ import (
"context"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"os"
@@ -353,6 +354,11 @@ func loadPackageLiteral(sourceDir, codePath string) ([]byte, error) {
return nil, fmt.Errorf("read source_dir source file %q: %w", mainFilePath, err)
}
// Node.js runtime ожидает ZIP с package.json + main.js (ESM wrapper).
if filepath.Ext(mainFilePath) == ".js" {
return buildJSDeployZip(string(mainFileBytes))
}
return mainFileBytes, nil
}
@@ -364,6 +370,52 @@ func loadPackageLiteral(sourceDir, codePath string) ([]byte, error) {
return literalBytes, nil
}
// buildJSDeployZip wraps Node.js user code into a ZIP with package.json (ESM) + main.js wrapper.
// This matches the format expected by ghcr.io/fission/node-env runtime.
func buildJSDeployZip(code string) ([]byte, error) {
var buf bytes.Buffer
zw := zip.NewWriter(&buf)
pkgfw, err := zw.Create("package.json")
if err != nil {
return nil, err
}
if _, err := pkgfw.Write([]byte(`{"type":"module"}`)); err != nil {
return nil, err
}
codeJSON, err := json.Marshal(code)
if err != nil {
return nil, fmt.Errorf("marshal user code: %w", err)
}
wrapper := fmt.Sprintf(`const __mod = { exports: {} };
(new Function('module', 'exports', %s))(__mod, __mod.exports);
const _fn = __mod.exports;
export default async function(ctx) {
const fn = typeof _fn === 'function' ? _fn : (_fn.default || _fn.handler || _fn.main);
if (!fn) throw new Error('no exported function found in user code');
const result = await fn(ctx);
if (!result) return { status: 200, body: '' };
if (typeof result.status !== 'undefined') return result;
return { status: 200, ...result };
}
`, string(codeJSON))
fw, err := zw.Create("main.js")
if err != nil {
return nil, err
}
if _, err := fw.Write([]byte(wrapper)); err != nil {
return nil, err
}
if err := zw.Close(); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
// loadPackageSourceArchive создает zip-архив из source_dir для builder pipeline.
func loadPackageSourceArchive(sourceDir string) ([]byte, error) {
var buf bytes.Buffer