@meza/adr-tools 1.0.8 → 1.0.11
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/.gitattributes +40 -0
- package/.github/renovate.json +5 -0
- package/.github/workflows/ci-pr.yml +44 -0
- package/.github/workflows/ci.yml +21 -22
- package/.github/workflows/sync-deps-to-main.yml +25 -0
- package/.github/workflows/sync-to-deps.yml +26 -0
- package/.releaserc.json +2 -7
- package/CHANGELOG.md +84 -0
- package/LICENSE +674 -0
- package/README.md +64 -5
- package/biome.json +148 -0
- package/dist/index.js +105 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/adr.js +177 -0
- package/dist/lib/adr.js.map +1 -0
- package/dist/lib/config.js +33 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/links.js +25 -0
- package/dist/lib/links.js.map +1 -0
- package/dist/lib/links.test.js +65 -0
- package/dist/lib/links.test.js.map +1 -0
- package/dist/lib/manipulator.js +84 -0
- package/dist/lib/manipulator.js.map +1 -0
- package/dist/lib/manipulator.test.js +76 -0
- package/dist/lib/manipulator.test.js.map +1 -0
- package/dist/lib/numbering.js +25 -0
- package/dist/lib/numbering.js.map +1 -0
- package/dist/lib/numbering.test.js +32 -0
- package/dist/lib/numbering.test.js.map +1 -0
- package/dist/lib/prompt.js +14 -0
- package/dist/lib/prompt.js.map +1 -0
- package/dist/lib/prompt.test.js +33 -0
- package/dist/lib/prompt.test.js.map +1 -0
- package/dist/lib/template.js +21 -0
- package/dist/lib/template.js.map +1 -0
- package/{doc/adr/0001-record-architecture-decisions.md → dist/templates/init.md} +2 -2
- package/dist/templates/template.md +19 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/lib/adr.d.ts +18 -0
- package/dist/types/lib/adr.d.ts.map +1 -0
- package/dist/types/lib/config.d.ts +3 -0
- package/dist/types/lib/config.d.ts.map +1 -0
- package/dist/types/lib/links.d.ts +10 -0
- package/dist/types/lib/links.d.ts.map +1 -0
- package/dist/types/lib/links.test.d.ts +2 -0
- package/dist/types/lib/links.test.d.ts.map +1 -0
- package/dist/types/lib/manipulator.d.ts +11 -0
- package/dist/types/lib/manipulator.d.ts.map +1 -0
- package/dist/types/lib/manipulator.test.d.ts +2 -0
- package/dist/types/lib/manipulator.test.d.ts.map +1 -0
- package/dist/types/lib/numbering.d.ts +2 -0
- package/dist/types/lib/numbering.d.ts.map +1 -0
- package/dist/types/lib/numbering.test.d.ts +2 -0
- package/dist/types/lib/numbering.test.d.ts.map +1 -0
- package/dist/types/lib/prompt.d.ts +2 -0
- package/dist/types/lib/prompt.d.ts.map +1 -0
- package/dist/types/lib/prompt.test.d.ts +2 -0
- package/dist/types/lib/prompt.test.d.ts.map +1 -0
- package/dist/types/lib/template.d.ts +2 -0
- package/dist/types/lib/template.d.ts.map +1 -0
- package/dist/types/version.d.ts +2 -0
- package/dist/types/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/doc/adr/.adr-sequence.lock +1 -0
- package/doc/adr/decisions.md +3 -0
- package/package.json +78 -48
- package/src/index.ts +52 -27
- package/src/lib/adr.ts +67 -72
- package/src/lib/config.ts +3 -3
- package/src/lib/links.test.ts +8 -24
- package/src/lib/links.ts +2 -2
- package/src/lib/manipulator.test.ts +44 -47
- package/src/lib/manipulator.ts +22 -10
- package/src/lib/numbering.test.ts +5 -9
- package/src/lib/numbering.ts +4 -5
- package/src/lib/prompt.test.ts +42 -0
- package/src/lib/prompt.ts +14 -0
- package/src/lib/template.ts +7 -3
- package/src/version.ts +1 -1
- package/tests/.adr-dir +1 -0
- package/tests/__snapshots__/generate-graph.e2e.test.ts.snap +23 -23
- package/tests/__snapshots__/init-adr-repository.e2e.test.ts.snap +1 -1
- package/tests/__snapshots__/linking-records.e2e.test.ts.snap +1 -1
- package/tests/__snapshots__/new-adr.e2e.test.ts.snap +1 -1
- package/tests/__snapshots__/superseding-records.e2e.test.ts.snap +1 -1
- package/tests/__snapshots__/toc-prefixing.e2e.test.ts.snap +1 -1
- package/tests/__snapshots__/use-template-override.e2e.test.ts.snap +1 -1
- package/tests/edit-on-create.e2e.test.ts +17 -12
- package/tests/funny-characters.e2e.test.ts +28 -21
- package/tests/generate-graph.e2e.test.ts +21 -13
- package/tests/init-adr-repository.e2e.test.ts +12 -8
- package/tests/linking-records.e2e.test.ts +21 -14
- package/tests/list-adrs.e2e.test.ts +23 -18
- package/tests/new-adr.e2e.test.ts +15 -12
- package/tests/superseding-records.e2e.test.ts +16 -11
- package/tests/toc-prefixing.e2e.test.ts +15 -11
- package/tests/use-template-override.e2e.test.ts +18 -10
- package/tests/work-form-other-directories.e2e.test.ts +14 -12
- package/tsconfig.json +9 -8
- package/vitest.config.e2e.ts +13 -0
- package/vitest.config.ts +8 -1
- package/.eslintignore +0 -2
- package/.eslintrc.json +0 -23
- package/.github/dependabot.yml +0 -14
- package/.github/workflows/auto-merge.yml +0 -14
- package/doc/adr/0002-using-heavy-e2e-tests.md +0 -20
- /package/src/{environment.d.ts → types/environment.d.ts} +0 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
+
import { getDir } from './config.js';
|
|
4
|
+
import { getLinkDetails } from './links.js';
|
|
5
|
+
vi.mock('./config.js');
|
|
6
|
+
vi.mock('fs/promises');
|
|
7
|
+
describe('The link lib', () => {
|
|
8
|
+
afterEach(() => {
|
|
9
|
+
vi.resetAllMocks();
|
|
10
|
+
});
|
|
11
|
+
it('does not care if there are no matches', async () => {
|
|
12
|
+
vi.mocked(getDir).mockResolvedValueOnce('/');
|
|
13
|
+
vi.mocked(fs.readdir).mockResolvedValueOnce([]);
|
|
14
|
+
const linkString = '1:overrides:overriden by';
|
|
15
|
+
const response = await getLinkDetails(linkString);
|
|
16
|
+
expect(response).toEqual({
|
|
17
|
+
pattern: '1',
|
|
18
|
+
original: '1:overrides:overriden by',
|
|
19
|
+
link: 'overrides',
|
|
20
|
+
reverseLink: 'overriden by',
|
|
21
|
+
matches: []
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
it('does handles multiple matches', async () => {
|
|
25
|
+
vi.mocked(getDir).mockResolvedValueOnce('/');
|
|
26
|
+
vi.mocked(fs.readdir).mockResolvedValueOnce(['1-one', '1-two', '1-three']);
|
|
27
|
+
const linkString = '1:overrides:overriden by';
|
|
28
|
+
const response = await getLinkDetails(linkString);
|
|
29
|
+
expect(response).toEqual({
|
|
30
|
+
pattern: '1',
|
|
31
|
+
original: '1:overrides:overriden by',
|
|
32
|
+
link: 'overrides',
|
|
33
|
+
reverseLink: 'overriden by',
|
|
34
|
+
matches: ['1-one', '1-two', '1-three']
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
it('returns only files that match the pattern', async () => {
|
|
38
|
+
vi.mocked(getDir).mockResolvedValueOnce('/');
|
|
39
|
+
vi.mocked(fs.readdir).mockResolvedValueOnce(['on1e', '1-two', 'three']);
|
|
40
|
+
const linkString = '1:overrides:overriden by';
|
|
41
|
+
const response = await getLinkDetails(linkString);
|
|
42
|
+
expect(response).toEqual({
|
|
43
|
+
pattern: '1',
|
|
44
|
+
original: '1:overrides:overriden by',
|
|
45
|
+
link: 'overrides',
|
|
46
|
+
reverseLink: 'overriden by',
|
|
47
|
+
matches: ['on1e', '1-two']
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
it('handles superseding', async () => {
|
|
51
|
+
vi.mocked(getDir).mockResolvedValueOnce('/');
|
|
52
|
+
vi.mocked(fs.readdir).mockResolvedValueOnce([]);
|
|
53
|
+
const linkString = '1';
|
|
54
|
+
const supersede = true;
|
|
55
|
+
const response = await getLinkDetails(linkString, supersede);
|
|
56
|
+
expect(response).toEqual({
|
|
57
|
+
pattern: '1',
|
|
58
|
+
original: '1',
|
|
59
|
+
link: 'Supersedes',
|
|
60
|
+
reverseLink: 'Superseded by',
|
|
61
|
+
matches: []
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
//# sourceMappingURL=links.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"links.test.js","sourceRoot":"src/","sources":["lib/links.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { marked } from 'marked';
|
|
2
|
+
const convertToMd = (tokens) => {
|
|
3
|
+
return tokens.map((token) => token.raw).join('');
|
|
4
|
+
};
|
|
5
|
+
export const getLinksFrom = (markdown) => {
|
|
6
|
+
const tokens = marked.lexer(markdown);
|
|
7
|
+
const linkRegex = new RegExp(/^(.*)\s\[(.*)\]\((.*)\)$/);
|
|
8
|
+
const links = tokens.filter((token) => token.type === 'paragraph' && linkRegex.test(token.text));
|
|
9
|
+
return links.map((link) => {
|
|
10
|
+
const linkToken = link;
|
|
11
|
+
const linkMatches = linkToken.text.match(linkRegex);
|
|
12
|
+
if (!linkMatches || linkMatches.length < 3) {
|
|
13
|
+
throw new Error(`Could not parse link from "${linkToken.text}"`);
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
targetNumber: linkMatches[2].substring(0, linkMatches[2].indexOf('.')),
|
|
17
|
+
label: linkMatches[1],
|
|
18
|
+
href: linkMatches[3],
|
|
19
|
+
text: linkMatches[2],
|
|
20
|
+
raw: linkMatches[0]
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
export const getTitleFrom = (adr) => {
|
|
25
|
+
const tokens = marked.lexer(adr);
|
|
26
|
+
const mainHead = tokens.find((token) => token.type === 'heading' && token.depth === 1);
|
|
27
|
+
if (!mainHead) {
|
|
28
|
+
throw new Error('No main heading found');
|
|
29
|
+
}
|
|
30
|
+
return mainHead.text.trim();
|
|
31
|
+
};
|
|
32
|
+
export const supersede = (markdown, link) => {
|
|
33
|
+
const tokens = marked.lexer(markdown);
|
|
34
|
+
const statusIndex = tokens.findIndex((token) => token.type === 'heading' && token.text.toLowerCase() === 'status');
|
|
35
|
+
if (statusIndex < 0) {
|
|
36
|
+
throw new Error('Could not find status section');
|
|
37
|
+
}
|
|
38
|
+
const statusDepth = tokens[statusIndex].depth;
|
|
39
|
+
const followingHeadingIndex = tokens.findIndex((token, index) => token.type === 'heading' && token.depth === statusDepth && index > statusIndex);
|
|
40
|
+
const followingParagraphIndex = tokens.findIndex((token, index) => token.type === 'paragraph' && index > statusIndex && index < followingHeadingIndex);
|
|
41
|
+
if (followingParagraphIndex > followingHeadingIndex || followingParagraphIndex === -1) {
|
|
42
|
+
throw new Error('There is no status paragraph. Please format your adr properly');
|
|
43
|
+
}
|
|
44
|
+
tokens[followingParagraphIndex] = {
|
|
45
|
+
type: 'paragraph',
|
|
46
|
+
text: link,
|
|
47
|
+
raw: link,
|
|
48
|
+
tokens: [
|
|
49
|
+
{
|
|
50
|
+
type: 'text',
|
|
51
|
+
raw: link,
|
|
52
|
+
text: link
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
};
|
|
56
|
+
return convertToMd(tokens);
|
|
57
|
+
};
|
|
58
|
+
export const injectLink = (markdown, link) => {
|
|
59
|
+
const tokens = marked.lexer(markdown);
|
|
60
|
+
const statusIndex = tokens.findIndex((token) => token.type === 'heading' && token.text.toLowerCase() === 'status');
|
|
61
|
+
if (statusIndex < 0) {
|
|
62
|
+
throw new Error('Could not find status section');
|
|
63
|
+
}
|
|
64
|
+
const statusDepth = tokens[statusIndex].depth;
|
|
65
|
+
let followingHeadingIndex = tokens.findIndex((token, index) => token.type === 'heading' && token.depth === statusDepth && index > statusIndex);
|
|
66
|
+
if (followingHeadingIndex < 0) {
|
|
67
|
+
followingHeadingIndex = tokens.length;
|
|
68
|
+
}
|
|
69
|
+
tokens.splice(followingHeadingIndex, 0, {
|
|
70
|
+
type: 'paragraph',
|
|
71
|
+
text: link,
|
|
72
|
+
raw: link,
|
|
73
|
+
tokens: [
|
|
74
|
+
{
|
|
75
|
+
type: 'text',
|
|
76
|
+
raw: link,
|
|
77
|
+
text: link
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
});
|
|
81
|
+
tokens.splice(followingHeadingIndex + 1, 0, { type: 'space', raw: '\n\n' });
|
|
82
|
+
return convertToMd(tokens);
|
|
83
|
+
};
|
|
84
|
+
//# sourceMappingURL=manipulator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manipulator.js","sourceRoot":"src/","sources":["lib/manipulator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { getLinksFrom, getTitleFrom, injectLink } from './manipulator.js';
|
|
3
|
+
describe('The ADR manipulator', () => {
|
|
4
|
+
const original = '# NUMBER. TITLE\n' +
|
|
5
|
+
'\n' +
|
|
6
|
+
'Date: DATE\n' +
|
|
7
|
+
'\n' +
|
|
8
|
+
'## Status\n' +
|
|
9
|
+
'\n' +
|
|
10
|
+
'STATUS\n' +
|
|
11
|
+
'\n' +
|
|
12
|
+
'## Context\n' +
|
|
13
|
+
'\n' +
|
|
14
|
+
'The issue motivating this decision, and any context that influences or constrains the decision.\n' +
|
|
15
|
+
'\n' +
|
|
16
|
+
'## Decision\n' +
|
|
17
|
+
'\n' +
|
|
18
|
+
"The change that we're proposing or have agreed to implement.\n" +
|
|
19
|
+
'\n' +
|
|
20
|
+
'## Consequences\n' +
|
|
21
|
+
'\n' +
|
|
22
|
+
'What becomes easier or more difficult to do and any risks introduced by the change that will need to be mitigated.\n';
|
|
23
|
+
const modified = '# NUMBER. TITLE\n' +
|
|
24
|
+
'\n' +
|
|
25
|
+
'Date: DATE\n' +
|
|
26
|
+
'\n' +
|
|
27
|
+
'## Status\n' +
|
|
28
|
+
'\n' +
|
|
29
|
+
'STATUS\n' +
|
|
30
|
+
'\n' +
|
|
31
|
+
'INJECTED STUFF\n' +
|
|
32
|
+
'\n' +
|
|
33
|
+
'## Context\n' +
|
|
34
|
+
'\n' +
|
|
35
|
+
'The issue motivating this decision, and any context that influences or constrains the decision.\n' +
|
|
36
|
+
'\n' +
|
|
37
|
+
'## Decision\n' +
|
|
38
|
+
'\n' +
|
|
39
|
+
"The change that we're proposing or have agreed to implement.\n" +
|
|
40
|
+
'\n' +
|
|
41
|
+
'## Consequences\n' +
|
|
42
|
+
'\n' +
|
|
43
|
+
'What becomes easier or more difficult to do and any risks introduced by the change that will need to be mitigated.\n';
|
|
44
|
+
it('can inject links to the status section', () => {
|
|
45
|
+
const test = injectLink(original, 'INJECTED STUFF');
|
|
46
|
+
expect(test).toEqual(modified);
|
|
47
|
+
});
|
|
48
|
+
it('throws an error when status cannot be found', () => {
|
|
49
|
+
const noStatus = '# NUMBER. TITLE\n';
|
|
50
|
+
const test = () => injectLink(noStatus, 'INJECTED STUFF');
|
|
51
|
+
expect(test).toThrowError('Could not find status section');
|
|
52
|
+
});
|
|
53
|
+
it('adds to the status section even when there are no following headers', () => {
|
|
54
|
+
const noFollowingHeaders = '## STATUS\nACCEPTED\n\n';
|
|
55
|
+
const expected = '## STATUS\nACCEPTED\n\nINJECTED STUFF\n\n';
|
|
56
|
+
const test = injectLink(noFollowingHeaders, 'INJECTED STUFF');
|
|
57
|
+
expect(test).toEqual(expected);
|
|
58
|
+
});
|
|
59
|
+
it('can return the title and number', () => {
|
|
60
|
+
const original = '# 2. This is the title\n';
|
|
61
|
+
const test = getTitleFrom(original);
|
|
62
|
+
expect(test).toEqual('2. This is the title');
|
|
63
|
+
});
|
|
64
|
+
it('can extract links from the status section', () => {
|
|
65
|
+
const original = '## Status\n' + '\n' + 'Superseded by [3. title here](and-a-link-here.md)\n';
|
|
66
|
+
const extractedLink = getLinksFrom(original);
|
|
67
|
+
expect(extractedLink[0]).toEqual({
|
|
68
|
+
label: 'Superseded by',
|
|
69
|
+
targetNumber: '3',
|
|
70
|
+
text: '3. title here',
|
|
71
|
+
href: 'and-a-link-here.md',
|
|
72
|
+
raw: 'Superseded by [3. title here](and-a-link-here.md)'
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
//# sourceMappingURL=manipulator.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manipulator.test.js","sourceRoot":"src/","sources":["lib/manipulator.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE1E,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,MAAM,QAAQ,GACZ,mBAAmB;QACnB,IAAI;QACJ,cAAc;QACd,IAAI;QACJ,aAAa;QACb,IAAI;QACJ,UAAU;QACV,IAAI;QACJ,cAAc;QACd,IAAI;QACJ,mGAAmG;QACnG,IAAI;QACJ,eAAe;QACf,IAAI;QACJ,gEAAgE;QAChE,IAAI;QACJ,mBAAmB;QACnB,IAAI;QACJ,sHAAsH,CAAC;IAEzH,MAAM,QAAQ,GACZ,mBAAmB;QACnB,IAAI;QACJ,cAAc;QACd,IAAI;QACJ,aAAa;QACb,IAAI;QACJ,UAAU;QACV,IAAI;QACJ,kBAAkB;QAClB,IAAI;QACJ,cAAc;QACd,IAAI;QACJ,mGAAmG;QACnG,IAAI;QACJ,eAAe;QACf,IAAI;QACJ,gEAAgE;QAChE,IAAI;QACJ,mBAAmB;QACnB,IAAI;QACJ,sHAAsH,CAAC;IAEzH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QACpD,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,QAAQ,GAAG,mBAAmB,CAAC;QACrC,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QAC1D,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,+BAA+B,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC7E,MAAM,kBAAkB,GAAG,yBAAyB,CAAC;QACrD,MAAM,QAAQ,GAAG,2CAA2C,CAAC;QAC7D,MAAM,IAAI,GAAG,UAAU,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,CAAC;QAC9D,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,QAAQ,GAAG,0BAA0B,CAAC;QAC5C,MAAM,IAAI,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,QAAQ,GAAG,aAAa,GAAG,IAAI,GAAG,qDAAqD,CAAC;QAC9F,MAAM,aAAa,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QAE7C,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/B,KAAK,EAAE,eAAe;YACtB,YAAY,EAAE,GAAG;YACjB,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,oBAAoB;YAC1B,GAAG,EAAE,mDAAmD;SACzD,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import fs from 'fs/promises';
|
|
3
|
+
import { getDir } from './config.js';
|
|
4
|
+
export const newNumber = async () => {
|
|
5
|
+
try {
|
|
6
|
+
const lockfile = await fs.readFile(path.resolve(await getDir(), '.adr-sequence.lock'));
|
|
7
|
+
return parseInt(lockfile.toString().trim(), 10) + 1;
|
|
8
|
+
}
|
|
9
|
+
catch (_e) {
|
|
10
|
+
// This is for backward compatibility. If someone upgrades from an older tool without a lockfile,
|
|
11
|
+
// we create one.
|
|
12
|
+
const filePattern = /^0*(\d+)-.*$/;
|
|
13
|
+
const files = await fs.readdir(await getDir());
|
|
14
|
+
const numbers = files.map((f) => {
|
|
15
|
+
const adrFile = f.match(filePattern);
|
|
16
|
+
if (adrFile) {
|
|
17
|
+
return parseInt(adrFile[1], 10);
|
|
18
|
+
}
|
|
19
|
+
return 0;
|
|
20
|
+
});
|
|
21
|
+
const largestNumber = numbers.reduce((a, b) => Math.max(a, b), 0);
|
|
22
|
+
return largestNumber + 1;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=numbering.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"numbering.js","sourceRoot":"src/","sources":["lib/numbering.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;IAClC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,MAAM,EAAE,EAAE,oBAAoB,CAAC,CAAC,CAAC;QACvF,OAAO,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;IACtD,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,iGAAiG;QACjG,iBAAiB;QACjB,MAAM,WAAW,GAAG,cAAc,CAAC;QACnC,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YAC9B,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YACrC,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAClC,CAAC;YACD,OAAO,CAAC,CAAC;QACX,CAAC,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAClE,OAAO,aAAa,GAAG,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import { afterAll, describe, expect, it, vi } from 'vitest';
|
|
3
|
+
import { newNumber } from './numbering.js';
|
|
4
|
+
vi.mock('fs/promises');
|
|
5
|
+
vi.mock('./config.js', () => ({
|
|
6
|
+
getDir: vi.fn().mockResolvedValue('/')
|
|
7
|
+
}));
|
|
8
|
+
describe('The numbering logic', () => {
|
|
9
|
+
afterAll(() => {
|
|
10
|
+
vi.resetAllMocks();
|
|
11
|
+
});
|
|
12
|
+
it('can read from the sequence file', async () => {
|
|
13
|
+
const random = Math.floor(Math.random() * 100);
|
|
14
|
+
vi.mocked(fs.readFile).mockResolvedValueOnce(random.toString());
|
|
15
|
+
const num = await newNumber();
|
|
16
|
+
expect(num).toEqual(random + 1);
|
|
17
|
+
});
|
|
18
|
+
it('returns 1 if there are no files', async () => {
|
|
19
|
+
vi.mocked(fs.readFile).mockRejectedValueOnce('no sequence file');
|
|
20
|
+
vi.mocked(fs.readdir).mockResolvedValueOnce([]);
|
|
21
|
+
const num = await newNumber();
|
|
22
|
+
expect(num).toEqual(1);
|
|
23
|
+
});
|
|
24
|
+
it('processes existing files if there is no lockfile', async () => {
|
|
25
|
+
const fakeFiles = ['0001-first-file.md', '0002-first-file.md'];
|
|
26
|
+
vi.mocked(fs.readFile).mockRejectedValueOnce('no sequence file');
|
|
27
|
+
vi.mocked(fs.readdir).mockResolvedValueOnce(fakeFiles);
|
|
28
|
+
const num = await newNumber();
|
|
29
|
+
expect(num).toEqual(3);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
//# sourceMappingURL=numbering.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"numbering.test.js","sourceRoot":"src/","sources":["lib/numbering.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAI3C,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACvB,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5B,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC;CACvC,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,QAAQ,CAAC,GAAG,EAAE;QACZ,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC;QAC/C,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QAChE,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,CAAC;QACjE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC;QAChD,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,SAAS,GAAa,CAAC,oBAAoB,EAAE,oBAAoB,CAAC,CAAC;QACzE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,CAAC;QACjE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,OAAiC,CAAC,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;QACjF,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
export const askForClarification = async (searchString, matches) => {
|
|
4
|
+
const selection = await inquirer.prompt([
|
|
5
|
+
{
|
|
6
|
+
type: 'list',
|
|
7
|
+
name: 'target',
|
|
8
|
+
message: `Which file do you want to link to for ${chalk.blue(searchString)}?`,
|
|
9
|
+
choices: matches
|
|
10
|
+
}
|
|
11
|
+
]);
|
|
12
|
+
return selection.target;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"src/","sources":["lib/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EAAE,YAAoB,EAAE,OAAiB,EAAE,EAAE;IACnF,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;QACtC;YACE,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,yCAAyC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG;YAC7E,OAAO,EAAE,OAAO;SACjB;KACF,CAAC,CAAC;IACH,OAAO,SAAS,CAAC,MAAM,CAAC;AAC1B,CAAC,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { faker } from '@faker-js/faker';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
4
|
+
import { askForClarification } from './prompt.js';
|
|
5
|
+
vi.mock('inquirer');
|
|
6
|
+
vi.mock('chalk', () => ({
|
|
7
|
+
default: {
|
|
8
|
+
blue: (str) => {
|
|
9
|
+
return `BLUE[${str}]`;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}));
|
|
13
|
+
describe('The prompt helper', () => {
|
|
14
|
+
it('calls inquirer correctly', async () => {
|
|
15
|
+
const prompt = vi.mocked(inquirer.prompt);
|
|
16
|
+
prompt.mockResolvedValueOnce({ target: 'does not matter' });
|
|
17
|
+
const randomChoices = [faker.system.filePath(), faker.system.filePath(), faker.system.filePath()];
|
|
18
|
+
await askForClarification('this is the search string', randomChoices);
|
|
19
|
+
expect(prompt).toHaveBeenCalledOnce();
|
|
20
|
+
const calledWith = prompt.mock.calls[0][0];
|
|
21
|
+
expect(calledWith[0].type).toEqual('list');
|
|
22
|
+
expect(calledWith[0].choices).toEqual(randomChoices);
|
|
23
|
+
expect(calledWith[0].message).toMatchInlineSnapshot('"Which file do you want to link to for BLUE[this is the search string]?"');
|
|
24
|
+
});
|
|
25
|
+
it('returns the selected choice', async () => {
|
|
26
|
+
const prompt = vi.mocked(inquirer.prompt);
|
|
27
|
+
const randomResult = faker.system.filePath();
|
|
28
|
+
prompt.mockResolvedValueOnce({ target: randomResult });
|
|
29
|
+
const result = await askForClarification('this is the search string', ['does not matter']);
|
|
30
|
+
expect(result).toEqual(randomResult);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
//# sourceMappingURL=prompt.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.test.js","sourceRoot":"src/","sources":["lib/prompt.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,QAAoC,MAAM,UAAU,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AACpB,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;IACtB,OAAO,EAAE;QACP,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE;YACpB,OAAO,QAAQ,GAAG,GAAG,CAAC;QACxB,CAAC;KACF;CACF,CAAC,CAAC,CAAC;AACJ,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC1C,MAAM,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAE5D,MAAM,aAAa,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QAClG,MAAM,mBAAmB,CAAC,2BAA2B,EAAE,aAAa,CAAC,CAAC;QAEtE,MAAM,CAAC,MAAM,CAAC,CAAC,oBAAoB,EAAE,CAAC;QACtC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAe,CAAC;QACzD,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,CAAE,UAAU,CAAC,CAAC,CAAkB,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QACvE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,qBAAqB,CACjD,0EAA0E,CAC3E,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAE1C,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QAE7C,MAAM,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;QAEvD,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,2BAA2B,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;QAE3F,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import fs from 'fs/promises';
|
|
4
|
+
import { getDir } from './config.js';
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
export const template = async (templateFile) => {
|
|
8
|
+
if (templateFile) {
|
|
9
|
+
return await fs.readFile(path.resolve(templateFile), 'utf8');
|
|
10
|
+
}
|
|
11
|
+
if (process.env.ADR_TEMPLATE) {
|
|
12
|
+
return await fs.readFile(path.resolve(process.env.ADR_TEMPLATE), 'utf8');
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
return await fs.readFile(path.join(await getDir(), 'templates/template.md'), 'utf8');
|
|
16
|
+
}
|
|
17
|
+
catch (_e) {
|
|
18
|
+
return await fs.readFile(path.resolve(path.join(__dirname, '../templates/template.md')), 'utf8');
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"src/","sources":["lib/template.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,EAAE,YAAqB,EAAmB,EAAE;IACvE,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC7B,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,MAAM,EAAE,EAAE,uBAAuB,CAAC,EAAE,MAAM,CAAC,CAAC;IACvF,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,0BAA0B,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACnG,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 1. Record architecture decisions
|
|
2
2
|
|
|
3
|
-
Date:
|
|
3
|
+
Date: DATE
|
|
4
4
|
|
|
5
5
|
## Status
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ We need to record the architectural decisions made on this project.
|
|
|
12
12
|
|
|
13
13
|
## Decision
|
|
14
14
|
|
|
15
|
-
We will use Architecture Decision Records, as [described by Michael Nygard](
|
|
15
|
+
We will use Architecture Decision Records, as [described by Michael Nygard](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions).
|
|
16
16
|
|
|
17
17
|
## Consequences
|
|
18
18
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# NUMBER. TITLE
|
|
2
|
+
|
|
3
|
+
Date: DATE
|
|
4
|
+
|
|
5
|
+
## Status
|
|
6
|
+
|
|
7
|
+
STATUS
|
|
8
|
+
|
|
9
|
+
## Context
|
|
10
|
+
|
|
11
|
+
The issue motivating this decision, and any context that influences or constrains the decision.
|
|
12
|
+
|
|
13
|
+
## Decision
|
|
14
|
+
|
|
15
|
+
The change that we're proposing or have agreed to implement.
|
|
16
|
+
|
|
17
|
+
## Consequences
|
|
18
|
+
|
|
19
|
+
What becomes easier or more difficult to do and any risks introduced by the change that will need to be mitigated.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"src/","sources":["index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface NewOptions {
|
|
2
|
+
supersedes?: string[];
|
|
3
|
+
date?: string | undefined;
|
|
4
|
+
suppressPrompts?: boolean;
|
|
5
|
+
template?: string;
|
|
6
|
+
links?: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare const generateToc: (options?: {
|
|
9
|
+
prefix?: string;
|
|
10
|
+
}) => Promise<void>;
|
|
11
|
+
export declare const newAdr: (title: string, config?: NewOptions) => Promise<void>;
|
|
12
|
+
export declare const init: (directory?: string) => Promise<void>;
|
|
13
|
+
export declare const link: (source: string, link: string, target: string, reverseLink: string, options?: {
|
|
14
|
+
quiet?: boolean;
|
|
15
|
+
}) => Promise<void>;
|
|
16
|
+
export declare const listAdrs: () => Promise<string[]>;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=adr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adr.d.ts","sourceRoot":"src/","sources":["lib/adr.ts"],"names":[],"mappings":"AAaA,UAAU,UAAU;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AA6GD,eAAO,MAAM,WAAW,GAAU,UAAU;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,kBAc9D,CAAC;AAEF,eAAO,MAAM,MAAM,GAAU,OAAO,MAAM,EAAE,SAAS,UAAU,kBAuC9D,CAAC;AAEF,eAAO,MAAM,IAAI,GAAU,YAAY,MAAM,kBAQ5C,CAAC;AAEF,eAAO,MAAM,IAAI,GACf,QAAQ,MAAM,EACd,MAAM,MAAM,EACZ,QAAQ,MAAM,EACd,aAAa,MAAM,EACnB,UAAU;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,kBAqB9B,CAAC;AAEF,eAAO,MAAM,QAAQ,yBAapB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"src/","sources":["lib/config.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,UAAU,cAAsB,CAAC;AAyB9C,eAAO,MAAM,MAAM,QAAa,OAAO,CAAC,MAAM,CAI7C,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface LinkDetails {
|
|
2
|
+
pattern: string;
|
|
3
|
+
original: string;
|
|
4
|
+
link: string;
|
|
5
|
+
reverseLink: string;
|
|
6
|
+
matches: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare const findMatchingFilesFor: (pattern: string) => Promise<string[]>;
|
|
9
|
+
export declare const getLinkDetails: (linkString: string, isSupersede?: boolean) => Promise<LinkDetails>;
|
|
10
|
+
//# sourceMappingURL=links.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"links.d.ts","sourceRoot":"src/","sources":["lib/links.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,eAAO,MAAM,oBAAoB,GAAU,SAAS,MAAM,sBAGzD,CAAC;AAEF,eAAO,MAAM,cAAc,GAAU,YAAY,MAAM,EAAE,cAAa,OAAe,KAAG,OAAO,CAAC,WAAW,CAiB1G,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"links.test.d.ts","sourceRoot":"src/","sources":["lib/links.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const getLinksFrom: (markdown: string) => {
|
|
2
|
+
targetNumber: string;
|
|
3
|
+
label: string;
|
|
4
|
+
href: string;
|
|
5
|
+
text: string;
|
|
6
|
+
raw: string;
|
|
7
|
+
}[];
|
|
8
|
+
export declare const getTitleFrom: (adr: string) => string;
|
|
9
|
+
export declare const supersede: (markdown: string, link: string) => string;
|
|
10
|
+
export declare const injectLink: (markdown: string, link: string) => string;
|
|
11
|
+
//# sourceMappingURL=manipulator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manipulator.d.ts","sourceRoot":"src/","sources":["lib/manipulator.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,YAAY,GAAI,UAAU,MAAM;;;;;;GAmB5C,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,WAOvC,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,UAAU,MAAM,EAAE,MAAM,MAAM,WA+BvD,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,UAAU,MAAM,EAAE,MAAM,MAAM,WA4BxD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manipulator.test.d.ts","sourceRoot":"src/","sources":["lib/manipulator.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"numbering.d.ts","sourceRoot":"src/","sources":["lib/numbering.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,SAAS,uBAoBrB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"numbering.test.d.ts","sourceRoot":"src/","sources":["lib/numbering.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"src/","sources":["lib/prompt.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mBAAmB,GAAU,cAAc,MAAM,EAAE,SAAS,MAAM,EAAE,iBAUhF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.test.d.ts","sourceRoot":"src/","sources":["lib/prompt.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.d.ts","sourceRoot":"src/","sources":["lib/template.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,QAAQ,GAAU,eAAe,MAAM,KAAG,OAAO,CAAC,MAAM,CAapE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"src/","sources":["version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,WAAW,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"src/","sources":["version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1
|