@podosoft/podokit 1.0.1 → 1.0.2

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.
@@ -38,7 +38,7 @@ export declare function derivedRuntimeConfig(profile: DockerComposeProfileV1): R
38
38
  * the containers instead of leaving stale values running.
39
39
  */
40
40
  export declare function rolloutStateDigest(profile: DockerComposeProfileV1, secretIdentities: Record<string, string>): string;
41
- export declare function renderComposeDocument(profile: DockerComposeProfileV1, release: string, images: ComposeImages, stateDigest: string): string;
41
+ export declare function renderComposeDocument(profile: DockerComposeProfileV1, release: string, images: ComposeImages, stateDigest: string, workerCommand?: string[]): string;
42
42
  /**
43
43
  * The migration runs as its own Compose project so it can be started, waited on,
44
44
  * and removed without touching the running application definition.
@@ -239,7 +239,7 @@ function applicationService(profile, role, image, release, stateDigest, options)
239
239
  " healthcheck:\n disable: true\n") +
240
240
  labelsBlock(profile, release, stateDigest, " "));
241
241
  }
242
- function renderComposeDocument(profile, release, images, stateDigest) {
242
+ function renderComposeDocument(profile, release, images, stateDigest, workerCommand = ["bun", "dist/main-worker.js"]) {
243
243
  const services = [];
244
244
  if (profile.dependencies.postgres.mode === "managed" && images.postgres) {
245
245
  services.push(postgresService(profile, images.postgres));
@@ -264,7 +264,7 @@ function renderComposeDocument(profile, release, images, stateDigest) {
264
264
  // The worker runs the API image with a different entry point, exactly as the
265
265
  // Kubernetes driver does.
266
266
  services.push(applicationService(profile, "worker", images.api, release, stateDigest, {
267
- command: `["node", "dist/main-worker"]`,
267
+ command: `[${workerCommand.map((part) => quote(part)).join(", ")}]`,
268
268
  }));
269
269
  }
270
270
  const volumes = [
@@ -288,7 +288,7 @@ function renderComposeDocument(profile, release, images, stateDigest) {
288
288
  * The migration runs as its own Compose project so it can be started, waited on,
289
289
  * and removed without touching the running application definition.
290
290
  */
