@tailorkit/vite 0.1.0-beta.36 → 0.1.0-beta.38

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 CHANGED
@@ -1,8 +1,10 @@
1
1
  # TailorKit Vite integration
2
2
 
3
- `@tailorkit/vite` owns TailorKit app configuration, route discovery, instance resolver extraction, backend bundling, migration validation, and deployment manifests. The app runtime lives in `@tailorkit/app`.
3
+ `@tailorkit/vite` builds TailorKit apps. It loads app configuration, discovers routes, extracts instance resolvers, bundles backend code, validates migrations, and writes deployment manifests. The app runtime lives in `@tailorkit/app`.
4
4
 
5
- App authors import the plugin through `tailorkit/vite`:
5
+ ## Configure the plugin
6
+
7
+ Import the plugin through `tailorkit/vite`:
6
8
 
7
9
  ```ts
8
10
  import { tailorkit } from "tailorkit/vite";
@@ -15,4 +17,6 @@ export default defineConfig({
15
17
 
16
18
  For ordinary Vite, import `defineConfig` from `vite` and set `plugins: [tailorkit()]`. The plugin finds `tailorkit.config.ts` beside the loaded Vite config. To use another file, pass `tailorkit({ configPath: "./config/tailorkit.config.ts" })`; relative paths always resolve from the Vite config directory. App source and output paths also resolve from that directory. Build output defaults to `.tailorkit`; customize `build.outDir`, aliases, constants, and plugins in the app's Vite config.
17
19
 
20
+ ## Internal entry points
21
+
18
22
  The CLI imports config loading from `@tailorkit/vite/config/loader` and migration and deployment helpers from `@tailorkit/vite/builder`. The `tailorkit/app/config` entry point exposes the app config authoring API.
@@ -1,26 +1,5 @@
1
- import { z } from "zod";
1
+ import { TailorKitUploadManifest, createTailorKitUploadManifest, tailorkitUploadManifestSchema } from "./upload-manifest.mjs";
2
2
  import { Plugin } from "vite";
3
- //#region src/builder/upload-manifest.d.ts
4
- export declare const tailorkitUploadManifestSchema: z.ZodObject<{
5
- assets: z.ZodObject<{
6
- client: z.ZodLiteral<"client/client.js">;
7
- logos: z.ZodOptional<z.ZodObject<{
8
- dark: z.ZodOptional<z.ZodString>;
9
- light: z.ZodOptional<z.ZodString>;
10
- }, z.core.$strip>>;
11
- server: z.ZodOptional<z.ZodLiteral<"server/server.js">>;
12
- }, z.core.$strip>;
13
- version: z.ZodLiteral<1>;
14
- views: z.ZodOptional<z.ZodArray<z.ZodObject<{
15
- disabled: z.ZodOptional<z.ZodLiteral<true>>;
16
- instances: z.ZodOptional<z.ZodLiteral<true>>;
17
- path: z.ZodString;
18
- slot: z.ZodString;
19
- }, z.core.$strip>>>;
20
- }, z.core.$strip>;
21
- type TailorKitUploadManifest = z.output<typeof tailorkitUploadManifestSchema>;
22
- export declare const createTailorKitUploadManifest: (logos?: TailorKitUploadManifest["assets"]["logos"], server?: boolean, views?: TailorKitUploadManifest["views"]) => TailorKitUploadManifest;
23
- //#endregion
24
3
  //#region src/builder/generate-migrations.d.ts
25
4
  interface GenerateAppMigrationsOptions {
26
5
  configPath?: string;
@@ -33,4 +12,4 @@ export declare const generateAppMigrations: (options?: GenerateAppMigrationsOpti
33
12
  /** Root, layout, view and binding sources to check before deployment. */
34
13
  export declare const getClientSourceFiles: (root: string) => Promise<string[]>;
35
14
  //#endregion
36
- export type { GenerateAppMigrationsOptions, TailorKitUploadManifest };
15
+ export { type GenerateAppMigrationsOptions, type TailorKitUploadManifest, createTailorKitUploadManifest, tailorkitUploadManifestSchema };
package/dist/builder.mjs CHANGED
@@ -1,5 +1,6 @@
1
- import { d as createTailorKitUploadManifest, f as tailorkitUploadManifestSchema, l as drizzleGenerateArguments, o as checkAppSchema, r as getClientSourceFiles, u as appDatabasePaths } from "./file-routes-7N97Zavb.mjs";
1
+ import { createTailorKitUploadManifest, tailorkitUploadManifestSchema } from "./upload-manifest.mjs";
2
2
  import { loadTailorKitConfig } from "./config-loader.mjs";
3
+ import { d as appDatabasePaths, r as getClientSourceFiles, s as checkAppSchema, u as drizzleGenerateArguments } from "./file-routes-BYuuJaSg.mjs";
3
4
  import { spawn } from "node:child_process";
4
5
  import { access } from "node:fs/promises";
5
6
  import path from "node:path";
@@ -7,35 +7,6 @@ import { tmpdir } from "node:os";
7
7
  import { promisify } from "node:util";
8
8
  import { existsSync, watch } from "node:fs";
9
9
  import { parseSync } from "vite";
10
- //#region src/builder/upload-manifest.ts
11
- const tailorkitUploadManifestSchema = z.object({
12
- assets: z.object({
13
- client: z.literal("client/client.js"),
14
- logos: z.object({
15
- dark: z.string().regex(/^client\/logo-dark\.(?:png|svg|webp)$/u).optional(),
16
- light: z.string().regex(/^client\/logo-light\.(?:png|svg|webp)$/u).optional()
17
- }).optional(),
18
- server: z.literal("server/server.js").optional()
19
- }),
20
- version: z.literal(1),
21
- views: z.array(z.object({
22
- disabled: z.literal(true).optional(),
23
- instances: z.literal(true).optional(),
24
- path: z.string().startsWith("/").max(1024),
25
- slot: z.string().min(1).max(255)
26
- })).max(1e3).optional()
27
- });
28
- const createTailorKitUploadManifest = (logos, server = false, views) => {
29
- const assets = { client: "client/client.js" };
30
- if (server) assets.server = "server/server.js";
31
- if (logos && Object.keys(logos).length > 0) assets.logos = logos;
32
- return tailorkitUploadManifestSchema.parse({
33
- assets,
34
- version: 1,
35
- views
36
- });
37
- };
38
- //#endregion
39
10
  //#region src/builder/database-paths.ts
40
11
  const appDatabasePaths = (root, migrations) => ({
41
12
  migrations: path.resolve(root, migrations ?? "./src/db/migrations"),
@@ -46,21 +17,27 @@ const appDatabasePaths = (root, migrations) => ({
46
17
  /** Use the app's Drizzle version with explicit flags; no Drizzle config file is needed. */
47
18
  const drizzleGenerateArguments = async (root, output, name) => {
48
19
  const require = createRequire(path.join(root, "package.json"));
49
- for (const directory of require.resolve.paths("drizzle-kit") ?? []) {
20
+ const cli = (await Promise.all((require.resolve.paths("drizzle-kit") ?? []).map(async (directory) => {
50
21
  const cli = path.join(directory, "drizzle-kit/bin.cjs");
51
- if (await access(cli).then(() => true).catch(() => false)) return [
52
- "--preserve-symlinks-main",
53
- cli,
54
- "generate",
55
- "--dialect",
56
- "sqlite",
57
- "--schema",
58
- appDatabasePaths(root).schema,
59
- "--out",
60
- output,
61
- ...name === void 0 ? [] : ["--name", name]
62
- ];
63
- }
22
+ try {
23
+ await access(cli);
24
+ return cli;
25
+ } catch {
26
+ return null;
27
+ }
28
+ }))).find((candidate) => candidate !== null);
29
+ if (cli !== void 0 && cli !== null && cli !== "") return [
30
+ "--preserve-symlinks-main",
31
+ cli,
32
+ "generate",
33
+ "--dialect",
34
+ "sqlite",
35
+ "--schema",
36
+ appDatabasePaths(root).schema,
37
+ "--out",
38
+ output,
39
+ ...name === void 0 ? [] : ["--name", name]
40
+ ];
64
41
  throw new Error("Install drizzle-kit and drizzle-orm as dev dependencies, then run tailorkit db generate.");
65
42
  };
66
43
  //#endregion
@@ -72,7 +49,7 @@ const getBuildEnvironment = () => process.env;
72
49
  const isMissingFile = (cause) => cause !== null && typeof cause === "object" && "code" in cause && cause.code === "ENOENT";
73
50
  //#endregion
74
51
  //#region src/builder/schema-check.ts
75
- const isObjectValue$1 = (value) => typeof value === "object" && value !== null;
52
+ const isObjectValue = (value) => typeof value === "object" && value !== null;
76
53
  const run = promisify(execFile);
77
54
  const snapshot = async (directory) => {
78
55
  const latest = (await readdir(directory, { withFileTypes: true }).catch((error) => {
@@ -91,7 +68,7 @@ const snapshot = async (directory) => {
91
68
  };
92
69
  const canonical = (value) => {
93
70
  if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
94
- if (isObjectValue$1(value)) return `{${Object.entries(value).toSorted(([left], [right]) => left.localeCompare(right)).map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`).join(",")}}`;
71
+ if (isObjectValue(value)) return `{${Object.entries(value).toSorted(([left], [right]) => left.localeCompare(right)).map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`).join(",")}}`;
95
72
  return JSON.stringify(value);
96
73
  };
97
74
  /** Generate a fresh snapshot with Drizzle in disposable storage, leaving committed history unchanged. */
@@ -130,6 +107,12 @@ const checkAppSchema = async (root, migrationsDirectory) => {
130
107
  }
131
108
  };
132
109
  //#endregion
110
+ //#region src/for-each-sequential.ts
111
+ /** Complete each operation before starting the next, and stop on the first failure. */
112
+ const forEachSequential = async (values, operation) => {
113
+ for (const value of values) await operation(value);
114
+ };
115
+ //#endregion
133
116
  //#region src/builder/define-view.ts
134
117
  const clientImports = /* @__PURE__ */ new Set([
135
118
  "tailorkit/client",
@@ -255,7 +238,6 @@ const createDefineViewMatcher = (program) => {
255
238
  };
256
239
  //#endregion
257
240
  //#region src/builder/file-routes.ts
258
- const isObjectValue = (value) => typeof value === "object" && value !== null;
259
241
  const clientRuntimeImport = "tailorkit:file-client-runtime";
260
242
  const routePath = (name, filename, indexView = false) => {
261
243
  const segments = name.split(/[./]/u);
@@ -310,10 +292,7 @@ const inferFileView = (initialSource, filename, root) => {
310
292
  text: defaults
311
293
  });
312
294
  }
313
- for (const value of Object.values(node)) {
314
- const children = Array.isArray(value) ? value : [value];
315
- for (const child of children) if (isObjectValue(child) && Boolean(child) && "type" in child) visit(child);
316
- }
295
+ for (const child of childNodes(node)) visit(child);
317
296
  };
318
297
  visit(parsed.program);
319
298
  for (const edit of edits.toSorted((a, b) => b.position - a.position)) source = source.slice(0, edit.position) + edit.text + source.slice(edit.position);
@@ -333,7 +312,7 @@ const discoverFileRoutes = async (root) => {
333
312
  throw error;
334
313
  }
335
314
  })();
336
- for (const entry of entries.toSorted((a, b) => a.name.localeCompare(b.name))) {
315
+ await forEachSequential(entries.toSorted((a, b) => a.name.localeCompare(b.name)), async (entry) => {
337
316
  const filename = path.join(directory, entry.name);
338
317
  if (entry.isDirectory()) await scan(filename, slot ?? entry.name, slot !== void 0 && slot !== null && slot !== "" ? `${prefix}${entry.name}/` : "");
339
318
  else if (entry.isFile() && slot !== void 0 && slot !== null && slot !== "") {
@@ -356,7 +335,7 @@ const discoverFileRoutes = async (root) => {
356
335
  });
357
336
  }
358
337
  }
359
- }
338
+ });
360
339
  };
361
340
  await scan(slotsDir);
362
341
  const rootFile = path.join(root, "src/root.tsx");
@@ -462,4 +441,4 @@ const fileRoutesPlugin = (root) => ({
462
441
  }
463
442
  });
464
443
  //#endregion
465
- export { createDefineViewMatcher as a, getBuildEnvironment as c, createTailorKitUploadManifest as d, tailorkitUploadManifestSchema as f, inferFileView as i, drizzleGenerateArguments as l, fileRoutesPlugin as n, checkAppSchema as o, getClientSourceFiles as r, isMissingFile as s, createFileRouteEntry as t, appDatabasePaths as u };
444
+ export { createDefineViewMatcher as a, isMissingFile as c, appDatabasePaths as d, inferFileView as i, getBuildEnvironment as l, fileRoutesPlugin as n, forEachSequential as o, getClientSourceFiles as r, checkAppSchema as s, createFileRouteEntry as t, drizzleGenerateArguments as u };
package/dist/index.mjs CHANGED
@@ -1,5 +1,6 @@
1
- import { a as createDefineViewMatcher, c as getBuildEnvironment, d as createTailorKitUploadManifest, f as tailorkitUploadManifestSchema, i as inferFileView, n as fileRoutesPlugin, o as checkAppSchema, s as isMissingFile, t as createFileRouteEntry, u as appDatabasePaths } from "./file-routes-7N97Zavb.mjs";
1
+ import { createTailorKitUploadManifest, tailorkitUploadManifestSchema } from "./upload-manifest.mjs";
2
2
  import { loadTailorKitConfig } from "./config-loader.mjs";
3
+ import { a as createDefineViewMatcher, c as isMissingFile, d as appDatabasePaths, i as inferFileView, l as getBuildEnvironment, n as fileRoutesPlugin, o as forEachSequential, s as checkAppSchema, t as createFileRouteEntry } from "./file-routes-BYuuJaSg.mjs";
3
4
  import { createRequire } from "node:module";
4
5
  import { z } from "zod";
5
6
  import { execFile } from "node:child_process";
@@ -435,7 +436,7 @@ const readAppMigrations = async (directory, optional = false) => {
435
436
  const migrations = [];
436
437
  const files = [directory];
437
438
  const names = entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).toSorted();
438
- for (const name of names) {
439
+ await forEachSequential(names, async (name) => {
439
440
  if (!/^\d{14}_[\w-]+$/u.test(name)) throw new Error(`Unsupported app migration folder: ${name}. Use Drizzle Kit v1 migrations.`);
440
441
  const file = path.join(directory, name, "migration.sql");
441
442
  const sql = await readFile(file, "utf-8");
@@ -447,7 +448,7 @@ const readAppMigrations = async (directory, optional = false) => {
447
448
  statements
448
449
  });
449
450
  files.push(file);
450
- }
451
+ });
451
452
  return {
452
453
  files,
453
454
  migrations
@@ -672,9 +673,9 @@ const tailorkit = (options = {}) => {
672
673
  resolve: resolved.resolve
673
674
  });
674
675
  const logoManifest = {};
675
- for (const variant of ["light", "dark"]) {
676
+ await forEachSequential(["light", "dark"], async (variant) => {
676
677
  const configuredPath = loaded.config.logos?.[variant];
677
- if (!(configuredPath !== void 0 && configuredPath !== null && configuredPath !== "")) continue;
678
+ if (!(configuredPath !== void 0 && configuredPath !== null && configuredPath !== "")) return;
678
679
  const extension = path.extname(configuredPath).toLowerCase().slice(1);
679
680
  const contentType = (/* @__PURE__ */ new Map([
680
681
  ["png", "image/png"],
@@ -687,7 +688,7 @@ const tailorkit = (options = {}) => {
687
688
  const filename = `logo-${variant}.${extension}`;
688
689
  await writeFile(path.join(clientOutDir, filename), content);
689
690
  logoManifest[variant] = `client/${filename}`;
690
- }
691
+ });
691
692
  await writeFile(path.join(clientOutDir, "views.json"), `${JSON.stringify(views)}\n`);
692
693
  await writeFile(path.join(resolvedOutDir, "tailorkit-upload.json"), `${JSON.stringify(createTailorKitUploadManifest(logoManifest, Boolean(loaded.config.server), views), null, 2)}\n`, "utf-8");
693
694
  };
@@ -0,0 +1,22 @@
1
+ import { z } from "zod";
2
+ //#region src/builder/upload-manifest.d.ts
3
+ export declare const tailorkitUploadManifestSchema: z.ZodObject<{
4
+ assets: z.ZodObject<{
5
+ client: z.ZodLiteral<"client/client.js">;
6
+ logos: z.ZodOptional<z.ZodObject<{
7
+ dark: z.ZodOptional<z.ZodString>;
8
+ light: z.ZodOptional<z.ZodString>;
9
+ }, z.core.$strip>>;
10
+ server: z.ZodOptional<z.ZodLiteral<"server/server.js">>;
11
+ }, z.core.$strip>;
12
+ version: z.ZodLiteral<1>;
13
+ views: z.ZodOptional<z.ZodArray<z.ZodObject<{
14
+ disabled: z.ZodOptional<z.ZodLiteral<true>>;
15
+ instances: z.ZodOptional<z.ZodLiteral<true>>;
16
+ path: z.ZodString;
17
+ slot: z.ZodString;
18
+ }, z.core.$strip>>>;
19
+ }, z.core.$strip>;
20
+ export type TailorKitUploadManifest = z.output<typeof tailorkitUploadManifestSchema>;
21
+ export declare const createTailorKitUploadManifest: (logos?: TailorKitUploadManifest["assets"]["logos"], server?: boolean, views?: TailorKitUploadManifest["views"]) => TailorKitUploadManifest;
22
+ //#endregion
@@ -0,0 +1,31 @@
1
+ import { z } from "zod";
2
+ //#region src/builder/upload-manifest.ts
3
+ const tailorkitUploadManifestSchema = z.object({
4
+ assets: z.object({
5
+ client: z.literal("client/client.js"),
6
+ logos: z.object({
7
+ dark: z.string().regex(/^client\/logo-dark\.(?:png|svg|webp)$/u).optional(),
8
+ light: z.string().regex(/^client\/logo-light\.(?:png|svg|webp)$/u).optional()
9
+ }).optional(),
10
+ server: z.literal("server/server.js").optional()
11
+ }),
12
+ version: z.literal(1),
13
+ views: z.array(z.object({
14
+ disabled: z.literal(true).optional(),
15
+ instances: z.literal(true).optional(),
16
+ path: z.string().startsWith("/").max(1024),
17
+ slot: z.string().min(1).max(255)
18
+ })).max(1e3).optional()
19
+ });
20
+ const createTailorKitUploadManifest = (logos, server = false, views) => {
21
+ const assets = { client: "client/client.js" };
22
+ if (server) assets.server = "server/server.js";
23
+ if (logos && Object.keys(logos).length > 0) assets.logos = logos;
24
+ return tailorkitUploadManifestSchema.parse({
25
+ assets,
26
+ version: 1,
27
+ views
28
+ });
29
+ };
30
+ //#endregion
31
+ export { createTailorKitUploadManifest, tailorkitUploadManifestSchema };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tailorkit/vite",
3
- "version": "0.1.0-beta.36",
3
+ "version": "0.1.0-beta.38",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -30,6 +30,10 @@
30
30
  "types": "./dist/builder.d.mts",
31
31
  "import": "./dist/builder.mjs"
32
32
  },
33
+ "./upload-manifest": {
34
+ "types": "./dist/upload-manifest.d.mts",
35
+ "import": "./dist/upload-manifest.mjs"
36
+ },
33
37
  "./config": {
34
38
  "types": "./dist/config.d.mts",
35
39
  "import": "./dist/config.mjs"
@@ -43,7 +47,7 @@
43
47
  "access": "public"
44
48
  },
45
49
  "dependencies": {
46
- "@tailorkit/app": "0.1.0-beta.36",
50
+ "@tailorkit/app": "0.1.0-beta.38",
47
51
  "cosmiconfig": "^10.0.1",
48
52
  "zod": "^4.6.5"
49
53
  },