Skip to content

Commit 1db1a99

Browse files
committed
IS-11008: add typecheck, prettier and build to the ci workflow
1 parent 1d8de84 commit 1db1a99

8 files changed

Lines changed: 88 additions & 10 deletions

.github/workflows/lwa-github-ci-workflow.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,20 @@ jobs:
5656
- name: App — Run Tests
5757
run: npm run test -w src/haapi-react-app -- run
5858

59+
- name: Docs — Check Formatting
60+
run: npm run prettier-check -w @curity/haapi-react-sdk-docs
61+
62+
# Type-checks the example sources (incl. catalog.ts's mock HAAPI steps) against the SDK's
63+
# published types, so the fixtures can't structurally drift from the SDK without failing CI.
64+
- name: Docs — Typecheck
65+
run: npm run typecheck -w @curity/haapi-react-sdk-docs
66+
67+
# Runs the full generator chain (predocs:build) then `docusaurus build` with
68+
# `onBrokenLinks: 'throw'` — so a generator crash, a broken link/anchor or an MDX
69+
# compile error fails the PR instead of surfacing on someone's next local run.
70+
- name: Docs — Build
71+
run: npm run docs:build -w @curity/haapi-react-sdk-docs
72+
5973
notify-slack:
6074
name: Notify Slack
6175
needs: build-and-test
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (C) 2026 Curity AB. All rights reserved.
3+
*
4+
* The contents of this file are the property of Curity AB.
5+
* You may not copy or use this file, in either source code
6+
* or executable form, except in compliance with terms
7+
* set by Curity AB.
8+
*
9+
* For further information, please contact Curity AB.
10+
*/
11+
12+
/*
13+
* Ambient stubs so the example typecheck (`npm run typecheck`) can resolve modules that aren't real
14+
* dependencies of this docs project.
15+
*
16+
* Why stub instead of installing them:
17+
* - The third-party UI libs below (antd, icons, recaptcha) are used ONLY inside example playgrounds,
18+
* and Sandpack pulls them from a CDN at runtime — they were never docs dependencies. Installing them
19+
* just to typecheck would drag their large dependency trees into this project for no runtime benefit.
20+
* - The point of the example typecheck is to catch drift in *SDK and catalog* usage (the fixtures in
21+
* `examples/catalog.ts` are typed against the SDK). We don't need to type-check the third-party UI
22+
* calls — so we declare those modules as `any` and keep the dependency surface small. The trade-off is
23+
* that misuse of an antd/recaptcha API isn't caught here (it would surface in the running playground).
24+
*
25+
* The `*.module.css` stub covers the CSS-module imports in the SDK source that the examples pull in
26+
* transitively (e.g. Spinner) — the SDK's own build provides this via its vite client types.
27+
*/
28+
29+
declare module 'antd';
30+
declare module '@ant-design/icons';
31+
declare module '@google-recaptcha/react';
32+
33+
declare module '*.module.css' {
34+
const classes: { readonly [key: string]: string };
35+
export default classes;
36+
}

