@relayfile/adapter-linear 0.2.8 → 0.2.9
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/digest.d.ts +33 -0
- package/dist/digest.d.ts.map +1 -0
- package/dist/digest.js +62 -0
- package/dist/digest.js.map +1 -0
- package/dist/digest.test.d.ts +2 -0
- package/dist/digest.test.d.ts.map +1 -0
- package/dist/digest.test.js +53 -0
- package/dist/digest.test.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/layout.d.ts +4 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +35 -0
- package/dist/layout.js.map +1 -0
- package/dist/layout.test.d.ts +2 -0
- package/dist/layout.test.d.ts.map +1 -0
- package/dist/layout.test.js +32 -0
- package/dist/layout.test.js.map +1 -0
- package/package.json +2 -2
package/dist/digest.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface DigestWindow {
|
|
2
|
+
readonly from: string;
|
|
3
|
+
readonly to: string;
|
|
4
|
+
}
|
|
5
|
+
export interface DigestChangeEvent {
|
|
6
|
+
readonly id?: string;
|
|
7
|
+
readonly timestamp?: string;
|
|
8
|
+
readonly occurredAt?: string;
|
|
9
|
+
readonly eventType?: string;
|
|
10
|
+
readonly type?: string;
|
|
11
|
+
readonly action?: string;
|
|
12
|
+
readonly canonicalPath?: string;
|
|
13
|
+
readonly path?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface DigestContext {
|
|
16
|
+
readonly provider: string;
|
|
17
|
+
readonly window: DigestWindow;
|
|
18
|
+
changeEvents(filter?: {
|
|
19
|
+
providers?: string[];
|
|
20
|
+
paths?: string[];
|
|
21
|
+
}): Promise<readonly DigestChangeEvent[]>;
|
|
22
|
+
}
|
|
23
|
+
export interface DigestBullet {
|
|
24
|
+
readonly text: string;
|
|
25
|
+
readonly canonicalPath: string;
|
|
26
|
+
}
|
|
27
|
+
export interface DigestSection {
|
|
28
|
+
readonly provider: string;
|
|
29
|
+
readonly bullets: readonly DigestBullet[];
|
|
30
|
+
}
|
|
31
|
+
export type DigestHandler = (ctx: DigestContext) => Promise<DigestSection | null>;
|
|
32
|
+
export declare const digest: DigestHandler;
|
|
33
|
+
//# sourceMappingURL=digest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digest.d.ts","sourceRoot":"","sources":["../src/digest.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,YAAY,CAAC,MAAM,CAAC,EAAE;QACpB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;KAClB,GAAG,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;CAC3C;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;AAElF,eAAO,MAAM,MAAM,EAAE,aAepB,CAAC"}
|
package/dist/digest.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export const digest = async (ctx) => {
|
|
2
|
+
const events = await ctx.changeEvents({ providers: [ctx.provider] });
|
|
3
|
+
const bullets = events
|
|
4
|
+
.filter(hasCanonicalPath)
|
|
5
|
+
.slice()
|
|
6
|
+
.sort(compareEvents)
|
|
7
|
+
.map((event) => {
|
|
8
|
+
const canonicalPath = normalizeDigestPath(event.canonicalPath);
|
|
9
|
+
return {
|
|
10
|
+
text: `${linearIdentifier(canonicalPath)} ${pastTense(event)}`,
|
|
11
|
+
canonicalPath,
|
|
12
|
+
};
|
|
13
|
+
});
|
|
14
|
+
return bullets.length === 0 ? null : { provider: ctx.provider, bullets };
|
|
15
|
+
};
|
|
16
|
+
function hasCanonicalPath(event) {
|
|
17
|
+
return (typeof event.canonicalPath === 'string'
|
|
18
|
+
&& (event.canonicalPath === 'linear' || event.canonicalPath.startsWith('linear/') || event.canonicalPath.startsWith('/linear/')));
|
|
19
|
+
}
|
|
20
|
+
function compareEvents(left, right) {
|
|
21
|
+
// Compare parsed timestamps in ms rather than ISO strings: lexicographic
|
|
22
|
+
// string compare misorders events whose timestamps describe the same
|
|
23
|
+
// instant with different textual offsets (e.g. `Z` vs `+00:00`).
|
|
24
|
+
const leftMs = eventTimeMs(left);
|
|
25
|
+
const rightMs = eventTimeMs(right);
|
|
26
|
+
return (leftMs - rightMs
|
|
27
|
+
|| (left.id ?? '').localeCompare(right.id ?? '')
|
|
28
|
+
|| (left.canonicalPath ?? '').localeCompare(right.canonicalPath ?? ''));
|
|
29
|
+
}
|
|
30
|
+
function eventTime(event) {
|
|
31
|
+
return event.timestamp ?? event.occurredAt ?? '';
|
|
32
|
+
}
|
|
33
|
+
function eventTimeMs(event) {
|
|
34
|
+
const raw = eventTime(event);
|
|
35
|
+
if (!raw)
|
|
36
|
+
return Number.NEGATIVE_INFINITY;
|
|
37
|
+
const ms = Date.parse(raw);
|
|
38
|
+
return Number.isNaN(ms) ? Number.NEGATIVE_INFINITY : ms;
|
|
39
|
+
}
|
|
40
|
+
function normalizeDigestPath(path) {
|
|
41
|
+
return path.replace(/^\/+/u, '');
|
|
42
|
+
}
|
|
43
|
+
function linearIdentifier(path) {
|
|
44
|
+
const segment = path.split('/').filter(Boolean).at(-1) ?? path;
|
|
45
|
+
const basename = segment.replace(/\.[^.]+$/u, '');
|
|
46
|
+
const separatorIndex = basename.lastIndexOf('__');
|
|
47
|
+
return separatorIndex > 0 ? basename.slice(0, separatorIndex) : basename;
|
|
48
|
+
}
|
|
49
|
+
function pastTense(event) {
|
|
50
|
+
const action = (event.action ?? event.eventType ?? event.type ?? '').toLowerCase();
|
|
51
|
+
if (/(create|created|open|opened|add|added|write|written)/u.test(action)) {
|
|
52
|
+
return 'was created';
|
|
53
|
+
}
|
|
54
|
+
if (/(delete|deleted|remove|removed)/u.test(action)) {
|
|
55
|
+
return 'was deleted';
|
|
56
|
+
}
|
|
57
|
+
if (/(close|closed|resolve|resolved|cancel|canceled)/u.test(action)) {
|
|
58
|
+
return 'was closed';
|
|
59
|
+
}
|
|
60
|
+
return 'was updated';
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=digest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digest.js","sourceRoot":"","sources":["../src/digest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digest.test.d.ts","sourceRoot":"","sources":["../src/digest.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import test from 'node:test';
|
|
3
|
+
import { digest } from './digest.js';
|
|
4
|
+
test('digest returns deterministic Linear bullets sorted by event time and id', async () => {
|
|
5
|
+
const ctx = {
|
|
6
|
+
provider: 'linear',
|
|
7
|
+
window: { from: '2026-05-12T00:00:00.000Z', to: '2026-05-13T00:00:00.000Z' },
|
|
8
|
+
async changeEvents(filter) {
|
|
9
|
+
assert.deepEqual(filter, { providers: ['linear'] });
|
|
10
|
+
return [
|
|
11
|
+
{
|
|
12
|
+
id: 'evt-2',
|
|
13
|
+
timestamp: '2026-05-12T09:00:00.000Z',
|
|
14
|
+
action: 'updated',
|
|
15
|
+
canonicalPath: 'linear/issues/AGE-17__lin_17.json',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: 'evt-1',
|
|
19
|
+
timestamp: '2026-05-12T08:00:00.000Z',
|
|
20
|
+
action: 'created',
|
|
21
|
+
canonicalPath: '/linear/issues/AGE-16__lin_16.json',
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
const first = await digest(ctx);
|
|
27
|
+
const second = await digest(ctx);
|
|
28
|
+
assert.deepEqual(first, second);
|
|
29
|
+
assert.deepEqual(first, {
|
|
30
|
+
provider: 'linear',
|
|
31
|
+
bullets: [
|
|
32
|
+
{
|
|
33
|
+
text: 'AGE-16 was created',
|
|
34
|
+
canonicalPath: 'linear/issues/AGE-16__lin_16.json',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
text: 'AGE-17 was updated',
|
|
38
|
+
canonicalPath: 'linear/issues/AGE-17__lin_17.json',
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
test('digest returns null for an empty Linear event window', async () => {
|
|
44
|
+
const ctx = {
|
|
45
|
+
provider: 'linear',
|
|
46
|
+
window: { from: '2026-05-12T00:00:00.000Z', to: '2026-05-13T00:00:00.000Z' },
|
|
47
|
+
async changeEvents() {
|
|
48
|
+
return [];
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
assert.equal(await digest(ctx), null);
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=digest.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digest.test.js","sourceRoot":"","sources":["../src/digest.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,MAAM,EAAsB,MAAM,aAAa,CAAC;AAEzD,IAAI,CAAC,yEAAyE,EAAE,KAAK,IAAI,EAAE;IACzF,MAAM,GAAG,GAAkB;QACzB,QAAQ,EAAE,QAAQ;QAClB,MAAM,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE,EAAE,EAAE,0BAA0B,EAAE;QAC5E,KAAK,CAAC,YAAY,CAAC,MAAM;YACvB,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACpD,OAAO;gBACL;oBACE,EAAE,EAAE,OAAO;oBACX,SAAS,EAAE,0BAA0B;oBACrC,MAAM,EAAE,SAAS;oBACjB,aAAa,EAAE,mCAAmC;iBACnD;gBACD;oBACE,EAAE,EAAE,OAAO;oBACX,SAAS,EAAE,0BAA0B;oBACrC,MAAM,EAAE,SAAS;oBACjB,aAAa,EAAE,oCAAoC;iBACpD;aACF,CAAC;QACJ,CAAC;KACF,CAAC;IAEF,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;IAEjC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAChC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE;QACtB,QAAQ,EAAE,QAAQ;QAClB,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,oBAAoB;gBAC1B,aAAa,EAAE,mCAAmC;aACnD;YACD;gBACE,IAAI,EAAE,oBAAoB;gBAC1B,aAAa,EAAE,mCAAmC;aACnD;SACF;KACF,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;IACtE,MAAM,GAAG,GAAkB;QACzB,QAAQ,EAAE,QAAQ;QAClB,MAAM,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE,EAAE,EAAE,0BAA0B,EAAE;QAC5E,KAAK,CAAC,YAAY;YAChB,OAAO,EAAE,CAAC;QACZ,CAAC;KACF,CAAC;IAEF,MAAM,CAAC,KAAK,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;AACxC,CAAC,CAAC,CAAC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC;AAE1C,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC;AAE1C,cAAc,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// Public barrel for runtime helpers, normalizers, and exported types.
|
|
2
2
|
export * from './linear-adapter.js';
|
|
3
|
+
export * from './digest.js';
|
|
3
4
|
export * from './index-emitter.js';
|
|
5
|
+
export * from './layout.js';
|
|
4
6
|
export * from './layout-prompt.js';
|
|
5
7
|
export * from './path-mapper.js';
|
|
6
8
|
export * from './summary.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC;AAE1C,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC;AAE1C,cAAc,gBAAgB,CAAC"}
|
package/dist/layout.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { LayoutManifestProvider as CoreLayoutManifestProvider } from '@relayfile/adapter-core';
|
|
2
|
+
export type { LayoutManifest, LayoutManifestProvider, LayoutResourceManifest, MaterializationMode, WritebackResourceManifest, } from '@relayfile/adapter-core';
|
|
3
|
+
export declare const layoutManifest: CoreLayoutManifestProvider;
|
|
4
|
+
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,IAAI,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAEpG,YAAY,EACV,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC;AAEjC,eAAO,MAAM,cAAc,EAAE,0BAiC3B,CAAC"}
|
package/dist/layout.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export const layoutManifest = () => ({
|
|
2
|
+
provider: 'linear',
|
|
3
|
+
filenameConvention: '<identifier>__<uuid>.json',
|
|
4
|
+
// Top-level aliasSegments is the union of every resource's alias segments
|
|
5
|
+
// so consumers that inspect only the manifest root can discover all
|
|
6
|
+
// lookup keys. `by-name` belongs here because `linear/teams` exposes it.
|
|
7
|
+
aliasSegments: ['by-id', 'by-name', 'by-title', 'by-state'],
|
|
8
|
+
resources: [
|
|
9
|
+
{
|
|
10
|
+
path: 'linear/issues',
|
|
11
|
+
title: 'Issues',
|
|
12
|
+
materialization: 'eager',
|
|
13
|
+
aliasSegments: ['by-id', 'by-title', 'by-state'],
|
|
14
|
+
writebackResources: [
|
|
15
|
+
{ path: 'linear/issues', schemaId: 'linear/issue' },
|
|
16
|
+
{ path: 'linear/issues/comments', schemaId: 'linear/comment' },
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
path: 'linear/projects',
|
|
21
|
+
title: 'Projects',
|
|
22
|
+
materialization: 'eager',
|
|
23
|
+
aliasSegments: ['by-id', 'by-title'],
|
|
24
|
+
writebackResources: [],
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
path: 'linear/teams',
|
|
28
|
+
title: 'Teams',
|
|
29
|
+
materialization: 'eager',
|
|
30
|
+
aliasSegments: ['by-id', 'by-name'],
|
|
31
|
+
writebackResources: [],
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,MAAM,cAAc,GAA+B,GAAG,EAAE,CAAC,CAAC;IAC/D,QAAQ,EAAE,QAAQ;IAClB,kBAAkB,EAAE,2BAA2B;IAC/C,0EAA0E;IAC1E,oEAAoE;IACpE,yEAAyE;IACzE,aAAa,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,CAAC;IAC3D,SAAS,EAAE;QACT;YACE,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE,QAAQ;YACf,eAAe,EAAE,OAAO;YACxB,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,CAAC;YAChD,kBAAkB,EAAE;gBAClB,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,cAAc,EAAE;gBACnD,EAAE,IAAI,EAAE,wBAAwB,EAAE,QAAQ,EAAE,gBAAgB,EAAE;aAC/D;SACF;QACD;YACE,IAAI,EAAE,iBAAiB;YACvB,KAAK,EAAE,UAAU;YACjB,eAAe,EAAE,OAAO;YACxB,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC;YACpC,kBAAkB,EAAE,EAAE;SACvB;QACD;YACE,IAAI,EAAE,cAAc;YACpB,KAAK,EAAE,OAAO;YACd,eAAe,EAAE,OAAO;YACxB,aAAa,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC;YACnC,kBAAkB,EAAE,EAAE;SACvB;KACF;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.test.d.ts","sourceRoot":"","sources":["../src/layout.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import test from 'node:test';
|
|
3
|
+
import { layoutManifest } from './layout.js';
|
|
4
|
+
const CANONICAL_ALIAS_SEGMENTS = new Set(['by-id', 'by-name', 'by-state', 'by-title']);
|
|
5
|
+
test('layoutManifest exposes Linear resources with canonical aliases and writeback schema pointers', () => {
|
|
6
|
+
const manifest = layoutManifest();
|
|
7
|
+
assert.equal(manifest.provider, 'linear');
|
|
8
|
+
assert.deepEqual(manifest.aliasSegments, ['by-id', 'by-name', 'by-title', 'by-state']);
|
|
9
|
+
assert.ok(manifest.resources.length > 0);
|
|
10
|
+
for (const resource of manifest.resources) {
|
|
11
|
+
assert.ok(resource.path.startsWith('linear/'));
|
|
12
|
+
assert.doesNotMatch(resource.path, /^\//u);
|
|
13
|
+
for (const alias of resource.aliasSegments) {
|
|
14
|
+
assert.ok(CANONICAL_ALIAS_SEGMENTS.has(alias), `unexpected alias segment ${alias}`);
|
|
15
|
+
}
|
|
16
|
+
for (const writeback of resource.writebackResources) {
|
|
17
|
+
assert.ok(writeback.path.startsWith('linear/'));
|
|
18
|
+
assert.doesNotMatch(writeback.path, /^\//u);
|
|
19
|
+
assert.match(writeback.schemaId, /^linear\/[a-z-]+$/u);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
test('layoutManifest top-level aliasSegments contains the union of all resource alias segments', () => {
|
|
24
|
+
const manifest = layoutManifest();
|
|
25
|
+
const declared = new Set(manifest.aliasSegments);
|
|
26
|
+
for (const resource of manifest.resources) {
|
|
27
|
+
for (const alias of resource.aliasSegments) {
|
|
28
|
+
assert.ok(declared.has(alias), `top-level aliasSegments missing ${alias} declared by resource ${resource.path}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
//# sourceMappingURL=layout.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.test.js","sourceRoot":"","sources":["../src/layout.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,wBAAwB,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;AAEvF,IAAI,CAAC,8FAA8F,EAAE,GAAG,EAAE;IACxG,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;IAElC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC1C,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;IACvF,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEzC,KAAK,MAAM,QAAQ,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;QAC1C,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC3C,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,aAAa,EAAE,CAAC;YAC3C,MAAM,CAAC,EAAE,CAAC,wBAAwB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,4BAA4B,KAAK,EAAE,CAAC,CAAC;QACtF,CAAC;QACD,KAAK,MAAM,SAAS,IAAI,QAAQ,CAAC,kBAAkB,EAAE,CAAC;YACpD,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;YAChD,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC5C,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0FAA0F,EAAE,GAAG,EAAE;IACpG,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;IAClC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IACjD,KAAK,MAAM,QAAQ,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;QAC1C,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,aAAa,EAAE,CAAC;YAC3C,MAAM,CAAC,EAAE,CACP,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EACnB,mCAAmC,KAAK,yBAAyB,QAAQ,CAAC,IAAI,EAAE,CACjF,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@relayfile/adapter-linear",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
4
4
|
"description": "Linear adapter bootstrap package for Relayfile",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"directory": "packages/linear"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@relayfile/adapter-core": "^0.2.
|
|
58
|
+
"@relayfile/adapter-core": "^0.2.22"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@relayfile/sdk": ">=0.6.0 <1"
|