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

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/dist/builder.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { d as createTailorKitUploadManifest, f as tailorkitUploadManifestSchema, l as drizzleGenerateArguments, o as checkAppSchema, r as getClientSourceFiles, u as appDatabasePaths } from "./file-routes-CjOIw7fH.mjs";
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";
2
2
  import { loadTailorKitConfig } from "./config-loader.mjs";
3
3
  import { spawn } from "node:child_process";
4
4
  import { access } from "node:fs/promises";
@@ -187,6 +187,14 @@ const callScopes = (program) => {
187
187
  if (node.kind === "var") while (!target.functionScope && target.parent) target = target.parent;
188
188
  for (const declaration of node.declarations) bind(declaration.id, target);
189
189
  };
190
+ const visitFunction = (node, scope, visit) => {
191
+ if (node.type === "FunctionDeclaration") bind(node.id, scope);
192
+ const parameters = createScope(scope, true);
193
+ if (node.type !== "ArrowFunctionExpression") bind(node.id, parameters);
194
+ for (const parameter of node.params) bind(parameter, parameters);
195
+ for (const parameter of node.params) visit(parameter, parameters);
196
+ if (node.body) visit(node.body, createScope(parameters, true));
197
+ };
190
198
  const visit = (node, initialScope) => {
191
199
  let scope = initialScope;
192
200
  scopes.set(node, scope);
@@ -200,7 +208,7 @@ const callScopes = (program) => {
200
208
  case "FunctionDeclaration":
201
209
  case "FunctionExpression":
202
210
  case "ArrowFunctionExpression":
203
- visitFunction(node, scope);
211
+ visitFunction(node, scope, visit);
204
212
  return;
205
213
  case "ClassDeclaration":
206
214
  case "ClassExpression":
@@ -230,14 +238,6 @@ const callScopes = (program) => {
230
238
  }
231
239
  for (const child of childNodes(node)) visit(child, scope);
232
240
  };
233
- const visitFunction = (node, scope) => {
234
- if (node.type === "FunctionDeclaration") bind(node.id, scope);
235
- const parameters = createScope(scope, true);
236
- if (node.type !== "ArrowFunctionExpression") bind(node.id, parameters);
237
- for (const parameter of node.params) bind(parameter, parameters);
238
- for (const parameter of node.params) visit(parameter, parameters);
239
- if (node.body) visit(node.body, createScope(parameters, true));
240
- };
241
241
  visit(program, createScope(void 0, true));
242
242
  return scopes;
243
243
  };
