@sha3/code-standards 0.1.3 → 0.1.5

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 (39) hide show
  1. package/README.md +42 -0
  2. package/bin/code-standards.mjs +507 -96
  3. package/eslint/test.mjs +1 -5
  4. package/package.json +1 -1
  5. package/prettier/index.cjs +1 -1
  6. package/profiles/default.profile.json +2 -0
  7. package/profiles/schema.json +7 -7
  8. package/resources/ai/templates/examples/demo/src/billing/billing-service.ts +18 -3
  9. package/resources/ai/templates/examples/demo/src/config.ts +3 -0
  10. package/resources/ai/templates/examples/demo/src/invoices/invoice-errors.ts +12 -0
  11. package/resources/ai/templates/examples/demo/src/invoices/invoice-service.ts +14 -1
  12. package/resources/ai/templates/examples/rules/async-bad.ts +12 -0
  13. package/resources/ai/templates/examples/rules/async-good.ts +12 -0
  14. package/resources/ai/templates/examples/rules/class-first-bad.ts +12 -0
  15. package/resources/ai/templates/examples/rules/class-first-good.ts +12 -0
  16. package/resources/ai/templates/examples/rules/constructor-bad.ts +12 -0
  17. package/resources/ai/templates/examples/rules/constructor-good.ts +12 -0
  18. package/resources/ai/templates/examples/rules/control-flow-bad.ts +12 -0
  19. package/resources/ai/templates/examples/rules/control-flow-good.ts +12 -0
  20. package/resources/ai/templates/examples/rules/errors-bad.ts +12 -0
  21. package/resources/ai/templates/examples/rules/errors-good.ts +12 -0
  22. package/resources/ai/templates/examples/rules/functions-bad.ts +12 -0
  23. package/resources/ai/templates/examples/rules/functions-good.ts +12 -0
  24. package/resources/ai/templates/examples/rules/returns-bad.ts +12 -0
  25. package/resources/ai/templates/examples/rules/returns-good.ts +12 -0
  26. package/resources/ai/templates/examples/rules/testing-bad.ts +12 -0
  27. package/resources/ai/templates/examples/rules/testing-good.ts +12 -0
  28. package/resources/ai/templates/rules/architecture.md +2 -0
  29. package/resources/ai/templates/rules/class-first.md +2 -0
  30. package/resources/ai/templates/rules/functions.md +2 -0
  31. package/standards/architecture.md +2 -1
  32. package/standards/manifest.json +1 -1
  33. package/standards/schema.json +2 -11
  34. package/standards/style.md +13 -9
  35. package/templates/node-lib/src/config.ts +1 -0
  36. package/templates/node-lib/src/index.ts +3 -1
  37. package/templates/node-service/src/config.ts +3 -0
  38. package/templates/node-service/src/index.ts +4 -3
  39. package/templates/node-service/test/smoke.test.ts +1 -1
