@sha3/code-standards 0.1.5 → 0.1.6

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  <div align="center">
2
2
 
3
- # @sha3/code-standards
3
+ # 📏 @sha3/code-standards
4
4
 
5
5
  **Scaffold TypeScript projects + enforce how AI writes code.**
6
6
 
@@ -117,10 +117,13 @@ After `init`, your new repo contains:
117
117
  - `ai/examples/rules/*.ts` (good/bad examples per rule)
118
118
  - `ai/examples/demo/src/*` (feature-folder demo with classes and section blocks)
119
119
  - `src/config.ts` for centralized hardcoded configuration values
120
+ - `README.md` generated with an icon emoji in the main header
120
121
  - `.gitignore` preconfigured for Node/TypeScript output
121
122
  - lint/format/typecheck/test-ready project template
122
123
  - `package.json.codeStandards` metadata used by `refresh` (`template`, `profilePath`, `withAiAdapters`, `lastRefreshWith`)
123
124
 
125
+ `config.ts` convention: export a single default object and import it as `import CONFIG from "./config.js"`.
126
+
124
127
  That means the next step is **not** configuring tools. The next step is telling your assistant to obey `AGENTS.md` before coding.
125
128
 
126
129
  Generated project code is TypeScript-only: implementation and tests live in `.ts` files.
