@final-commerce/common 2.0.16 → 2.0.18-beta.1

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/bin/gate-save.mjs CHANGED
@@ -3,8 +3,7 @@
3
3
  * gate-save — pre-commit hook.
4
4
  *
5
5
  * 1. Runs lint-staged over modified surfaces.
6
- * 2. Scans staged .ts/.tsx/.js files for TODO comments that lack a Jira ticket
7
- * reference (e.g. "// TODO: do something FI-123"). Bare TODOs block commit.
6
+ * 2. Syncs i18n bundles when the repo opts in via the fc-i18n package.json key.
8
7
  *
9
8
  * Exits 0 on success, 1 on any gate failure.
10
9
  *
@@ -48,7 +47,6 @@ if (stagedResult.status !== 0) {
48
47
  fail(`Could not enumerate staged files:\n${stagedResult.stderr.trim()}`);
49
48
  }
50
49
 
51
- const CODE_EXTS = /\.(ts|tsx|mts|cts|js|mjs|cjs|jsx)$/;
52
50
  const VERSION_BUMP_FILES = /^(package\.json|package-lock\.json|yarn\.lock)$/;
53
51
 
54
52
  const allStaged = stagedResult.stdout
@@ -61,8 +59,6 @@ if (allStaged.length > 0 && allStaged.every((f) => VERSION_BUMP_FILES.test(f)))
61
59
  process.exit(0);
62
60
  }
63
61
 
64
- const codeFiles = allStaged.filter((f) => CODE_EXTS.test(f) && !f.startsWith('bin/'));
65
-
66
62
  // ── 1. lint-staged ────────────────────────────────────────────────────────────
67
63
 
68
64
  info('Running lint-staged…');
@@ -74,64 +70,16 @@ if (lintResult.status !== 0) {
74
70
 
75
71
  ok('lint-staged passed.');
76
72
 
77
- // ── 2. TODO scanner ──────────────────────────────────────────────────────────
78
-
79
- info('Scanning staged files for bare TODOs…');
80
-
81
- // A Jira-style ticket reference: one or more uppercase letters, a dash, and digits.
82
- const JIRA_REF_RE = /[A-Z]+-\d+/;
83
- // Matches any TODO annotation (case-insensitive), with optional owner parens.
84
- const TODO_LINE_RE = /TODO(?:\s*\([^)]*\))?\s*[::]?\s+(.+)/i;
85
-
86
- const violations = [];
87
-
88
- for (const file of codeFiles) {
89
- // Read the staged blob, not the working-tree file, to avoid false positives
90
- // from unstaged edits made after the last `git add`.
91
- const blobResult = capture(`git show :${file}`);
92
- if (blobResult.status !== 0) continue;
93
-
94
- const lines = blobResult.stdout.split('\n');
95
-
96
- for (let i = 0; i < lines.length; i++) {
97
- const match = lines[i].match(TODO_LINE_RE);
98
- if (match && !JIRA_REF_RE.test(lines[i])) {
99
- violations.push({ file, line: i + 1, text: lines[i].trim() });
100
- }
101
- }
102
- }
103
-
104
- if (violations.length > 0) {
105
- process.stderr.write(
106
- '\x1b[31m✖ Bare TODOs detected — each TODO must carry a Jira ticket reference:\x1b[0m\n',
107
- );
108
-
109
- const byFile = violations.reduce((acc, v) => {
110
- (acc[v.file] ??= []).push(v);
111
- return acc;
112
- }, {});
113
-
114
- for (const [file, items] of Object.entries(byFile)) {
115
- process.stderr.write(`\x1b[33m\n ${file}\x1b[0m\n`);
116
- items.forEach(({ line, text }) => {
117
- process.stderr.write(`\x1b[90m ${String(line).padStart(4)} ${text}\x1b[0m\n`);
118
- });
119
- }
120
-
121
- process.stderr.write(
122
- '\x1b[90m\n Example fix: // TODO: refactor this FI-999\x1b[0m\n',
123
- );
124
- fail(`${violations.length} bare TODO(s) must be resolved before committing.`);
125
- }
126
-
127
- ok('No bare TODOs detected.');
128
-
129
- // ── 3. i18n sync ──────────────────────────────────────────────────────────────
73
+ // ── 2. i18n sync ──────────────────────────────────────────────────────────────
130
74
 
131
75
  const pkgJsonPath = resolve(process.cwd(), 'package.json');
