@ontrails/trails 1.0.0-beta.3 → 1.0.0-beta.4
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 +27 -0
- package/dist/src/trails/add-surface.js +9 -9
- package/dist/src/trails/add-surface.js.map +1 -1
- package/dist/src/trails/add-trail.d.ts +1 -2
- package/dist/src/trails/add-trail.d.ts.map +1 -1
- package/dist/src/trails/add-trail.js +16 -24
- package/dist/src/trails/add-trail.js.map +1 -1
- package/dist/src/trails/add-verify.js +9 -9
- package/dist/src/trails/add-verify.js.map +1 -1
- package/dist/src/trails/create-scaffold.js +25 -25
- package/dist/src/trails/create-scaffold.js.map +1 -1
- package/dist/src/trails/create.d.ts +1 -1
- package/dist/src/trails/create.js +10 -10
- package/dist/src/trails/create.js.map +1 -1
- package/dist/src/trails/guide.js +12 -12
- package/dist/src/trails/guide.js.map +1 -1
- package/dist/src/trails/survey.d.ts +0 -2
- package/dist/src/trails/survey.d.ts.map +1 -1
- package/dist/src/trails/survey.js +21 -25
- package/dist/src/trails/survey.js.map +1 -1
- package/dist/src/trails/warden.js +28 -28
- package/dist/src/trails/warden.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/create.test.ts +7 -7
- package/src/__tests__/guide.test.ts +4 -4
- package/src/__tests__/survey.test.ts +6 -8
- package/src/__tests__/warden.test.ts +2 -2
- package/src/trails/add-surface.ts +9 -9
- package/src/trails/add-trail.ts +16 -25
- package/src/trails/add-verify.ts +9 -9
- package/src/trails/create-scaffold.ts +27 -27
- package/src/trails/create.ts +10 -10
- package/src/trails/guide.ts +14 -14
- package/src/trails/survey.ts +29 -36
- package/src/trails/warden.ts +33 -33
package/src/trails/create.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { FollowFn } from '@ontrails/core';
|
|
9
|
-
import { Result,
|
|
9
|
+
import { Result, trail } from '@ontrails/core';
|
|
10
10
|
import { z } from 'zod';
|
|
11
11
|
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
@@ -146,7 +146,7 @@ const runCreate = async (
|
|
|
146
146
|
// Route definition
|
|
147
147
|
// ---------------------------------------------------------------------------
|
|
148
148
|
|
|
149
|
-
export const createRoute =
|
|
149
|
+
export const createRoute = trail('create', {
|
|
150
150
|
description: 'Create a new Trails project',
|
|
151
151
|
fields: {
|
|
152
152
|
starter: {
|
|
@@ -157,7 +157,7 @@ export const createRoute = hike('create', {
|
|
|
157
157
|
value: 'hello',
|
|
158
158
|
},
|
|
159
159
|
{
|
|
160
|
-
hint: '4 trails,
|
|
160
|
+
hint: '4 trails, event, store',
|
|
161
161
|
label: 'Entity CRUD',
|
|
162
162
|
value: 'entity',
|
|
163
163
|
},
|
|
@@ -175,13 +175,7 @@ export const createRoute = hike('create', {
|
|
|
175
175
|
],
|
|
176
176
|
},
|
|
177
177
|
},
|
|
178
|
-
|
|
179
|
-
implementation: async (input: BlazeInput, ctx) => {
|
|
180
|
-
if (!ctx.follow) {
|
|
181
|
-
return Result.err(new Error('create route requires ctx.follow'));
|
|
182
|
-
}
|
|
183
|
-
return await runCreate(ctx.follow, input);
|
|
184
|
-
},
|
|
178
|
+
follow: ['create.scaffold', 'add.surface', 'add.verify'],
|
|
185
179
|
input: z.object({
|
|
186
180
|
dir: z.string().optional().describe('Parent directory'),
|
|
187
181
|
name: z.string().describe('Project name'),
|
|
@@ -200,4 +194,10 @@ export const createRoute = hike('create', {
|
|
|
200
194
|
dir: z.string(),
|
|
201
195
|
name: z.string(),
|
|
202
196
|
}),
|
|
197
|
+
run: async (input: BlazeInput, ctx) => {
|
|
198
|
+
if (!ctx.follow) {
|
|
199
|
+
return Result.err(new Error('create route requires ctx.follow'));
|
|
200
|
+
}
|
|
201
|
+
return await runCreate(ctx.follow, input);
|
|
202
|
+
},
|
|
203
203
|
});
|
package/src/trails/guide.ts
CHANGED
|
@@ -63,19 +63,6 @@ export const guideTrail = trail('guide', {
|
|
|
63
63
|
name: 'List trail guidance',
|
|
64
64
|
},
|
|
65
65
|
],
|
|
66
|
-
implementation: async (input, ctx) => {
|
|
67
|
-
const app = await loadApp(input.module, ctx.cwd ?? '.');
|
|
68
|
-
|
|
69
|
-
if (input.trailId) {
|
|
70
|
-
const item = app.get(input.trailId);
|
|
71
|
-
if (!item) {
|
|
72
|
-
return Result.err(new Error(`Trail not found: ${input.trailId}`));
|
|
73
|
-
}
|
|
74
|
-
return Result.ok(toGuideDetail(item as Trail<unknown, unknown>));
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return Result.ok(toGuideEntries(app));
|
|
78
|
-
},
|
|
79
66
|
input: z.object({
|
|
80
67
|
module: z
|
|
81
68
|
.string()
|
|
@@ -83,6 +70,7 @@ export const guideTrail = trail('guide', {
|
|
|
83
70
|
.describe('Path to the app module'),
|
|
84
71
|
trailId: z.string().optional().describe('Trail ID for detailed guidance'),
|
|
85
72
|
}),
|
|
73
|
+
intent: 'read',
|
|
86
74
|
output: z.union([
|
|
87
75
|
z.array(
|
|
88
76
|
z.object({
|
|
@@ -100,5 +88,17 @@ export const guideTrail = trail('guide', {
|
|
|
100
88
|
kind: z.string(),
|
|
101
89
|
}),
|
|
102
90
|
]),
|
|
103
|
-
|
|
91
|
+
run: async (input, ctx) => {
|
|
92
|
+
const app = await loadApp(input.module, ctx.cwd ?? '.');
|
|
93
|
+
|
|
94
|
+
if (input.trailId) {
|
|
95
|
+
const item = app.get(input.trailId);
|
|
96
|
+
if (!item) {
|
|
97
|
+
return Result.err(new Error(`Trail not found: ${input.trailId}`));
|
|
98
|
+
}
|
|
99
|
+
return Result.ok(toGuideDetail(item as Trail<unknown, unknown>));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return Result.ok(toGuideEntries(app));
|
|
103
|
+
},
|
|
104
104
|
});
|
package/src/trails/survey.ts
CHANGED
|
@@ -32,11 +32,9 @@ export interface BriefReport {
|
|
|
32
32
|
readonly outputSchemas: boolean;
|
|
33
33
|
readonly examples: boolean;
|
|
34
34
|
readonly detours: boolean;
|
|
35
|
-
readonly hikes: boolean;
|
|
36
35
|
readonly events: boolean;
|
|
37
36
|
};
|
|
38
37
|
readonly trails: number;
|
|
39
|
-
readonly hikes: number;
|
|
40
38
|
readonly events: number;
|
|
41
39
|
}
|
|
42
40
|
|
|
@@ -73,10 +71,8 @@ export const generateBriefReport = (app: Topo): BriefReport => {
|
|
|
73
71
|
detours: hasDetours,
|
|
74
72
|
events: app.events.size > 0,
|
|
75
73
|
examples: hasExamples,
|
|
76
|
-
hikes: app.hikes.size > 0,
|
|
77
74
|
outputSchemas: hasOutputSchemas,
|
|
78
75
|
},
|
|
79
|
-
hikes: app.hikes.size,
|
|
80
76
|
name: app.name,
|
|
81
77
|
trails: app.trails.size,
|
|
82
78
|
version: '0.1.0',
|
|
@@ -88,14 +84,13 @@ export const generateBriefReport = (app: Topo): BriefReport => {
|
|
|
88
84
|
// ---------------------------------------------------------------------------
|
|
89
85
|
|
|
90
86
|
const safetyLabel = (entry: {
|
|
91
|
-
|
|
92
|
-
destructive?: boolean;
|
|
87
|
+
intent?: 'read' | 'write' | 'destroy';
|
|
93
88
|
}): string => {
|
|
94
|
-
if (entry.
|
|
95
|
-
return '
|
|
89
|
+
if (entry.intent === 'destroy') {
|
|
90
|
+
return 'destroy';
|
|
96
91
|
}
|
|
97
|
-
if (entry.
|
|
98
|
-
return '
|
|
92
|
+
if (entry.intent === 'read') {
|
|
93
|
+
return 'read';
|
|
99
94
|
}
|
|
100
95
|
return '-';
|
|
101
96
|
};
|
|
@@ -104,7 +99,7 @@ const formatTrailList = (app: Topo): object => {
|
|
|
104
99
|
const items = app.list();
|
|
105
100
|
const entries = items.map((item) => {
|
|
106
101
|
const safety = safetyLabel(
|
|
107
|
-
item as unknown as {
|
|
102
|
+
item as unknown as { intent?: 'read' | 'write' | 'destroy' }
|
|
108
103
|
);
|
|
109
104
|
const examples = Array.isArray(
|
|
110
105
|
(item as unknown as { examples?: unknown[] }).examples
|
|
@@ -132,7 +127,7 @@ const formatTrailList = (app: Topo): object => {
|
|
|
132
127
|
*/
|
|
133
128
|
const formatTrailDetail = (item: Trail<unknown, unknown>): object => {
|
|
134
129
|
const safety = safetyLabel(
|
|
135
|
-
item as unknown as {
|
|
130
|
+
item as unknown as { intent?: 'read' | 'write' | 'destroy' }
|
|
136
131
|
);
|
|
137
132
|
|
|
138
133
|
return {
|
|
@@ -218,27 +213,6 @@ export const surveyTrail = trail('survey', {
|
|
|
218
213
|
name: 'Brief capability report',
|
|
219
214
|
},
|
|
220
215
|
],
|
|
221
|
-
implementation: async (input, ctx) => {
|
|
222
|
-
const app = await loadApp(input.module, ctx.cwd ?? '.');
|
|
223
|
-
|
|
224
|
-
if (input.brief) {
|
|
225
|
-
return Result.ok(generateBriefReport(app));
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
if (input.diff) {
|
|
229
|
-
return await buildSurveyDiff(app, input.breakingOnly);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
if (input.trailId) {
|
|
233
|
-
return buildSurveyDetail(app, input.trailId);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
if (input.generate) {
|
|
237
|
-
return await buildSurveyGenerate(app);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
return Result.ok(formatTrailList(app));
|
|
241
|
-
},
|
|
242
216
|
input: z.object({
|
|
243
217
|
breakingOnly: z
|
|
244
218
|
.boolean()
|
|
@@ -256,6 +230,7 @@ export const surveyTrail = trail('survey', {
|
|
|
256
230
|
.describe('Path to the app module'),
|
|
257
231
|
trailId: z.string().optional().describe('Trail ID for detail view'),
|
|
258
232
|
}),
|
|
233
|
+
intent: 'read',
|
|
259
234
|
output: z.union([
|
|
260
235
|
z.object({
|
|
261
236
|
count: z.number(),
|
|
@@ -275,10 +250,8 @@ export const surveyTrail = trail('survey', {
|
|
|
275
250
|
detours: z.boolean(),
|
|
276
251
|
events: z.boolean(),
|
|
277
252
|
examples: z.boolean(),
|
|
278
|
-
hikes: z.boolean(),
|
|
279
253
|
outputSchemas: z.boolean(),
|
|
280
254
|
}),
|
|
281
|
-
hikes: z.number(),
|
|
282
255
|
name: z.string(),
|
|
283
256
|
trails: z.number(),
|
|
284
257
|
version: z.string(),
|
|
@@ -303,5 +276,25 @@ export const surveyTrail = trail('survey', {
|
|
|
303
276
|
mapPath: z.string(),
|
|
304
277
|
}),
|
|
305
278
|
]),
|
|
306
|
-
|
|
279
|
+
run: async (input, ctx) => {
|
|
280
|
+
const app = await loadApp(input.module, ctx.cwd ?? '.');
|
|
281
|
+
|
|
282
|
+
if (input.brief) {
|
|
283
|
+
return Result.ok(generateBriefReport(app));
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if (input.diff) {
|
|
287
|
+
return await buildSurveyDiff(app, input.breakingOnly);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (input.trailId) {
|
|
291
|
+
return buildSurveyDetail(app, input.trailId);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (input.generate) {
|
|
295
|
+
return await buildSurveyGenerate(app);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return Result.ok(formatTrailList(app));
|
|
299
|
+
},
|
|
307
300
|
});
|
package/src/trails/warden.ts
CHANGED
|
@@ -37,38 +37,6 @@ export const wardenTrail = trail('warden', {
|
|
|
37
37
|
name: 'GitHub Actions annotations',
|
|
38
38
|
},
|
|
39
39
|
],
|
|
40
|
-
implementation: async (input, ctx) => {
|
|
41
|
-
const rootDir = input.rootDir ?? ctx.cwd ?? process.cwd();
|
|
42
|
-
// oxlint-disable-next-line prefer-await-to-then -- catch converts rejection to undefined cleanly
|
|
43
|
-
const topo = await loadApp('./src/app.ts', rootDir).catch(
|
|
44
|
-
(): undefined => undefined
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
const report = await runWarden({
|
|
48
|
-
driftOnly: input.driftOnly,
|
|
49
|
-
lintOnly: input.lintOnly,
|
|
50
|
-
rootDir,
|
|
51
|
-
topo,
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
const formatters: Record<string, (r: typeof report) => string> = {
|
|
55
|
-
github: formatGitHubAnnotations,
|
|
56
|
-
json: formatJson,
|
|
57
|
-
summary: formatSummary,
|
|
58
|
-
text: formatWardenReport,
|
|
59
|
-
};
|
|
60
|
-
const formatter = formatters[input.format] ?? formatWardenReport;
|
|
61
|
-
const formatted = formatter(report);
|
|
62
|
-
|
|
63
|
-
return Result.ok({
|
|
64
|
-
diagnostics: report.diagnostics,
|
|
65
|
-
drift: report.drift,
|
|
66
|
-
errorCount: report.errorCount,
|
|
67
|
-
formatted,
|
|
68
|
-
passed: report.passed,
|
|
69
|
-
warnCount: report.warnCount,
|
|
70
|
-
});
|
|
71
|
-
},
|
|
72
40
|
input: z.object({
|
|
73
41
|
driftOnly: z.boolean().default(false).describe('Only run drift detection'),
|
|
74
42
|
format: z
|
|
@@ -78,6 +46,7 @@ export const wardenTrail = trail('warden', {
|
|
|
78
46
|
lintOnly: z.boolean().default(false).describe('Only run lint rules'),
|
|
79
47
|
rootDir: z.string().optional().describe('Root directory to scan'),
|
|
80
48
|
}),
|
|
49
|
+
intent: 'read',
|
|
81
50
|
output: z.object({
|
|
82
51
|
diagnostics: z.array(
|
|
83
52
|
z.object({
|
|
@@ -100,5 +69,36 @@ export const wardenTrail = trail('warden', {
|
|
|
100
69
|
passed: z.boolean(),
|
|
101
70
|
warnCount: z.number(),
|
|
102
71
|
}),
|
|
103
|
-
|
|
72
|
+
run: async (input, ctx) => {
|
|
73
|
+
const rootDir = input.rootDir ?? ctx.cwd ?? process.cwd();
|
|
74
|
+
// oxlint-disable-next-line prefer-await-to-then -- catch converts rejection to undefined cleanly
|
|
75
|
+
const topo = await loadApp('./src/app.ts', rootDir).catch(
|
|
76
|
+
(): undefined => undefined
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const report = await runWarden({
|
|
80
|
+
driftOnly: input.driftOnly,
|
|
81
|
+
lintOnly: input.lintOnly,
|
|
82
|
+
rootDir,
|
|
83
|
+
topo,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const formatters: Record<string, (r: typeof report) => string> = {
|
|
87
|
+
github: formatGitHubAnnotations,
|
|
88
|
+
json: formatJson,
|
|
89
|
+
summary: formatSummary,
|
|
90
|
+
text: formatWardenReport,
|
|
91
|
+
};
|
|
92
|
+
const formatter = formatters[input.format] ?? formatWardenReport;
|
|
93
|
+
const formatted = formatter(report);
|
|
94
|
+
|
|
95
|
+
return Result.ok({
|
|
96
|
+
diagnostics: report.diagnostics,
|
|
97
|
+
drift: report.drift,
|
|
98
|
+
errorCount: report.errorCount,
|
|
99
|
+
formatted,
|
|
100
|
+
passed: report.passed,
|
|
101
|
+
warnCount: report.warnCount,
|
|
102
|
+
});
|
|
103
|
+
},
|
|
104
104
|
});
|