@@ -257,9 +257,10 @@ const createDefineViewMatcher = (program) => {
257
257
  //#region src/builder/file-routes.ts
258
258
  const isObjectValue = (value) => typeof value === "object" && value !== null;
259
259
  const clientRuntimeImport = "tailorkit:file-client-runtime";
260
- const routePath = (name, filename) => {
260
+ const routePath = (name, filename, indexView = false) => {
261
261
  const segments = name.split(/[./]/u);
262
262
  if (segments.some((segment) => !segment || segment === "..")) throw new Error(`${filename} has an empty route segment. Use route.nested-route.view.tsx.`);
263
+ if (indexView && segments.at(-1) === "index") segments.pop();
263
264
  return `/${segments.join("/")}`;
264
265
  };
265
266
  const fileViewLocation = (filename, root) => {
@@ -269,10 +270,22 @@ const fileViewLocation = (filename, root) => {
269
270
  if (!(slot !== void 0 && slot !== null && slot !== "")) return;
270
271
  const basename = routeSegments.join("/").slice(0, -9);
271
272
  return {
272
- path: routePath(basename, filename),
273
+ path: routePath(basename, filename, true),
273
274
  slot
274
275
  };
275
276
  };
277
+ const validateViewOptions = (options, expected, filename) => {
278
+ const properties = /* @__PURE__ */ new Set();
279
+ for (const property of options.properties) {
280
+ if (property.type !== "Property" || property.computed && property.key.type !== "Literal") throw new Error(`${filename}: use named defineView properties so the build can validate the slot and view against the file location.`);
281
+ let key;
282
+ if (property.key.type === "Identifier") key = property.key.name;
283
+ else if (property.key.type === "Literal") key = String(property.key.value);
284
+ if ((key === "slot" || key === "view") && (property.kind !== "init" || property.method || property.value.type !== "Literal" || property.value.value !== expected[key])) throw new Error(`${filename}: defineView ${key} must be ${JSON.stringify(expected[key])} to match the file location. Omit ${key} to infer it, or move the file to the matching location.`);
285
+ if (key !== void 0) properties.add(key);
286
+ }
287
+ return properties;
288
+ };
276
289
  /** Fill missing defineView options before instance extraction, on both build sides. */
277
290
  const inferFileView = (initialSource, filename, root) => {
278
291
  let source = initialSource;
@@ -287,12 +300,10 @@ const inferFileView = (initialSource, filename, root) => {
287
300
  if (isDefineViewCall(node)) {
288
301
  const [options] = node.arguments;
289
302
  if (options?.type !== "ObjectExpression") throw new Error(`${filename}: file views require defineView with an inline options object.`);
290
- const properties = new Set(options.properties.flatMap((property) => {
291
- if (property.type !== "Property" || property.computed) return [];
292
- if (property.key.type === "Identifier") return [property.key.name];
293
- if (property.key.type === "Literal") return [String(property.key.value)];
294
- return [];
295
- }));
303
+ const properties = validateViewOptions(options, {
304
+ slot,
305
+ view: viewPath
306
+ }, filename);
296
307
  const defaults = [properties.has("slot") ? "" : `slot: ${JSON.stringify(slot)},`, properties.has("view") ? "" : `view: ${JSON.stringify(viewPath)},`].join("");
297
308
  if (defaults) edits.push({
298
309
  position: options.start + 1,
@@ -327,10 +338,10 @@ const discoverFileRoutes = async (root) => {
327
338
  if (entry.isDirectory()) await scan(filename, slot ?? entry.name, slot !== void 0 && slot !== null && slot !== "" ? `${prefix}${entry.name}/` : "");
328
339
  else if (entry.isFile() && slot !== void 0 && slot !== null && slot !== "") {
329
340
  if (entry.name.endsWith(".view.tsx")) {
330
- fileViewLocation(filename, root);
331
- views.push({
341
+ const location = fileViewLocation(filename, root);
342
+ if (location) views.push({
332
343
  filename,
333
- slot
344
+ ...location
334
345
  });
335
346
  } else if (entry.name === "root.tsx" && !prefix) roots.push({
336
347
  filename,
@@ -380,7 +391,7 @@ const fileClientSource = async (root) => {
380
391
  const rootModule = discovered.root ? `${module(discovered.root)} }` : "undefined";
381
392
  const roots = discovered.roots.map((entry) => `${module(entry)}, slot: ${JSON.stringify(entry.slot)} }`);
382
393
  const layouts = discovered.layouts.map((entry) => `${module(entry)}, slot: ${JSON.stringify(entry.slot)}, path: ${JSON.stringify(entry.path)} }`);
383
- const views = discovered.views.map((entry) => `${module(entry)}, slot: ${JSON.stringify(entry.slot)} }`);
394
+ const views = discovered.views.map((entry) => `${module(entry)}, slot: ${JSON.stringify(entry.slot)}, path: ${JSON.stringify(entry.path)} }`);
384
395
  return `${imports.join("\n")}\nexport default createFileClient({ root: ${rootModule}, roots: [${roots.join(",")}], layouts: [${layouts.join(",")}], views: [${views.join(",")}] });`;
385
396
  };
386
397
  /** A generated entry in build output lets the bundler track imports normally.
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
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-CjOIw7fH.mjs";
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";
2
2
  import { loadTailorKitConfig } from "./config-loader.mjs";
3
3
  import { createRequire } from "node:module";
4
4
  import { z } from "zod";
@@ -162,6 +162,18 @@ const isFunction = (node) => [
162
162
  /** Lexical references, excluding property names and bindings local to a function/block. */
163
163
  const freeNames = (root) => {
164
164
  const references = /* @__PURE__ */ new Set();
165
+ const pattern = (node, scope, visit) => {
166
+ if (node.type === "AssignmentPattern") {
167
+ visit(node.right, scope);
168
+ pattern(node.left, scope, visit);
169
+ } else if (node.type === "ObjectPattern") for (const p of node.properties) if (p.type === "Property") {
170
+ if (p.computed) visit(p.key, scope);
171
+ pattern(p.value, scope, visit);
172
+ } else pattern(p.argument, scope, visit);
173
+ else if (node.type === "ArrayPattern") {
174
+ for (const element of node.elements) if (element) pattern(element, scope, visit);
175
+ } else if (node.type === "RestElement") pattern(node.argument, scope, visit);
176
+ };
165
177
  const visit = (node, parent) => {
166
178
  if (node.type === "Identifier") {
167
179
  if (!parent.has(node.name)) references.add(node.name);
@@ -184,7 +196,7 @@ const freeNames = (root) => {
184
196
  for (const child of children(body)) hoisted(child);
185
197
  };
186
198
  if (node.body) hoisted(node.body);
187
- for (const p of node.params) pattern(p, scope);
199
+ for (const p of node.params) pattern(p, scope, visit);
188
200
  if (node.body) visit(node.body, scope);
189
201
  return;
190
202
  }
@@ -194,7 +206,7 @@ const freeNames = (root) => {
194
206
  return;
195
207
  }
196
208
  if (node.type === "VariableDeclarator") {
197
- pattern(node.id, parent);
209
+ pattern(node.id, parent, visit);
198
210
  if (node.init) visit(node.init, parent);
199
211
  return;
200
212
  }
@@ -210,7 +222,7 @@ const freeNames = (root) => {
210
222
  }
211
223
  if (node.type === "CatchClause") {
212
224
  const scope = /* @__PURE__ */ new Set([...parent, ...boundNames(node.param)]);
213
- if (node.param) pattern(node.param, scope);
225
+ if (node.param) pattern(node.param, scope, visit);
214
226
  visit(node.body, scope);
215
227
  return;
216
228
  }
@@ -233,18 +245,6 @@ const freeNames = (root) => {
233
245
  if (node.type === "BreakStatement" || node.type === "ContinueStatement") return;
234
246
  for (const child of children(node)) visit(child, parent);
235
247
  };
236
- const pattern = (node, scope) => {
237
- if (node.type === "AssignmentPattern") {
238
- visit(node.right, scope);
239
- pattern(node.left, scope);
240
- } else if (node.type === "ObjectPattern") for (const p of node.properties) if (p.type === "Property") {
241
- if (p.computed) visit(p.key, scope);
242
- pattern(p.value, scope);
243
- } else pattern(p.argument, scope);
244
- else if (node.type === "ArrayPattern") {
245
- for (const element of node.elements) if (element) pattern(element, scope);
246
- } else if (node.type === "RestElement") pattern(node.argument, scope);
247
- };
248
248
  visit(root, /* @__PURE__ */ new Set());
249
249
  return references;
250
250
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tailorkit/vite",
3
- "version": "0.1.0-beta.34",
3
+ "version": "0.1.0-beta.36",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -43,7 +43,7 @@
43
43
  "access": "public"
44
44
  },
45
45
  "dependencies": {
46
- "@tailorkit/app": "0.1.0-beta.34",
46
+ "@tailorkit/app": "0.1.0-beta.36",
47
47
  "cosmiconfig": "^10.0.1",
48
48
  "zod": "^4.6.5"
49
49
  },