@startsimpli/integrations 0.2.29 → 0.2.30
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@startsimpli/integrations",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.30",
|
|
4
4
|
"description": "Provider-agnostic types, API clients, hooks, and UI primitives for email + calendar integrations across StartSimpli apps.",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EVERY PAGE COMPOSER IS REACHABLE FROM THE PACKAGE ROOT.
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS EXISTS. `PlanningPage` shipped in the tarball — the FILE was there,
|
|
5
|
+
* at `src/components/pages/PlanningPage.tsx` — while the one line exporting it
|
|
6
|
+
* from `src/components/index.ts` had been dropped by an unrelated PR's merge
|
|
7
|
+
* resolution. Nothing caught it: type-check passes (the file compiles), the unit
|
|
8
|
+
* tests pass (they import the module directly), and `npm pack` includes it. The
|
|
9
|
+
* failure surfaced two publishes later, in a CUSTOMER'S docker build:
|
|
10
|
+
*
|
|
11
|
+
* The export PlanningPage was not found in module
|
|
12
|
+
* .../@startsimpli/integrations/src/index.ts
|
|
13
|
+
* Did you mean to import ConnectionsPage?
|
|
14
|
+
*
|
|
15
|
+
* That is the worst possible place to find it — a tenant's deploy, against a
|
|
16
|
+
* published artifact, with the composer's own tests green the whole time.
|
|
17
|
+
*
|
|
18
|
+
* So the barrel is asserted against the DIRECTORY rather than against a list
|
|
19
|
+
* somebody has to remember to update. A new composer is exported or this fails;
|
|
20
|
+
* a merge that drops an export line fails here instead of in a deploy.
|
|
21
|
+
*/
|
|
22
|
+
import { readdirSync } from 'node:fs';
|
|
23
|
+
import { join } from 'node:path';
|
|
24
|
+
import { describe, expect, it } from 'vitest';
|
|
25
|
+
|
|
26
|
+
import * as pkg from '../index';
|
|
27
|
+
|
|
28
|
+
const PAGES_DIR = join(__dirname, '..', 'components', 'pages');
|
|
29
|
+
|
|
30
|
+
/** Files that are not composers and are deliberately not re-exported by name. */
|
|
31
|
+
const NOT_A_COMPOSER = new Set([
|
|
32
|
+
// Shared prop/api types — re-exported explicitly and selectively by the barrel
|
|
33
|
+
// so a fork gets the ones it needs without the internal slot unions.
|
|
34
|
+
'types.ts',
|
|
35
|
+
// The shared pieces two composers mount; exported by NAME, asserted below.
|
|
36
|
+
'work-items.tsx',
|
|
37
|
+
// A SUB-COMPONENT, not a composer: ConnectionsPage is its only mount, and the
|
|
38
|
+
// roster is the one list on that screen that shows OTHER people's accounts —
|
|
39
|
+
// it is meaningless outside the page that gates it. Listed here rather than
|
|
40
|
+
// exported, so this stays a real assertion about what a fork can reach and not
|
|
41
|
+
// a rubber stamp.
|
|
42
|
+
'MemberConnectionRoster.tsx',
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
function composerNames(): string[] {
|
|
46
|
+
return readdirSync(PAGES_DIR)
|
|
47
|
+
.filter((f) => f.endsWith('.tsx') && !NOT_A_COMPOSER.has(f))
|
|
48
|
+
.map((f) => f.replace(/\.tsx$/, ''));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
describe('package barrel', () => {
|
|
52
|
+
it('re-exports every page composer in components/pages', () => {
|
|
53
|
+
const missing = composerNames().filter((name) => !(name in pkg));
|
|
54
|
+
expect(missing, `not exported from @startsimpli/integrations: ${missing.join(', ')}`)
|
|
55
|
+
.toEqual([]);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('exports the pieces the tracker and the planner share', () => {
|
|
59
|
+
// These are what stop the two screens drifting. If the barrel loses them, a
|
|
60
|
+
// fork silently reimplements the row and the divergence starts.
|
|
61
|
+
for (const name of ['WorkItemRow', 'UnfilteredNotice', 'isOverdue', 'compareForScreen']) {
|
|
62
|
+
expect(pkg, `missing shared export ${name}`).toHaveProperty(name);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('exports the planning client alongside its screen', () => {
|
|
67
|
+
// A screen with no client is a mount nobody can wire; they ship together or
|
|
68
|
+
// the fork gets a confusing half-error at build time.
|
|
69
|
+
expect(pkg).toHaveProperty('PlanningPage');
|
|
70
|
+
expect(pkg).toHaveProperty('createPlanningApi');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('still exports the composers that were already shipping', () => {
|
|
74
|
+
for (const name of ['ConnectionsPage', 'LibraryPage', 'AskPage', 'TrackerPage']) {
|
|
75
|
+
expect(pkg, `regressed export ${name}`).toHaveProperty(name);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
});
|
package/src/components/index.ts
CHANGED
|
@@ -36,3 +36,20 @@ export type {
|
|
|
36
36
|
export * from './pages/LibraryPage';
|
|
37
37
|
export * from './pages/AskPage';
|
|
38
38
|
export * from './pages/TrackerPage';
|
|
39
|
+
|
|
40
|
+
// The planning toolset (bd startsim-8l6ef): focuses, and the items filed under
|
|
41
|
+
// them. `work-items` carries the pieces the tracker and the planner SHARE — the
|
|
42
|
+
// row, the honesty banner, the overdue/changed predicates — so two views over
|
|
43
|
+
// one list cannot drift into disagreeing about what they mean.
|
|
44
|
+
export * from './pages/PlanningPage';
|
|
45
|
+
export {
|
|
46
|
+
PRIORITY_LABELS,
|
|
47
|
+
UnfilteredNotice,
|
|
48
|
+
WORK_ITEM_DEFAULTS,
|
|
49
|
+
WorkItemRow,
|
|
50
|
+
changedSince,
|
|
51
|
+
compareForScreen,
|
|
52
|
+
isOverdue,
|
|
53
|
+
priorityLabel,
|
|
54
|
+
} from './pages/work-items';
|
|
55
|
+
export type { WorkItemSlot } from './pages/work-items';
|