@stacksjs/buddy 0.70.87 → 0.70.88

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.
Files changed (143) hide show
  1. package/package.json +2 -2
  2. package/dist/cli.d.ts +0 -1
  3. package/dist/cli.js +0 -165
  4. package/dist/commands/about.d.ts +0 -2
  5. package/dist/commands/about.js +0 -35
  6. package/dist/commands/add.d.ts +0 -2
  7. package/dist/commands/add.js +0 -33
  8. package/dist/commands/auth.d.ts +0 -2
  9. package/dist/commands/auth.js +0 -68
  10. package/dist/commands/build.d.ts +0 -2
  11. package/dist/commands/build.js +0 -153
  12. package/dist/commands/cd.d.ts +0 -20
  13. package/dist/commands/cd.js +0 -39
  14. package/dist/commands/changelog.d.ts +0 -2
  15. package/dist/commands/changelog.js +0 -32
  16. package/dist/commands/clean.d.ts +0 -2
  17. package/dist/commands/clean.js +0 -37
  18. package/dist/commands/cloud.d.ts +0 -2
  19. package/dist/commands/cloud.js +0 -503
  20. package/dist/commands/commit.d.ts +0 -2
  21. package/dist/commands/commit.js +0 -16
  22. package/dist/commands/completion.d.ts +0 -2
  23. package/dist/commands/completion.js +0 -143
  24. package/dist/commands/config-migrate.d.ts +0 -26
  25. package/dist/commands/config-migrate.js +0 -94
  26. package/dist/commands/configure.d.ts +0 -2
  27. package/dist/commands/configure.js +0 -48
  28. package/dist/commands/create.d.ts +0 -2
  29. package/dist/commands/create.js +0 -141
  30. package/dist/commands/deploy.d.ts +0 -107
  31. package/dist/commands/deploy.js +0 -1439
  32. package/dist/commands/dev.d.ts +0 -10
  33. package/dist/commands/dev.js +0 -907
  34. package/dist/commands/dns.d.ts +0 -2
  35. package/dist/commands/dns.js +0 -102
  36. package/dist/commands/doctor.d.ts +0 -2
  37. package/dist/commands/doctor.js +0 -285
  38. package/dist/commands/domains.d.ts +0 -2
  39. package/dist/commands/domains.js +0 -159
  40. package/dist/commands/email.d.ts +0 -2
  41. package/dist/commands/email.js +0 -524
  42. package/dist/commands/env.d.ts +0 -2
  43. package/dist/commands/env.js +0 -246
  44. package/dist/commands/extension.d.ts +0 -8
  45. package/dist/commands/extension.js +0 -78
  46. package/dist/commands/features.d.ts +0 -180
  47. package/dist/commands/features.js +0 -422
  48. package/dist/commands/fresh.d.ts +0 -2
  49. package/dist/commands/fresh.js +0 -39
  50. package/dist/commands/generate.d.ts +0 -2
  51. package/dist/commands/generate.js +0 -104
  52. package/dist/commands/http.d.ts +0 -2
  53. package/dist/commands/http.js +0 -33
  54. package/dist/commands/index.d.ts +0 -53
  55. package/dist/commands/index.js +0 -53
  56. package/dist/commands/install.d.ts +0 -2
  57. package/dist/commands/install.js +0 -22
  58. package/dist/commands/key.d.ts +0 -2
  59. package/dist/commands/key.js +0 -23
  60. package/dist/commands/lint.d.ts +0 -2
  61. package/dist/commands/lint.js +0 -46
  62. package/dist/commands/list.d.ts +0 -2
  63. package/dist/commands/list.js +0 -108
  64. package/dist/commands/mail.d.ts +0 -2
  65. package/dist/commands/mail.js +0 -693
  66. package/dist/commands/maintenance.d.ts +0 -2
  67. package/dist/commands/maintenance.js +0 -141
  68. package/dist/commands/make.d.ts +0 -2
  69. package/dist/commands/make.js +0 -375
  70. package/dist/commands/migrate-project.d.ts +0 -2
  71. package/dist/commands/migrate-project.js +0 -49
  72. package/dist/commands/migrate.d.ts +0 -4
  73. package/dist/commands/migrate.js +0 -455
  74. package/dist/commands/outdated.d.ts +0 -2
  75. package/dist/commands/outdated.js +0 -19
  76. package/dist/commands/package.d.ts +0 -2
  77. package/dist/commands/package.js +0 -17
  78. package/dist/commands/phone.d.ts +0 -2
  79. package/dist/commands/phone.js +0 -188
  80. package/dist/commands/ports.d.ts +0 -2
  81. package/dist/commands/ports.js +0 -118
  82. package/dist/commands/prepublish.d.ts +0 -2
  83. package/dist/commands/prepublish.js +0 -17
  84. package/dist/commands/projects.d.ts +0 -2
  85. package/dist/commands/projects.js +0 -29
  86. package/dist/commands/publish.d.ts +0 -2
  87. package/dist/commands/publish.js +0 -172
  88. package/dist/commands/queue.d.ts +0 -2
  89. package/dist/commands/queue.js +0 -248
  90. package/dist/commands/release.d.ts +0 -2
  91. package/dist/commands/release.js +0 -30
  92. package/dist/commands/route.d.ts +0 -2
  93. package/dist/commands/route.js +0 -21
  94. package/dist/commands/saas.d.ts +0 -2
  95. package/dist/commands/saas.js +0 -25
  96. package/dist/commands/schedule.d.ts +0 -2
  97. package/dist/commands/schedule.js +0 -61
  98. package/dist/commands/search.d.ts +0 -2
  99. package/dist/commands/search.js +0 -84
  100. package/dist/commands/seed.d.ts +0 -2
  101. package/dist/commands/seed.js +0 -71
  102. package/dist/commands/serve.d.ts +0 -25
  103. package/dist/commands/serve.js +0 -182
  104. package/dist/commands/setup.d.ts +0 -12
  105. package/dist/commands/setup.js +0 -215
  106. package/dist/commands/share.d.ts +0 -2
  107. package/dist/commands/share.js +0 -214
  108. package/dist/commands/sms.d.ts +0 -2
  109. package/dist/commands/sms.js +0 -328
  110. package/dist/commands/stacks.d.ts +0 -2
  111. package/dist/commands/stacks.js +0 -69
  112. package/dist/commands/telemetry.d.ts +0 -2
  113. package/dist/commands/telemetry.js +0 -74
  114. package/dist/commands/test.d.ts +0 -2
  115. package/dist/commands/test.js +0 -130
  116. package/dist/commands/tinker.d.ts +0 -2
  117. package/dist/commands/tinker.js +0 -37
  118. package/dist/commands/types.d.ts +0 -2
  119. package/dist/commands/types.js +0 -18
  120. package/dist/commands/upgrade.d.ts +0 -2
  121. package/dist/commands/upgrade.js +0 -98
  122. package/dist/commands/version.d.ts +0 -2
  123. package/dist/commands/version.js +0 -16
  124. package/dist/config.d.ts +0 -43
  125. package/dist/config.js +0 -223
  126. package/dist/custom-cli.d.ts +0 -1
  127. package/dist/custom-cli.js +0 -23
  128. package/dist/index.d.ts +0 -1
  129. package/dist/index.js +0 -1
  130. package/dist/lazy-commands.d.ts +0 -61
  131. package/dist/lazy-commands.js +0 -188
  132. package/dist/migrators/index.d.ts +0 -9
  133. package/dist/migrators/index.js +0 -62
  134. package/dist/migrators/laravel/index.d.ts +0 -2
  135. package/dist/migrators/laravel/index.js +0 -148
  136. package/dist/migrators/laravel/migrations.d.ts +0 -52
  137. package/dist/migrators/laravel/migrations.js +0 -232
  138. package/dist/migrators/laravel/models.d.ts +0 -34
  139. package/dist/migrators/laravel/models.js +0 -134
  140. package/dist/migrators/rails/index.d.ts +0 -2
  141. package/dist/migrators/rails/index.js +0 -11
  142. package/dist/migrators/types.d.ts +0 -44
  143. package/dist/migrators/types.js +0 -0
