@hesed/recipe 0.1.0

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.
@@ -0,0 +1,48 @@
1
+ export type Context = Record<string, unknown>;
2
+ export interface LogStep {
3
+ if?: string;
4
+ log: string;
5
+ }
6
+ export interface SetStep {
7
+ if?: string;
8
+ set: string;
9
+ value: unknown;
10
+ }
11
+ export interface RunStep {
12
+ args?: string[];
13
+ capture?: string;
14
+ if?: string;
15
+ run: string;
16
+ }
17
+ export interface ExecStep {
18
+ capture?: string;
19
+ exec: string;
20
+ if?: string;
21
+ json?: boolean;
22
+ silent?: boolean;
23
+ }
24
+ export interface RepeatStep {
25
+ as?: string;
26
+ if?: string;
27
+ repeat: number | string;
28
+ steps: Step[];
29
+ }
30
+ export interface ForEachStep {
31
+ as: string;
32
+ forEach: string;
33
+ if?: string;
34
+ steps: Step[];
35
+ }
36
+ export interface IfStep {
37
+ else?: Step[];
38
+ if: string;
39
+ then?: Step[];
40
+ }
41
+ export type Step = ExecStep | ForEachStep | IfStep | LogStep | RepeatStep | RunStep | SetStep;
42
+ export interface Recipe {
43
+ description?: string;
44
+ name: string;
45
+ steps: Step[];
46
+ vars?: Context;
47
+ version?: string;
48
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,382 @@
1
+ {
2
+ "commands": {
3
+ "recipe:create": {
4
+ "aliases": [],
5
+ "args": {
6
+ "name": {
7
+ "description": "Name for the new recipe.",
8
+ "name": "name",
9
+ "required": true
10
+ }
11
+ },
12
+ "description": "Creates a starter recipe in the recipe store that you can edit and run.",
13
+ "examples": [
14
+ "<%= config.bin %> <%= command.id %> close-user-tickets",
15
+ "<%= config.bin %> <%= command.id %> close-user-tickets --description \"Close all tickets for a user\""
16
+ ],
17
+ "flags": {
18
+ "json": {
19
+ "description": "Format output as json.",
20
+ "helpGroup": "GLOBAL",
21
+ "name": "json",
22
+ "allowNo": false,
23
+ "type": "boolean"
24
+ },
25
+ "description": {
26
+ "char": "d",
27
+ "description": "Description for the recipe.",
28
+ "name": "description",
29
+ "hasDynamicHelp": false,
30
+ "multiple": false,
31
+ "type": "option"
32
+ },
33
+ "force": {
34
+ "char": "f",
35
+ "description": "Overwrite an existing recipe with the same name.",
36
+ "name": "force",
37
+ "allowNo": false,
38
+ "type": "boolean"
39
+ }
40
+ },
41
+ "hasDynamicHelp": false,
42
+ "hiddenAliases": [],
43
+ "id": "recipe:create",
44
+ "pluginAlias": "@hesed/recipe",
45
+ "pluginName": "@hesed/recipe",
46
+ "pluginType": "core",
47
+ "strict": true,
48
+ "summary": "Scaffold a new recipe.",
49
+ "enableJsonFlag": true,
50
+ "isESM": true,
51
+ "relativePath": [
52
+ "dist",
53
+ "commands",
54
+ "recipe",
55
+ "create.js"
56
+ ]
57
+ },
58
+ "recipe:export": {
59
+ "aliases": [],
60
+ "args": {
61
+ "recipe": {
62
+ "description": "Name of the saved recipe to export.",
63
+ "name": "recipe",
64
+ "required": true
65
+ }
66
+ },
67
+ "description": "Write a saved recipe to a JSON file so it can be shared or version-controlled.\n\nWith --stdout the recipe is printed instead of written to a file.",
68
+ "examples": [
69
+ "<%= config.bin %> <%= command.id %> close-user-tickets",
70
+ "<%= config.bin %> <%= command.id %> close-user-tickets --output ./shared/close-user-tickets.json",
71
+ "<%= config.bin %> <%= command.id %> close-user-tickets --stdout"
72
+ ],
73
+ "flags": {
74
+ "json": {
75
+ "description": "Format output as json.",
76
+ "helpGroup": "GLOBAL",
77
+ "name": "json",
78
+ "allowNo": false,
79
+ "type": "boolean"
80
+ },
81
+ "force": {
82
+ "char": "f",
83
+ "description": "Overwrite the output file if it already exists.",
84
+ "name": "force",
85
+ "allowNo": false,
86
+ "type": "boolean"
87
+ },
88
+ "output": {
89
+ "char": "o",
90
+ "description": "Output file path. Defaults to ./<name>.json.",
91
+ "name": "output",
92
+ "hasDynamicHelp": false,
93
+ "multiple": false,
94
+ "type": "option"
95
+ },
96
+ "stdout": {
97
+ "description": "Print the recipe to stdout instead of writing a file.",
98
+ "name": "stdout",
99
+ "allowNo": false,
100
+ "type": "boolean"
101
+ }
102
+ },
103
+ "hasDynamicHelp": false,
104
+ "hiddenAliases": [],
105
+ "id": "recipe:export",
106
+ "pluginAlias": "@hesed/recipe",
107
+ "pluginName": "@hesed/recipe",
108
+ "pluginType": "core",
109
+ "strict": true,
110
+ "summary": "Export a recipe to a file.",
111
+ "enableJsonFlag": true,
112
+ "isESM": true,
113
+ "relativePath": [
114
+ "dist",
115
+ "commands",
116
+ "recipe",
117
+ "export.js"
118
+ ]
119
+ },
120
+ "recipe:import": {
121
+ "aliases": [],
122
+ "args": {
123
+ "path": {
124
+ "description": "Path to a recipe JSON file to import.",
125
+ "name": "path",
126
+ "required": true
127
+ }
128
+ },
129
+ "description": "Import a recipe from a JSON file into the recipe store so it can be run by name.",
130
+ "examples": [
131
+ "<%= config.bin %> <%= command.id %> ./close-user-tickets.json",
132
+ "<%= config.bin %> <%= command.id %> ./shared-recipe.json --name my-copy"
133
+ ],
134
+ "flags": {
135
+ "json": {
136
+ "description": "Format output as json.",
137
+ "helpGroup": "GLOBAL",
138
+ "name": "json",
139
+ "allowNo": false,
140
+ "type": "boolean"
141
+ },
142
+ "force": {
143
+ "char": "f",
144
+ "description": "Overwrite an existing recipe with the same name.",
145
+ "name": "force",
146
+ "allowNo": false,
147
+ "type": "boolean"
148
+ },
149
+ "name": {
150
+ "description": "Save the imported recipe under a different name.",
151
+ "name": "name",
152
+ "hasDynamicHelp": false,
153
+ "multiple": false,
154
+ "type": "option"
155
+ }
156
+ },
157
+ "hasDynamicHelp": false,
158
+ "hiddenAliases": [],
159
+ "id": "recipe:import",
160
+ "pluginAlias": "@hesed/recipe",
161
+ "pluginName": "@hesed/recipe",
162
+ "pluginType": "core",
163
+ "strict": true,
164
+ "summary": "Import a recipe from a file.",
165
+ "enableJsonFlag": true,
166
+ "isESM": true,
167
+ "relativePath": [
168
+ "dist",
169
+ "commands",
170
+ "recipe",
171
+ "import.js"
172
+ ]
173
+ },
174
+ "recipe": {
175
+ "aliases": [],
176
+ "args": {},
177
+ "description": "List saved recipes.",
178
+ "examples": [
179
+ "<%= config.bin %> <%= command.id %>"
180
+ ],
181
+ "flags": {
182
+ "json": {
183
+ "description": "Format output as json.",
184
+ "helpGroup": "GLOBAL",
185
+ "name": "json",
186
+ "allowNo": false,
187
+ "type": "boolean"
188
+ }
189
+ },
190
+ "hasDynamicHelp": false,
191
+ "hiddenAliases": [],
192
+ "id": "recipe",
193
+ "pluginAlias": "@hesed/recipe",
194
+ "pluginName": "@hesed/recipe",
195
+ "pluginType": "core",
196
+ "strict": true,
197
+ "summary": "List saved recipes.",
198
+ "enableJsonFlag": true,
199
+ "isESM": true,
200
+ "relativePath": [
201
+ "dist",
202
+ "commands",
203
+ "recipe",
204
+ "index.js"
205
+ ]
206
+ },
207
+ "recipe:remove": {
208
+ "aliases": [
209
+ "recipe:delete"
210
+ ],
211
+ "args": {
212
+ "recipe": {
213
+ "description": "Name of the saved recipe to remove.",
214
+ "name": "recipe",
215
+ "required": true
216
+ }
217
+ },
218
+ "description": "Delete a recipe from the recipe store.",
219
+ "examples": [
220
+ "<%= config.bin %> <%= command.id %> close-user-tickets"
221
+ ],
222
+ "flags": {
223
+ "json": {
224
+ "description": "Format output as json.",
225
+ "helpGroup": "GLOBAL",
226
+ "name": "json",
227
+ "allowNo": false,
228
+ "type": "boolean"
229
+ }
230
+ },
231
+ "hasDynamicHelp": false,
232
+ "hiddenAliases": [],
233
+ "id": "recipe:remove",
234
+ "pluginAlias": "@hesed/recipe",
235
+ "pluginName": "@hesed/recipe",
236
+ "pluginType": "core",
237
+ "strict": true,
238
+ "summary": "Remove a saved recipe.",
239
+ "enableJsonFlag": true,
240
+ "isESM": true,
241
+ "relativePath": [
242
+ "dist",
243
+ "commands",
244
+ "recipe",
245
+ "remove.js"
246
+ ]
247
+ },
248
+ "recipe:run": {
249
+ "aliases": [],
250
+ "args": {
251
+ "recipe": {
252
+ "description": "Name of a saved recipe, or a path to a recipe file.",
253
+ "name": "recipe",
254
+ "required": true
255
+ }
256
+ },
257
+ "description": "Each step runs a command, with optional conditions, loops and JSON operations between them.\n\nUse --var to override the recipe's default variables, and --dry-run to preview the commands without running them.",
258
+ "examples": [
259
+ "<%= config.bin %> <%= command.id %> close-user-tickets",
260
+ "<%= config.bin %> <%= command.id %> close-user-tickets --var assignee=jdoe",
261
+ "<%= config.bin %> <%= command.id %> ./my-recipe.json --dry-run"
262
+ ],
263
+ "flags": {
264
+ "json": {
265
+ "description": "Format output as json.",
266
+ "helpGroup": "GLOBAL",
267
+ "name": "json",
268
+ "allowNo": false,
269
+ "type": "boolean"
270
+ },
271
+ "dry-run": {
272
+ "description": "Print the commands that would run without executing them.",
273
+ "name": "dry-run",
274
+ "allowNo": false,
275
+ "type": "boolean"
276
+ },
277
+ "var": {
278
+ "description": "Override a recipe variable (key=value). Repeatable. Values are parsed as JSON when possible.",
279
+ "name": "var",
280
+ "hasDynamicHelp": false,
281
+ "multiple": true,
282
+ "type": "option"
283
+ }
284
+ },
285
+ "hasDynamicHelp": false,
286
+ "hiddenAliases": [],
287
+ "id": "recipe:run",
288
+ "pluginAlias": "@hesed/recipe",
289
+ "pluginName": "@hesed/recipe",
290
+ "pluginType": "core",
291
+ "strict": true,
292
+ "summary": "Run a recipe: a sequence of commands chained with conditions, loops and JSON operations.",
293
+ "enableJsonFlag": true,
294
+ "isESM": true,
295
+ "relativePath": [
296
+ "dist",
297
+ "commands",
298
+ "recipe",
299
+ "run.js"
300
+ ]
301
+ },
302
+ "recipe:show": {
303
+ "aliases": [],
304
+ "args": {
305
+ "recipe": {
306
+ "description": "Name of a saved recipe, or a path to a recipe file.",
307
+ "name": "recipe",
308
+ "required": true
309
+ }
310
+ },
311
+ "description": "Print the full definition of a recipe.",
312
+ "examples": [
313
+ "<%= config.bin %> <%= command.id %> close-user-tickets"
314
+ ],
315
+ "flags": {
316
+ "json": {
317
+ "description": "Format output as json.",
318
+ "helpGroup": "GLOBAL",
319
+ "name": "json",
320
+ "allowNo": false,
321
+ "type": "boolean"
322
+ }
323
+ },
324
+ "hasDynamicHelp": false,
325
+ "hiddenAliases": [],
326
+ "id": "recipe:show",
327
+ "pluginAlias": "@hesed/recipe",
328
+ "pluginName": "@hesed/recipe",
329
+ "pluginType": "core",
330
+ "strict": true,
331
+ "summary": "Print a recipe definition.",
332
+ "enableJsonFlag": true,
333
+ "isESM": true,
334
+ "relativePath": [
335
+ "dist",
336
+ "commands",
337
+ "recipe",
338
+ "show.js"
339
+ ]
340
+ },
341
+ "recipe:validate": {
342
+ "aliases": [],
343
+ "args": {
344
+ "recipe": {
345
+ "description": "Name of a saved recipe, or a path to a recipe file.",
346
+ "name": "recipe",
347
+ "required": true
348
+ }
349
+ },
350
+ "description": "Check that a recipe is well-formed without running it.",
351
+ "examples": [
352
+ "<%= config.bin %> <%= command.id %> ./my-recipe.json"
353
+ ],
354
+ "flags": {
355
+ "json": {
356
+ "description": "Format output as json.",
357
+ "helpGroup": "GLOBAL",
358
+ "name": "json",
359
+ "allowNo": false,
360
+ "type": "boolean"
361
+ }
362
+ },
363
+ "hasDynamicHelp": false,
364
+ "hiddenAliases": [],
365
+ "id": "recipe:validate",
366
+ "pluginAlias": "@hesed/recipe",
367
+ "pluginName": "@hesed/recipe",
368
+ "pluginType": "core",
369
+ "strict": true,
370
+ "summary": "Validate a recipe.",
371
+ "enableJsonFlag": true,
372
+ "isESM": true,
373
+ "relativePath": [
374
+ "dist",
375
+ "commands",
376
+ "recipe",
377
+ "validate.js"
378
+ ]
379
+ }
380
+ },
381
+ "version": "0.1.0"
382
+ }
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@hesed/recipe",
3
+ "description": "Chains multiple CLI commands together to accomplish a task",
4
+ "version": "0.1.0",
5
+ "author": "Hesed",
6
+ "bin": {
7
+ "ai": "./bin/run.js"
8
+ },
9
+ "bugs": "https://github.com/hesedcasa/recipe/issues",
10
+ "dependencies": {
11
+ "@hesed/plugin-lib": "^0.10.0",
12
+ "@oclif/core": "^4",
13
+ "ansis": "^3"
14
+ },
15
+ "devDependencies": {
16
+ "@eslint/compat": "^2",
17
+ "@oclif/prettier-config": "^0.2.1",
18
+ "@oclif/test": "^4",
19
+ "@types/chai": "^4",
20
+ "@types/mocha": "^10",
21
+ "@types/node": "^26",
22
+ "chai": "^4",
23
+ "eslint": "^9",
24
+ "eslint-config-oclif": "^6",
25
+ "eslint-config-prettier": "^10",
26
+ "mocha": "^11",
27
+ "oclif": "^4",
28
+ "prettier": "^3.8.1",
29
+ "shx": "^0.3.3",
30
+ "ts-node": "^10",
31
+ "ts-prune": "^0.10.3",
32
+ "typescript": "^5"
33
+ },
34
+ "engines": {
35
+ "node": ">=22.19.0"
36
+ },
37
+ "files": [
38
+ "./bin",
39
+ "./dist",
40
+ "./oclif.manifest.json"
41
+ ],
42
+ "homepage": "https://github.com/hesedcasa/recipe",
43
+ "keywords": [
44
+ "recipe",
45
+ "oclif"
46
+ ],
47
+ "license": "Apache 2.0",
48
+ "main": "dist/index.js",
49
+ "type": "module",
50
+ "oclif": {
51
+ "bin": "recipe",
52
+ "dirname": "recipe",
53
+ "commands": "./dist/commands",
54
+ "topicSeparator": " "
55
+ },
56
+ "repository": "hesedcasa/recipe",
57
+ "scripts": {
58
+ "build": "shx rm -rf dist && tsc -b",
59
+ "lint": "eslint",
60
+ "postpack": "shx rm -f oclif.manifest.json",
61
+ "posttest": "npm run lint",
62
+ "prepack": "oclif manifest && oclif readme",
63
+ "test": "mocha --forbid-only \"test/**/*.test.ts\"",
64
+ "version": "oclif readme && git add README.md",
65
+ "find-deadcode": "ts-prune --ignore '(run|default)'",
66
+ "format": "eslint --cache --fix --quiet . && prettier --write --cache .",
67
+ "pre-commit": "npm run format && npm run find-deadcode"
68
+ },
69
+ "types": "dist/index.d.ts"
70
+ }