package/eslint/test.mjs CHANGED
@@ -4,11 +4,7 @@ import nodeConfig from "./node.mjs";
4
4
  export default [
5
5
  ...nodeConfig,
6
6
  {
7
- files: [
8
- "**/*.test.{js,mjs,cjs,ts,mts,cts}",
9
- "**/*.spec.{js,mjs,cjs,ts,mts,cts}",
10
- "test/**/*.{js,mjs,cjs,ts,mts,cts}"
11
- ],
7
+ files: ["**/*.test.{js,mjs,cjs,ts,mts,cts}", "**/*.spec.{js,mjs,cjs,ts,mts,cts}", "test/**/*.{js,mjs,cjs,ts,mts,cts}"],
12
8
  languageOptions: {
13
9
  globals: {
14
10
  ...globals.mocha,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sha3/code-standards",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "AI-first code standards, tooling exports, and project initializer",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,5 +1,5 @@
1
1
  module.exports = {
2
- printWidth: 100,
2
+ printWidth: 160,
3
3
  tabWidth: 2,
4
4
  useTabs: false,
5
5
  semi: true,
@@ -18,12 +18,14 @@
18
18
  "consts",
19
19
  "types",
20
20
  "private:attributes",
21
+ "protected:attributes",
21
22
  "private:properties",
22
23
  "public:properties",
23
24
  "constructor",
24
25
  "static:properties",
25
26
  "factory",
26
27
  "private:methods",
28
+ "protected:methods",
27
29
  "public:methods",
28
30
  "static:methods"
29
31
  ],
@@ -43,11 +43,7 @@
43
43
  },
44
44
  "return_policy": {
45
45
  "type": "string",
46
- "enum": [
47
- "single_return_strict_no_exceptions",
48
- "single_return_with_guard_clauses",
49
- "free_return_style"
50
- ]
46
+ "enum": ["single_return_strict_no_exceptions", "single_return_with_guard_clauses", "free_return_style"]
51
47
  },
52
48
  "class_design": {
53
49
  "type": "string",
@@ -87,8 +83,8 @@
87
83
  },
88
84
  "comment_section_blocks": {
89
85
  "type": "array",
90
- "minItems": 13,
91
- "maxItems": 13,
86
+ "minItems": 15,
87
+ "maxItems": 15,
92
88
  "items": {
93
89
  "type": "string",
94
90
  "enum": [
@@ -97,12 +93,14 @@
97
93
  "consts",
98
94
  "types",
99
95
  "private:attributes",
96
+ "protected:attributes",
100
97
  "private:properties",
101
98
  "public:properties",
102
99
  "constructor",
103
100
  "static:properties",
104
101
  "factory",
105
102
  "private:methods",
103
+ "protected:methods",
106
104
  "public:methods",
107
105
  "static:methods"
108
106
  ]
@@ -113,12 +111,14 @@
113
111
  "consts",
114
112
  "types",
115
113
  "private:attributes",
114
+ "protected:attributes",
116
115
  "private:properties",
117
116
  "public:properties",
118
117
  "constructor",
119
118
  "static:properties",
120
119
  "factory",
121
120
  "private:methods",
121
+ "protected:methods",
122
122
  "public:methods",
123
123
  "static:methods"
124
124
  ]
@@ -8,6 +8,7 @@
8
8
  * @section imports:internals
9
9
  */
10
10
 
11
+ import { BILLING_CURRENCY_SYMBOL, STATUS_SERVICE_URL } from "../config.js";
11
12
  import type { InvoiceService } from "../invoices/invoice-service.js";
12
13
  import type { InvoiceSummary } from "../invoices/invoice-types.js";
13
14
 
@@ -15,7 +16,7 @@ import type { InvoiceSummary } from "../invoices/invoice-types.js";
15
16
  * @section consts
16
17
  */
17
18
 
18
- const CURRENCY_SYMBOL = "$";
19
+ // empty
19
20
 
20
21
  /**
21
22
  * @section types
@@ -26,6 +27,7 @@ export type BillingSnapshot = {
26
27
  invoiceCount: number;
27
28
  totalAmount: number;
28
29
  formattedTotal: string;
30
+ statusServiceUrl: string;
29
31
  };
30
32
 
31
33
  export class BillingService {
@@ -35,6 +37,12 @@ export class BillingService {
35
37
 
36
38
  // empty
37
39
 
40
+ /**
41
+ * @section protected:attributes
42
+ */
43
+
44
+ // empty
45
+
38
46
  /**
39
47
  * @section private:properties
40
48
  */
@@ -75,10 +83,16 @@ export class BillingService {
75
83
  */
76
84
 
77
85
  private formatCurrency(amount: number): string {
78
- const formattedAmount = `${CURRENCY_SYMBOL}${amount.toFixed(2)}`;
86
+ const formattedAmount = `${BILLING_CURRENCY_SYMBOL}${amount.toFixed(2)}`;
79
87
  return formattedAmount;
80
88
  }
81
89
 
90
+ /**
91
+ * @section protected:methods
92
+ */
93
+
94
+ // empty
95
+
82
96
  /**
83
97
  * @section public:methods
84
98
  */
@@ -89,7 +103,8 @@ export class BillingService {
89
103
  customerId,
90
104
  invoiceCount: summary.count,
91
105
  totalAmount: summary.totalAmount,
92
- formattedTotal: this.formatCurrency(summary.totalAmount)
106
+ formattedTotal: this.formatCurrency(summary.totalAmount),
107
+ statusServiceUrl: STATUS_SERVICE_URL
93
108
  };
94
109
  return snapshot;
95
110
  }
@@ -0,0 +1,3 @@
1
+ export const MINIMUM_INVOICE_AMOUNT = 0;
2
+ export const BILLING_CURRENCY_SYMBOL = "$";
3
+ export const STATUS_SERVICE_URL = "https://status.example.com/health";
@@ -29,6 +29,12 @@ export class InvalidInvoiceCommandError extends Error {
29
29
 
30
30
  // empty
31
31
 
32
+ /**
33
+ * @section protected:attributes
34
+ */
35
+
36
+ // empty
37
+
32
38
  /**
33
39
  * @section private:properties
34
40
  */
@@ -72,6 +78,12 @@ export class InvalidInvoiceCommandError extends Error {
72
78
 
73
79
  // empty
74
80
 
81
+ /**
82
+ * @section protected:methods
83
+ */
84
+
85
+ // empty
86
+
75
87
  /**
76
88
  * @section public:methods
77
89
  */
@@ -8,6 +8,7 @@ import { randomUUID } from "node:crypto";
8
8
  * @section imports:internals
9
9
  */
10
10
 
11
+ import { MINIMUM_INVOICE_AMOUNT } from "../config.js";
11
12
  import { InvalidInvoiceCommandError } from "./invoice-errors.js";
12
13
  import type { CreateInvoiceCommand, Invoice, InvoiceSummary } from "./invoice-types.js";
13
14
 
@@ -15,7 +16,7 @@ import type { CreateInvoiceCommand, Invoice, InvoiceSummary } from "./invoice-ty
15
16
  * @section consts
16
17
  */
17
18
 
18
- const MINIMUM_INVOICE_AMOUNT = 0;
19
+ // empty
19
20
 
20
21
  /**
21
22
  * @section types
@@ -30,6 +31,12 @@ export class InvoiceService {
30
31
 
31
32
  // empty
32
33
 
34
+ /**
35
+ * @section protected:attributes
36
+ */
37
+
38
+ // empty
39
+
33
40
  /**
34
41
  * @section private:properties
35
42
  */
@@ -89,6 +96,12 @@ export class InvoiceService {
89
96
  return invoice;
90
97
  }
91
98
 
99
+ /**
100
+ * @section protected:methods
101
+ */
102
+
103
+ // empty
104
+
92
105
  /**
93
106
  * @section public:methods
94
107
  */
@@ -33,6 +33,12 @@ export class InvoiceSyncService {
33
33
 
34
34
  // empty
35
35
 
36
+ /**
37
+ * @section protected:attributes
38
+ */
39
+
40
+ // empty
41
+
36
42
  /**
37
43
  * @section private:properties
38
44
  */
@@ -76,6 +82,12 @@ export class InvoiceSyncService {
76
82
 
77
83
  // empty
78
84
 
85
+ /**
86
+ * @section protected:methods
87
+ */
88
+
89
+ // empty
90
+
79
91
  /**
80
92
  * @section public:methods
81
93
  */
@@ -33,6 +33,12 @@ export class InvoiceSyncService {
33
33
 
34
34
  // empty
35
35
 
36
+ /**
37
+ * @section protected:attributes
38
+ */
39
+
40
+ // empty
41
+
36
42
  /**
37
43
  * @section private:properties
38
44
  */
@@ -76,6 +82,12 @@ export class InvoiceSyncService {
76
82
 
77
83
  // empty
78
84
 
85
+ /**
86
+ * @section protected:methods
87
+ */
88
+
89
+ // empty
90
+
79
91
  /**
80
92
  * @section public:methods
81
93
  */
@@ -30,6 +30,12 @@ export class InvoiceService {
30
30
 
31
31
  // empty
32
32
 
33
+ /**
34
+ * @section protected:attributes
35
+ */
36
+
37
+ // empty
38
+
33
39
  /**
34
40
  * @section private:properties
35
41
  */
@@ -69,6 +75,12 @@ export class InvoiceService {
69
75
 
70
76
  // empty
71
77
 
78
+ /**
79
+ * @section protected:methods
80
+ */
81
+
82
+ // empty
83
+
72
84
  /**
73
85
  * @section public:methods
74
86
  */
@@ -30,6 +30,12 @@ export class InvoiceService {
30
30
 
31
31
  private readonly requestId: string;
32
32
 
33
+ /**
34
+ * @section protected:attributes
35
+ */
36
+
37
+ // empty
38
+
33
39
  /**
34
40
  * @section private:properties
35
41
  */
@@ -81,6 +87,12 @@ export class InvoiceService {
81
87
  return invoice;
82
88
  }
83
89
 
90
+ /**
91
+ * @section protected:methods
92
+ */
93
+
94
+ // empty
95
+
84
96
  /**
85
97
  * @section public:methods
86
98
  */
@@ -30,6 +30,12 @@ export class InvoiceIdBuilder {
30
30
 
31
31
  // empty
32
32
 
33
+ /**
34
+ * @section protected:attributes
35
+ */
36
+
37
+ // empty
38
+
33
39
  /**
34
40
  * @section private:properties
35
41
  */
@@ -79,6 +85,12 @@ export class InvoiceIdBuilder {
79
85
  return year;
80
86
  }
81
87
 
88
+ /**
89
+ * @section protected:methods
90
+ */
91
+
92
+ // empty
93
+
82
94
  /**
83
95
  * @section public:methods
84
96
  */
@@ -30,6 +30,12 @@ export class InvoiceIdBuilder {
30
30
 
31
31
  // empty
32
32
 
33
+ /**
34
+ * @section protected:attributes
35
+ */
36
+
37
+ // empty
38
+
33
39
  /**
34
40
  * @section private:properties
35
41
  */
@@ -78,6 +84,12 @@ export class InvoiceIdBuilder {
78
84
  return year;
79
85
  }
80
86
 
87
+ /**
88
+ * @section protected:methods
89
+ */
90
+
91
+ // empty
92
+
81
93
  /**
82
94
  * @section public:methods
83
95
  */
@@ -29,6 +29,12 @@ export class ControlFlowPolicy {
29
29
 
30
30
  // empty
31
31
 
32
+ /**
33
+ * @section protected:attributes
34
+ */
35
+
36
+ // empty
37
+
32
38
  /**
33
39
  * @section private:properties
34
40
  */
@@ -68,6 +74,12 @@ export class ControlFlowPolicy {
68
74
 
69
75
  // empty
70
76
 
77
+ /**
78
+ * @section protected:methods
79
+ */
80
+
81
+ // empty
82
+
71
83
  /**
72
84
  * @section public:methods
73
85
  */
@@ -29,6 +29,12 @@ export class FeatureGate {
29
29
 
30
30
  // empty
31
31
 
32
+ /**
33
+ * @section protected:attributes
34
+ */
35
+
36
+ // empty
37
+
32
38
  /**
33
39
  * @section private:properties
34
40
  */
@@ -70,6 +76,12 @@ export class FeatureGate {
70
76
 
71
77
  // empty
72
78
 
79
+ /**
80
+ * @section protected:methods
81
+ */
82
+
83
+ // empty
84
+
73
85
  /**
74
86
  * @section public:methods
75
87
  */
@@ -29,6 +29,12 @@ export class InvoiceLookup {
29
29
 
30
30
  // empty
31
31
 
32
+ /**
33
+ * @section protected:attributes
34
+ */
35
+
36
+ // empty
37
+
32
38
  /**
33
39
  * @section private:properties
34
40
  */
@@ -68,6 +74,12 @@ export class InvoiceLookup {
68
74
 
69
75
  // empty
70
76
 
77
+ /**
78
+ * @section protected:methods
79
+ */
80
+
81
+ // empty
82
+
71
83
  /**
72
84
  * @section public:methods
73
85
  */
@@ -29,6 +29,12 @@ export class InvoiceNotFoundError extends Error {
29
29
 
30
30
  // empty
31
31
 
32
+ /**
33
+ * @section protected:attributes
34
+ */
35
+
36
+ // empty
37
+
32
38
  /**
33
39
  * @section private:properties
34
40
  */
@@ -72,6 +78,12 @@ export class InvoiceNotFoundError extends Error {
72
78
 
73
79
  // empty
74
80
 
81
+ /**
82
+ * @section protected:methods
83
+ */
84
+
85
+ // empty
86
+
75
87
  /**
76
88
  * @section public:methods
77
89
  */
@@ -30,6 +30,12 @@ export class PaymentNormalizer {
30
30
 
31
31
  // empty
32
32
 
33
+ /**
34
+ * @section protected:attributes
35
+ */
36
+
37
+ // empty
38
+
33
39
  /**
34
40
  * @section private:properties
35
41
  */
@@ -69,6 +75,12 @@ export class PaymentNormalizer {
69
75
 
70
76
  // empty
71
77
 
78
+ /**
79
+ * @section protected:methods
80
+ */
81
+
82
+ // empty
83
+
72
84
  /**
73
85
  * @section public:methods
74
86
  */
@@ -30,6 +30,12 @@ export class PaymentNormalizer {
30
30
 
31
31
  // empty
32
32
 
33
+ /**
34
+ * @section protected:attributes
35
+ */
36
+
37
+ // empty
38
+
33
39
  /**
34
40
  * @section private:properties
35
41
  */
@@ -82,6 +88,12 @@ export class PaymentNormalizer {
82
88
  return sanitizedMetadata;
83
89
  }
84
90
 
91
+ /**
92
+ * @section protected:methods
93
+ */
94
+
95
+ // empty
96
+
85
97
  /**
86
98
  * @section public:methods
87
99
  */
@@ -29,6 +29,12 @@ export class InvoiceStatusPresenter {
29
29
 
30
30
  // empty
31
31
 
32
+ /**
33
+ * @section protected:attributes
34
+ */
35
+
36
+ // empty
37
+
32
38
  /**
33
39
  * @section private:properties
34
40
  */
@@ -68,6 +74,12 @@ export class InvoiceStatusPresenter {
68
74
 
69
75
  // empty
70
76
 
77
+ /**
78
+ * @section protected:methods
79
+ */
80
+
81
+ // empty
82
+
71
83
  /**
72
84
  * @section public:methods
73
85
  */
@@ -29,6 +29,12 @@ export class InvoiceStatusPresenter {
29
29
 
30
30
  // empty
31
31
 
32
+ /**
33
+ * @section protected:attributes
34
+ */
35
+
36
+ // empty
37
+
32
38
  /**
33
39
  * @section private:properties
34
40
  */
@@ -68,6 +74,12 @@ export class InvoiceStatusPresenter {
68
74
 
69
75
  // empty
70
76
 
77
+ /**
78
+ * @section protected:methods
79
+ */
80
+
81
+ // empty
82
+
71
83
  /**
72
84
  * @section public:methods
73
85
  */
@@ -29,6 +29,12 @@ export class InvoiceEscalationPolicy {
29
29
 
30
30
  // empty
31
31
 
32
+ /**
33
+ * @section protected:attributes
34
+ */
35
+
36
+ // empty
37
+
32
38
  /**
33
39
  * @section private:properties
34
40
  */
@@ -68,6 +74,12 @@ export class InvoiceEscalationPolicy {
68
74
 
69
75
  // empty
70
76
 
77
+ /**
78
+ * @section protected:methods
79
+ */
80
+
81
+ // empty
82
+
71
83
  /**
72
84
  * @section public:methods
73
85
  */
@@ -30,6 +30,12 @@ export class InvoiceEscalationPolicy {
30
30
 
31
31
  // empty
32
32
 
33
+ /**
34
+ * @section protected:attributes
35
+ */
36
+
37
+ // empty
38
+
33
39
  /**
34
40
  * @section private:properties
35
41
  */
@@ -73,6 +79,12 @@ export class InvoiceEscalationPolicy {
73
79
  return dayCount;
74
80
  }
75
81
 
82
+ /**
83
+ * @section protected:methods
84
+ */
85
+
86
+ // empty
87
+
76
88
  /**
77
89
  * @section public:methods
78
90
  */
@@ -3,9 +3,11 @@
3
3
  - Code MUST be organized by feature (for example: `src/users`, `src/billing`, `src/invoices`).
4
4
  - Each feature MUST keep its own domain model, application services, and infrastructure adapters grouped by feature.
5
5
  - Cross-feature imports MUST happen through explicit public entry points.
6
+ - Hardcoded, non-parameterized configuration MUST be centralized in `src/config.ts` (for example, external service URLs).
6
7
 
7
8
  Good example:
8
9
 
10
+ - `ai/examples/demo/src/config.ts`
9
11
  - `ai/examples/demo/src/invoices/invoice-service.ts`
10
12
  - `ai/examples/demo/src/invoices/invoice-errors.ts`
11
13
  - `ai/examples/demo/src/invoices/invoice-types.ts`
@@ -14,12 +14,14 @@
14
14
  - `consts`
15
15
  - `types`
16
16
  - `private:attributes`
17
+ - `protected:attributes`
17
18
  - `private:properties`
18
19
  - `public:properties`
19
20
  - `constructor`
20
21
  - `static:properties`
21
22
  - `factory`
22
23
  - `private:methods`
24
+ - `protected:methods`
23
25
  - `public:methods`
24
26
  - `static:methods`
25
27
  - All section blocks MUST exist even when empty, using `// empty` after the section marker.
@@ -6,6 +6,8 @@
6
6
  - Types MUST be preferred over interfaces for local modeling unless a public contract requires an interface.
7
7
  - New implementation and test files MUST be `.ts`.
8
8
  - JavaScript source files (`.js`, `.mjs`, `.cjs`) are not allowed in `src/` or `test/`.
9
+ - If a declaration/expression fits in one line within 160 chars, it MUST stay on one line.
10
+ - If a function/method needs many inputs, define a named `<FunctionName>Options` type and pass one `options` parameter.
9
11
 
10
12
  Good example:
11
13