@lucra/sdk 0.1.0
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/LICENSE +21 -0
- package/README.md +116 -0
- package/dist/embed.d.ts +37 -0
- package/dist/embed.js +84 -0
- package/dist/generated/client/client.gen.d.ts +2 -0
- package/dist/generated/client/client.gen.js +216 -0
- package/dist/generated/client/index.d.ts +10 -0
- package/dist/generated/client/index.js +6 -0
- package/dist/generated/client/types.gen.d.ts +120 -0
- package/dist/generated/client/types.gen.js +2 -0
- package/dist/generated/client/utils.gen.d.ts +37 -0
- package/dist/generated/client/utils.gen.js +228 -0
- package/dist/generated/client.gen.d.ts +12 -0
- package/dist/generated/client.gen.js +3 -0
- package/dist/generated/core/auth.gen.d.ts +25 -0
- package/dist/generated/core/auth.gen.js +14 -0
- package/dist/generated/core/bodySerializer.gen.d.ts +25 -0
- package/dist/generated/core/bodySerializer.gen.js +57 -0
- package/dist/generated/core/params.gen.d.ts +43 -0
- package/dist/generated/core/params.gen.js +109 -0
- package/dist/generated/core/pathSerializer.gen.d.ts +33 -0
- package/dist/generated/core/pathSerializer.gen.js +106 -0
- package/dist/generated/core/queryKeySerializer.gen.d.ts +18 -0
- package/dist/generated/core/queryKeySerializer.gen.js +92 -0
- package/dist/generated/core/serverSentEvents.gen.d.ts +71 -0
- package/dist/generated/core/serverSentEvents.gen.js +132 -0
- package/dist/generated/core/types.gen.d.ts +83 -0
- package/dist/generated/core/types.gen.js +2 -0
- package/dist/generated/core/utils.gen.d.ts +19 -0
- package/dist/generated/core/utils.gen.js +87 -0
- package/dist/generated/index.d.ts +2 -0
- package/dist/generated/index.js +2 -0
- package/dist/generated/sdk.gen.d.ts +599 -0
- package/dist/generated/sdk.gen.js +2268 -0
- package/dist/generated/types.gen.d.ts +6103 -0
- package/dist/generated/types.gen.js +2 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.js +62 -0
- package/dist/react.d.ts +28 -0
- package/dist/react.js +51 -0
- package/dist/types.d.ts +13 -0
- package/dist/types.js +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +2 -0
- package/package.json +60 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { LucraApi } from "./generated/sdk.gen.js";
|
|
2
|
+
import type { Problem } from "./generated/types.gen.js";
|
|
3
|
+
export type * from "./generated/types.gen.js";
|
|
4
|
+
export type { LucraAppearance, LucraComponent } from "./types.js";
|
|
5
|
+
export type LucraOptions = {
|
|
6
|
+
/** Act for a client account (`acct_…`) or roster creator (`crtr_…`); or use `lucra.as(account)`. */
|
|
7
|
+
account?: string;
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
};
|
|
10
|
+
/** A failed request: Lucra's problem, with its stable `code` and, when there's a next step, how to `fix` it. */
|
|
11
|
+
export declare class LucraError extends Error {
|
|
12
|
+
readonly status: number;
|
|
13
|
+
readonly code: string;
|
|
14
|
+
readonly fix?: string;
|
|
15
|
+
readonly requestId?: string;
|
|
16
|
+
readonly retryable: boolean;
|
|
17
|
+
readonly errors: Problem["errors"];
|
|
18
|
+
constructor(problem: Partial<Problem>, status: number);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Server-side client, with an API key or an OAuth access token a member granted your app; keep either on your server.
|
|
22
|
+
* Every method throws a LucraError on failure and resolves to
|
|
23
|
+
* `{ data, response }`; send `headers: { "Idempotency-Key": … }` on a write you may retry.
|
|
24
|
+
*
|
|
25
|
+
* const lucra = new Lucra(process.env.LUCRA_API_KEY)
|
|
26
|
+
* const { data: creator } = await lucra.creators.create({ body: { email: "sam@example.com" } })
|
|
27
|
+
* const { data: embed } = await lucra.as(creator.id).embeds.create({ body: { components: ["onboarding"] } })
|
|
28
|
+
*/
|
|
29
|
+
export declare class Lucra extends LucraApi {
|
|
30
|
+
private readonly apiKey;
|
|
31
|
+
private readonly options;
|
|
32
|
+
constructor(apiKey: string, options?: LucraOptions);
|
|
33
|
+
/** The same client, acting for a brand (`acct_…`) or roster creator (`crtr_…`). */
|
|
34
|
+
as(account: string): Lucra;
|
|
35
|
+
}
|
|
36
|
+
type Page<T> = {
|
|
37
|
+
data: {
|
|
38
|
+
data: T[];
|
|
39
|
+
nextCursor: string | null;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
/** Every item of a list, fetching pages as you go: `for await (const creator of paginate((o) => lucra.creators.list(o)))`. */
|
|
43
|
+
export declare function paginate<T, Options extends {
|
|
44
|
+
query?: object;
|
|
45
|
+
}>(list: (options: Options) => Promise<Page<T>>, options?: NoInfer<Options>): AsyncGenerator<T>;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { createClient, createConfig } from "./generated/client/index.js";
|
|
2
|
+
import { LucraApi } from "./generated/sdk.gen.js";
|
|
3
|
+
import { LUCRA_API_VERSION } from "./version.js";
|
|
4
|
+
/** A failed request: Lucra's problem, with its stable `code` and, when there's a next step, how to `fix` it. */
|
|
5
|
+
export class LucraError extends Error {
|
|
6
|
+
status;
|
|
7
|
+
code;
|
|
8
|
+
fix;
|
|
9
|
+
requestId;
|
|
10
|
+
retryable;
|
|
11
|
+
errors;
|
|
12
|
+
constructor(problem, status) {
|
|
13
|
+
super(problem.detail ?? `Lucra returned ${status}.`);
|
|
14
|
+
this.name = "LucraError";
|
|
15
|
+
this.status = problem.status ?? status;
|
|
16
|
+
this.code = problem.code ?? "unknown";
|
|
17
|
+
this.fix = problem.fix;
|
|
18
|
+
this.requestId = problem.requestId;
|
|
19
|
+
this.retryable = problem.retryable ?? false;
|
|
20
|
+
this.errors = problem.errors ?? [];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Server-side client, with an API key or an OAuth access token a member granted your app; keep either on your server.
|
|
25
|
+
* Every method throws a LucraError on failure and resolves to
|
|
26
|
+
* `{ data, response }`; send `headers: { "Idempotency-Key": … }` on a write you may retry.
|
|
27
|
+
*
|
|
28
|
+
* const lucra = new Lucra(process.env.LUCRA_API_KEY)
|
|
29
|
+
* const { data: creator } = await lucra.creators.create({ body: { email: "sam@example.com" } })
|
|
30
|
+
* const { data: embed } = await lucra.as(creator.id).embeds.create({ body: { components: ["onboarding"] } })
|
|
31
|
+
*/
|
|
32
|
+
export class Lucra extends LucraApi {
|
|
33
|
+
apiKey;
|
|
34
|
+
options;
|
|
35
|
+
constructor(apiKey, options = {}) {
|
|
36
|
+
const client = createClient(createConfig({
|
|
37
|
+
baseUrl: options.baseUrl ?? "https://api.onlucra.com",
|
|
38
|
+
auth: apiKey,
|
|
39
|
+
throwOnError: true,
|
|
40
|
+
headers: { "Lucra-Version": LUCRA_API_VERSION, ...(options.account ? { "Lucra-Account": options.account } : {}) },
|
|
41
|
+
}));
|
|
42
|
+
// A network error or abort has no failed response: it's rethrown as it is.
|
|
43
|
+
client.interceptors.error.use((error, response) => !response || response.ok ? error
|
|
44
|
+
: new LucraError(error && typeof error === "object" ? error : {}, response.status));
|
|
45
|
+
super({ client });
|
|
46
|
+
this.apiKey = apiKey;
|
|
47
|
+
this.options = options;
|
|
48
|
+
}
|
|
49
|
+
/** The same client, acting for a brand (`acct_…`) or roster creator (`crtr_…`). */
|
|
50
|
+
as(account) {
|
|
51
|
+
return new Lucra(this.apiKey, { ...this.options, account });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** Every item of a list, fetching pages as you go: `for await (const creator of paginate((o) => lucra.creators.list(o)))`. */
|
|
55
|
+
export async function* paginate(list, options = {}) {
|
|
56
|
+
let cursor;
|
|
57
|
+
do {
|
|
58
|
+
const { data } = await list({ ...options, query: { ...options.query, cursor } });
|
|
59
|
+
yield* data.data;
|
|
60
|
+
cursor = data.nextCursor ?? undefined;
|
|
61
|
+
} while (cursor);
|
|
62
|
+
}
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type CSSProperties } from "react";
|
|
2
|
+
import { loadLucra, type LucraEmbed, type LucraEventDetail, type LoadLucraOptions } from "./embed.js";
|
|
3
|
+
import type { LucraAppearance } from "./types.js";
|
|
4
|
+
export type { LucraAppearance, LucraComponent, LucraObjectEvent } from "./types.js";
|
|
5
|
+
export type { LucraEventDetail } from "./embed.js";
|
|
6
|
+
/** Pass the result of loadLucra(...) once, above every Lucra component. */
|
|
7
|
+
export declare function LucraProvider({ lucra, children }: {
|
|
8
|
+
lucra: LucraEmbed;
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
}): import("react").JSX.Element;
|
|
11
|
+
export { loadLucra, type LoadLucraOptions };
|
|
12
|
+
export type LucraComponentProps = {
|
|
13
|
+
appearance?: LucraAppearance;
|
|
14
|
+
className?: string;
|
|
15
|
+
style?: CSSProperties;
|
|
16
|
+
onReady?: (detail: LucraEventDetail) => void;
|
|
17
|
+
onChange?: (detail: LucraEventDetail) => void;
|
|
18
|
+
onComplete?: (detail: LucraEventDetail) => void;
|
|
19
|
+
onError?: (detail: LucraEventDetail) => void;
|
|
20
|
+
onClose?: (detail: LucraEventDetail) => void;
|
|
21
|
+
};
|
|
22
|
+
export declare const LucraOnboarding: (props: LucraComponentProps) => import("react").JSX.Element;
|
|
23
|
+
export declare const LucraCreatorPrograms: (props: LucraComponentProps) => import("react").JSX.Element;
|
|
24
|
+
export declare const LucraWallet: (props: LucraComponentProps) => import("react").JSX.Element;
|
|
25
|
+
export declare const LucraPrograms: (props: LucraComponentProps) => import("react").JSX.Element;
|
|
26
|
+
export declare const LucraPayments: (props: LucraComponentProps) => import("react").JSX.Element;
|
|
27
|
+
export declare const LucraAds: (props: LucraComponentProps) => import("react").JSX.Element;
|
|
28
|
+
export declare const LucraMessages: (props: LucraComponentProps) => import("react").JSX.Element;
|
package/dist/react.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useEffect, useRef } from "react";
|
|
3
|
+
import { loadLucra } from "./embed.js";
|
|
4
|
+
const LucraContext = createContext(null);
|
|
5
|
+
/** Pass the result of loadLucra(...) once, above every Lucra component. */
|
|
6
|
+
export function LucraProvider({ lucra, children }) {
|
|
7
|
+
return _jsx(LucraContext.Provider, { value: lucra, children: children });
|
|
8
|
+
}
|
|
9
|
+
export { loadLucra };
|
|
10
|
+
function useLucraComponent(component, props) {
|
|
11
|
+
const lucra = useContext(LucraContext);
|
|
12
|
+
const element = useRef(null);
|
|
13
|
+
const handlers = useRef(props);
|
|
14
|
+
handlers.current = props;
|
|
15
|
+
const appearance = JSON.stringify(props.appearance ?? {});
|
|
16
|
+
const mounted = useRef(null);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!lucra || !element.current)
|
|
19
|
+
return;
|
|
20
|
+
const target = element.current;
|
|
21
|
+
mounted.current = lucra.mount(component, target, { appearance: handlers.current.appearance });
|
|
22
|
+
const forward = (event) => {
|
|
23
|
+
const detail = event.detail;
|
|
24
|
+
const name = event.type.slice("lucra:".length);
|
|
25
|
+
const key = `on${name[0]?.toUpperCase()}${name.slice(1)}`;
|
|
26
|
+
const handler = handlers.current[key];
|
|
27
|
+
if (typeof handler === "function")
|
|
28
|
+
handler(detail);
|
|
29
|
+
};
|
|
30
|
+
const types = ["ready", "change", "complete", "error", "close"].map((type) => `lucra:${type}`);
|
|
31
|
+
types.forEach((type) => target.addEventListener(type, forward));
|
|
32
|
+
return () => {
|
|
33
|
+
types.forEach((type) => target.removeEventListener(type, forward));
|
|
34
|
+
mounted.current?.unmount();
|
|
35
|
+
mounted.current = null;
|
|
36
|
+
};
|
|
37
|
+
}, [lucra, component]);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
mounted.current?.update(JSON.parse(appearance));
|
|
40
|
+
}, [appearance]);
|
|
41
|
+
if (!lucra)
|
|
42
|
+
throw new Error("Wrap Lucra components in <LucraProvider lucra={loadLucra(...)}>.");
|
|
43
|
+
return _jsx("div", { ref: element, className: props.className, style: props.style });
|
|
44
|
+
}
|
|
45
|
+
export const LucraOnboarding = (props) => useLucraComponent("onboarding", props);
|
|
46
|
+
export const LucraCreatorPrograms = (props) => useLucraComponent("creator_programs", props);
|
|
47
|
+
export const LucraWallet = (props) => useLucraComponent("wallet", props);
|
|
48
|
+
export const LucraPrograms = (props) => useLucraComponent("programs", props);
|
|
49
|
+
export const LucraPayments = (props) => useLucraComponent("payments", props);
|
|
50
|
+
export const LucraAds = (props) => useLucraComponent("ads", props);
|
|
51
|
+
export const LucraMessages = (props) => useLucraComponent("messages", props);
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** The Lucra UI an embed can show: seven components, each a whole job. */
|
|
2
|
+
export type LucraComponent = "onboarding" | "messages" | "creator_programs" | "wallet" | "programs" | "payments" | "ads";
|
|
3
|
+
/** What a component reports with change or complete, alongside the step. */
|
|
4
|
+
export type LucraObjectEvent = "application.created" | "submission.created" | "withdrawal.created" | "profile.updated" | "program.created" | "program.updated" | "application.approved" | "application.rejected" | "submission.approved" | "submission.revision_requested" | "submission.rejected" | "payment.created" | "campaign.created" | "campaign.launched" | "campaign.paused" | "message.sent";
|
|
5
|
+
/** Components look like Lucra's app; pick the theme, your accent color (#rrggbb) and the corner radius. */
|
|
6
|
+
export type LucraAppearance = {
|
|
7
|
+
theme?: "light" | "dark" | "auto";
|
|
8
|
+
colors?: {
|
|
9
|
+
primary?: string;
|
|
10
|
+
};
|
|
11
|
+
/** Corner radius in px, 0–24. */
|
|
12
|
+
radius?: number;
|
|
13
|
+
};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const LUCRA_API_VERSION = "2026-10-01";
|
package/dist/version.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lucra/sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Lucra's server client and embeddable components.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://www.onlucra.com/docs?page=api-introduction",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"lucra",
|
|
9
|
+
"creator marketing",
|
|
10
|
+
"creator ads",
|
|
11
|
+
"ugc",
|
|
12
|
+
"api",
|
|
13
|
+
"sdk",
|
|
14
|
+
"typescript"
|
|
15
|
+
],
|
|
16
|
+
"author": "On Lucra, Inc.",
|
|
17
|
+
"type": "module",
|
|
18
|
+
"sideEffects": false,
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"default": "./dist/index.js"
|
|
27
|
+
},
|
|
28
|
+
"./embed": {
|
|
29
|
+
"types": "./dist/embed.d.ts",
|
|
30
|
+
"default": "./dist/embed.js"
|
|
31
|
+
},
|
|
32
|
+
"./react": {
|
|
33
|
+
"types": "./dist/react.d.ts",
|
|
34
|
+
"default": "./dist/react.js"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"generate": "openapi-ts",
|
|
39
|
+
"build": "rm -rf dist && tsc -p .",
|
|
40
|
+
"typecheck": "tsc -p . --noEmit",
|
|
41
|
+
"generate:check": "openapi-ts && git diff --quiet -- src/generated || (echo 'src/generated is stale: run npm run generate.' && exit 1)",
|
|
42
|
+
"prepublishOnly": "npm run generate:check && npm run build"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"react": ">=18"
|
|
46
|
+
},
|
|
47
|
+
"peerDependenciesMeta": {
|
|
48
|
+
"react": {
|
|
49
|
+
"optional": true
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@hey-api/openapi-ts": "^0.99.0",
|
|
54
|
+
"@types/react": "^19.0.0",
|
|
55
|
+
"typescript": "^5.9.0"
|
|
56
|
+
},
|
|
57
|
+
"publishConfig": {
|
|
58
|
+
"access": "public"
|
|
59
|
+
}
|
|
60
|
+
}
|