291
- function renderMigrationDocument(profile, release, images, defaultCommand = ["npm", "run", "migrate:all"]) {
291
+ function renderMigrationDocument(profile, release, images, defaultCommand = ["bun", "run", "migrate:all"]) {
292
292
  const command = profile.migration?.command ?? defaultCommand;
293
293
  return (`# Generated by PodoKit. One-shot migration for ${release}.\n` +
294
294
  `name: ${profile.target.project}-migrate\n` +
@@ -325,8 +325,8 @@ function renderComposeDeployment(projectRoot, profileName, profile, release, res
325
325
  const root = (0, node_path_1.join)((0, node_path_1.resolve)(projectRoot), ".podokit", "runtime", "deploy", profileName);
326
326
  (0, node_fs_1.rmSync)(root, { recursive: true, force: true });
327
327
  (0, node_fs_1.mkdirSync)(root, { recursive: true });
328
- const composeDocument = renderComposeDocument(profile, release, images, effectiveStateDigest);
329
328
  const toolchain = (0, lockfile_1.readManifest)(projectRoot)?.toolchain ?? (0, toolchain_1.resolveToolchain)();
329
+ const composeDocument = renderComposeDocument(profile, release, images, effectiveStateDigest, (0, toolchain_1.toolchainWorkerCommand)(toolchain));
330
330
  const migrationDocument = renderMigrationDocument(profile, release, images, (0, toolchain_1.toolchainMigrationCommand)(toolchain));
331
331
  const composeFile = (0, node_path_1.join)(root, "compose.yaml");
332
332
  const migrationFile = (0, node_path_1.join)(root, "compose.migrate.yaml");
@@ -461,7 +461,7 @@ spec:
461
461
  - { name: http, port: 3000, targetPort: 3000 }
462
462
  `;
463
463
  }
464
- function workerDeployment(profile, image, rolloutStateDigest, runtimeConfigDigest) {
464
+ function workerDeployment(profile, image, rolloutStateDigest, runtimeConfigDigest, command) {
465
465
  const workload = profile.workloads.worker;
466
466
  if (!workload)
467
467
  return "";
@@ -495,7 +495,7 @@ ${labels(name, 8)} spec:
495
495
  - name: worker
496
496
  image: ${quote(image)}
497
497
  imagePullPolicy: IfNotPresent
498
- command: [node, dist/main-worker]
498
+ command: ${yamlStringSequence(command)}
499
499
  envFrom:
500
500
  - configMapRef: { name: ${profile.target.release}-runtime }
501
501
  - secretRef: { name: ${profile.secrets.api.name} }
@@ -569,13 +569,13 @@ ${webSocketPaths} - path: /
569
569
  port: { number: 3000 }
570
570
  `;
571
571
  }
572
- function applicationManifest(profile, images, rolloutStateDigest) {
572
+ function applicationManifest(profile, images, rolloutStateDigest, workerCommand) {
573
573
  const runtimeConfigDigest = derivedRuntimeConfigDigest(profile);
574
574
  return [
575
575
  configMap(profile),
576
576
  deployment(profile, "api", profile.workloads.api, images.api, rolloutStateDigest, runtimeConfigDigest),
577
577
  deployment(profile, "web", profile.workloads.web, images.web, rolloutStateDigest, runtimeConfigDigest),
578
- workerDeployment(profile, images.api, rolloutStateDigest, runtimeConfigDigest),
578
+ workerDeployment(profile, images.api, rolloutStateDigest, runtimeConfigDigest, workerCommand),
579
579
  disruptionBudget(profile, "api"),
580
580
  disruptionBudget(profile, "web"),
581
581
  profile.workloads.worker ? disruptionBudget(profile, "worker") : "",
@@ -659,8 +659,8 @@ function renderDeployment(projectRoot, profileName, profile, release, resolvedIm
659
659
  const applicationChart = (0, node_path_1.join)(root, "application");
660
660
  const effectiveRolloutStateDigest = rolloutStateDigest ?? offlineRolloutStateDigest(profile);
661
661
  const dependencies = dependencyManifest(profile, images, effectiveRolloutStateDigest);
662
- const application = applicationManifest(profile, images, effectiveRolloutStateDigest);
663
662
  const toolchain = (0, lockfile_1.readManifest)(projectRoot)?.toolchain ?? (0, toolchain_1.resolveToolchain)();
663
+ const application = applicationManifest(profile, images, effectiveRolloutStateDigest, (0, toolchain_1.toolchainWorkerCommand)(toolchain));
664
664
  const migration = migrationManifest(profile, release, images, (0, toolchain_1.toolchainMigrationCommand)(toolchain));
665
665
  chart(dependencyChart, "podokit-dependencies", dependencies);
666
666
  chart(applicationChart, "podokit-application", application);
@@ -265,7 +265,7 @@
265
265
  const { data: res, error } = await api.auth.twoFactor.enable({ password: twoFaPassword });
266
266
  twoFaBusy = false;
267
267
  if (error) return void toast.error(error.message ?? i18n.t.account.changeFailed);
268
- if (!res?.totpURI || !Array.isArray(res.backupCodes)) {
268
+ if (!res || !("totpURI" in res) || !res.totpURI || !Array.isArray(res.backupCodes)) {
269
269
  return void toast.error(i18n.t.account.changeFailed);
270
270
  }
271
271
  setup = { totpURI: res.totpURI, backupCodes: res.backupCodes };
@@ -39,7 +39,7 @@
39
39
  error = e.code === "INVALID_PASSWORD" ? i18n.t.setup2fa.wrongPassword : i18n.t.setup2fa.enableFailed;
40
40
  return;
41
41
  }
42
- if (!data?.totpURI || !Array.isArray(data.backupCodes)) {
42
+ if (!data || !("totpURI" in data) || !data.totpURI || !Array.isArray(data.backupCodes)) {
43
43
  error = i18n.t.setup2fa.enableFailed;
44
44
  return;
45
45
  }
@@ -14,7 +14,11 @@ const REDIRECT = "https://example.com/callback";
14
14
  // docs/modules.md for the manual round-trip checklist.
15
15
  test("OIDC provider: discovery, JWKS, client registration, authorize handoff", async ({ page, baseURL }) => {
16
16
  const headers = { origin: baseURL ?? "" };
17
- await page.request.put("/api/account/settings", { data: { oidcProvider: true }, headers });
17
+ const enabled = await page.request.put("/api/account/settings", {
18
+ data: { oidcProvider: true },
19
+ headers,
20
+ });
21
+ expect(enabled.ok(), await enabled.text()).toBeTruthy();
18
22
  await expect
19
23
  .poll(async () => (await page.request.get("/api/auth/.well-known/openid-configuration")).status(), { timeout: 8000 })
20
24
  .toBe(200);
@@ -61,6 +65,10 @@ test("OIDC provider: discovery, JWKS, client registration, authorize handoff", a
61
65
  await page.goto(consentUrl);
62
66
  await expect(page.getByRole("button", { name: "Allow" })).toBeVisible();
63
67
  } finally {
64
- await page.request.put("/api/account/settings", { data: { oidcProvider: false }, headers });
68
+ const disabled = await page.request.put("/api/account/settings", {
69
+ data: { oidcProvider: false },
70
+ headers,
71
+ });
72
+ expect(disabled.ok(), await disabled.text()).toBeTruthy();
65
73
  }
66
74
  });
@@ -11,3 +11,4 @@ export declare function resolveToolchain(runtime?: string, packageManager?: stri
11
11
  export declare function toolchainTemplateVars(toolchain: Toolchain): TemplateVars;
12
12
  export declare function isRuntime(value: string): value is Runtime;
13
13
  export declare function toolchainMigrationCommand(_toolchain: Toolchain): string[];
14
+ export declare function toolchainWorkerCommand(_toolchain: Toolchain): string[];
package/dist/toolchain.js CHANGED
@@ -5,6 +5,7 @@ exports.resolveToolchain = resolveToolchain;
5
5
  exports.toolchainTemplateVars = toolchainTemplateVars;
6
6
  exports.isRuntime = isRuntime;
7
7
  exports.toolchainMigrationCommand = toolchainMigrationCommand;
8
+ exports.toolchainWorkerCommand = toolchainWorkerCommand;
8
9
  exports.BUN_VERSION = "1.4.0";
9
10
  function resolveToolchain(runtime = "bun", packageManager) {
10
11
  if (runtime !== "bun") {
@@ -42,3 +43,6 @@ function isRuntime(value) {
42
43
  function toolchainMigrationCommand(_toolchain) {
43
44
  return ["bun", "run", "migrate:all"];
44
45
  }
46
+ function toolchainWorkerCommand(_toolchain) {
47
+ return ["bun", "dist/main-worker.js"];
48
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@podosoft/podokit",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "An opinionated Bun and Elysia full-stack TypeScript starter toolkit and CLI with SvelteKit, TailwindCSS, shadcn-svelte, Docker, and k3s.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {