eser 0.8.3 → 0.8.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/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # eser
2
+
3
+ Eser Ozvataf's command-line tooling to access things.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ # Using npx (no installation required)
9
+ npx eser <command>
10
+
11
+ # Using Deno
12
+ deno run -A jsr:@eser/cli <command>
13
+
14
+ # Global installation via npm
15
+ npm install -g eser
16
+ ```
17
+
18
+ ## Commands
19
+
20
+ ### codebase
21
+
22
+ Codebase validation and management tools.
23
+
24
+ ```bash
25
+ eser codebase <subcommand> [options]
26
+ ```
27
+
28
+ **Subcommands:**
29
+
30
+ - `check` - Run all codebase checks
31
+ - `check-circular-deps` - Check for circular dependencies
32
+ - `check-docs` - Check documentation coverage
33
+ - `check-export-names` - Check export naming conventions
34
+ - `check-licenses` - Check license compliance
35
+ - `check-mod-exports` - Check module exports
36
+ - `check-package-configs` - Check package configurations
37
+
38
+ **Options:**
39
+
40
+ - `-h, --help` - Show help message
41
+ - `--root <path>` - Root directory (default: current directory)
42
+
43
+ ## Examples
44
+
45
+ ```bash
46
+ # Run all checks on current directory
47
+ eser codebase check
48
+
49
+ # Check for circular dependencies
50
+ eser codebase check-circular-deps
51
+
52
+ # Run checks on a specific directory
53
+ eser codebase check --root ./my-project
54
+ ```
55
+
56
+ ## License
57
+
58
+ Apache-2.0
@@ -1,6 +1,6 @@
1
- #!/usr/bin/env -S node
1
+ #!/usr/bin/env node
2
2
  // Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
3
3
 
4
- import { main } from "./main.ts";
4
+ import { main } from "./main.js";
5
5
 
6
6
  await main();
@@ -1,20 +1,3 @@
1
- // Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
2
-
3
- /**
4
- * Codebase command group - validation and management tools
5
- *
6
- * Subcommands:
7
- * check-circular-deps Detect circular package dependencies
8
- * check-mod-exports Validate mod.ts exports all files
9
- * check-export-names Validate export naming conventions
10
- * check-docs Validate JSDoc documentation
11
- * check-licenses Validate license headers
12
- * check-package-configs Validate deno.json/package.json consistency
13
- * versions Manage workspace versions
14
- *
15
- * @module
16
- */
17
-
18
1
  import * as cliParseArgs from "@std/cli/parse-args";
19
2
  import * as fmtColors from "@std/fmt/colors";
20
3
  import * as standardsRuntime from "@eser/standards/runtime";
@@ -25,17 +8,11 @@ import * as checkDocs from "@eser/codebase/check-docs";
25
8
  import * as checkLicenses from "@eser/codebase/check-licenses";
26
9
  import * as checkPackageConfigs from "@eser/codebase/check-package-configs";
27
10
  import * as versions from "@eser/codebase/versions";
28
-
29
- type SubcommandDef = {
30
- description: string;
31
- usage: string;
32
- options: Array<{ flag: string; description: string }>;
33
- handler: (args: string[], flags: Record<string, unknown>) => Promise<void>;
34
- };
35
-
36
- const showSubcommandHelp = (name: string, def: SubcommandDef): void => {
37
- console.log(`eser codebase ${name} - ${def.description}\n`);
38
- console.log(`Usage: ${def.usage}\n`);
11
+ const showSubcommandHelp = (name, def) => {
12
+ console.log(`eser codebase ${name} - ${def.description}
13
+ `);
14
+ console.log(`Usage: ${def.usage}
15
+ `);
39
16
  if (def.options.length > 0) {
40
17
  console.log("Options:");
41
18
  for (const opt of def.options) {
@@ -43,101 +20,95 @@ const showSubcommandHelp = (name: string, def: SubcommandDef): void => {
43
20
  }
44
21
  }
45
22
  };
46
-
47
- const subcommands: Record<string, SubcommandDef> = {
23
+ const subcommands = {
48
24
  "check-circular-deps": {
49
25
  description: "Detect circular package dependencies",
50
26
  usage: "eser codebase check-circular-deps [options]",
51
27
  options: [
52
28
  {
53
29
  flag: "--root <path>",
54
- description: "Root directory (default: current)",
30
+ description: "Root directory (default: current)"
55
31
  },
56
- { flag: "-h, --help", description: "Show this help message" },
32
+ { flag: "-h, --help", description: "Show this help message" }
57
33
  ],
58
34
  handler: async (_args, flags) => {
59
- const root = flags["root"] as string | undefined;
35
+ const root = flags["root"];
60
36
  console.log("Checking for circular dependencies...\n");
61
-
62
37
  const result = await checkCircularDeps.checkCircularDeps({ root });
63
-
64
38
  console.log(`Checked ${result.packagesChecked} packages.`);
65
-
66
39
  if (result.hasCycles) {
67
40
  console.log(
68
41
  fmtColors.red(
69
- `\nFound ${result.cycles.length} circular dependencies:\n`,
70
- ),
42
+ `
43
+ Found ${result.cycles.length} circular dependencies:
44
+ `
45
+ )
71
46
  );
72
47
  for (const cycle of result.cycles) {
73
- console.log(fmtColors.yellow(` ${cycle.join(" ")}`));
48
+ console.log(fmtColors.yellow(` ${cycle.join(" \u2192 ")}`));
74
49
  }
75
50
  standardsRuntime.runtime.process.exit(1);
76
51
  } else {
77
52
  console.log(fmtColors.green("\nNo circular dependencies found."));
78
53
  }
79
- },
54
+ }
80
55
  },
81
-
82
56
  "check-mod-exports": {
83
57
  description: "Validate mod.ts exports all public files",
84
58
  usage: "eser codebase check-mod-exports [options]",
85
59
  options: [
86
60
  {
87
61
  flag: "--root <path>",
88
- description: "Root directory (default: current)",
62
+ description: "Root directory (default: current)"
89
63
  },
90
- { flag: "-h, --help", description: "Show this help message" },
64
+ { flag: "-h, --help", description: "Show this help message" }
91
65
  ],
92
66
  handler: async (_args, flags) => {
93
- const root = flags["root"] as string | undefined;
67
+ const root = flags["root"];
94
68
  console.log("Checking mod.ts exports...\n");
95
-
96
69
  const result = await checkModExports.checkModExports({ root });
97
-
98
70
  console.log(`Checked ${result.packagesChecked} packages.`);
99
-
100
71
  if (!result.isComplete) {
101
72
  console.log(
102
73
  fmtColors.red(
103
- `\nFound ${result.missingExports.length} missing exports:\n`,
104
- ),
74
+ `
75
+ Found ${result.missingExports.length} missing exports:
76
+ `
77
+ )
105
78
  );
106
79
  for (const missing of result.missingExports) {
107
80
  console.log(
108
- fmtColors.yellow(` ${missing.packageName}: ${missing.file}`),
81
+ fmtColors.yellow(` ${missing.packageName}: ${missing.file}`)
109
82
  );
110
83
  }
111
84
  standardsRuntime.runtime.process.exit(1);
112
85
  } else {
113
86
  console.log(fmtColors.green("\nAll mod.ts exports are complete."));
114
87
  }
115
- },
88
+ }
116
89
  },
117
-
118
90
  "check-export-names": {
119
91
  description: "Validate export naming conventions",
120
92
  usage: "eser codebase check-export-names [options]",
121
93
  options: [
122
94
  {
123
95
  flag: "--root <path>",
124
- description: "Root directory (default: current)",
96
+ description: "Root directory (default: current)"
125
97
  },
126
- { flag: "-h, --help", description: "Show this help message" },
98
+ { flag: "-h, --help", description: "Show this help message" }
127
99
  ],
128
100
  handler: async (_args, flags) => {
129
- const root = flags["root"] as string | undefined;
101
+ const root = flags["root"];
130
102
  console.log("Checking export naming conventions...\n");
131
-
132
103
  const result = await checkExportNames.checkExportNames({ root });
133
-
134
104
  console.log(`Checked ${result.packagesChecked} packages.`);
135
-
136
105
  if (!result.isValid) {
137
106
  console.log(
138
107
  fmtColors.red(
139
- `\nFound ${result.violations.length} naming violations:\n`,
140
- ),
108
+ `
109
+ Found ${result.violations.length} naming violations:
110
+ `
111
+ )
141
112
  );
142
113
  for (const violation of result.violations) {
143
114
  console.log(fmtColors.yellow(` ${violation.packageName}:`));
@@ -148,79 +119,70 @@ const subcommands: Record<string, SubcommandDef> = {
148
119
  } else {
149
120
  console.log(fmtColors.green("\nAll export names follow conventions."));
150
121
  }
151
- },
122
+ }
152
123
  },
153
-
154
124
  "check-docs": {
155
125
  description: "Validate JSDoc documentation",
156
126
  usage: "eser codebase check-docs [options]",
157
127
  options: [
158
128
  {
159
129
  flag: "--root <path>",
160
- description: "Root directory (default: current)",
130
+ description: "Root directory (default: current)"
161
131
  },
162
- { flag: "-h, --help", description: "Show this help message" },
132
+ { flag: "-h, --help", description: "Show this help message" }
163
133
  ],
164
134
  handler: async (_args, flags) => {
165
- const root = flags["root"] as string | undefined;
135
+ const root = flags["root"];
166
136
  console.log("Checking documentation...\n");
167
-
168
137
  const result = await checkDocs.checkDocs({ root });
169
-
170
138
  console.log(
171
- `Checked ${result.filesChecked} files, ${result.symbolsChecked} symbols.`,
139
+ `Checked ${result.filesChecked} files, ${result.symbolsChecked} symbols.`
172
140
  );
173
-
174
141
  if (!result.isValid) {
175
142
  console.log(
176
143
  fmtColors.red(
177
- `\nFound ${result.issues.length} documentation issues:\n`,
178
- ),
144
+ `
145
+ Found ${result.issues.length} documentation issues:
146
+ `
147
+ )
179
148
  );
180
-
181
- // Group by file
182
- const byFile = new Map<string, checkDocs.DocIssue[]>();
149
+ const byFile = /* @__PURE__ */ new Map();
183
150
  for (const issue of result.issues) {
184
151
  const existing = byFile.get(issue.file) ?? [];
185
152
  existing.push(issue);
186
153
  byFile.set(issue.file, existing);
187
154
  }
188
-
189
155
  for (const [file, fileIssues] of byFile) {
190
- console.log(fmtColors.yellow(`\n${file}:`));
156
+ console.log(fmtColors.yellow(`
157
+ ${file}:`));
191
158
  for (const issue of fileIssues) {
192
- const lineInfo = issue.line !== undefined ? `:${issue.line}` : "";
159
+ const lineInfo = issue.line !== void 0 ? `:${issue.line}` : "";
193
160
  console.log(` ${issue.symbol}${lineInfo}: ${issue.issue}`);
194
161
  }
195
162
  }
196
-
197
163
  standardsRuntime.runtime.process.exit(1);
198
164
  } else {
199
165
  console.log(fmtColors.green("\nAll documentation is valid."));
200
166
  }
201
- },
167
+ }
202
168
  },
203
-
204
169
  "check-licenses": {
205
170
  description: "Validate license headers in source files",
206
171
  usage: "eser codebase check-licenses [options]",
207
172
  options: [
208
173
  { flag: "--fix", description: "Auto-fix missing or incorrect headers" },
209
- { flag: "-h, --help", description: "Show this help message" },
174
+ { flag: "-h, --help", description: "Show this help message" }
210
175
  ],
211
176
  handler: async (_args, flags) => {
212
- const fix = flags["fix"] as boolean | undefined;
177
+ const fix = flags["fix"];
213
178
  console.log("Validating license headers...\n");
214
-
215
179
  const result = await checkLicenses.validateLicenses({ fix });
216
-
217
180
  if (result.issues.length === 0) {
218
181
  console.log(
219
- `Checked ${result.checked} files. All licenses are valid.`,
182
+ `Checked ${result.checked} files. All licenses are valid.`
220
183
  );
221
184
  return;
222
185
  }
223
-
224
186
  if (fix) {
225
187
  for (const issue of result.issues) {
226
188
  if (issue.fixed) {
@@ -232,76 +194,65 @@ const subcommands: Record<string, SubcommandDef> = {
232
194
  for (const issue of result.issues) {
233
195
  console.error(
234
196
  fmtColors.red(
235
- `${
236
- issue.issue === "missing" ? "Missing" : "Incorrect"
237
- } copyright header: ${issue.path}`,
238
- ),
197
+ `${issue.issue === "missing" ? "Missing" : "Incorrect"} copyright header: ${issue.path}`
198
+ )
239
199
  );
240
200
  }
241
201
  console.log(
242
202
  fmtColors.yellow(
243
- `\nCopyright header should be "// Copyright YYYY-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license."`,
244
- ),
203
+ `
204
+ Copyright header should be "// Copyright YYYY-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license."`
205
+ )
245
206
  );
246
207
  standardsRuntime.runtime.process.exit(1);
247
208
  }
248
- },
209
+ }
249
210
  },
250
-
251
211
  "check-package-configs": {
252
212
  description: "Validate deno.json and package.json consistency",
253
213
  usage: "eser codebase check-package-configs [options]",
254
214
  options: [
255
215
  {
256
216
  flag: "--root <path>",
257
- description: "Root directory (default: current)",
217
+ description: "Root directory (default: current)"
258
218
  },
259
- { flag: "-h, --help", description: "Show this help message" },
219
+ { flag: "-h, --help", description: "Show this help message" }
260
220
  ],
261
221
  handler: async (_args, flags) => {
262
- const root = flags["root"] as string | undefined;
222
+ const root = flags["root"];
263
223
  console.log("Checking package config consistency...\n");
264
-
265
224
  const result = await checkPackageConfigs.checkPackageConfigs({ root });
266
-
267
225
  console.log(`Checked ${result.packagesChecked} packages.`);
268
-
269
226
  if (!result.isConsistent) {
270
227
  console.log(
271
228
  fmtColors.red(
272
- `\nFound ${result.inconsistencies.length} inconsistencies:\n`,
273
- ),
229
+ `
230
+ Found ${result.inconsistencies.length} inconsistencies:
231
+ `
232
+ )
274
233
  );
275
-
276
- // Group by package
277
- const byPackage = new Map<
278
- string,
279
- checkPackageConfigs.ConfigInconsistency[]
280
- >();
234
+ const byPackage = /* @__PURE__ */ new Map();
281
235
  for (const inc of result.inconsistencies) {
282
236
  const existing = byPackage.get(inc.packageName) ?? [];
283
237
  existing.push(inc);
284
238
  byPackage.set(inc.packageName, existing);
285
239
  }
286
-
287
240
  for (const [pkgName, inconsistencies] of byPackage) {
288
241
  console.log(fmtColors.yellow(`${pkgName}:`));
289
242
  for (const inc of inconsistencies) {
290
- console.log(fmtColors.red(` ${inc.field} mismatch:`));
243
+ console.log(fmtColors.red(` \u26A0 ${inc.field} mismatch:`));
291
244
  console.log(` deno.json: ${JSON.stringify(inc.denoValue)}`);
292
245
  console.log(
293
- ` package.json: ${JSON.stringify(inc.packageValue)}`,
246
+ ` package.json: ${JSON.stringify(inc.packageValue)}`
294
247
  );
295
248
  }
296
249
  }
297
-
298
250
  standardsRuntime.runtime.process.exit(1);
299
251
  } else {
300
252
  console.log(fmtColors.green("\nAll package configs are consistent."));
301
253
  }
302
- },
254
+ }
303
255
  },
304
-
305
256
  versions: {
306
257
  description: "Manage workspace package versions",
307
258
  usage: "eser codebase versions [command] [options]",
@@ -311,52 +262,45 @@ const subcommands: Record<string, SubcommandDef> = {
311
262
  { flag: "minor", description: "Bump minor version (0.x.0)" },
312
263
  { flag: "major", description: "Bump major version (x.0.0)" },
313
264
  { flag: "--dry-run", description: "Preview changes without applying" },
314
- { flag: "-h, --help", description: "Show this help message" },
265
+ { flag: "-h, --help", description: "Show this help message" }
315
266
  ],
316
267
  handler: async (args, flags) => {
317
- const command = args[0] as versions.VersionCommand | undefined;
318
- const dryRun = flags["dry-run"] as boolean | undefined;
319
-
320
- if (command === undefined) {
321
- const result = await versions.showVersions();
322
- console.table(result.packages);
268
+ const command = args[0];
269
+ const dryRun = flags["dry-run"];
270
+ if (command === void 0) {
271
+ const result2 = await versions.showVersions();
272
+ console.table(result2.packages);
323
273
  return;
324
274
  }
325
-
326
275
  const validCommands = ["sync", "patch", "minor", "major"];
327
276
  if (!validCommands.includes(command)) {
328
277
  console.error(fmtColors.red(`Invalid command: ${command}`));
329
278
  console.error(
330
- "Usage: eser codebase versions [sync|patch|minor|major] [--dry-run]",
279
+ "Usage: eser codebase versions [sync|patch|minor|major] [--dry-run]"
331
280
  );
332
281
  standardsRuntime.runtime.process.exit(1);
333
282
  }
334
-
335
283
  if (command === "sync") {
336
284
  console.log("Syncing all versions...");
337
285
  } else {
338
286
  console.log(`Bumping all versions (${command})...`);
339
287
  }
340
-
341
288
  const result = await versions.versions(command, { dryRun });
342
-
343
289
  console.log(`Target version: ${result.targetVersion}`);
344
290
  console.table(result.updates);
345
-
346
291
  if (result.dryRun) {
347
292
  console.log(
348
293
  fmtColors.cyan(
349
- `Dry run - ${result.changedCount} packages would be modified.`,
350
- ),
294
+ `Dry run - ${result.changedCount} packages would be modified.`
295
+ )
351
296
  );
352
297
  } else {
353
298
  console.log(`Done. Updated ${result.changedCount} packages.`);
354
299
  }
355
- },
356
- },
300
+ }
301
+ }
357
302
  };
358
-
359
- const showHelp = (): void => {
303
+ const showHelp = () => {
360
304
  console.log("eser codebase - Codebase validation tools\n");
361
305
  console.log("Usage: eser codebase <subcommand> [options]\n");
362
306
  console.log("Subcommands:");
@@ -366,46 +310,37 @@ const showHelp = (): void => {
366
310
  console.log(" check-docs Validate JSDoc documentation");
367
311
  console.log(" check-licenses Validate license headers");
368
312
  console.log(
369
- " check-package-configs Validate deno.json/package.json consistency",
313
+ " check-package-configs Validate deno.json/package.json consistency"
370
314
  );
371
315
  console.log(" versions Manage workspace versions");
372
316
  console.log(
373
- "\nRun 'eser codebase <subcommand> --help' for subcommand options.",
317
+ "\nRun 'eser codebase <subcommand> --help' for subcommand options."
374
318
  );
375
319
  };
376
-
377
- export const codebaseCommand = async (
378
- rawArgs: string[],
379
- _parentFlags: Record<string, unknown>,
380
- ): Promise<void> => {
381
- // Parse all flags (don't use stopEarly so --help is always captured)
320
+ const codebaseCommand = async (rawArgs, _parentFlags) => {
382
321
  const parsed = cliParseArgs.parseArgs(rawArgs, {
383
322
  boolean: ["help", "dry-run", "fix"],
384
323
  string: ["root"],
385
- alias: { h: "help" },
324
+ alias: { h: "help" }
386
325
  });
387
-
388
- const subcommand = parsed._[0] as string | undefined;
389
-
390
- // Show main help if no subcommand or help without subcommand
391
- if (subcommand === undefined) {
326
+ const subcommand = parsed._[0];
327
+ if (subcommand === void 0) {
392
328
  showHelp();
393
329
  return;
394
330
  }
395
-
396
331
  const def = subcommands[subcommand];
397
- if (def === undefined) {
332
+ if (def === void 0) {
398
333
  console.error(fmtColors.red(`Unknown subcommand: ${subcommand}`));
399
334
  console.log("");
400
335
  showHelp();
401
336
  standardsRuntime.runtime.process.exit(1);
402
337
  }
403
-
404
- // Show subcommand help if --help flag
405
338
  if (parsed.help) {
406
339
  showSubcommandHelp(subcommand, def);
407
340
  return;
408
341
  }
409
-
410
- await def.handler(parsed._.slice(1) as string[], parsed);
342
+ await def.handler(parsed._.slice(1), parsed);
343
+ };
344
+ export {
345
+ codebaseCommand
411
346
  };
package/main.js ADDED
@@ -0,0 +1,48 @@
1
+ import * as cliParseArgs from "@std/cli/parse-args";
2
+ import * as standardsRuntime from "@eser/standards/runtime";
3
+ import { codebaseCommand } from "./commands/codebase/mod.js";
4
+ import config from "./package.json" with { type: "json" };
5
+ const commands = {
6
+ codebase: codebaseCommand
7
+ };
8
+ const showHelp = () => {
9
+ console.log("eser - Eser Ozvataf's command-line tooling to access things\n");
10
+ console.log("Usage: eser <command> [subcommand] [options]\n");
11
+ console.log("Commands:");
12
+ console.log(" codebase Codebase validation and management tools");
13
+ console.log("\nOptions:");
14
+ console.log(" -h, --help Show this help message");
15
+ console.log(" -v, --version Show version number");
16
+ console.log("\nRun 'eser <command> --help' for command-specific help.");
17
+ };
18
+ const main = async () => {
19
+ const args = cliParseArgs.parseArgs(standardsRuntime.runtime.process.args, {
20
+ boolean: ["help", "version"],
21
+ alias: { h: "help", v: "version" },
22
+ stopEarly: true
23
+ // Stop parsing at first non-option to pass rest to subcommand
24
+ });
25
+ if (args.version) {
26
+ console.log(`eser ${config.version}`);
27
+ return;
28
+ }
29
+ const command = args._[0];
30
+ if (command === void 0) {
31
+ showHelp();
32
+ return;
33
+ }
34
+ const handler = commands[command];
35
+ if (handler === void 0) {
36
+ console.error(`Unknown command: ${command}`);
37
+ console.log("");
38
+ showHelp();
39
+ standardsRuntime.runtime.process.exit(1);
40
+ }
41
+ await handler(args._.slice(1), args);
42
+ };
43
+ if (import.meta.main) {
44
+ await main();
45
+ }
46
+ export {
47
+ main
48
+ };
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "eser",
3
- "version": "0.8.3",
3
+ "version": "0.8.4",
4
4
  "type": "module",
5
- "exports": "./main.ts",
5
+ "exports": "./main.js",
6
6
  "bin": {
7
- "eser": "./bin.ts"
7
+ "eser": "./bin.js"
8
8
  },
9
9
  "dependencies": {
10
- "@eser/codebase": "npm:@jsr/eser__codebase@^0.8.3",
11
- "@eser/standards": "npm:@jsr/eser__standards@^0.8.3",
10
+ "@eser/codebase": "npm:@jsr/eser__codebase@^0.8.4",
11
+ "@eser/standards": "npm:@jsr/eser__standards@^0.8.4",
12
12
  "@std/cli": "npm:@jsr/std__cli@^1.0.25",
13
13
  "@std/fmt": "npm:@jsr/std__fmt@^1.0.8",
14
14
  "@std/path": "npm:@jsr/std__path@^1.1.4"
package/deno.json DELETED
@@ -1,10 +0,0 @@
1
- {
2
- "name": "@eser/cli",
3
- "version": "0.8.3",
4
- "exports": "./main.ts",
5
- "imports": {
6
- "@std/cli": "jsr:@std/cli@^1.0.25",
7
- "@std/fmt": "jsr:@std/fmt@^1.0.8",
8
- "@std/path": "jsr:@std/path@^1.1.4"
9
- }
10
- }
package/main.ts DELETED
@@ -1,79 +0,0 @@
1
- // Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
2
-
3
- /**
4
- * eser - Versatile development CLI
5
- *
6
- * A multi-purpose command-line tool for development workflows.
7
- * Similar in design to `gh` (GitHub CLI) or `wrangler` (Cloudflare).
8
- *
9
- * Usage:
10
- * deno run -A ./main.ts <command> [subcommand] [options]
11
- * dx jsr:@eser/cli <command> [subcommand] [options]
12
- *
13
- * Commands:
14
- * codebase Codebase validation and management tools
15
- *
16
- * @module
17
- */
18
-
19
- import * as cliParseArgs from "@std/cli/parse-args";
20
- import * as standardsRuntime from "@eser/standards/runtime";
21
- import { codebaseCommand } from "./commands/codebase/mod.ts";
22
- import config from "./deno.json" with { type: "json" };
23
-
24
- type CommandHandler = (
25
- args: string[],
26
- flags: Record<string, unknown>,
27
- ) => Promise<void>;
28
-
29
- const commands: Record<string, CommandHandler> = {
30
- codebase: codebaseCommand,
31
- };
32
-
33
- const showHelp = (): void => {
34
- console.log("eser - Versatile development CLI\n");
35
- console.log("Usage: eser <command> [subcommand] [options]\n");
36
- console.log("Commands:");
37
- console.log(" codebase Codebase validation and management tools");
38
- console.log("\nOptions:");
39
- console.log(" -h, --help Show this help message");
40
- console.log(" -v, --version Show version number");
41
- console.log("\nRun 'eser <command> --help' for command-specific help.");
42
- };
43
-
44
- export const main = async (): Promise<void> => {
45
- // @ts-ignore parseArgs doesn't mutate the array, readonly is safe
46
- const args = cliParseArgs.parseArgs(standardsRuntime.runtime.process.args, {
47
- boolean: ["help", "version"],
48
- alias: { h: "help", v: "version" },
49
- stopEarly: true, // Stop parsing at first non-option to pass rest to subcommand
50
- });
51
-
52
- if (args.version) {
53
- console.log(`eser ${config.version}`);
54
- return;
55
- }
56
-
57
- const command = args._[0] as string | undefined;
58
-
59
- // Show main help only if no command or help without command
60
- if (command === undefined) {
61
- showHelp();
62
- return;
63
- }
64
-
65
- const handler = commands[command];
66
- if (handler === undefined) {
67
- console.error(`Unknown command: ${command}`);
68
- console.log("");
69
- showHelp();
70
- standardsRuntime.runtime.process.exit(1);
71
- }
72
-
73
- // Pass remaining args to command handler
74
- await handler(args._.slice(1) as string[], args);
75
- };
76
-
77
- if (import.meta.main) {
78
- await main();
79
- }
@@ -1,16 +0,0 @@
1
- {
2
- "name": "@eser/cli",
3
- "version": "0.8.3",
4
- "type": "module",
5
- "exports": "./main.ts",
6
- "bin": {
7
- "eser": "./bin.ts"
8
- },
9
- "dependencies": {
10
- "@eser/codebase": "workspace:*",
11
- "@eser/standards": "workspace:*",
12
- "@std/cli": "npm:@jsr/std__cli@^1.0.25",
13
- "@std/fmt": "npm:@jsr/std__fmt@^1.0.8",
14
- "@std/path": "npm:@jsr/std__path@^1.1.4"
15
- }
16
- }
@@ -1,123 +0,0 @@
1
- // Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
2
-
3
- /**
4
- * Prepares package.json for npm publishing.
5
- *
6
- * Reads package.json.template, replaces workspace:* dependencies with
7
- * npm:@jsr/eser__<package>@^<version>, sets name to "eser", and writes
8
- * the result to package.json.
9
- *
10
- * @module
11
- */
12
-
13
- import * as path from "@std/path";
14
-
15
- type PackageJson = {
16
- name: string;
17
- version: string;
18
- type?: string;
19
- exports?: string | Record<string, string>;
20
- bin?: Record<string, string>;
21
- dependencies?: Record<string, string>;
22
- devDependencies?: Record<string, string>;
23
- };
24
-
25
- type DenoJson = {
26
- name: string;
27
- version: string;
28
- };
29
-
30
- const isWorkspaceDep = (spec: string): boolean => {
31
- return spec === "workspace:*" || spec.startsWith("workspace:");
32
- };
33
-
34
- const extractPackageName = (depName: string): string => {
35
- // @eser/codebase -> codebase
36
- const parts = depName.split("/");
37
- return parts.length > 1 ? parts[1] : depName;
38
- };
39
-
40
- const getPackageVersion = async (
41
- pkgDir: string,
42
- depName: string,
43
- ): Promise<string> => {
44
- const packageName = extractPackageName(depName);
45
- const denoJsonPath = path.join(pkgDir, "..", packageName, "deno.json");
46
-
47
- const content = await Deno.readTextFile(denoJsonPath);
48
- const denoJson = JSON.parse(content) as DenoJson;
49
-
50
- return denoJson.version;
51
- };
52
-
53
- const convertWorkspaceDep = async (
54
- pkgDir: string,
55
- depName: string,
56
- ): Promise<string> => {
57
- const packageName = extractPackageName(depName);
58
- const version = await getPackageVersion(pkgDir, depName);
59
-
60
- // @eser/codebase -> npm:@jsr/eser__codebase@^0.8.0
61
- return `npm:@jsr/eser__${packageName}@^${version}`;
62
- };
63
-
64
- const processDependencies = async (
65
- pkgDir: string,
66
- deps: Record<string, string> | undefined,
67
- ): Promise<Record<string, string> | undefined> => {
68
- if (deps === undefined) {
69
- return undefined;
70
- }
71
-
72
- const result: Record<string, string> = {};
73
-
74
- for (const [name, spec] of Object.entries(deps)) {
75
- if (isWorkspaceDep(spec)) {
76
- result[name] = await convertWorkspaceDep(pkgDir, name);
77
- } else {
78
- result[name] = spec;
79
- }
80
- }
81
-
82
- return result;
83
- };
84
-
85
- const main = async (): Promise<void> => {
86
- const scriptDir = import.meta.dirname;
87
- if (scriptDir === undefined) {
88
- throw new Error("Cannot determine script directory");
89
- }
90
-
91
- const pkgDir = path.dirname(scriptDir);
92
- const templatePath = path.join(pkgDir, "package.json.template");
93
- const outputPath = path.join(pkgDir, "package.json");
94
-
95
- // Read template
96
- const templateContent = await Deno.readTextFile(templatePath);
97
- const pkg = JSON.parse(templateContent) as PackageJson;
98
-
99
- // Set name to "eser" for npx
100
- pkg.name = "eser";
101
-
102
- // Process dependencies
103
- pkg.dependencies = await processDependencies(pkgDir, pkg.dependencies);
104
- pkg.devDependencies = await processDependencies(pkgDir, pkg.devDependencies);
105
-
106
- // Write output
107
- const outputContent = JSON.stringify(pkg, null, 2) + "\n";
108
- await Deno.writeTextFile(outputPath, outputContent);
109
-
110
- // deno-lint-ignore no-console
111
- console.log(`Generated ${outputPath}`);
112
- // deno-lint-ignore no-console
113
- console.log(` name: ${pkg.name}`);
114
-
115
- if (pkg.dependencies !== undefined) {
116
- for (const [name, spec] of Object.entries(pkg.dependencies)) {
117
- // deno-lint-ignore no-console
118
- console.log(` ${name}: ${spec}`);
119
- }
120
- }
121
- };
122
-
123
- main();
@@ -1,30 +0,0 @@
1
- // Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
2
-
3
- /**
4
- * Reverts package.json to local development state.
5
- *
6
- * Copies package.json.template to package.json to restore workspace:*
7
- * dependencies for local development.
8
- *
9
- * @module
10
- */
11
-
12
- import * as path from "@std/path";
13
-
14
- const main = async (): Promise<void> => {
15
- const scriptDir = import.meta.dirname;
16
- if (scriptDir === undefined) {
17
- throw new Error("Cannot determine script directory");
18
- }
19
-
20
- const pkgDir = path.dirname(scriptDir);
21
- const templatePath = path.join(pkgDir, "package.json.template");
22
- const outputPath = path.join(pkgDir, "package.json");
23
-
24
- await Deno.copyFile(templatePath, outputPath);
25
-
26
- // deno-lint-ignore no-console
27
- console.log(`Copied ${templatePath} to ${outputPath}`);
28
- };
29
-
30
- main();