132
76
  if (existsSync(pkgJsonPath)) {
133
77
  let rootPkg;
134
- try { rootPkg = JSON.parse(readFileSync(pkgJsonPath, 'utf8')); } catch { /* ignore */ }
78
+ try {
79
+ rootPkg = JSON.parse(readFileSync(pkgJsonPath, 'utf8'));
80
+ } catch {
81
+ /* ignore */
82
+ }
135
83
 
136
84
  if (rootPkg?.['fc-i18n']?.slug) {
137
85
  info('Running i18n sync…');
@@ -114,15 +114,6 @@ function writeHook(name, content) {
114
114
  writeHook('pre-commit', 'npx gate-save');
115
115
  writeHook('pre-push', 'npx gate-done');
116
116
 
117
- const prepareCommitMsgHook = join(huskyDir, 'prepare-commit-msg');
118
- if (existsSync(prepareCommitMsgHook)) {
119
- skip('.husky/prepare-commit-msg');
120
- } else {
121
- writeFileSync(prepareCommitMsgHook, readFileSync(join(import.meta.dirname, 'prepare-commit-msg.sh'), 'utf8'), 'utf8');
122
- chmodSync(prepareCommitMsgHook, 0o755);
123
- ok('Created .husky/prepare-commit-msg');
124
- }
125
-
126
117
  writeHook('commit-msg', 'npx --no -- commitlint --edit "$1"');
127
118
 
128
119
  // ── 6. package.json mutations ─────────────────────────────────────────────────
@@ -157,7 +148,7 @@ if (!pkg['lint-staged']) {
157
148
  ok('Added lint-staged config to package.json');
158
149
  }
159
150
 
160
- // devDependencies — add husky, lint-staged, commitlint, and jira hook if missing.
151
+ // devDependencies — add husky, lint-staged, and commitlint if missing.
161
152
  pkg.devDependencies ??= {};
162
153
  const devDepsToAdd = [
163
154
  ['husky', '^9.0.0'],
@@ -3,22 +3,18 @@
3
3
  * gate-start — Developer session initialiser.
4
4
  *
5
5
  * 1. Verifies @final-commerce/common in node_modules matches latest registry release.
6
- * 2. Prompts for (or accepts via arg/env) a Jira ticket ID.
7
6
  *
8
- * Branch checkout is handled by the tasks-manager workspace tooling.
7
+ * Branch checkout and ticket tracking are handled by the tasks-manager workspace tooling.
9
8
  *
10
9
  * Usage:
11
- * gate-start [TICKET-ID]
12
- * JIRA_TICKET_ID=FI-1234 gate-start
10
+ * gate-start
13
11
  */
14
12
 
15
13
  import { spawnSync } from 'node:child_process';
16
- import { createInterface } from 'node:readline';
17
14
  import { existsSync, readFileSync } from 'node:fs';
18
15
  import { resolve } from 'node:path';
19
16
 
20
17
  const PKG_NAME = '@final-commerce/common';
21
- const TICKET_RE = /^[A-Z]+-\d+$/;
22
18
 
23
19
  // ── helpers ──────────────────────────────────────────────────────────────────
24
20
 
@@ -39,16 +35,6 @@ function ok(msg) {
39
35
  process.stdout.write(`\x1b[32m✔ ${msg}\x1b[0m\n`);
40
36
  }
41
37
 
42
- function ask(question) {
43
- return new Promise((resolve) => {
44
- const rl = createInterface({ input: process.stdin, output: process.stdout });
45
- rl.question(question, (answer) => {
46
- rl.close();
47
- resolve(answer.trim());
48
- });
49
- });
50
- }
51
-
52
38
  // ── 1. upstream version check ─────────────────────────────────────────────────
53
39
 
54
40
  info(`Checking ${PKG_NAME} upstream version…`);
@@ -84,18 +70,4 @@ if (localVersion !== latestVersion) {
84
70
  );
85
71
  }
86
72
 
87
- ok(`${PKG_NAME}@${localVersion} is current.`);
88
-
89
- // ── 2. Jira ticket ID ─────────────────────────────────────────────────────────
90
-
91
- let ticketId = (process.env.JIRA_TICKET_ID ?? process.argv[2] ?? '').toUpperCase();
92
-
93
- if (!ticketId) {
94
- ticketId = (await ask('\nJira ticket ID (e.g. FI-1234): ')).toUpperCase();
95
- }
96
-
97
- if (!TICKET_RE.test(ticketId)) {
98
- fail(`"${ticketId}" is not a valid Jira ticket ID. Expected format: PROJECT-123`);
99
- }
100
-
101
- ok(`Ticket ${ticketId} confirmed. Ready to work.`);
73
+ ok(`${PKG_NAME}@${localVersion} is current. Ready to work.`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@final-commerce/common",
3
- "version": "2.0.16",
3
+ "version": "2.0.18-beta.1",
4
4
  "description": "Shared utilities, types, constants, and engineering governance configs for the Final Commerce platform.",
5
5
  "homepage": "https://github.com/Final-Commerce/common#readme",
6
6
  "bugs": {
@@ -1,16 +0,0 @@
1
- #!/usr/bin/env sh
2
-
3
- BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null)
4
- if [ -z "$BRANCH" ]; then exit 0; fi
5
-
6
- # Skip protected branches
7
- if echo "$BRANCH" | grep -qE '^(main|master|develop|pre-prod|release-staging.*)$'; then exit 0; fi
8
-
9
- TICKET=$(echo "$BRANCH" | grep -oE '[A-Z]+-[0-9]+' | head -1)
10
- if [ -z "$TICKET" ]; then exit 0; fi
11
-
12
- MSG_FILE="$1"
13
- CURRENT=$(cat "$MSG_FILE")
14
- if echo "$CURRENT" | grep -q "$TICKET"; then exit 0; fi
15
-
16
- awk -v ticket="[$TICKET]" 'NR==1{print $0 " " ticket; next}{print}' "$MSG_FILE" > "$MSG_FILE.tmp" && mv "$MSG_FILE.tmp" "$MSG_FILE"