ado-sync 0.1.2 → 0.1.3

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/dist/config.js CHANGED
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.CONFIG_TEMPLATE_JSON = void 0;
37
37
  exports.resolveConfigPath = resolveConfigPath;
38
38
  exports.loadConfig = loadConfig;
39
+ exports.applyOverrides = applyOverrides;
39
40
  const fs = __importStar(require("fs"));
40
41
  const yaml = __importStar(require("js-yaml"));
41
42
  const path = __importStar(require("path"));
@@ -79,6 +80,9 @@ function loadConfig(configPath) {
79
80
  // Default values
80
81
  cfg.sync = cfg.sync ?? {};
81
82
  cfg.sync.tagPrefix = cfg.sync.tagPrefix ?? 'tc';
83
+ cfg.sync.titleField = cfg.sync.titleField ?? 'System.Title';
84
+ cfg.sync.conflictAction = cfg.sync.conflictAction ?? 'overwrite';
85
+ cfg.sync.disableLocalChanges = cfg.sync.disableLocalChanges ?? false;
82
86
  return cfg;
83
87
  }
84
88
  function validateConfig(cfg, filePath) {
@@ -97,13 +101,52 @@ function validateConfig(cfg, filePath) {
97
101
  if (cfg.auth.type === 'managedIdentity' && !cfg.auth.applicationIdURI) {
98
102
  err('"auth.applicationIdURI" is required when auth.type is "managedIdentity"');
99
103
  }
100
- if (!cfg.testPlan?.id)
101
- err('"testPlan.id" is required');
104
+ if (!cfg.testPlan?.id && !cfg.testPlans?.length) {
105
+ err('"testPlan.id" or "testPlans" array is required');
106
+ }
102
107
  if (!cfg.local?.type)
103
108
  err('"local.type" is required (gherkin | markdown)');
104
109
  if (!cfg.local?.include)
105
110
  err('"local.include" is required');
106
111
  }
112
+ /**
113
+ * Apply CLI --config-override values to a loaded config.
114
+ * Each override is a string like "sync.tagPrefix=mytag" or "testPlan.id=42".
115
+ * Dot-path navigation sets nested values. Numbers are coerced automatically.
116
+ */
117
+ function applyOverrides(cfg, overrides) {
118
+ for (const override of overrides) {
119
+ const eqIdx = override.indexOf('=');
120
+ if (eqIdx === -1) {
121
+ throw new Error(`Invalid --config-override "${override}": expected format "path=value"`);
122
+ }
123
+ const dotPath = override.slice(0, eqIdx).trim();
124
+ const rawValue = override.slice(eqIdx + 1);
125
+ const segments = dotPath.split('.');
126
+ let obj = cfg;
127
+ for (let i = 0; i < segments.length - 1; i++) {
128
+ const seg = segments[i];
129
+ if (obj[seg] === undefined || obj[seg] === null)
130
+ obj[seg] = {};
131
+ obj = obj[seg];
132
+ }
133
+ const lastKey = segments[segments.length - 1];
134
+ // Coerce: number if parseable, boolean if 'true'/'false', else string
135
+ const numVal = Number(rawValue);
136
+ if (rawValue === 'true') {
137
+ obj[lastKey] = true;
138
+ }
139
+ else if (rawValue === 'false') {
140
+ obj[lastKey] = false;
141
+ }
142
+ else if (!isNaN(numVal) && rawValue.trim() !== '') {
143
+ obj[lastKey] = numVal;
144
+ }
145
+ else {
146
+ obj[lastKey] = rawValue;
147
+ }
148
+ }
149
+ }
107
150
  exports.CONFIG_TEMPLATE_JSON = JSON.stringify({
108
151
  orgUrl: 'https://dev.azure.com/YOUR_ORG',
109
152
  project: 'YOUR_PROJECT',
@@ -114,6 +157,7 @@ exports.CONFIG_TEMPLATE_JSON = JSON.stringify({
114
157
  testPlan: {
115
158
  id: 0,
116
159
  suiteId: 0,
160
+ suiteMapping: 'flat',
117
161
  },
118
162
  local: {
119
163
  type: 'gherkin',
@@ -122,8 +166,12 @@ exports.CONFIG_TEMPLATE_JSON = JSON.stringify({
122
166
  },
123
167
  sync: {
124
168
  tagPrefix: 'tc',
169
+ titleField: 'System.Title',
125
170
  areaPath: '',
126
171
  iterationPath: '',
172
+ disableLocalChanges: false,
173
+ conflictAction: 'overwrite',
174
+ links: [],
127
175
  },
128
176
  }, null, 2);
129
177
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -5,11 +5,11 @@
5
5
  * playwright-bdd). This produces both the GherkinDocument (AST) and Pickles
6
6
  * (compiled, example-substituted scenarios) in a single pass.
7
7
  *
8
- * Pickles are the canonical unit of work — they already have:
9
- * - Example values substituted in titles and step text
10
- * - Background steps merged into every scenario
11
- * - Tags inherited from Feature + Scenario + Examples blocks
12
- * - Step type (Context/Action/Outcome) instead of keyword
8
+ * For regular Scenarios: uses Pickles (background-merged, already correct).
9
+ * For Scenario Outlines: uses the AST directly to produce ONE ParsedTest
10
+ * with template steps and an outlineParameters table,
11
+ * so Azure gets a single parametrized TC instead of
12
+ * one TC per example row.
13
13
  *
14
14
  * ID tag convention: @tc:12345 (prefix configurable via sync.tagPrefix)
15
15
  *
@@ -17,14 +17,9 @@
17
17
  * Directory segments prefixed with @ are added as tags automatically.
18
18
  * e.g. specs/@smoke/@regression/login.feature → tags: ['smoke', 'regression']
19
19
  */
20
- import { ParsedTest } from '../types';
20
+ import { LinkConfig, ParsedTest } from '../types';
21
+ import { extractPathTags } from './shared';
22
+ export { extractPathTags };
21
23
  /** Extract Azure Test Case ID from a list of tag names. e.g. ['tc:123', 'smoke'] → 123 */
22
24
  export declare function extractAzureId(tags: string[], tagPrefix: string): number | undefined;
23
- /**
24
- * Extract auto-tags from directory segments that start with '@'.
25
- *
26
- * Given /project/specs/@smoke/@regression/login.feature
27
- * returns ['smoke', 'regression']
28
- */
29
- export declare function extractPathTags(filePath: string): string[];
30
- export declare function parseGherkinFile(filePath: string, tagPrefix: string): ParsedTest[];
25
+ export declare function parseGherkinFile(filePath: string, tagPrefix: string, linkConfigs?: LinkConfig[]): ParsedTest[];
@@ -6,11 +6,11 @@
6
6
  * playwright-bdd). This produces both the GherkinDocument (AST) and Pickles
7
7
  * (compiled, example-substituted scenarios) in a single pass.
8
8
  *
9
- * Pickles are the canonical unit of work — they already have:
10
- * - Example values substituted in titles and step text
11
- * - Background steps merged into every scenario
12
- * - Tags inherited from Feature + Scenario + Examples blocks
13
- * - Step type (Context/Action/Outcome) instead of keyword
9
+ * For regular Scenarios: uses Pickles (background-merged, already correct).
10
+ * For Scenario Outlines: uses the AST directly to produce ONE ParsedTest
11
+ * with template steps and an outlineParameters table,
12
+ * so Azure gets a single parametrized TC instead of
13
+ * one TC per example row.
14
14
  *
15
15
  * ID tag convention: @tc:12345 (prefix configurable via sync.tagPrefix)
16
16
  *
@@ -52,13 +52,14 @@ var __importStar = (this && this.__importStar) || (function () {
52
52
  };
53
53
  })();
54
54
  Object.defineProperty(exports, "__esModule", { value: true });
55
+ exports.extractPathTags = void 0;
55
56
  exports.extractAzureId = extractAzureId;
56
- exports.extractPathTags = extractPathTags;
57
57
  exports.parseGherkinFile = parseGherkinFile;
58
58
  const gherkin_1 = require("@cucumber/gherkin");
59
59
  const messages_1 = require("@cucumber/messages");
60
60
  const fs = __importStar(require("fs"));
61
- const path = __importStar(require("path"));
61
+ const shared_1 = require("./shared");
62
+ Object.defineProperty(exports, "extractPathTags", { enumerable: true, get: function () { return shared_1.extractPathTags; } });
62
63
  // ─── Step type → keyword mapping ─────────────────────────────────────────────
63
64
  const STEP_TYPE_KEYWORD = {
64
65
  Context: 'Given',
@@ -83,26 +84,6 @@ function extractAzureId(tags, tagPrefix) {
83
84
  }
84
85
  return undefined;
85
86
  }
86
- /**
87
- * Extract auto-tags from directory segments that start with '@'.
88
- *
89
- * Given /project/specs/@smoke/@regression/login.feature
90
- * returns ['smoke', 'regression']
91
- */
92
- function extractPathTags(filePath) {
93
- const segments = filePath.split(path.sep);
94
- const tags = [];
95
- // Walk directory segments (not the filename itself)
96
- for (let i = 0; i < segments.length - 1; i++) {
97
- const seg = segments[i];
98
- // A segment may contain multiple @tags separated by spaces or be just one tag
99
- const matches = seg.match(/@[^\s@/\\]+/g);
100
- if (matches) {
101
- tags.push(...matches.map(stripAt));
102
- }
103
- }
104
- return tags;
105
- }
106
87
  /**
107
88
  * Given a GherkinDocument and a pickle, find the source line of the
108
89
  * scenario that produced this pickle (using astNodeIds).
@@ -129,8 +110,45 @@ function pickleStepToParsedStep(step) {
129
110
  text: step.text.trim(),
130
111
  };
131
112
  }
113
+ /**
114
+ * Build a ParsedTest from a ScenarioOutline AST node.
115
+ * Produces one TC with template step text (keeping <param> angle brackets)
116
+ * and an outlineParameters table for Azure's parametrized TC format.
117
+ */
118
+ function scenarioOutlineToParsedTest(scenario, filePath, pathTags, tagPrefix, linkConfigs) {
119
+ const scenarioTags = scenario.tags.map((t) => stripAt(t.name));
120
+ const allTags = [...new Set([...pathTags, ...scenarioTags])];
121
+ // Template steps keep <param> angle-bracket syntax as-is
122
+ const steps = scenario.steps.map((s) => ({
123
+ keyword: (s.keyword ?? '').trim(),
124
+ text: s.text.trim(),
125
+ }));
126
+ // Merge all Examples tables (may be multiple blocks)
127
+ let headers = [];
128
+ const rows = [];
129
+ for (const examples of scenario.examples ?? []) {
130
+ if (!examples.tableHeader)
131
+ continue;
132
+ const exHeaders = examples.tableHeader.cells.map((c) => c.value);
133
+ if (!headers.length)
134
+ headers = exHeaders;
135
+ for (const bodyRow of examples.tableBody) {
136
+ rows.push(bodyRow.cells.map((c) => c.value));
137
+ }
138
+ }
139
+ return {
140
+ filePath,
141
+ title: scenario.name.trim(),
142
+ steps,
143
+ tags: allTags,
144
+ azureId: extractAzureId(allTags, tagPrefix),
145
+ line: scenario.location?.line ?? 1,
146
+ outlineParameters: headers.length ? { headers, rows } : undefined,
147
+ linkRefs: (0, shared_1.extractLinkRefs)(allTags, linkConfigs),
148
+ };
149
+ }
132
150
  // ─── Public parser ────────────────────────────────────────────────────────────
133
- function parseGherkinFile(filePath, tagPrefix) {
151
+ function parseGherkinFile(filePath, tagPrefix, linkConfigs) {
134
152
  const source = fs.readFileSync(filePath, 'utf8');
135
153
  const newId = messages_1.IdGenerator.uuid();
136
154
  let messages;
@@ -159,19 +177,61 @@ function parseGherkinFile(filePath, tagPrefix) {
159
177
  .filter((m) => m.pickle)
160
178
  .map((m) => m.pickle);
161
179
  // Tags from directory path segments (e.g. specs/@smoke/ → 'smoke')
162
- const pathTags = extractPathTags(filePath);
163
- return pickles.map((pickle) => {
164
- // Pickle tags already include Feature + Scenario + Examples tags (inherited)
180
+ const pathTags = (0, shared_1.extractPathTags)(filePath);
181
+ const results = [];
182
+ // Collect all Scenario nodes from the AST (including inside Rules)
183
+ const allScenarios = [];
184
+ for (const child of doc.feature?.children ?? []) {
185
+ if (child.scenario)
186
+ allScenarios.push(child.scenario);
187
+ if (child.rule) {
188
+ for (const rc of child.rule.children ?? []) {
189
+ if (rc.scenario)
190
+ allScenarios.push(rc.scenario);
191
+ }
192
+ }
193
+ }
194
+ // Identify outline scenarios (have at least one non-empty examples table)
195
+ const outlineIds = new Set(allScenarios
196
+ .filter((s) => s.examples?.some((ex) => (ex.tableBody?.length ?? 0) > 0))
197
+ .map((s) => s.id));
198
+ // For Scenario Outlines: one ParsedTest per outline (not per example row)
199
+ for (const scenario of allScenarios) {
200
+ if (outlineIds.has(scenario.id)) {
201
+ results.push(scenarioOutlineToParsedTest(scenario, filePath, pathTags, tagPrefix, linkConfigs));
202
+ }
203
+ }
204
+ // Build set of all AST node IDs that belong to outlines (scenario + example rows)
205
+ const outlineAstNodeIds = new Set();
206
+ for (const scenario of allScenarios) {
207
+ if (!outlineIds.has(scenario.id))
208
+ continue;
209
+ outlineAstNodeIds.add(scenario.id);
210
+ for (const ex of scenario.examples ?? []) {
211
+ for (const row of ex.tableBody ?? []) {
212
+ outlineAstNodeIds.add(row.id);
213
+ }
214
+ }
215
+ }
216
+ // For regular Scenarios: use pickles (background steps merged, correct keywords)
217
+ for (const pickle of pickles) {
218
+ // Skip pickles that originate from an outline
219
+ if (pickle.astNodeIds.some((id) => outlineAstNodeIds.has(id)))
220
+ continue;
165
221
  const pickleTags = pickle.tags.map((t) => stripAt(t.name));
166
222
  const allTags = [...new Set([...pathTags, ...pickleTags])];
167
- return {
223
+ results.push({
168
224
  filePath,
169
225
  title: pickle.name.trim(),
170
226
  steps: pickle.steps.map(pickleStepToParsedStep),
171
227
  tags: allTags,
172
228
  azureId: extractAzureId(allTags, tagPrefix),
173
229
  line: findScenarioLine(doc, pickle),
174
- };
175
- });
230
+ linkRefs: (0, shared_1.extractLinkRefs)(allTags, linkConfigs),
231
+ });
232
+ }
233
+ // Sort by line number to preserve file order
234
+ results.sort((a, b) => a.line - b.line);
235
+ return results;
176
236
  }
177
237
  //# sourceMappingURL=gherkin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gherkin.js","sourceRoot":"","sources":["../../src/parsers/gherkin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gherkin.js","sourceRoot":"","sources":["../../src/parsers/gherkin.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,9 @@
9
9
  *
10
10
  * ### 1. Scenario title ← H3 heading = one test case
11
11
  *
12
+ * <!-- tags: @smoke, @regression --> ← optional tags (Gap 5)
13
+ * <!-- tc: 12345 --> ← written back after first push
14
+ *
12
15
  * Assumption: ... ← optional prose, used as description
13
16
  *
14
17
  * Steps:
@@ -19,13 +22,11 @@
19
22
  * - Result A
20
23
  * - Result B
21
24
  *
22
- * <!-- azure-tc: 12345 --> ← written back after first push
23
- *
24
25
  * --- ← separator between scenarios
25
26
  *
26
27
  * ID tag convention: <!-- {tagPrefix}: 12345 --> anywhere within the scenario block
27
- * e.g. with default tagPrefix "tc": <!-- tc: 12345 -->
28
- * The prefix is set via sync.tagPrefix in the config file.
28
+ * Tags convention: <!-- tags: @tag1, @tag2 --> anywhere within the scenario block
29
+ * Path-based auto-tagging: same as Gherkin (directory segments starting with @)
29
30
  */
30
- import { ParsedTest } from '../types';
31
- export declare function parseMarkdownFile(filePath: string, tagPrefix: string): ParsedTest[];
31
+ import { LinkConfig, ParsedTest } from '../types';
32
+ export declare function parseMarkdownFile(filePath: string, tagPrefix: string, linkConfigs?: LinkConfig[]): ParsedTest[];
@@ -10,6 +10,9 @@
10
10
  *
11
11
  * ### 1. Scenario title ← H3 heading = one test case
12
12
  *
13
+ * <!-- tags: @smoke, @regression --> ← optional tags (Gap 5)
14
+ * <!-- tc: 12345 --> ← written back after first push
15
+ *
13
16
  * Assumption: ... ← optional prose, used as description
14
17
  *
15
18
  * Steps:
@@ -20,13 +23,11 @@
20
23
  * - Result A
21
24
  * - Result B
22
25
  *
23
- * <!-- azure-tc: 12345 --> ← written back after first push
24
- *
25
26
  * --- ← separator between scenarios
26
27
  *
27
28
  * ID tag convention: <!-- {tagPrefix}: 12345 --> anywhere within the scenario block
28
- * e.g. with default tagPrefix "tc": <!-- tc: 12345 -->
29
- * The prefix is set via sync.tagPrefix in the config file.
29
+ * Tags convention: <!-- tags: @tag1, @tag2 --> anywhere within the scenario block
30
+ * Path-based auto-tagging: same as Gherkin (directory segments starting with @)
30
31
  */
31
32
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
32
33
  if (k2 === undefined) k2 = k;
@@ -64,6 +65,7 @@ var __importStar = (this && this.__importStar) || (function () {
64
65
  Object.defineProperty(exports, "__esModule", { value: true });
65
66
  exports.parseMarkdownFile = parseMarkdownFile;
66
67
  const fs = __importStar(require("fs"));
68
+ const shared_1 = require("./shared");
67
69
  // ─── Regexes ─────────────────────────────────────────────────────────────────
68
70
  const H3_RE = /^###\s+(?:\d+\.\s+)?(.+)$/; // ### N. Title or ### Title
69
71
  const STEPS_HEADING_RE = /^steps\s*:/i;
@@ -72,6 +74,7 @@ const NUMBERED_STEP_RE = /^\s*\d+\.\s+(.+)$/;
72
74
  const BULLET_STEP_RE = /^\s*[-*]\s+(.+)$/;
73
75
  const SEPARATOR_RE = /^---+\s*$/;
74
76
  const mdTcCommentRe = (prefix) => new RegExp(`<!--\\s*${prefix}\\s*:\\s*(\\d+)\\s*-->`, 'i');
77
+ const TAGS_COMMENT_RE = /<!--\s*tags\s*:\s*([^>]+)-->/i;
75
78
  function splitIntoScenarios(lines) {
76
79
  const blocks = [];
77
80
  let current = null;
@@ -97,15 +100,28 @@ function splitIntoScenarios(lines) {
97
100
  blocks.push(current);
98
101
  return blocks;
99
102
  }
100
- function parseScenarioBlock(block, filePath, tagPrefix) {
103
+ function parseScenarioBlock(block, filePath, tagPrefix, pathTags, linkConfigs) {
101
104
  const lines = block.lines;
105
+ const blockText = lines.join('\n');
102
106
  const tcRe = mdTcCommentRe(tagPrefix);
103
107
  // Find ID comment
104
108
  let azureId;
105
- const tcComment = lines.join('\n').match(tcRe);
109
+ const tcComment = blockText.match(tcRe);
106
110
  if (tcComment) {
107
111
  azureId = parseInt(tcComment[1], 10);
108
112
  }
113
+ // Find <!-- tags: @smoke, @regression --> comment (Gap 5)
114
+ const blockTags = [...pathTags];
115
+ const tagsComment = blockText.match(TAGS_COMMENT_RE);
116
+ if (tagsComment) {
117
+ const rawTags = tagsComment[1]
118
+ .split(',')
119
+ .map((t) => t.trim())
120
+ .filter(Boolean)
121
+ .map((t) => (t.startsWith('@') ? t.slice(1) : t));
122
+ blockTags.push(...rawTags);
123
+ }
124
+ const allTags = [...new Set(blockTags)];
109
125
  // Extract sections
110
126
  let section = 'description';
111
127
  const descLines = [];
@@ -114,6 +130,8 @@ function parseScenarioBlock(block, filePath, tagPrefix) {
114
130
  for (const line of lines) {
115
131
  if (tcRe.test(line))
116
132
  continue; // skip ID comment lines
133
+ if (TAGS_COMMENT_RE.test(line))
134
+ continue; // skip tags comment lines
117
135
  if (STEPS_HEADING_RE.test(line.trim())) {
118
136
  section = 'steps';
119
137
  continue;
@@ -171,15 +189,18 @@ function parseScenarioBlock(block, filePath, tagPrefix) {
171
189
  title: block.title,
172
190
  description,
173
191
  steps: parsedSteps,
174
- tags: [], // markdown specs don't have Gherkin tags
192
+ tags: allTags,
175
193
  azureId,
176
194
  line: block.startLine,
195
+ linkRefs: (0, shared_1.extractLinkRefs)(allTags, linkConfigs),
177
196
  };
178
197
  }
179
- function parseMarkdownFile(filePath, tagPrefix) {
198
+ function parseMarkdownFile(filePath, tagPrefix, linkConfigs) {
180
199
  const source = fs.readFileSync(filePath, 'utf8');
181
200
  const lines = source.split('\n');
182
201
  const blocks = splitIntoScenarios(lines);
183
- return blocks.map((b) => parseScenarioBlock(b, filePath, tagPrefix));
202
+ // Path-based auto-tags (same as Gherkin)
203
+ const pathTags = (0, shared_1.extractPathTags)(filePath);
204
+ return blocks.map((b) => parseScenarioBlock(b, filePath, tagPrefix, pathTags, linkConfigs));
184
205
  }
185
206
  //# sourceMappingURL=markdown.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/parsers/markdown.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/parsers/markdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Shared parser utilities used by both gherkin.ts and markdown.ts.
3
+ */
4
+ /**
5
+ * Extract auto-tags from directory segments that start with '@'.
6
+ *
7
+ * Given /project/specs/@smoke/@regression/login.feature
8
+ * returns ['smoke', 'regression']
9
+ */
10
+ export declare function extractPathTags(filePath: string): string[];
11
+ /**
12
+ * Parse link references from a list of tags given a set of configured link prefixes.
13
+ * e.g. tags=['story:123','smoke'], prefixes=['story'] → [{ prefix:'story', id:123 }]
14
+ */
15
+ export declare function extractLinkRefs(tags: string[], linkConfigs: Array<{
16
+ prefix: string;
17
+ }> | undefined): Array<{
18
+ prefix: string;
19
+ id: number;
20
+ }>;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ /**
3
+ * Shared parser utilities used by both gherkin.ts and markdown.ts.
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.extractPathTags = extractPathTags;
40
+ exports.extractLinkRefs = extractLinkRefs;
41
+ const path = __importStar(require("path"));
42
+ /**
43
+ * Extract auto-tags from directory segments that start with '@'.
44
+ *
45
+ * Given /project/specs/@smoke/@regression/login.feature
46
+ * returns ['smoke', 'regression']
47
+ */
48
+ function extractPathTags(filePath) {
49
+ const segments = filePath.split(path.sep);
50
+ const tags = [];
51
+ // Walk directory segments (not the filename itself)
52
+ for (let i = 0; i < segments.length - 1; i++) {
53
+ const seg = segments[i];
54
+ const matches = seg.match(/@[^\s@/\\]+/g);
55
+ if (matches) {
56
+ tags.push(...matches.map((t) => (t.startsWith('@') ? t.slice(1) : t)));
57
+ }
58
+ }
59
+ return tags;
60
+ }
61
+ /**
62
+ * Parse link references from a list of tags given a set of configured link prefixes.
63
+ * e.g. tags=['story:123','smoke'], prefixes=['story'] → [{ prefix:'story', id:123 }]
64
+ */
65
+ function extractLinkRefs(tags, linkConfigs) {
66
+ if (!linkConfigs?.length)
67
+ return [];
68
+ const refs = [];
69
+ for (const cfg of linkConfigs) {
70
+ const pfx = cfg.prefix + ':';
71
+ for (const tag of tags) {
72
+ if (tag.startsWith(pfx)) {
73
+ const n = parseInt(tag.slice(pfx.length), 10);
74
+ if (!isNaN(n))
75
+ refs.push({ prefix: cfg.prefix, id: n });
76
+ }
77
+ }
78
+ }
79
+ return refs;
80
+ }
81
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/parsers/shared.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUH,0CAYC;AAMD,0CAgBC;AA1CD,2CAA6B;AAE7B;;;;;GAKG;AACH,SAAgB,eAAe,CAAC,QAAgB;IAC9C,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,oDAAoD;IACpD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAC1C,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,SAAgB,eAAe,CAC7B,IAAc,EACd,WAAkD;IAElD,IAAI,CAAC,WAAW,EAAE,MAAM;QAAE,OAAO,EAAE,CAAC;IACpC,MAAM,IAAI,GAA0C,EAAE,CAAC;IACvD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC;QAC7B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC9C,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;oBAAE,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Local state cache (.ado-sync-state.json).
3
+ *
4
+ * Stores the last-synced state of each Azure Test Case, enabling:
5
+ * - Conflict detection: remote was changed since we last pushed
6
+ * - Faster status checks: skip Azure API call when nothing changed
7
+ *
8
+ * Commit this file to version control so all team members and CI
9
+ * share the same last-synced state.
10
+ */
11
+ import { AzureStep, ParsedStep } from '../types';
12
+ export interface CacheEntry {
13
+ title: string;
14
+ stepsHash: string;
15
+ descriptionHash: string;
16
+ /** ISO changedDate from Azure at time of last sync */
17
+ changedDate: string;
18
+ filePath: string;
19
+ }
20
+ export type SyncCache = Record<number, CacheEntry>;
21
+ export declare function loadCache(configDir: string): SyncCache;
22
+ export declare function saveCache(configDir: string, cache: SyncCache): void;
23
+ export declare function hashSteps(steps: ParsedStep[] | AzureStep[]): string;
24
+ export declare function hashString(s: string | undefined): string;