@tanstack/cta-engine 0.48.0 → 0.49.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @tanstack/cta-engine
2
2
 
3
+ ## 0.49.1
4
+
5
+ ### Patch Changes
6
+
7
+ - fix: remove relative file prefixes ([`78af490`](https://github.com/TanStack/create-tsrouter-app/commit/78af49072b54a08ebfdafe72be146efecf4ce77c))
8
+
9
+ ## 0.49.0
10
+
11
+ ### Minor Changes
12
+
13
+ - Added categories, colors, exclusive tagging, addon file attribution utils, and railway addon ([#303](https://github.com/TanStack/create-tsrouter-app/pull/303))
14
+
3
15
  ## 0.48.0
4
16
 
5
17
  ### Minor Changes
@@ -0,0 +1,162 @@
1
+ function normalizePath(path) {
2
+ let p = path.startsWith('./') ? path.slice(2) : path;
3
+ p = p.replace(/\.ejs$/, '').replace(/_dot_/g, '.');
4
+ const match = p.match(/^(.+\/)?__([^_]+)__(.+)$/);
5
+ return match ? (match[1] || '') + match[3] : p;
6
+ }
7
+ async function getFileProvenance(filePath, framework, addOns, starter) {
8
+ const target = filePath.startsWith('./') ? filePath.slice(2) : filePath;
9
+ if (starter) {
10
+ const files = await starter.getFiles();
11
+ if (files.some((f) => normalizePath(f) === target)) {
12
+ return {
13
+ source: 'starter',
14
+ sourceId: starter.id,
15
+ sourceName: starter.name,
16
+ };
17
+ }
18
+ }
19
+ // Order add-ons by type then phase (matches writeFiles order), check in reverse
20
+ const typeOrder = ['add-on', 'example', 'toolchain', 'deployment'];
21
+ const phaseOrder = ['setup', 'add-on', 'example'];
22
+ const ordered = typeOrder.flatMap((type) => phaseOrder.flatMap((phase) => addOns.filter((a) => a.phase === phase && a.type === type)));
23
+ for (let i = ordered.length - 1; i >= 0; i--) {
24
+ const files = await ordered[i].getFiles();
25
+ if (files.some((f) => normalizePath(f) === target)) {
26
+ return {
27
+ source: 'add-on',
28
+ sourceId: ordered[i].id,
29
+ sourceName: ordered[i].name,
30
+ };
31
+ }
32
+ }
33
+ const frameworkFiles = await framework.getFiles();
34
+ if (frameworkFiles.some((f) => normalizePath(f) === target)) {
35
+ return {
36
+ source: 'framework',
37
+ sourceId: framework.id,
38
+ sourceName: framework.name,
39
+ };
40
+ }
41
+ return null;
42
+ }
43
+ // Build injection patterns from integrations (for source files)
44
+ function integrationInjections(int) {
45
+ const source = { sourceId: int._sourceId, sourceName: int._sourceName };
46
+ const injections = [];
47
+ const appliesTo = (path) => {
48
+ if (int.type === 'vite-plugin')
49
+ return path.includes('vite.config');
50
+ if (int.type === 'provider' ||
51
+ int.type === 'root-provider' ||
52
+ int.type === 'devtools') {
53
+ return path.includes('__root') || path.includes('root.tsx');
54
+ }
55
+ return false;
56
+ };
57
+ if (int.import) {
58
+ const prefix = int.import.split(' from ')[0];
59
+ injections.push({
60
+ matches: (line) => line.includes(prefix),
61
+ appliesTo,
62
+ source,
63
+ });
64
+ }
65
+ const code = int.code || int.jsName;
66
+ if (code) {
67
+ injections.push({
68
+ matches: (line) => line.includes(code),
69
+ appliesTo,
70
+ source,
71
+ });
72
+ }
73
+ return injections;
74
+ }
75
+ // Build injection pattern from a dependency (for package.json)
76
+ function dependencyInjection(dep) {
77
+ return {
78
+ matches: (line) => line.includes(`"${dep.name}"`),
79
+ appliesTo: (path) => path.endsWith('package.json'),
80
+ source: { sourceId: dep.sourceId, sourceName: dep.sourceName },
81
+ };
82
+ }
83
+ export async function computeAttribution(input) {
84
+ const { framework, chosenAddOns, starter, files } = input;
85
+ // Collect integrations tagged with source
86
+ const integrations = chosenAddOns.flatMap((addOn) => (addOn.integrations || []).map((int) => ({
87
+ ...int,
88
+ _sourceId: addOn.id,
89
+ _sourceName: addOn.name,
90
+ })));
91
+ // Collect dependencies from add-ons (from packageAdditions or packageTemplate)
92
+ const dependencies = chosenAddOns.flatMap((addOn) => {
93
+ const result = [];
94
+ const source = { sourceId: addOn.id, sourceName: addOn.name };
95
+ const addDeps = (deps, type) => {
96
+ if (!deps)
97
+ return;
98
+ for (const [name, version] of Object.entries(deps)) {
99
+ if (typeof version === 'string') {
100
+ result.push({ name, version, type, ...source });
101
+ }
102
+ }
103
+ };
104
+ // From static package.json
105
+ addDeps(addOn.packageAdditions?.dependencies, 'dependency');
106
+ addDeps(addOn.packageAdditions?.devDependencies, 'devDependency');
107
+ // From package.json.ejs template (strip EJS tags and parse)
108
+ if (addOn.packageTemplate) {
109
+ try {
110
+ const tmpl = JSON.parse(addOn.packageTemplate.replace(/"[^"]*<%[^%]*%>[^"]*"/g, '""'));
111
+ addDeps(tmpl.dependencies, 'dependency');
112
+ addDeps(tmpl.devDependencies, 'devDependency');
113
+ }
114
+ catch { }
115
+ }
116
+ return result;
117
+ });
118
+ // Build unified injection patterns from both integrations and dependencies
119
+ const injections = [
120
+ ...integrations.flatMap(integrationInjections),
121
+ ...dependencies.map(dependencyInjection),
122
+ ];
123
+ const attributedFiles = {};
124
+ for (const [filePath, content] of Object.entries(files)) {
125
+ const provenance = await getFileProvenance(filePath, framework, chosenAddOns, starter);
126
+ if (!provenance)
127
+ continue;
128
+ const lines = content.split('\n');
129
+ const relevant = injections.filter((inj) => inj.appliesTo(filePath));
130
+ // Find injected lines
131
+ const injectedLines = new Map();
132
+ for (const inj of relevant) {
133
+ lines.forEach((line, i) => {
134
+ if (inj.matches(line) && !injectedLines.has(i + 1)) {
135
+ injectedLines.set(i + 1, inj.source);
136
+ }
137
+ });
138
+ }
139
+ attributedFiles[filePath] = {
140
+ content,
141
+ provenance,
142
+ lineAttributions: lines.map((_, i) => {
143
+ const lineNum = i + 1;
144
+ const inj = injectedLines.get(lineNum);
145
+ return inj
146
+ ? {
147
+ line: lineNum,
148
+ sourceId: inj.sourceId,
149
+ sourceName: inj.sourceName,
150
+ type: 'injected',
151
+ }
152
+ : {
153
+ line: lineNum,
154
+ sourceId: provenance.sourceId,
155
+ sourceName: provenance.sourceName,
156
+ type: 'original',
157
+ };
158
+ }),
159
+ };
160
+ }
161
+ return { attributedFiles, dependencies };
162
+ }
@@ -5,7 +5,7 @@ import { createMemoryEnvironment } from '../environment.js';
5
5
  import { finalizeAddOns, populateAddOnOptionsDefaults } from '../add-ons.js';
6
6
  import { getFrameworkById } from '../frameworks.js';
7
7
  import { readConfigFileFromEnvironment } from '../config-file.js';
8
- import { readFileHelper } from '../file-helpers.js';
8
+ import { readFileHelper, toCleanPath } from '../file-helpers.js';
9
9
  import { loadStarter } from '../custom-add-ons/starter.js';
10
10
  export function createPackageAdditions(originalPackageJson, currentPackageJson) {
11
11
  const packageAdditions = {};
@@ -87,9 +87,10 @@ export async function runCreateApp(options) {
87
87
  ...options,
88
88
  targetDir,
89
89
  });
90
- output.files = Object.fromEntries(Object.entries(output.files).map(([key, value]) => {
91
- return [key.replace(targetDir, '.'), value];
92
- }));
90
+ output.files = Object.fromEntries(Object.entries(output.files).map(([key, value]) => [
91
+ toCleanPath(key, targetDir),
92
+ value,
93
+ ]));
93
94
  return output;
94
95
  }
95
96
  export async function compareFilesRecursively(path, ignore, original, changedFiles) {
@@ -28,6 +28,16 @@ export function getBinaryFile(content) {
28
28
  }
29
29
  return null;
30
30
  }
31
+ /**
32
+ * Convert an absolute path to a clean relative path by removing a base directory.
33
+ * Returns a path without leading ./ or / prefix.
34
+ */
35
+ export function toCleanPath(absolutePath, baseDir) {
36
+ let cleanPath = absolutePath.replace(baseDir, '');
37
+ if (cleanPath.startsWith('/'))
38
+ cleanPath = cleanPath.slice(1);
39
+ return cleanPath;
40
+ }
31
41
  export function relativePath(from, to, stripExtension = false) {
32
42
  const fixedOnWindows = from.startsWith('.\\')
33
43
  ? from.replace(/\\/g, '/')
@@ -88,7 +98,7 @@ async function recursivelyGatherFilesHelper(basePath, path, files, ignore) {
88
98
  }
89
99
  else {
90
100
  const filePath = resolve(path, file.name);
91
- files[filePath.replace(basePath, '.')] = await readFileHelper(filePath);
101
+ files[toCleanPath(filePath, basePath)] = await readFileHelper(filePath);
92
102
  }
93
103
  }
94
104
  }
@@ -109,7 +119,7 @@ async function recursivelyGatherFilesFromEnvironmentHelper(environment, basePath
109
119
  }
110
120
  else {
111
121
  const filePath = resolve(path, file);
112
- files[filePath.replace(basePath, '.')] =
122
+ files[toCleanPath(filePath, basePath)] =
113
123
  await environment.readFile(filePath);
114
124
  }
115
125
  }
@@ -158,7 +168,7 @@ export function createIgnore(path, includeProjectFiles = true) {
158
168
  export function cleanUpFiles(files, targetDir) {
159
169
  return Object.keys(files).reduce((acc, file) => {
160
170
  if (basename(file) !== '.cta.json') {
161
- acc[targetDir ? file.replace(targetDir, '.') : file] = files[file];
171
+ acc[targetDir ? toCleanPath(file, targetDir) : file] = files[file];
162
172
  }
163
173
  return acc;
164
174
  }, {});
@@ -166,7 +176,7 @@ export function cleanUpFiles(files, targetDir) {
166
176
  export function cleanUpFileArray(files, targetDir) {
167
177
  return files.reduce((acc, file) => {
168
178
  if (basename(file) !== '.cta.json') {
169
- acc.push(targetDir ? file.replace(targetDir, '.') : file);
179
+ acc.push(targetDir ? toCleanPath(file, targetDir) : file);
170
180
  }
171
181
  return acc;
172
182
  }, []);
@@ -1,12 +1,12 @@
1
1
  import { existsSync, readFileSync, readdirSync } from 'node:fs';
2
2
  import { resolve } from 'node:path';
3
- import { findFilesRecursively, isDirectory, readFileHelper, } from './file-helpers.js';
3
+ import { findFilesRecursively, isDirectory, readFileHelper, toCleanPath, } from './file-helpers.js';
4
4
  const frameworks = [];
5
5
  export function scanProjectDirectory(projectDirectory, baseDirectory) {
6
6
  const absolutePaths = {};
7
7
  findFilesRecursively(baseDirectory, absolutePaths);
8
8
  const files = Object.keys(absolutePaths).reduce((acc, path) => {
9
- acc[path.replace(baseDirectory, '.')] = absolutePaths[path];
9
+ acc[toCleanPath(path, baseDirectory)] = absolutePaths[path];
10
10
  return acc;
11
11
  }, {});
12
12
  const basePackageJSON = existsSync(resolve(baseDirectory, 'package.json'))
@@ -52,7 +52,7 @@ export function scanAddOnDirectories(addOnsDirectories) {
52
52
  }
53
53
  const files = {};
54
54
  for (const file of Object.keys(absoluteFiles)) {
55
- files[file.replace(assetsDir, '.')] = readFileHelper(file);
55
+ files[toCleanPath(file, assetsDir)] = readFileHelper(file);
56
56
  }
57
57
  const getFiles = () => {
58
58
  return Promise.resolve(Object.keys(files));
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export { createApp } from './create-app.js';
2
+ export { computeAttribution } from './attribution.js';
2
3
  export { addToApp } from './add-to-app.js';
3
- export { finalizeAddOns, getAllAddOns, populateAddOnOptionsDefaults } from './add-ons.js';
4
+ export { finalizeAddOns, getAllAddOns, populateAddOnOptionsDefaults, } from './add-ons.js';
4
5
  export { loadRemoteAddOn } from './custom-add-ons/add-on.js';
5
6
  export { loadStarter } from './custom-add-ons/starter.js';
6
7
  export { createMemoryEnvironment, createDefaultEnvironment, } from './environment.js';
@@ -8,7 +9,7 @@ export { CONFIG_FILE } from './constants.js';
8
9
  export { DEFAULT_PACKAGE_MANAGER, SUPPORTED_PACKAGE_MANAGERS, getPackageManager, } from './package-manager.js';
9
10
  export { registerFramework, getFrameworkById, getFrameworkByName, getFrameworks, scanProjectDirectory, scanAddOnDirectories, } from './frameworks.js';
10
11
  export { writeConfigFileToEnvironment, readConfigFileFromEnvironment, readConfigFile, } from './config-file.js';
11
- export { cleanUpFiles, cleanUpFileArray, readFileHelper, getBinaryFile, recursivelyGatherFiles, relativePath, } from './file-helpers.js';
12
+ export { cleanUpFiles, cleanUpFileArray, readFileHelper, getBinaryFile, recursivelyGatherFiles, relativePath, toCleanPath, } from './file-helpers.js';
12
13
  export { formatCommand, handleSpecialURL } from './utils.js';
13
14
  export { initStarter, compileStarter } from './custom-add-ons/starter.js';
14
15
  export { initAddOn, compileAddOn } from './custom-add-ons/add-on.js';
@@ -26,11 +26,16 @@ export function createTemplateFile(environment, options) {
26
26
  this.name = 'IgnoreFileError';
27
27
  }
28
28
  }
29
+ // Collect integrations and tag them with source add-on for attribution
29
30
  const integrations = [];
30
31
  for (const addOn of options.chosenAddOns) {
31
32
  if (addOn.integrations) {
32
33
  for (const integration of addOn.integrations) {
33
- integrations.push(integration);
34
+ integrations.push({
35
+ ...integration,
36
+ _sourceId: addOn.id,
37
+ _sourceName: addOn.name,
38
+ });
34
39
  }
35
40
  }
36
41
  }
@@ -0,0 +1,12 @@
1
+ import type { AddOn, AttributedFile, DependencyAttribution, Framework, Starter } from './types.js';
2
+ export interface AttributionInput {
3
+ framework: Framework;
4
+ chosenAddOns: Array<AddOn>;
5
+ starter?: Starter;
6
+ files: Record<string, string>;
7
+ }
8
+ export interface AttributionOutput {
9
+ attributedFiles: Record<string, AttributedFile>;
10
+ dependencies: Array<DependencyAttribution>;
11
+ }
12
+ export declare function computeAttribution(input: AttributionInput): Promise<AttributionOutput>;
@@ -39,6 +39,9 @@ export declare function generateProject(persistedOptions: PersistedOptions): Pro
39
39
  link?: string | undefined;
40
40
  license?: string | undefined;
41
41
  warning?: string | undefined;
42
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
43
+ exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
44
+ color?: string | undefined;
42
45
  priority?: number | undefined;
43
46
  routes?: {
44
47
  path: string;
@@ -67,14 +70,7 @@ export declare function generateProject(persistedOptions: PersistedOptions): Pro
67
70
  }[] | undefined;
68
71
  readme?: string | undefined;
69
72
  };
70
- output: {
71
- files: Record<string, string>;
72
- deletedFiles: Array<string>;
73
- commands: Array<{
74
- command: string;
75
- args: Array<string>;
76
- }>;
77
- };
73
+ output: import("../environment.js").MemoryEnvironmentOutput;
78
74
  }>;
79
75
  export declare function buildAssetsDirectory(output: {
80
76
  files: Record<string, string>;
@@ -3,13 +3,6 @@ import type { PersistedOptions } from '../config-file.js';
3
3
  export declare function createPackageAdditions(originalPackageJson: Record<string, any>, currentPackageJson: Record<string, any>): Record<string, any>;
4
4
  export declare function createAppOptionsFromPersisted(json: PersistedOptions): Promise<Options>;
5
5
  export declare function createSerializedOptionsFromPersisted(json: PersistedOptions): SerializedOptions;
6
- export declare function runCreateApp(options: Required<Options>): Promise<{
7
- files: Record<string, string>;
8
- deletedFiles: Array<string>;
9
- commands: Array<{
10
- command: string;
11
- args: Array<string>;
12
- }>;
13
- }>;
6
+ export declare function runCreateApp(options: Required<Options>): Promise<import("../environment.js").MemoryEnvironmentOutput>;
14
7
  export declare function compareFilesRecursively(path: string, ignore: (filePath: string) => boolean, original: Record<string, string>, changedFiles: Record<string, string>): Promise<void>;
15
8
  export declare function readCurrentProjectOptions(environment: Environment): Promise<PersistedOptions>;
@@ -1,13 +1,14 @@
1
1
  import type { Environment } from './types.js';
2
+ export interface MemoryEnvironmentOutput {
3
+ files: Record<string, string>;
4
+ deletedFiles: Array<string>;
5
+ commands: Array<{
6
+ command: string;
7
+ args: Array<string>;
8
+ }>;
9
+ }
2
10
  export declare function createDefaultEnvironment(): Environment;
3
11
  export declare function createMemoryEnvironment(returnPathsRelativeTo?: string): {
4
12
  environment: Environment;
5
- output: {
6
- files: Record<string, string>;
7
- deletedFiles: Array<string>;
8
- commands: Array<{
9
- command: string;
10
- args: Array<string>;
11
- }>;
12
- };
13
+ output: MemoryEnvironmentOutput;
13
14
  };
@@ -4,6 +4,11 @@ export declare function isBinaryFile(path: string): boolean;
4
4
  export declare function convertBinaryContentsToBase64(contents: any): string;
5
5
  export declare function isBase64(content: string): boolean;
6
6
  export declare function getBinaryFile(content: string): string | null;
7
+ /**
8
+ * Convert an absolute path to a clean relative path by removing a base directory.
9
+ * Returns a path without leading ./ or / prefix.
10
+ */
11
+ export declare function toCleanPath(absolutePath: string, baseDir: string): string;
7
12
  export declare function relativePath(from: string, to: string, stripExtension?: boolean): string;
8
13
  export declare function isDirectory(path: string): boolean;
9
14
  export declare function findFilesRecursively(path: string, files: Record<string, string>): void;
@@ -1,6 +1,7 @@
1
1
  export { createApp } from './create-app.js';
2
+ export { computeAttribution } from './attribution.js';
2
3
  export { addToApp } from './add-to-app.js';
3
- export { finalizeAddOns, getAllAddOns, populateAddOnOptionsDefaults } from './add-ons.js';
4
+ export { finalizeAddOns, getAllAddOns, populateAddOnOptionsDefaults, } from './add-ons.js';
4
5
  export { loadRemoteAddOn } from './custom-add-ons/add-on.js';
5
6
  export { loadStarter } from './custom-add-ons/starter.js';
6
7
  export { createMemoryEnvironment, createDefaultEnvironment, } from './environment.js';
@@ -8,7 +9,7 @@ export { CONFIG_FILE } from './constants.js';
8
9
  export { DEFAULT_PACKAGE_MANAGER, SUPPORTED_PACKAGE_MANAGERS, getPackageManager, } from './package-manager.js';
9
10
  export { registerFramework, getFrameworkById, getFrameworkByName, getFrameworks, scanProjectDirectory, scanAddOnDirectories, } from './frameworks.js';
10
11
  export { writeConfigFileToEnvironment, readConfigFileFromEnvironment, readConfigFile, } from './config-file.js';
11
- export { cleanUpFiles, cleanUpFileArray, readFileHelper, getBinaryFile, recursivelyGatherFiles, relativePath, } from './file-helpers.js';
12
+ export { cleanUpFiles, cleanUpFileArray, readFileHelper, getBinaryFile, recursivelyGatherFiles, relativePath, toCleanPath, } from './file-helpers.js';
12
13
  export { formatCommand, handleSpecialURL } from './utils.js';
13
14
  export { initStarter, compileStarter } from './custom-add-ons/starter.js';
14
15
  export { initAddOn, compileAddOn } from './custom-add-ons/add-on.js';
@@ -16,6 +17,8 @@ export { createAppOptionsFromPersisted, createSerializedOptionsFromPersisted, }
16
17
  export { createSerializedOptions } from './options.js';
17
18
  export { getRawRegistry, getRegistry, getRegistryAddOns, getRegistryStarters, } from './registry.js';
18
19
  export { StarterCompiledSchema, StatusEvent, StatusStepType, StopEvent, AddOnCompiledSchema, AddOnInfoSchema, IntegrationSchema, } from './types.js';
19
- export type { AddOn, AddOnOption, AddOnOptions, AddOnSelectOption, AddOnSelection, Environment, FileBundleHandler, Framework, FrameworkDefinition, Options, SerializedOptions, Starter, StarterCompiled, } from './types.js';
20
+ export type { AddOn, AddOnOption, AddOnOptions, AddOnSelectOption, AddOnSelection, Environment, FileBundleHandler, Framework, FrameworkDefinition, Options, SerializedOptions, Starter, StarterCompiled, LineAttribution, FileProvenance, AttributedFile, DependencyAttribution, } from './types.js';
21
+ export type { AttributionInput, AttributionOutput } from './attribution.js';
22
+ export type { MemoryEnvironmentOutput } from './environment.js';
20
23
  export type { PersistedOptions } from './config-file.js';
21
24
  export type { PackageManager } from './package-manager.js';
@@ -114,6 +114,9 @@ export declare const AddOnBaseSchema: z.ZodObject<{
114
114
  warning: z.ZodOptional<z.ZodString>;
115
115
  tailwind: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
116
116
  type: z.ZodEnum<["add-on", "example", "starter", "toolchain", "deployment"]>;
117
+ category: z.ZodOptional<z.ZodEnum<["tanstack", "database", "orm", "auth", "deploy", "styling", "monitoring", "cms", "api", "i18n", "tooling", "other"]>>;
118
+ exclusive: z.ZodOptional<z.ZodArray<z.ZodEnum<["orm", "auth", "deploy", "database", "linter"]>, "many">>;
119
+ color: z.ZodOptional<z.ZodString>;
117
120
  priority: z.ZodOptional<z.ZodNumber>;
118
121
  command: z.ZodOptional<z.ZodObject<{
119
122
  command: z.ZodString;
@@ -222,6 +225,9 @@ export declare const AddOnBaseSchema: z.ZodObject<{
222
225
  link?: string | undefined;
223
226
  license?: string | undefined;
224
227
  warning?: string | undefined;
228
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
229
+ exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
230
+ color?: string | undefined;
225
231
  priority?: number | undefined;
226
232
  routes?: {
227
233
  path: string;
@@ -267,6 +273,9 @@ export declare const AddOnBaseSchema: z.ZodObject<{
267
273
  license?: string | undefined;
268
274
  warning?: string | undefined;
269
275
  tailwind?: boolean | undefined;
276
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
277
+ exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
278
+ color?: string | undefined;
270
279
  priority?: number | undefined;
271
280
  routes?: {
272
281
  path: string;
@@ -297,6 +306,9 @@ export declare const StarterSchema: z.ZodObject<{
297
306
  license: z.ZodOptional<z.ZodString>;
298
307
  warning: z.ZodOptional<z.ZodString>;
299
308
  type: z.ZodEnum<["add-on", "example", "starter", "toolchain", "deployment"]>;
309
+ category: z.ZodOptional<z.ZodEnum<["tanstack", "database", "orm", "auth", "deploy", "styling", "monitoring", "cms", "api", "i18n", "tooling", "other"]>>;
310
+ exclusive: z.ZodOptional<z.ZodArray<z.ZodEnum<["orm", "auth", "deploy", "database", "linter"]>, "many">>;
311
+ color: z.ZodOptional<z.ZodString>;
300
312
  priority: z.ZodOptional<z.ZodNumber>;
301
313
  command: z.ZodOptional<z.ZodObject<{
302
314
  command: z.ZodString;
@@ -414,6 +426,9 @@ export declare const StarterSchema: z.ZodObject<{
414
426
  link?: string | undefined;
415
427
  license?: string | undefined;
416
428
  warning?: string | undefined;
429
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
430
+ exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
431
+ color?: string | undefined;
417
432
  priority?: number | undefined;
418
433
  routes?: {
419
434
  path: string;
@@ -463,6 +478,9 @@ export declare const StarterSchema: z.ZodObject<{
463
478
  link?: string | undefined;
464
479
  license?: string | undefined;
465
480
  warning?: string | undefined;
481
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
482
+ exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
483
+ color?: string | undefined;
466
484
  priority?: number | undefined;
467
485
  routes?: {
468
486
  path: string;
@@ -494,6 +512,9 @@ export declare const StarterCompiledSchema: z.ZodObject<{
494
512
  license: z.ZodOptional<z.ZodString>;
495
513
  warning: z.ZodOptional<z.ZodString>;
496
514
  type: z.ZodEnum<["add-on", "example", "starter", "toolchain", "deployment"]>;
515
+ category: z.ZodOptional<z.ZodEnum<["tanstack", "database", "orm", "auth", "deploy", "styling", "monitoring", "cms", "api", "i18n", "tooling", "other"]>>;
516
+ exclusive: z.ZodOptional<z.ZodArray<z.ZodEnum<["orm", "auth", "deploy", "database", "linter"]>, "many">>;
517
+ color: z.ZodOptional<z.ZodString>;
497
518
  priority: z.ZodOptional<z.ZodNumber>;
498
519
  command: z.ZodOptional<z.ZodObject<{
499
520
  command: z.ZodString;
@@ -616,6 +637,9 @@ export declare const StarterCompiledSchema: z.ZodObject<{
616
637
  link?: string | undefined;
617
638
  license?: string | undefined;
618
639
  warning?: string | undefined;
640
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
641
+ exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
642
+ color?: string | undefined;
619
643
  priority?: number | undefined;
620
644
  routes?: {
621
645
  path: string;
@@ -667,6 +691,9 @@ export declare const StarterCompiledSchema: z.ZodObject<{
667
691
  link?: string | undefined;
668
692
  license?: string | undefined;
669
693
  warning?: string | undefined;
694
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
695
+ exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
696
+ color?: string | undefined;
670
697
  priority?: number | undefined;
671
698
  routes?: {
672
699
  path: string;
@@ -718,6 +745,9 @@ export declare const AddOnInfoSchema: z.ZodObject<{
718
745
  warning: z.ZodOptional<z.ZodString>;
719
746
  tailwind: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
720
747
  type: z.ZodEnum<["add-on", "example", "starter", "toolchain", "deployment"]>;
748
+ category: z.ZodOptional<z.ZodEnum<["tanstack", "database", "orm", "auth", "deploy", "styling", "monitoring", "cms", "api", "i18n", "tooling", "other"]>>;
749
+ exclusive: z.ZodOptional<z.ZodArray<z.ZodEnum<["orm", "auth", "deploy", "database", "linter"]>, "many">>;
750
+ color: z.ZodOptional<z.ZodString>;
721
751
  priority: z.ZodOptional<z.ZodNumber>;
722
752
  command: z.ZodOptional<z.ZodObject<{
723
753
  command: z.ZodString;
@@ -851,6 +881,9 @@ export declare const AddOnInfoSchema: z.ZodObject<{
851
881
  link?: string | undefined;
852
882
  license?: string | undefined;
853
883
  warning?: string | undefined;
884
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
885
+ exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
886
+ color?: string | undefined;
854
887
  priority?: number | undefined;
855
888
  routes?: {
856
889
  path: string;
@@ -906,6 +939,9 @@ export declare const AddOnInfoSchema: z.ZodObject<{
906
939
  license?: string | undefined;
907
940
  warning?: string | undefined;
908
941
  tailwind?: boolean | undefined;
942
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
943
+ exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
944
+ color?: string | undefined;
909
945
  priority?: number | undefined;
910
946
  routes?: {
911
947
  path: string;
@@ -945,6 +981,9 @@ export declare const AddOnCompiledSchema: z.ZodObject<{
945
981
  warning: z.ZodOptional<z.ZodString>;
946
982
  tailwind: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
947
983
  type: z.ZodEnum<["add-on", "example", "starter", "toolchain", "deployment"]>;
984
+ category: z.ZodOptional<z.ZodEnum<["tanstack", "database", "orm", "auth", "deploy", "styling", "monitoring", "cms", "api", "i18n", "tooling", "other"]>>;
985
+ exclusive: z.ZodOptional<z.ZodArray<z.ZodEnum<["orm", "auth", "deploy", "database", "linter"]>, "many">>;
986
+ color: z.ZodOptional<z.ZodString>;
948
987
  priority: z.ZodOptional<z.ZodNumber>;
949
988
  command: z.ZodOptional<z.ZodObject<{
950
989
  command: z.ZodString;
@@ -1084,6 +1123,9 @@ export declare const AddOnCompiledSchema: z.ZodObject<{
1084
1123
  link?: string | undefined;
1085
1124
  license?: string | undefined;
1086
1125
  warning?: string | undefined;
1126
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
1127
+ exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
1128
+ color?: string | undefined;
1087
1129
  priority?: number | undefined;
1088
1130
  routes?: {
1089
1131
  path: string;
@@ -1142,6 +1184,9 @@ export declare const AddOnCompiledSchema: z.ZodObject<{
1142
1184
  license?: string | undefined;
1143
1185
  warning?: string | undefined;
1144
1186
  tailwind?: boolean | undefined;
1187
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
1188
+ exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
1189
+ color?: string | undefined;
1145
1190
  priority?: number | undefined;
1146
1191
  routes?: {
1147
1192
  path: string;
@@ -1279,4 +1324,31 @@ type UIEnvironment = {
1279
1324
  confirm: (message: string) => Promise<boolean>;
1280
1325
  };
1281
1326
  export type Environment = ProjectEnvironment & FileEnvironment & UIEnvironment;
1327
+ export interface LineAttribution {
1328
+ line: number;
1329
+ sourceId: string;
1330
+ sourceName: string;
1331
+ type: 'original' | 'injected';
1332
+ }
1333
+ export interface FileProvenance {
1334
+ source: 'framework' | 'add-on' | 'starter';
1335
+ sourceId: string;
1336
+ sourceName: string;
1337
+ }
1338
+ export interface AttributedFile {
1339
+ content: string;
1340
+ provenance: FileProvenance;
1341
+ lineAttributions: Array<LineAttribution>;
1342
+ }
1343
+ export interface DependencyAttribution {
1344
+ name: string;
1345
+ version: string;
1346
+ type: 'dependency' | 'devDependency';
1347
+ sourceId: string;
1348
+ sourceName: string;
1349
+ }
1350
+ export type IntegrationWithSource = Integration & {
1351
+ _sourceId: string;
1352
+ _sourceName: string;
1353
+ };
1282
1354
  export {};
package/dist/types.js CHANGED
@@ -24,6 +24,26 @@ export const AddOnBaseSchema = z.object({
24
24
  warning: z.string().optional(),
25
25
  tailwind: z.boolean().optional().default(true),
26
26
  type: z.enum(['add-on', 'example', 'starter', 'toolchain', 'deployment']),
27
+ category: z
28
+ .enum([
29
+ 'tanstack',
30
+ 'database',
31
+ 'orm',
32
+ 'auth',
33
+ 'deploy',
34
+ 'styling',
35
+ 'monitoring',
36
+ 'cms',
37
+ 'api',
38
+ 'i18n',
39
+ 'tooling',
40
+ 'other',
41
+ ])
42
+ .optional(),
43
+ exclusive: z
44
+ .array(z.enum(['orm', 'auth', 'deploy', 'database', 'linter']))
45
+ .optional(),
46
+ color: z.string().optional(),
27
47
  priority: z.number().optional(),
28
48
  command: z
29
49
  .object({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/cta-engine",
3
- "version": "0.48.0",
3
+ "version": "0.49.1",
4
4
  "description": "Tanstack Application Builder Engine",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",