src/haapi-react-sdk/docs/examples/FullCustomizationUICompositionExample.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ function CustomFlowUI() {
6161
<List
6262
size="small"
6363
dataSource={history}
64-
renderItem={entry => (
64+
renderItem={(entry: (typeof history)[number]) => (
6565
<List.Item>
6666
<Text>
6767
{entry.step.type}{entry.timestamp.toLocaleTimeString()}

src/haapi-react-sdk/docs/examples/SelectorRenderInterceptorExample.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
import { Select } from 'antd';
1313
import { HaapiStepper } from '@curity/haapi-react-sdk/haapi-stepper/feature/stepper/HaapiStepper';
1414
import { HaapiStepperStepUI } from '@curity/haapi-react-sdk/haapi-stepper/feature/steps/HaapiStepperStepUI';
15-
import type { HaapiStepperStepUISelectorActionRenderInterceptor } from '@curity/haapi-react-sdk/haapi-stepper/feature/stepper/haapi-stepper.types';
15+
import type {
16+
HaapiStepperFormAction,
17+
HaapiStepperStepUISelectorActionRenderInterceptor,
18+
} from '@curity/haapi-react-sdk/haapi-stepper/feature/stepper/haapi-stepper.types';
1619
import { ExamplePreviewer } from './ExamplePreviewer';
1720
import { HAAPI_EXAMPLE } from './catalog';
1821

@@ -22,7 +25,7 @@ import { HAAPI_EXAMPLE } from './catalog';
2225
* the flow forward through `nextStep`, exactly like the built-in selector would.
2326
*/
2427
const selectorActionRenderInterceptor: HaapiStepperStepUISelectorActionRenderInterceptor = ({ action, nextStep }) => {
25-
const options = action.model.options;
28+
const options = action.model.options as HaapiStepperFormAction[];
2629

2730
return (
2831
<Select
@@ -32,7 +35,7 @@ const selectorActionRenderInterceptor: HaapiStepperStepUISelectorActionRenderInt
3235
style={{ width: '100%' }}
3336
optionFilterProp="label"
3437
options={options.map(option => ({ label: option.title, value: option.id }))}
35-
onChange={value => {
38+
onChange={(value: string) => {
3639
const option = options.find(candidate => candidate.id === value);
3740
if (option) {
3841
nextStep(option);

src/haapi-react-sdk/docs/examples/StepRenderInterceptorExample.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import type { CSSProperties } from 'react';
1313
import { HaapiStepper } from '@curity/haapi-react-sdk/haapi-stepper/feature/stepper/HaapiStepper';
1414
import { HaapiStepperStepUI } from '@curity/haapi-react-sdk/haapi-stepper/feature/steps/HaapiStepperStepUI';
15+
import type { HaapiStepperFormAction } from '@curity/haapi-react-sdk/haapi-stepper/feature/stepper/haapi-stepper.types';
1516
import { ExamplePreviewer } from './ExamplePreviewer';
1617
import { HAAPI_EXAMPLE } from './catalog';
1718

@@ -35,7 +36,7 @@ export default function App() {
3536

3637
const { nextStep } = stepperApi;
3738
const selector = stepperApi.currentStep.dataHelpers.actions?.selector?.[0];
38-
const options = selector?.model.options ?? [];
39+
const options = (selector?.model.options ?? []) as HaapiStepperFormAction[];
3940

4041
return (
4142
<section>

src/haapi-react-sdk/docs/examples/TabbedAuthenticatorUICompositionExample.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { HAAPI_STEPS } from '@curity/haapi-react-sdk/haapi-stepper/data-access/t
1919
import { HAAPI_ACTION_CLIENT_OPERATIONS } from '@curity/haapi-react-sdk/haapi-stepper/data-access/types/haapi-action.types';
2020
import type { HaapiFetchAction } from '@curity/haapi-react-sdk/haapi-stepper/data-access/types/haapi-fetch.types';
2121
import type {
22-
HaapiStepperAction,
22+
HaapiStepperFormAction,
2323
HaapiStepperStep,
2424
} from '@curity/haapi-react-sdk/haapi-stepper/feature/stepper/haapi-stepper.types';
2525
import { ExamplePreviewer } from './ExamplePreviewer';
@@ -49,8 +49,7 @@ function TabbedAuthenticatorSelector() {
4949
}
5050

5151
const selectorAction = selectStep.dataHelpers.actions?.selector[0];
52-
// Selector options are already typed as `HaapiStepperAction[]` — no cast needed.
53-
const options = selectorAction?.model.options ?? [];
52+
const options = (selectorAction?.model.options ?? []) as HaapiStepperFormAction[];
5453
const bankIdOption = options.find(isBankId);
5554
const tabOptions = bankIdOption ? [bankIdOption, ...options.filter(option => option !== bankIdOption)] : options;
5655
const activeTabOption = tabOptions[activeIndex];
@@ -75,7 +74,7 @@ function TabbedAuthenticatorSelector() {
7574
return (
7675
<Tabs
7776
activeKey={String(activeIndex)}
78-
onChange={key => selectTabOption(Number(key))}
77+
onChange={(key: string) => selectTabOption(Number(key))}
7978
items={tabOptions.map((option, index) => ({
8079
key: String(index),
8180
label: option.title,
@@ -128,7 +127,7 @@ const isCustomAuthenticatorSelectStep = (step: HaapiStepperStep | null) =>
128127
step.metadata?.templateArea === CUSTOM_SELECT_TEMPLATE_AREA &&
129128
step.metadata.viewName === CUSTOM_SELECT_VIEW_NAME;
130129

131-
const isBankId = (option: HaapiStepperAction) =>
130+
const isBankId = (option: HaapiStepperFormAction) =>
132131
option.properties?.authenticatorType === HAAPI_ACTION_CLIENT_OPERATIONS.BANKID;
133132

134133
const isBankIdWaitStep = (step: HaapiStepperStep) => step.metadata?.viewName === BANKID_WAIT_VIEW_NAME;

src/haapi-react-sdk/docs/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"scripts": {
1313
"prettier-check": "prettier --check .",
1414
"prettier": "prettier --write .",
15+
"typecheck": "tsc --noEmit",
1516
"docs:gen": "node scripts/build-sandpack-sdk.mjs",
1617
"docs:split": "node scripts/split-docs.mjs",
1718
"docs:apiref": "node scripts/emit-api-reference.mjs",
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
// Type-checks the docs' example sources against the SDK's published types (run via `npm run typecheck`,
3+
// gated in CI). Most importantly `examples/catalog.ts`, whose mock HAAPI steps are annotated with
4+
// `HaapiActionStep`/`HaapiStep` etc. — so if the SDK's step model changes, the fixtures stop compiling.
5+
// `moduleResolution: bundler` resolves the deep `@curity/haapi-react-sdk/haapi-stepper/*` imports; the
6+
// Sandpack/CDN-only packages the playgrounds use (`antd`, `@ant-design/icons`, `@google-recaptcha/*`)
7+
// are dev-only deps so tsc can resolve them, and `declarations.d.ts` covers the SDK's CSS-module imports.
8+
//
9+
// The Docusaurus `src/` components are out of scope — they use `@theme`/`@site` aliases that need the
10+
// generated Docusaurus TS project.
11+
"compilerOptions": {
12+
"target": "ES2020",
13+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
14+
"module": "ESNext",
15+
"moduleResolution": "bundler",
16+
"jsx": "react-jsx",
17+
"isolatedModules": true,
18+
"moduleDetection": "force",
19+
"skipLibCheck": true,
20+
"noEmit": true,
21+
"strict": true
22+
},
23+
"include": ["examples", "declarations.d.ts"]
24+
}

0 commit comments

Comments
 (0)