@pikku/cli 0.12.55 → 0.12.56
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/cli.schema.json +1 -1
- package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-channel.js +6 -1
- package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-client.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.json +14 -0
- package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +14 -0
- package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
- package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
- package/dist/.pikku/function/pikku-function-types.gen.d.ts +7 -30
- package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.json +24 -5
- package/dist/.pikku/function/pikku-functions.gen.js +3 -1
- package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
- package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
- package/dist/.pikku/http/pikku-http-wirings-meta.gen.js +1 -1
- package/dist/.pikku/http/pikku-http-wirings.gen.d.ts +1 -1
- package/dist/.pikku/http/pikku-http-wirings.gen.js +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
- package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
- package/dist/.pikku/pikku-meta-service.gen.js +1 -1
- package/dist/.pikku/pikku-services.gen.d.ts +4 -2
- package/dist/.pikku/pikku-services.gen.js +2 -0
- package/dist/.pikku/pikku-types.gen.d.ts +1 -1
- package/dist/.pikku/pikku-types.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.json +0 -248
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +1 -0
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
- package/dist/.pikku/schemas/register.gen.js +5 -1
- package/dist/.pikku/schemas/schemas/FabricAddonVerifyInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/FabricAddonVerifyOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
- package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
- package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
- package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
- package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
- package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
- package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +1 -1
- package/dist/.pikku/workflow/pikku-workflow-types.gen.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
- package/dist/bin/pikku-bin.mjs +2 -2
- package/dist/src/deploy/analyzer/analyzer.d.ts +6 -0
- package/dist/src/deploy/analyzer/analyzer.js +5 -4
- package/dist/src/deploy/build-pipeline.d.ts +5 -1
- package/dist/src/deploy/build-pipeline.js +5 -5
- package/dist/src/deploy/bundler/bun-bundler.d.ts +14 -0
- package/dist/src/deploy/bundler/bun-bundler.js +121 -0
- package/dist/src/deploy/bundler/bundler.d.ts +25 -30
- package/dist/src/deploy/bundler/bundler.interface.d.ts +54 -0
- package/dist/src/deploy/bundler/bundler.interface.js +11 -0
- package/dist/src/deploy/bundler/bundler.js +120 -190
- package/dist/src/deploy/bundler/dep-extractor.d.ts +11 -3
- package/dist/src/deploy/bundler/dep-extractor.js +12 -6
- package/dist/src/deploy/bundler/index.d.ts +5 -2
- package/dist/src/deploy/bundler/index.js +4 -2
- package/dist/src/deploy/bundler/node-bundler.d.ts +13 -0
- package/dist/src/deploy/bundler/node-bundler.js +80 -0
- package/dist/src/fabric/fabric-commands.d.ts +37 -0
- package/dist/src/fabric/fabric-commands.js +8 -0
- package/dist/src/fabric/functions/addon-verify.function.d.ts +54 -0
- package/dist/src/fabric/functions/addon-verify.function.js +153 -0
- package/dist/src/fabric/functions/llm-key.function.js +1 -1
- package/dist/src/fabric/functions/publish.function.js +8 -3
- package/dist/src/functions/commands/deploy-apply.js +3 -1
- package/dist/src/functions/commands/deploy-plan.js +3 -1
- package/dist/src/functions/commands/dev.js +11 -45
- package/dist/src/functions/db/db-codegen.js +14 -0
- package/dist/src/functions/wirings/functions/serialize-function-types.js +6 -29
- package/dist/src/server/bun-server-runner.d.ts +17 -0
- package/dist/src/server/bun-server-runner.js +25 -0
- package/dist/src/server/dev-server-runner.interface.d.ts +31 -0
- package/dist/src/server/dev-server-runner.interface.js +11 -0
- package/dist/src/server/node-server-runner.d.ts +12 -0
- package/dist/src/server/node-server-runner.js +30 -0
- package/dist/src/services.js +10 -0
- package/dist/src/utils/parse-cli-filters.d.ts +1 -0
- package/dist/src/utils/parse-cli-filters.js +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/skills/pikku-addon/SKILL.md +25 -117
- package/skills/pikku-addon/references/addon-package-manifest.md +63 -0
- package/skills/pikku-cli/SKILL.md +7 -93
- package/skills/pikku-cli/references/complete-example.md +82 -0
- package/skills/pikku-concepts/SKILL.md +17 -69
- package/skills/pikku-concepts/references/concept-mapping.md +37 -13
- package/skills/pikku-concepts/references/packages.md +29 -0
- package/skills/pikku-http/SKILL.md +14 -105
- package/skills/pikku-http/references/http-options.md +57 -0
- package/skills/pikku-middleware/SKILL.md +11 -68
- package/skills/pikku-middleware/references/middleware-patterns.md +61 -0
- package/skills/pikku-realtime/SKILL.md +56 -105
- package/skills/pikku-realtime/references/other-routes.md +23 -0
- package/skills/pikku-services/SKILL.md +25 -108
- package/skills/pikku-services/references/audit-wire-service.md +34 -0
- package/skills/pikku-testing/SKILL.md +51 -359
- package/skills/pikku-testing/references/cucumber-bdd-testing.md +176 -0
- package/skills/pikku-workflow/SKILL.md +93 -259
- package/skills/pikku-workflow/references/workflow-reference.md +63 -0
package/dist/bin/pikku-bin.mjs
CHANGED
|
@@ -11,8 +11,8 @@ async function checkForUpdate() {
|
|
|
11
11
|
})
|
|
12
12
|
if (!res.ok) return
|
|
13
13
|
const { version: latest } = await res.json()
|
|
14
|
-
if (latest !== '0.12.
|
|
15
|
-
process.stderr.write(`\n Update available 0.12.
|
|
14
|
+
if (latest !== '0.12.56') {
|
|
15
|
+
process.stderr.write(`\n Update available 0.12.56 → ${latest}\n brew upgrade pikku or npm install -g @pikku/cli\n\n`)
|
|
16
16
|
}
|
|
17
17
|
} catch {}
|
|
18
18
|
}
|
|
@@ -12,6 +12,12 @@ export interface AnalyzerOptions {
|
|
|
12
12
|
projectId: string;
|
|
13
13
|
/** Services that can't run serverless — functions using them get target: 'server' */
|
|
14
14
|
serverlessIncompatible?: string[];
|
|
15
|
+
/**
|
|
16
|
+
* Default deploy target for functions without an explicit `deploy` flag
|
|
17
|
+
* and no serverless-incompatible service. Sourced from `pikku.config.json`
|
|
18
|
+
* → `deploy.defaultTarget`. Defaults to 'serverless'.
|
|
19
|
+
*/
|
|
20
|
+
defaultTarget?: 'serverless' | 'server';
|
|
15
21
|
/**
|
|
16
22
|
* When `true` (default), the analyzer synthesizes a per-workflow
|
|
17
23
|
* orchestrator queue + a per-step queue, plus the matching producer
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { resolveDeployTarget, } from '@pikku/inspector';
|
|
10
10
|
export function analyzeDeployment(state, options) {
|
|
11
11
|
const serverlessIncompatible = new Set(options.serverlessIncompatible ?? []);
|
|
12
|
+
const defaultTarget = options.defaultTarget ?? 'serverless';
|
|
12
13
|
const workflowQueues = options.workflowQueues ?? true;
|
|
13
14
|
const units = [];
|
|
14
15
|
const queues = [];
|
|
@@ -118,7 +119,7 @@ export function analyzeDeployment(state, options) {
|
|
|
118
119
|
units.push({
|
|
119
120
|
name: toSafeKebab(funcId),
|
|
120
121
|
role: 'function',
|
|
121
|
-
target: resolveDeployTarget(funcMeta, serverlessIncompatible, funcId),
|
|
122
|
+
target: resolveDeployTarget(funcMeta, serverlessIncompatible, funcId, defaultTarget),
|
|
122
123
|
functionIds: [funcId],
|
|
123
124
|
services: collectServicesForFunction(funcMeta),
|
|
124
125
|
dependsOn: [],
|
|
@@ -263,7 +264,7 @@ export function analyzeDeployment(state, options) {
|
|
|
263
264
|
units.push({
|
|
264
265
|
name: dep,
|
|
265
266
|
role: 'function',
|
|
266
|
-
target: resolveDeployTarget(funcMeta, serverlessIncompatible, funcId),
|
|
267
|
+
target: resolveDeployTarget(funcMeta, serverlessIncompatible, funcId, defaultTarget),
|
|
267
268
|
functionIds: [funcId],
|
|
268
269
|
services: collectServicesForFunction(funcMeta),
|
|
269
270
|
dependsOn: [],
|
|
@@ -372,10 +373,10 @@ function buildWorkflows(graphMeta, functionsMeta, rpcMeta, _httpMeta, units, wor
|
|
|
372
373
|
continue;
|
|
373
374
|
const stepUnitName = toSafeKebab(node.rpcName);
|
|
374
375
|
// Step dispatch is decided per-function: a step runs inline unless its
|
|
375
|
-
// function
|
|
376
|
+
// function is marked `workflowQueued: true` (then it dispatches via queue).
|
|
376
377
|
const stepFuncId = rpcMeta[node.rpcName] ?? node.rpcName;
|
|
377
378
|
const stepFuncMeta = functionsMeta[stepFuncId] ?? functionsMeta[node.rpcName];
|
|
378
|
-
const isInline = stepFuncMeta?.
|
|
379
|
+
const isInline = stepFuncMeta?.workflowQueued !== true;
|
|
379
380
|
steps.push({
|
|
380
381
|
name: node.stepName ?? nodeId,
|
|
381
382
|
inline: isInline,
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { InspectorState } from '@pikku/inspector';
|
|
8
8
|
import type { DeploymentManifest } from './analyzer/manifest.js';
|
|
9
|
-
import type {
|
|
9
|
+
import type { Bundler } from './bundler/bundler.interface.js';
|
|
10
|
+
import type { BundleResult } from './bundler/types.js';
|
|
10
11
|
import type { ProviderAdapter } from './provider-adapter.js';
|
|
11
12
|
export interface BuildLogger {
|
|
12
13
|
info(msg: string): void;
|
|
@@ -35,10 +36,13 @@ export declare function runBuildPipeline(options: {
|
|
|
35
36
|
provider: ProviderAdapter;
|
|
36
37
|
inspectorState: InspectorState;
|
|
37
38
|
serverlessIncompatible?: string[];
|
|
39
|
+
defaultTarget?: 'serverless' | 'server';
|
|
38
40
|
getEntryContext: (unitDir: string, pikkuDir: string, unit: DeploymentManifest['units'][0], state: InspectorState) => unknown;
|
|
39
41
|
deployDir?: string;
|
|
40
42
|
outDir?: string;
|
|
41
43
|
/** Emit sourcemaps + per-unit `metafile.json` (debug-only). Default false. */
|
|
42
44
|
debugArtifacts?: boolean;
|
|
43
45
|
logger: BuildLogger;
|
|
46
|
+
/** Runtime-specific bundler (esbuild for node, Bun.build for bun). */
|
|
47
|
+
bundler: Bundler;
|
|
44
48
|
}): Promise<BuildPipelineResult>;
|
|
@@ -9,7 +9,6 @@ import { existsSync } from 'node:fs';
|
|
|
9
9
|
import { mkdir, writeFile, copyFile } from 'node:fs/promises';
|
|
10
10
|
import { analyzeDeployment } from './analyzer/index.js';
|
|
11
11
|
import { generatePerUnitCodegen } from './codegen/per-unit-codegen.js';
|
|
12
|
-
import { bundleUnits } from './bundler/index.js';
|
|
13
12
|
import { generateServerEntrySource, SERVER_DOCKERFILE, SERVER_DOCKERIGNORE, } from './server-entry.js';
|
|
14
13
|
const MERGED_SERVER_UNIT_NAME = 'pikku-server-container';
|
|
15
14
|
const UNITS_DIR_NAME = 'units';
|
|
@@ -38,7 +37,7 @@ function findLockfile(projectDir) {
|
|
|
38
37
|
return null;
|
|
39
38
|
}
|
|
40
39
|
export async function runBuildPipeline(options) {
|
|
41
|
-
const { projectDir, projectId, provider, inspectorState, getEntryContext, debugArtifacts, logger, } = options;
|
|
40
|
+
const { projectDir, projectId, provider, inspectorState, getEntryContext, debugArtifacts, logger, bundler, } = options;
|
|
42
41
|
const deployDir = options.deployDir ?? join(projectDir, '.deploy');
|
|
43
42
|
const providerDir = join(deployDir, provider.deployDirName);
|
|
44
43
|
// Step 1: Analyze
|
|
@@ -46,6 +45,7 @@ export async function runBuildPipeline(options) {
|
|
|
46
45
|
const manifest = analyzeDeployment(inspectorState, {
|
|
47
46
|
projectId,
|
|
48
47
|
serverlessIncompatible: options.serverlessIncompatible,
|
|
48
|
+
defaultTarget: options.defaultTarget,
|
|
49
49
|
workflowQueues,
|
|
50
50
|
});
|
|
51
51
|
let bundled = [];
|
|
@@ -79,7 +79,7 @@ export async function runBuildPipeline(options) {
|
|
|
79
79
|
await writeFile(entryPath, source, 'utf-8');
|
|
80
80
|
const entryFiles = new Map();
|
|
81
81
|
entryFiles.set(unitName, entryPath);
|
|
82
|
-
const bundleResult = await bundleUnits(projectDir, manifest, entryFiles, providerDir, {
|
|
82
|
+
const bundleResult = await bundler.bundleUnits(projectDir, manifest, entryFiles, providerDir, {
|
|
83
83
|
externals: provider.getExternals?.(),
|
|
84
84
|
stubModules: provider.getStubModules?.(),
|
|
85
85
|
aliases: provider.getAliases?.(),
|
|
@@ -206,7 +206,7 @@ export async function runBuildPipeline(options) {
|
|
|
206
206
|
...manifest,
|
|
207
207
|
units: manifest.units.filter((u) => u.target !== 'server'),
|
|
208
208
|
};
|
|
209
|
-
const result = await bundleUnits(projectDir, serverlessManifestForBundle, serverlessEntryFiles, providerDir, {
|
|
209
|
+
const result = await bundler.bundleUnits(projectDir, serverlessManifestForBundle, serverlessEntryFiles, providerDir, {
|
|
210
210
|
externals: provider.getExternals?.(),
|
|
211
211
|
stubModules: provider.getStubModules?.(),
|
|
212
212
|
aliases: provider.getAliases?.(),
|
|
@@ -231,7 +231,7 @@ export async function runBuildPipeline(options) {
|
|
|
231
231
|
...manifest,
|
|
232
232
|
units: manifest.units.filter((u) => u.target === 'server'),
|
|
233
233
|
};
|
|
234
|
-
const result = await bundleUnits(projectDir, serverManifestForBundle, serverEntryFiles, providerDir, {
|
|
234
|
+
const result = await bundler.bundleUnits(projectDir, serverManifestForBundle, serverEntryFiles, providerDir, {
|
|
235
235
|
externals: ['node:*'],
|
|
236
236
|
aliases: undefined,
|
|
237
237
|
define: undefined,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bun (Bun.build) bundler backend.
|
|
3
|
+
*
|
|
4
|
+
* Used when the CLI runs under Bun (bun projects). Bun resolves its own `.bun`
|
|
5
|
+
* store / per-workspace symlinks natively — esbuild's `nodePaths` walk assumes a
|
|
6
|
+
* hoisted root and can't — so no esbuild dependency is needed. Bun's metafile
|
|
7
|
+
* does NOT record external imports, so externals are captured via the resolve
|
|
8
|
+
* plugin instead (that capture drives per-unit dependency extraction).
|
|
9
|
+
*/
|
|
10
|
+
import { BaseBundler } from './bundler.js';
|
|
11
|
+
import type { CompileInput, CompileResult } from './bundler.interface.js';
|
|
12
|
+
export declare class BunBundler extends BaseBundler {
|
|
13
|
+
protected compile(input: CompileInput): Promise<CompileResult>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bun (Bun.build) bundler backend.
|
|
3
|
+
*
|
|
4
|
+
* Used when the CLI runs under Bun (bun projects). Bun resolves its own `.bun`
|
|
5
|
+
* store / per-workspace symlinks natively — esbuild's `nodePaths` walk assumes a
|
|
6
|
+
* hoisted root and can't — so no esbuild dependency is needed. Bun's metafile
|
|
7
|
+
* does NOT record external imports, so externals are captured via the resolve
|
|
8
|
+
* plugin instead (that capture drives per-unit dependency extraction).
|
|
9
|
+
*/
|
|
10
|
+
import { writeFile } from 'node:fs/promises';
|
|
11
|
+
import { BaseBundler } from './bundler.js';
|
|
12
|
+
function getBun() {
|
|
13
|
+
const bun = globalThis.Bun;
|
|
14
|
+
if (!bun) {
|
|
15
|
+
throw new Error('BunBundler used outside the Bun runtime');
|
|
16
|
+
}
|
|
17
|
+
return bun;
|
|
18
|
+
}
|
|
19
|
+
const pkgHead = (spec) => spec.startsWith('@')
|
|
20
|
+
? spec.split('/').slice(0, 2).join('/')
|
|
21
|
+
: spec.split('/')[0];
|
|
22
|
+
/**
|
|
23
|
+
* Unified resolve plugin. Bun resolves its `.bun` store natively, so this plugin
|
|
24
|
+
* only replicates the option-driven behaviour the esbuild backend gets for free:
|
|
25
|
+
* - `aliases`: rewrite bare builtins to their `node:`-prefixed form (CF's
|
|
26
|
+
* nodejs_compat_v2 only resolves prefixed imports).
|
|
27
|
+
* - stub patterns (dead services + provider `stubModules`): empty module.
|
|
28
|
+
* - `externals`: keep external (node:*, cloudflare:*, declared npm deps) and
|
|
29
|
+
* CAPTURE the real npm package names — Bun's metafile omits external
|
|
30
|
+
* imports, so capture is how per-unit dependency extraction works.
|
|
31
|
+
*/
|
|
32
|
+
function createBunResolvePlugin(opts) {
|
|
33
|
+
const { aliases, externals, stubPatterns, captured } = opts;
|
|
34
|
+
const externalMatchers = externals.map((pat) => {
|
|
35
|
+
if (pat.endsWith('*')) {
|
|
36
|
+
const prefix = pat.slice(0, -1);
|
|
37
|
+
return (s) => s.startsWith(prefix);
|
|
38
|
+
}
|
|
39
|
+
return (s) => s === pat || s.startsWith(pat + '/');
|
|
40
|
+
});
|
|
41
|
+
return {
|
|
42
|
+
name: 'pikku-bun-resolve',
|
|
43
|
+
setup(build) {
|
|
44
|
+
build.onResolve({ filter: /.*/ }, (args) => {
|
|
45
|
+
let path = args.path;
|
|
46
|
+
// Relative / absolute → let Bun resolve natively.
|
|
47
|
+
if (path.startsWith('.') || path.startsWith('/'))
|
|
48
|
+
return;
|
|
49
|
+
// Builtin alias (e.g. crypto → node:crypto).
|
|
50
|
+
if (aliases && aliases[path])
|
|
51
|
+
path = aliases[path];
|
|
52
|
+
// Dead/stubbed modules → empty module.
|
|
53
|
+
if (stubPatterns.some((re) => re.test(path))) {
|
|
54
|
+
return { path, namespace: 'pikku-stub' };
|
|
55
|
+
}
|
|
56
|
+
// node: builtins are always external (covers aliased builtins on CF).
|
|
57
|
+
if (path.startsWith('node:'))
|
|
58
|
+
return { path, external: true };
|
|
59
|
+
// Provider externals (cloudflare:*, declared npm deps).
|
|
60
|
+
if (externalMatchers.some((m) => m(path))) {
|
|
61
|
+
// Only real npm packages are install-time deps (skip scheme imports).
|
|
62
|
+
if (!path.includes(':'))
|
|
63
|
+
captured.add(pkgHead(path));
|
|
64
|
+
return { path, external: true };
|
|
65
|
+
}
|
|
66
|
+
// Everything else → Bun bundles it (resolving the .bun store natively).
|
|
67
|
+
return;
|
|
68
|
+
});
|
|
69
|
+
build.onLoad({ filter: /.*/, namespace: 'pikku-stub' }, () => ({
|
|
70
|
+
contents: 'export {}',
|
|
71
|
+
loader: 'js',
|
|
72
|
+
}));
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
export class BunBundler extends BaseBundler {
|
|
77
|
+
async compile(input) {
|
|
78
|
+
const captured = new Set();
|
|
79
|
+
const result = await getBun().build({
|
|
80
|
+
entrypoints: [input.entryPath],
|
|
81
|
+
target: input.platform === 'node' ? 'node' : 'browser',
|
|
82
|
+
format: input.format === 'cjs' ? 'cjs' : 'esm',
|
|
83
|
+
// identifiers:true is safe — pikku's only name-based reflection
|
|
84
|
+
// (error→status mapping) compares a class against an instance of the SAME
|
|
85
|
+
// (consistently-renamed) class, and workflow exceptions hardcode their
|
|
86
|
+
// `.name` string. So full minification preserves correctness.
|
|
87
|
+
minify: { whitespace: true, syntax: true, identifiers: true },
|
|
88
|
+
sourcemap: input.sourcemap ? 'external' : 'none',
|
|
89
|
+
define: input.define,
|
|
90
|
+
banner: input.bannerJs,
|
|
91
|
+
external: input.externals,
|
|
92
|
+
metafile: input.emitMetafile,
|
|
93
|
+
plugins: [
|
|
94
|
+
createBunResolvePlugin({
|
|
95
|
+
aliases: input.aliases,
|
|
96
|
+
externals: input.externals,
|
|
97
|
+
stubPatterns: input.deadPatterns,
|
|
98
|
+
captured,
|
|
99
|
+
}),
|
|
100
|
+
],
|
|
101
|
+
});
|
|
102
|
+
if (!result.success) {
|
|
103
|
+
throw new Error(`Bun.build failed for unit "${input.unitName}":\n` +
|
|
104
|
+
result.logs.map((l) => String(l)).join('\n'));
|
|
105
|
+
}
|
|
106
|
+
const entryArtifact = result.outputs.find((o) => o.kind === 'entry-point') ?? result.outputs[0];
|
|
107
|
+
await writeFile(input.bundlePath, await entryArtifact.text(), 'utf-8');
|
|
108
|
+
if (input.sourcemap) {
|
|
109
|
+
const mapArtifact = result.outputs.find((o) => o.kind === 'sourcemap');
|
|
110
|
+
if (mapArtifact) {
|
|
111
|
+
await writeFile(`${input.bundlePath}.map`, await mapArtifact.text(), 'utf-8');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
externalPackages: captured,
|
|
116
|
+
metafileJson: input.emitMetafile && result.metafile
|
|
117
|
+
? JSON.stringify(result.metafile, null, 2)
|
|
118
|
+
: undefined,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -1,35 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Shared bundling orchestration for Pikku deploys.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
4
|
+
* `BaseBundler` performs everything that is runtime-independent for each
|
|
5
|
+
* deployment unit:
|
|
6
|
+
* 1. Take a pre-generated entry point (provided by the deploy provider)
|
|
7
|
+
* 2. Stub gen files / npm modules not needed by this unit
|
|
8
|
+
* 3. Delegate the actual compile to a runtime backend (`compile`)
|
|
9
|
+
* 4. Resolve external dependency versions into a minimal package.json
|
|
10
|
+
* 5. Write all artifacts to `<outputDir>/<unit-name>/` and hash them
|
|
11
|
+
*
|
|
12
|
+
* The runtime-specific compile step lives in `NodeBundler` (esbuild) and
|
|
13
|
+
* `BunBundler` (Bun.build); the right one is injected from `services.ts`.
|
|
11
14
|
*/
|
|
12
|
-
import type { DeploymentManifest,
|
|
15
|
+
import type { DeploymentManifest, BundleOutput } from './types.js';
|
|
16
|
+
import type { Bundler, BundleUnitsOptions, CompileInput, CompileResult } from './bundler.interface.js';
|
|
13
17
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* Entry points must be pre-generated by the provider-specific package
|
|
17
|
-
* (e.g. @pikku/deploy-cloudflare) and passed in as entryFiles.
|
|
18
|
-
*
|
|
19
|
-
* @param projectDir - Root directory of the Pikku project
|
|
20
|
-
* @param manifest - The deployment manifest describing all units
|
|
21
|
-
* @param entryFiles - Map of unit name -> entry file path (generated by the deploy provider)
|
|
22
|
-
* @param outputDir - Base output directory (defaults to `<projectDir>/.deploy/build`)
|
|
18
|
+
* Runtime-independent bundling orchestration. Subclasses implement only
|
|
19
|
+
* `compile` — the actual esbuild / Bun.build invocation.
|
|
23
20
|
*/
|
|
24
|
-
export declare
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
resolveOutputDir?: (unit: DeploymentUnit, baseOutputDir: string) => string;
|
|
35
|
-
}): Promise<BundleOutput>;
|
|
21
|
+
export declare abstract class BaseBundler implements Bundler {
|
|
22
|
+
/**
|
|
23
|
+
* Runtime-specific compile step: write `input.bundlePath` (and its `.map`
|
|
24
|
+
* when `input.sourcemap`) and return the external packages + optional
|
|
25
|
+
* metafile JSON.
|
|
26
|
+
*/
|
|
27
|
+
protected abstract compile(input: CompileInput): Promise<CompileResult>;
|
|
28
|
+
bundleUnits(projectDir: string, manifest: DeploymentManifest, entryFiles: Map<string, string>, outputDir?: string, options?: BundleUnitsOptions): Promise<BundleOutput>;
|
|
29
|
+
private bundleUnit;
|
|
30
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bundler abstraction.
|
|
3
|
+
*
|
|
4
|
+
* A `Bundler` turns a deployment manifest's units into self-contained bundles.
|
|
5
|
+
* The shared orchestration (dead-module stubbing, dependency extraction,
|
|
6
|
+
* package.json + hashing) lives in `BaseBundler`; each runtime supplies only the
|
|
7
|
+
* compile step via a `Bundler` implementation (esbuild for node, Bun.build for
|
|
8
|
+
* bun). The runtime is resolved once in `services.ts` and injected — no
|
|
9
|
+
* `typeof Bun` checks in the pipeline.
|
|
10
|
+
*/
|
|
11
|
+
import type { DeploymentManifest, DeploymentUnit, BundleOutput } from './types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Inputs the shared orchestration hands to a backend's runtime-specific compile
|
|
14
|
+
* step. The backend writes `bundlePath` (and `${bundlePath}.map` when
|
|
15
|
+
* `sourcemap`) itself and returns the external packages + optional metafile.
|
|
16
|
+
*/
|
|
17
|
+
export interface CompileInput {
|
|
18
|
+
unitName: string;
|
|
19
|
+
entryPath: string;
|
|
20
|
+
bundlePath: string;
|
|
21
|
+
projectDir: string;
|
|
22
|
+
platform: 'node' | 'neutral' | 'browser';
|
|
23
|
+
format: 'esm' | 'cjs';
|
|
24
|
+
externals: string[];
|
|
25
|
+
aliases?: Record<string, string>;
|
|
26
|
+
define?: Record<string, string>;
|
|
27
|
+
/** ESM require/__filename/__dirname shim, or undefined when not needed. */
|
|
28
|
+
bannerJs?: string;
|
|
29
|
+
sourcemap: boolean;
|
|
30
|
+
emitMetafile: boolean;
|
|
31
|
+
/** Regexes for modules to replace with an empty `export {}` module. */
|
|
32
|
+
deadPatterns: RegExp[];
|
|
33
|
+
}
|
|
34
|
+
export interface CompileResult {
|
|
35
|
+
/** Real npm package names kept external — drive the unit's package.json. */
|
|
36
|
+
externalPackages: Set<string>;
|
|
37
|
+
/** Stringified metafile when `emitMetafile` was set; otherwise undefined. */
|
|
38
|
+
metafileJson?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface BundleUnitsOptions {
|
|
41
|
+
externals?: string[];
|
|
42
|
+
aliases?: Record<string, string>;
|
|
43
|
+
define?: Record<string, string>;
|
|
44
|
+
platform?: 'node' | 'neutral' | 'browser';
|
|
45
|
+
format?: 'esm' | 'cjs';
|
|
46
|
+
noRequireShim?: boolean;
|
|
47
|
+
sourcemap?: boolean;
|
|
48
|
+
emitMetafile?: boolean;
|
|
49
|
+
stubModules?: string[];
|
|
50
|
+
resolveOutputDir?: (unit: DeploymentUnit, baseOutputDir: string) => string;
|
|
51
|
+
}
|
|
52
|
+
export interface Bundler {
|
|
53
|
+
bundleUnits(projectDir: string, manifest: DeploymentManifest, entryFiles: Map<string, string>, outputDir?: string, options?: BundleUnitsOptions): Promise<BundleOutput>;
|
|
54
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bundler abstraction.
|
|
3
|
+
*
|
|
4
|
+
* A `Bundler` turns a deployment manifest's units into self-contained bundles.
|
|
5
|
+
* The shared orchestration (dead-module stubbing, dependency extraction,
|
|
6
|
+
* package.json + hashing) lives in `BaseBundler`; each runtime supplies only the
|
|
7
|
+
* compile step via a `Bundler` implementation (esbuild for node, Bun.build for
|
|
8
|
+
* bun). The runtime is resolved once in `services.ts` and injected — no
|
|
9
|
+
* `typeof Bun` checks in the pipeline.
|
|
10
|
+
*/
|
|
11
|
+
export {};
|