@@ -537,8 +537,10 @@ function getRelativeProfilePath(profilePath, targetPath) {
537
537
  const resolvedProfilePath = path.resolve(targetPath, profilePath);
538
538
  const relativePath = path.relative(targetPath, resolvedProfilePath);
539
539
 
540
+ // If the profile is outside the project directory, return null instead of absolute path
541
+ // to avoid storing machine-specific paths in package.json
540
542
  if (relativePath.startsWith("..") || path.isAbsolute(relativePath)) {
541
- return resolvedProfilePath;
543
+ return null;
542
544
  }
543
545
 
544
546
  return relativePath;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sha3/code-standards",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "AI-first code standards, tooling exports, and project initializer",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,7 +8,7 @@
8
8
  * @section imports:internals
9
9
  */
10
10
 
11
- import { BILLING_CURRENCY_SYMBOL, STATUS_SERVICE_URL } from "../config.js";
11
+ import CONFIG from "../config.js";
12
12
  import type { InvoiceService } from "../invoices/invoice-service.js";
13
13
  import type { InvoiceSummary } from "../invoices/invoice-types.js";
14
14
 
@@ -83,7 +83,7 @@ export class BillingService {
83
83
  */
84
84
 
85
85
  private formatCurrency(amount: number): string {
86
- const formattedAmount = `${BILLING_CURRENCY_SYMBOL}${amount.toFixed(2)}`;
86
+ const formattedAmount = `${CONFIG.BILLING_CURRENCY_SYMBOL}${amount.toFixed(2)}`;
87
87
  return formattedAmount;
88
88
  }
89
89
 
@@ -104,7 +104,7 @@ export class BillingService {
104
104
  invoiceCount: summary.count,
105
105
  totalAmount: summary.totalAmount,
106
106
  formattedTotal: this.formatCurrency(summary.totalAmount),
107
- statusServiceUrl: STATUS_SERVICE_URL
107
+ statusServiceUrl: CONFIG.STATUS_SERVICE_URL
108
108
  };
109
109
  return snapshot;
110
110
  }
@@ -1,3 +1,7 @@
1
- export const MINIMUM_INVOICE_AMOUNT = 0;
2
- export const BILLING_CURRENCY_SYMBOL = "$";
3
- export const STATUS_SERVICE_URL = "https://status.example.com/health";
1
+ const CONFIG = {
2
+ MINIMUM_INVOICE_AMOUNT: 0,
3
+ BILLING_CURRENCY_SYMBOL: "$",
4
+ STATUS_SERVICE_URL: "https://status.example.com/health"
5
+ } as const;
6
+
7
+ export default CONFIG;
@@ -8,7 +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
+ import CONFIG from "../config.js";
12
12
  import { InvalidInvoiceCommandError } from "./invoice-errors.js";
13
13
  import type { CreateInvoiceCommand, Invoice, InvoiceSummary } from "./invoice-types.js";
14
14
 
@@ -81,7 +81,7 @@ export class InvoiceService {
81
81
  throw InvalidInvoiceCommandError.forReason("customerId is required");
82
82
  }
83
83
 
84
- if (command.amount <= MINIMUM_INVOICE_AMOUNT) {
84
+ if (command.amount <= CONFIG.MINIMUM_INVOICE_AMOUNT) {
85
85
  throw InvalidInvoiceCommandError.forReason("amount must be greater than zero");
86
86
  }
87
87
  }
@@ -4,6 +4,7 @@
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
6
  - Hardcoded, non-parameterized configuration MUST be centralized in `src/config.ts` (for example, external service URLs).
7
+ - `src/config.ts` MUST export a single default object and it MUST always be imported as `import CONFIG from ".../config.js"`.
7
8
 
8
9
  Good example:
9
10
 
@@ -23,3 +23,4 @@ Both templates SHOULD keep this baseline structure:
23
23
  - Keep feature modules cohesive.
24
24
  - Avoid cyclic dependencies.
25
25
  - Keep hardcoded application configuration centralized in `src/config.ts`.
26
+ - `src/config.ts` MUST export a default object (for example `CONFIG`) and consumers MUST import it as `import CONFIG from "./config.js"`.
@@ -20,6 +20,7 @@ All code MUST follow the canonical rules in `standards/manifest.json`.
20
20
  - Use type-only imports when possible.
21
21
  - If a function/method needs many inputs, define a named `<FunctionName>Options` type and pass a single `options` parameter.
22
22
  - Always use braces in control flow (`if`, `else`, `for`, `while`, `do`).
23
+ - `src/config.ts` MUST export a default object and it MUST always be imported as `import CONFIG from ".../config.js"`.
23
24
 
24
25
  ## Naming
25
26
 
@@ -0,0 +1,37 @@
1
+ # 📚 {{packageName}}
2
+
3
+ Libreria TypeScript lista para publicar y reutilizar.
4
+
5
+ ## TL;DR
6
+
7
+ ```bash
8
+ npm install
9
+ npm run check
10
+ npm run build
11
+ ```
12
+
13
+ ## Uso
14
+
15
+ ```ts
16
+ import { greet } from "./dist/index.js";
17
+
18
+ console.log(greet("world"));
19
+ ```
20
+
21
+ ## Scripts
22
+
23
+ - `npm run check`: lint + format check + typecheck + tests
24
+ - `npm run fix`: aplica autofix de lint y prettier
25
+ - `npm run build`: compila a `dist/`
26
+ - `npm run test`: ejecuta tests con Node test runner
27
+
28
+ ## Estructura
29
+
30
+ - `src/`: implementacion
31
+ - `src/config.ts`: configuracion hardcodeada centralizada
32
+ - `test/`: pruebas
33
+ - `dist/`: salida de build
34
+
35
+ ## AI Workflow
36
+
37
+ Si trabajas con asistentes, usa `AGENTS.md` y `ai/*.md` como reglas bloqueantes.
@@ -1 +1,5 @@
1
- export const GREETING_PREFIX = "Hello";
1
+ const CONFIG = {
2
+ GREETING_PREFIX: "Hello"
3
+ } as const;
4
+
5
+ export default CONFIG;
@@ -1,5 +1,5 @@
1
- import { GREETING_PREFIX } from "./config.js";
1
+ import CONFIG from "./config.js";
2
2
 
3
3
  export function greet(name: string): string {
4
- return `${GREETING_PREFIX}, ${name}`;
4
+ return `${CONFIG.GREETING_PREFIX}, ${name}`;
5
5
  }
@@ -0,0 +1,36 @@
1
+ # 🚀 {{packageName}}
2
+
3
+ Servicio TypeScript listo para ejecutar en local y evolucionar por features.
4
+
5
+ ## TL;DR
6
+
7
+ ```bash
8
+ npm install
9
+ npm run check
10
+ npm run start
11
+ ```
12
+
13
+ ## Ejecucion
14
+
15
+ ```bash
16
+ npm run start
17
+ ```
18
+
19
+ El servicio arranca por defecto en `http://localhost:3000`.
20
+
21
+ ## Scripts
22
+
23
+ - `npm run start`: inicia el servicio con `tsx`
24
+ - `npm run check`: lint + format check + typecheck + tests
25
+ - `npm run fix`: aplica autofix de lint y prettier
26
+ - `npm run test`: ejecuta tests con Node test runner
27
+
28
+ ## Estructura
29
+
30
+ - `src/`: implementacion
31
+ - `src/config.ts`: configuracion hardcodeada centralizada
32
+ - `test/`: pruebas
33
+
34
+ ## AI Workflow
35
+
36
+ Si trabajas con asistentes, usa `AGENTS.md` y `ai/*.md` como reglas bloqueantes.
@@ -1,3 +1,7 @@
1
- export const RESPONSE_CONTENT_TYPE = "application/json";
2
- export const DEFAULT_PORT = 3000;
3
- export const EXTERNAL_STATUS_URL = "https://status.example.com/health";
1
+ const CONFIG = {
2
+ RESPONSE_CONTENT_TYPE: "application/json",
3
+ DEFAULT_PORT: 3000,
4
+ EXTERNAL_STATUS_URL: "https://status.example.com/health"
5
+ } as const;
6
+
7
+ export default CONFIG;
@@ -1,16 +1,16 @@
1
1
  import { createServer } from "node:http";
2
- import { DEFAULT_PORT, EXTERNAL_STATUS_URL, RESPONSE_CONTENT_TYPE } from "./config.js";
2
+ import CONFIG from "./config.js";
3
3
 
4
4
  export function buildServer() {
5
5
  return createServer((_, response) => {
6
6
  response.statusCode = 200;
7
- response.setHeader("content-type", RESPONSE_CONTENT_TYPE);
8
- response.end(JSON.stringify({ ok: true, statusSource: EXTERNAL_STATUS_URL }));
7
+ response.setHeader("content-type", CONFIG.RESPONSE_CONTENT_TYPE);
8
+ response.end(JSON.stringify({ ok: true, statusSource: CONFIG.EXTERNAL_STATUS_URL }));
9
9
  });
10
10
  }
11
11
 
12
12
  if (process.env.NODE_ENV !== "test") {
13
- const port = Number(process.env.PORT ?? String(DEFAULT_PORT));
13
+ const port = Number(process.env.PORT ?? String(CONFIG.DEFAULT_PORT));
14
14
  const server = buildServer();
15
15
  server.listen(port, () => {
16
16
  console.log(`service listening on http://localhost:${port}`);