@@ -1,232 +0,0 @@
1
- export function parseLaravelMigration(source) {
2
- const createMatch = source.match(/Schema::create\(\s*['"]([a-z0-9_]+)['"]\s*,\s*function\s*\([^)]*\)\s*\{([\s\S]*?)\}\s*\)\s*;/i);
3
- if (!createMatch?.[1] || createMatch[2] === void 0)
4
- return null;
5
- const table = createMatch[1], body = createMatch[2], skipped = [], columns = [], indexes = [], lines = body.split(`
6
- `).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("//") && !line.startsWith("*") && !line.startsWith("/*"));
7
- for (const line of lines) {
8
- const trimmed = line.replace(/;\s*$/, "");
9
- if (!trimmed.startsWith("$table->")) {
10
- skipped.push(line);
11
- continue;
12
- }
13
- const parsed = parseColumnLine(trimmed);
14
- if (!parsed) {
15
- skipped.push(line);
16
- continue;
17
- }
18
- if (parsed.kind === "columns") {
19
- columns.push(...parsed.columns);
20
- if (parsed.indexes)
21
- indexes.push(...parsed.indexes);
22
- } else if (parsed.kind === "index")
23
- indexes.push(parsed.index);
24
- else if (parsed.kind === "skip")
25
- skipped.push(line);
26
- }
27
- const sql = emitCreateTable(table, columns, indexes);
28
- return { table, sql, skipped };
29
- }
30
- function parseColumnLine(line) {
31
- const methodMatch = line.match(/^\$table->([a-zA-Z_]+)\s*\(([^)]*)\)(.*)$/);
32
- if (!methodMatch?.[1] || methodMatch[2] === void 0 || methodMatch[3] === void 0)
33
- return null;
34
- const method = methodMatch[1], args = methodMatch[2].trim(), rest = methodMatch[3];
35
- if (method === "timestamps")
36
- return {
37
- kind: "columns",
38
- columns: [
39
- { name: "created_at", type: "DATETIME", nullable: !0, unique: !1, primaryKey: !1, autoIncrement: !1, defaultValue: "CURRENT_TIMESTAMP", index: !1 },
40
- { name: "updated_at", type: "DATETIME", nullable: !0, unique: !1, primaryKey: !1, autoIncrement: !1, defaultValue: null, index: !1 }
41
- ]
42
- };
43
- if (method === "softDeletes")
44
- return {
45
- kind: "columns",
46
- columns: [
47
- { name: "deleted_at", type: "DATETIME", nullable: !0, unique: !1, primaryKey: !1, autoIncrement: !1, defaultValue: null, index: !1 }
48
- ]
49
- };
50
- if (method === "rememberToken")
51
- return {
52
- kind: "columns",
53
- columns: [
54
- { name: "remember_token", type: "TEXT", nullable: !0, unique: !1, primaryKey: !1, autoIncrement: !1, defaultValue: null, index: !1 }
55
- ]
56
- };
57
- if (method === "id" || method === "increments" || method === "bigIncrements")
58
- return {
59
- kind: "columns",
60
- columns: [
61
- { name: parseStringArg(args) || "id", type: "INTEGER", nullable: !1, unique: !1, primaryKey: !0, autoIncrement: !0, defaultValue: null, index: !1 }
62
- ]
63
- };
64
- if (method === "index" || method === "unique") {
65
- const cols = parseIndexArg(args);
66
- if (cols.length === 0)
67
- return { kind: "skip" };
68
- return {
69
- kind: "index",
70
- index: { name: "", columns: cols, unique: method === "unique" }
71
- };
72
- }
73
- const columnName = parseStringArg(args);
74
- if (!columnName)
75
- return null;
76
- const sqlType = mapType(method);
77
- if (!sqlType)
78
- return { kind: "skip" };
79
- const column = {
80
- name: columnName,
81
- type: sqlType,
82
- nullable: !1,
83
- unique: !1,
84
- primaryKey: !1,
85
- autoIncrement: !1,
86
- defaultValue: null,
87
- index: !1
88
- };
89
- applyModifiers(rest, column);
90
- const indexes = [];
91
- if (column.unique)
92
- indexes.push({ name: "", columns: [columnName], unique: !0 });
93
- if (column.index)
94
- indexes.push({ name: "", columns: [columnName], unique: !1 });
95
- return { kind: "columns", columns: [column], indexes };
96
- }
97
- function applyModifiers(rest, column) {
98
- const modRegex = /->([a-zA-Z_]+)\s*\(([^)]*)\)/g;
99
- let match;
100
- while ((match = modRegex.exec(rest)) !== null) {
101
- const mod = match[1], args = match[2]?.trim() ?? "";
102
- if (!mod)
103
- continue;
104
- switch (mod) {
105
- case "nullable":
106
- column.nullable = !0;
107
- break;
108
- case "unique":
109
- column.unique = !0;
110
- break;
111
- case "index":
112
- column.index = !0;
113
- break;
114
- case "default":
115
- column.defaultValue = parseDefaultArg(args);
116
- break;
117
- case "primary":
118
- column.primaryKey = !0;
119
- break;
120
- case "autoIncrement":
121
- column.autoIncrement = !0;
122
- break;
123
- case "unsigned":
124
- case "comment":
125
- case "after":
126
- case "change":
127
- break;
128
- default:
129
- break;
130
- }
131
- }
132
- }
133
- function parseStringArg(args) {
134
- return args.match(/^['"]([^'"]+)['"]/)?.[1] ?? null;
135
- }
136
- function parseIndexArg(args) {
137
- const single = parseStringArg(args);
138
- if (single)
139
- return [single];
140
- const arr = args.match(/\[([^\]]*)\]/);
141
- if (!arr?.[1])
142
- return [];
143
- return arr[1].split(",").map((s) => s.trim().replace(/^['"]|['"]$/g, "")).filter(Boolean);
144
- }
145
- function parseDefaultArg(args) {
146
- const stringMatch = args.match(/^['"]([^'"]*)['"]/);
147
- if (stringMatch?.[1] !== void 0)
148
- return `'${stringMatch[1].replace(/'/g, "''")}'`;
149
- const trimmed = args.trim();
150
- if (trimmed === "true")
151
- return "1";
152
- if (trimmed === "false")
153
- return "0";
154
- if (trimmed === "null")
155
- return "NULL";
156
- if (/^-?\d+(\.\d+)?$/.test(trimmed))
157
- return trimmed;
158
- return trimmed;
159
- }
160
- const TYPE_MAP = {
161
- string: "TEXT",
162
- text: "TEXT",
163
- mediumText: "TEXT",
164
- longText: "TEXT",
165
- char: "TEXT",
166
- integer: "INTEGER",
167
- tinyInteger: "INTEGER",
168
- smallInteger: "INTEGER",
169
- mediumInteger: "INTEGER",
170
- bigInteger: "INTEGER",
171
- unsignedBigInteger: "INTEGER",
172
- unsignedInteger: "INTEGER",
173
- foreignId: "INTEGER",
174
- boolean: "INTEGER",
175
- date: "DATE",
176
- dateTime: "DATETIME",
177
- dateTimeTz: "DATETIME",
178
- timestamp: "DATETIME",
179
- timestampTz: "DATETIME",
180
- time: "TIME",
181
- timeTz: "TIME",
182
- year: "INTEGER",
183
- json: "TEXT",
184
- jsonb: "TEXT",
185
- uuid: "TEXT",
186
- ulid: "TEXT",
187
- ipAddress: "TEXT",
188
- macAddress: "TEXT",
189
- float: "REAL",
190
- double: "REAL",
191
- decimal: "REAL",
192
- binary: "BLOB",
193
- enum: "TEXT",
194
- set: "TEXT"
195
- };
196
- function mapType(laravelMethod) {
197
- return TYPE_MAP[laravelMethod] ?? null;
198
- }
199
- function emitCreateTable(table, columns, indexes) {
200
- const lines = [];
201
- lines.push(`CREATE TABLE IF NOT EXISTS ${table} (`);
202
- const colDefs = columns.map((c) => {
203
- const parts = [` ${c.name} ${c.type}`];
204
- if (c.primaryKey)
205
- parts.push("PRIMARY KEY");
206
- if (c.autoIncrement)
207
- parts.push("AUTOINCREMENT");
208
- if (!c.nullable && !c.primaryKey)
209
- parts.push("NOT NULL");
210
- if (c.defaultValue !== null)
211
- parts.push(`DEFAULT ${c.defaultValue}`);
212
- return parts.join(" ");
213
- });
214
- lines.push(colDefs.join(`,
215
- `));
216
- lines.push(");");
217
- for (const idx of indexes) {
218
- const cols = idx.columns.join(", "), indexName = idx.name || `${table}_${idx.columns.join("_")}_${idx.unique ? "unique" : "index"}`, verb = idx.unique ? "CREATE UNIQUE INDEX" : "CREATE INDEX";
219
- lines.push(`${verb} IF NOT EXISTS ${indexName} ON ${table}(${cols});`);
220
- }
221
- return `${lines.join(`
222
- `)}
223
- `;
224
- }
225
- export function laravelFilenameToStacks(filename, sequence, table) {
226
- const padded = String(sequence).padStart(10, "0"), base = filename.toLowerCase();
227
- if (base.includes("create_") && base.includes("_table"))
228
- return `${padded}-create-${table}-table.sql`;
229
- if (base.includes("add_") || base.includes("alter_"))
230
- return `${padded}-alter-${table}-migration.sql`;
231
- return `${padded}-create-${table}-table.sql`;
232
- }
@@ -1,34 +0,0 @@
1
- export declare function parseLaravelModel(source: string): ParsedModel | null;
2
- /**
3
- * Laravel Eloquent → Stacks `defineModel({})` translator.
4
- *
5
- * Eloquent models are PHP classes that lean on convention plus a few
6
- * `protected $foo = ...` properties to describe schema and behaviour.
7
- * We pull the bits we need by regex:
8
- *
9
- * - class name → model `name`
10
- * - protected $table → `table`
11
- * - protected $fillable → which attributes are `fillable: true`
12
- * - protected $casts → which attributes get a typed
13
- * validation rule
14
- * - hasMany/hasOne/belongsTo → relationship hints in the report
15
- *
16
- * Anything else (scopes, accessors, mutators, observers) gets dropped
17
- * with a note in the migration report. The user can re-add them by
18
- * hand from the Stacks docs.
19
- */
20
- export declare interface ParsedModel {
21
- className: string
22
- table: string
23
- fillable: string[]
24
- hidden: string[]
25
- casts: Record<string, string>
26
- relationships: ParsedRelationship[]
27
- tsSource: string
28
- notes: string[]
29
- }
30
- export declare interface ParsedRelationship {
31
- name: string
32
- kind: 'belongsTo' | 'hasMany' | 'hasOne' | 'belongsToMany'
33
- target: string
34
- }
@@ -1,134 +0,0 @@
1
- const RELATION_KINDS = ["belongsTo", "hasMany", "hasOne", "belongsToMany"];
2
- export function parseLaravelModel(source) {
3
- const classMatch = source.match(/\bclass\s+([A-Z][A-Za-z0-9_]*)\b/);
4
- if (!classMatch?.[1])
5
- return null;
6
- const className = classMatch[1], table = extractStringProperty(source, "table") ?? snakeCasePlural(className), fillable = extractArrayProperty(source, "fillable"), hidden = extractArrayProperty(source, "hidden"), casts = extractKeyedArrayProperty(source, "casts"), relationships = extractRelationships(source), notes = [];
7
- if (/protected\s+\$appends\s*=/.test(source))
8
- notes.push("$appends accessors require a custom Stacks computed-attribute setup");
9
- if (/protected\s+\$dates\s*=/.test(source))
10
- notes.push("$dates is implicit in Stacks \u2014 datetime columns are already typed via validation rules");
11
- if (/\buse\b[^;]*\bSoftDeletes\b/.test(source))
12
- notes.push("SoftDeletes trait \u2192 enable `useDeletedAt` (or matching trait) in the Stacks model traits block");
13
- if (/\buse\b[^;]*\bHasFactory\b/.test(source))
14
- notes.push("HasFactory \u2192 Stacks generates factories automatically when `useSeeder` is enabled");
15
- const tsSource = emitStacksModel({ className, table, fillable, hidden, casts, relationships });
16
- return { className, table, fillable, hidden, casts, relationships, tsSource, notes };
17
- }
18
- function extractStringProperty(source, name) {
19
- const re = new RegExp(`protected\\s+\\$${name}\\s*=\\s*['"]([^'"]+)['"]`);
20
- return source.match(re)?.[1] ?? null;
21
- }
22
- function extractArrayProperty(source, name) {
23
- const re = new RegExp(`protected\\s+\\$${name}\\s*=\\s*\\[([^\\]]*)\\]`, "s"), m = source.match(re);
24
- if (!m?.[1])
25
- return [];
26
- return m[1].split(",").map((s) => s.trim().replace(/^['"]|['"]$/g, "")).filter(Boolean);
27
- }
28
- function extractKeyedArrayProperty(source, name) {
29
- const re = new RegExp(`protected\\s+\\$${name}\\s*=\\s*\\[([^\\]]*)\\]`, "s"), m = source.match(re);
30
- if (!m?.[1])
31
- return {};
32
- const out = {}, pairs = m[1].split(",");
33
- for (const pair of pairs) {
34
- const kv = pair.match(/['"]([^'"]+)['"]\s*=>\s*['"]([^'"]+)['"]/);
35
- if (kv?.[1] && kv[2] !== void 0)
36
- out[kv[1]] = kv[2];
37
- }
38
- return out;
39
- }
40
- function extractRelationships(source) {
41
- const found = [], methodRegex = /public\s+function\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\([^)]*\)\s*(?::\s*[^\{]+)?\{[\s\S]*?return\s+\$this\s*->\s*(belongsTo|hasMany|hasOne|belongsToMany)\s*\(\s*([A-Z][A-Za-z0-9_]*)::class/g;
42
- let m;
43
- while ((m = methodRegex.exec(source)) !== null) {
44
- const name = m[1], kind = m[2], target = m[3];
45
- if (!name || !kind || !target)
46
- continue;
47
- found.push({ name, kind, target });
48
- }
49
- return found;
50
- }
51
- function emitStacksModel(args) {
52
- const attributeNames = unique([...args.fillable, ...Object.keys(args.casts)]), attrBlock = attributeNames.length === 0 ? " attributes: {}," : ` attributes: {
53
- ${attributeNames.map((n) => emitAttribute(n, args)).join(`
54
- `)}
55
- },`, relationsBlock = args.relationships.length === 0 ? "" : `
56
- // Relationships translated from Eloquent \u2014 refine targets / foreign keys to match your schema.
57
- relations: {
58
- ${args.relationships.map((r) => ` ${r.name}: { type: '${r.kind}', target: '${r.target}' },`).join(`
59
- `)}
60
- },
61
- `;
62
- return `import { defineModel } from '@stacksjs/orm'
63
- import { schema } from '@stacksjs/validation'
64
-
65
- export default defineModel({
66
- name: '${args.className}',
67
- table: '${args.table}',
68
- primaryKey: 'id',
69
- autoIncrement: true,
70
-
71
- traits: {
72
- useTimestamps: true,
73
- },
74
- ${relationsBlock}
75
- ${attrBlock}
76
- } as const)
77
- `;
78
- }
79
- function emitAttribute(name, args) {
80
- const rule = ruleForCast(args.casts[name]) ?? "schema.string()", fillable = args.fillable.includes(name), hidden = args.hidden.includes(name), notes = [];
81
- if (hidden)
82
- notes.push("hidden from API responses in source \u2014 handle via your Stacks resource/transformer");
83
- const noteLine = notes.length > 0 ? ` // ${notes.join("; ")}
84
- ` : "";
85
- return ` ${name}: {
86
- fillable: ${fillable},
87
- ${noteLine} validation: {
88
- rule: ${rule},
89
- },
90
- },`;
91
- }
92
- function ruleForCast(cast) {
93
- if (!cast)
94
- return null;
95
- switch (cast.split(":")[0]) {
96
- case "integer":
97
- case "int":
98
- return "schema.number().int()";
99
- case "float":
100
- case "double":
101
- case "real":
102
- return "schema.number()";
103
- case "boolean":
104
- case "bool":
105
- return "schema.boolean()";
106
- case "string":
107
- return "schema.string()";
108
- case "array":
109
- case "collection":
110
- case "json":
111
- case "object":
112
- return "schema.unknown()";
113
- case "date":
114
- case "datetime":
115
- case "immutable_date":
116
- case "immutable_datetime":
117
- return "schema.string()";
118
- case "decimal":
119
- return "schema.number()";
120
- default:
121
- return null;
122
- }
123
- }
124
- function snakeCasePlural(className) {
125
- const snake = className.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase();
126
- if (snake.endsWith("y") && !/[aeiou]y$/.test(snake))
127
- return `${snake.slice(0, -1)}ies`;
128
- if (snake.endsWith("s") || snake.endsWith("x") || snake.endsWith("z") || snake.endsWith("ch") || snake.endsWith("sh"))
129
- return `${snake}es`;
130
- return `${snake}s`;
131
- }
132
- function unique(arr) {
133
- return [...new Set(arr)];
134
- }
@@ -1,2 +0,0 @@
1
- import type { Driver } from '../types';
2
- export declare const railsDriver: Driver;
@@ -1,11 +0,0 @@
1
- export const railsDriver = {
2
- name: "rails",
3
- async migrate(_req) {
4
- return [{
5
- source: ".",
6
- target: "",
7
- status: "skipped",
8
- note: "Rails driver is not yet implemented (stacksjs/stacks#1241 \u2014 Laravel driver shipped first). Track follow-up at github.com/stacksjs/stacks/issues/1241."
9
- }];
10
- }
11
- };
@@ -1,44 +0,0 @@
1
- export declare interface MigrateProjectRequest {
2
- source: string
3
- target: string
4
- from: SourceFramework
5
- dryRun?: boolean
6
- }
7
- /**
8
- * A single output produced (or attempted) by a driver. Drivers append
9
- * one `ReportEntry` per source file they touch so the report reads
10
- * like a checklist of what was translated.
11
- */
12
- export declare interface ReportEntry {
13
- source: string
14
- target: string
15
- status: 'translated' | 'copied' | 'skipped' | 'failed'
16
- note?: string
17
- }
18
- export declare interface MigrationReport {
19
- source: string
20
- target: string
21
- from: SourceFramework
22
- startedAt: string
23
- finishedAt: string
24
- entries: ReportEntry[]
25
- }
26
- export declare interface Driver {
27
- readonly name: SourceFramework
28
- migrate: (req: MigrateProjectRequest) => Promise<ReportEntry[]>
29
- }
30
- /**
31
- * Shared types for the `./buddy migrate:project` migrators (Laravel,
32
- * Rails, …). Each driver consumes a source-project root and emits
33
- * Stacks-shaped files under a target root, returning a structured
34
- * report so the CLI can show the user what landed and what got
35
- * skipped.
36
- *
37
- * The migration is intentionally best-effort. The drivers prioritise
38
- * the high-value 80% (schema → migrations, models, env) and surface
39
- * unrecognised constructs as `skipped` entries rather than throwing —
40
- * a partial port the user can clean up beats a full failure mid-run.
41
- *
42
- * stacksjs/stacks#1241.
43
- */
44
- export type SourceFramework = 'laravel' | 'rails';
File without changes