@feelflow/ffid-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/README.md +270 -0
- package/dist/chunk-A63MX52D.js +861 -0
- package/dist/chunk-YCMQXJOS.cjs +872 -0
- package/dist/components/index.cjs +22 -0
- package/dist/components/index.d.cts +3 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.js +1 -0
- package/dist/index-CtBBLbTn.d.cts +322 -0
- package/dist/index-CtBBLbTn.d.ts +322 -0
- package/dist/index.cjs +68 -0
- package/dist/index.d.cts +181 -0
- package/dist/index.d.ts +181 -0
- package/dist/index.js +31 -0
- package/dist/legal/index.cjs +180 -0
- package/dist/legal/index.d.cts +332 -0
- package/dist/legal/index.d.ts +332 -0
- package/dist/legal/index.js +176 -0
- package/package.json +84 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// src/constants.ts
|
|
2
|
+
var DEFAULT_API_BASE_URL = "https://id.feelflow.co.jp";
|
|
3
|
+
|
|
4
|
+
// src/legal/ffid-legal-client.ts
|
|
5
|
+
var API_PREFIX = "/api/v1/legal/ext";
|
|
6
|
+
var SDK_LOG_PREFIX = "[FFID Legal SDK]";
|
|
7
|
+
var NO_CONTENT_STATUS = 204;
|
|
8
|
+
var FFID_LEGAL_ERROR_CODES = {
|
|
9
|
+
/** API key is missing */
|
|
10
|
+
MISSING_API_KEY: "MISSING_API_KEY",
|
|
11
|
+
/** Network request failed (fetch threw) */
|
|
12
|
+
NETWORK_ERROR: "NETWORK_ERROR",
|
|
13
|
+
/** Server returned non-JSON response */
|
|
14
|
+
PARSE_ERROR: "PARSE_ERROR",
|
|
15
|
+
/** Server returned error without structured error body */
|
|
16
|
+
UNKNOWN_ERROR: "UNKNOWN_ERROR",
|
|
17
|
+
/** Input validation failed (empty required parameters) */
|
|
18
|
+
VALIDATION_ERROR: "VALIDATION_ERROR"
|
|
19
|
+
};
|
|
20
|
+
var noopLogger = {
|
|
21
|
+
debug: () => {
|
|
22
|
+
},
|
|
23
|
+
info: () => {
|
|
24
|
+
},
|
|
25
|
+
warn: () => {
|
|
26
|
+
},
|
|
27
|
+
error: (...args) => console.error(SDK_LOG_PREFIX, ...args)
|
|
28
|
+
};
|
|
29
|
+
var consoleLogger = {
|
|
30
|
+
debug: (...args) => console.debug(SDK_LOG_PREFIX, ...args),
|
|
31
|
+
info: (...args) => console.info(SDK_LOG_PREFIX, ...args),
|
|
32
|
+
warn: (...args) => console.warn(SDK_LOG_PREFIX, ...args),
|
|
33
|
+
error: (...args) => console.error(SDK_LOG_PREFIX, ...args)
|
|
34
|
+
};
|
|
35
|
+
function createFFIDLegalClient(config) {
|
|
36
|
+
if (!config.apiKey) {
|
|
37
|
+
throw new Error("FFID Legal Client: apiKey \u304C\u672A\u8A2D\u5B9A\u3067\u3059");
|
|
38
|
+
}
|
|
39
|
+
const baseUrl = config.apiBaseUrl ?? DEFAULT_API_BASE_URL;
|
|
40
|
+
const logger = config.logger ?? (config.debug ? consoleLogger : noopLogger);
|
|
41
|
+
async function fetchWithApiKey(endpoint, options = {}) {
|
|
42
|
+
const url = `${baseUrl}${API_PREFIX}${endpoint}`;
|
|
43
|
+
logger.debug("Fetching:", url);
|
|
44
|
+
let response;
|
|
45
|
+
try {
|
|
46
|
+
response = await fetch(url, {
|
|
47
|
+
...options,
|
|
48
|
+
headers: {
|
|
49
|
+
"Content-Type": "application/json",
|
|
50
|
+
"X-Service-Api-Key": config.apiKey,
|
|
51
|
+
...options.headers
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
} catch (error) {
|
|
55
|
+
logger.error("Network error:", { url, error });
|
|
56
|
+
return {
|
|
57
|
+
error: {
|
|
58
|
+
code: FFID_LEGAL_ERROR_CODES.NETWORK_ERROR,
|
|
59
|
+
message: error instanceof Error ? error.message : "\u30CD\u30C3\u30C8\u30EF\u30FC\u30AF\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
if (response.status === NO_CONTENT_STATUS) {
|
|
64
|
+
logger.debug("Response: 204 No Content (unexpected)", { url });
|
|
65
|
+
return {
|
|
66
|
+
error: {
|
|
67
|
+
code: FFID_LEGAL_ERROR_CODES.UNKNOWN_ERROR,
|
|
68
|
+
message: "\u4E88\u671F\u3057\u306A\u3044\u30EC\u30B9\u30DD\u30F3\u30B9: \u30B5\u30FC\u30D0\u30FC\u304B\u3089\u30B3\u30F3\u30C6\u30F3\u30C4\u304C\u8FD4\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F"
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
let data;
|
|
73
|
+
try {
|
|
74
|
+
data = await response.json();
|
|
75
|
+
} catch (parseError) {
|
|
76
|
+
logger.error("Parse error:", { url, status: response.status, parseError });
|
|
77
|
+
return {
|
|
78
|
+
error: {
|
|
79
|
+
code: FFID_LEGAL_ERROR_CODES.PARSE_ERROR,
|
|
80
|
+
message: `\u30B5\u30FC\u30D0\u30FC\u304B\u3089\u4E0D\u6B63\u306A\u30EC\u30B9\u30DD\u30F3\u30B9\u3092\u53D7\u4FE1\u3057\u307E\u3057\u305F (status: ${response.status})`
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
logger.debug("Response:", response.status, data);
|
|
85
|
+
if (!response.ok || !data.success) {
|
|
86
|
+
return {
|
|
87
|
+
error: data.error ?? {
|
|
88
|
+
code: FFID_LEGAL_ERROR_CODES.UNKNOWN_ERROR,
|
|
89
|
+
message: "\u4E0D\u660E\u306A\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
if (data.data === void 0) {
|
|
94
|
+
return {
|
|
95
|
+
error: {
|
|
96
|
+
code: FFID_LEGAL_ERROR_CODES.UNKNOWN_ERROR,
|
|
97
|
+
message: "\u30B5\u30FC\u30D0\u30FC\u304B\u3089\u30C7\u30FC\u30BF\u304C\u8FD4\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F"
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
return { data: data.data };
|
|
102
|
+
}
|
|
103
|
+
async function getDocuments() {
|
|
104
|
+
return fetchWithApiKey("/documents");
|
|
105
|
+
}
|
|
106
|
+
async function getDocument(documentId) {
|
|
107
|
+
if (!documentId) {
|
|
108
|
+
return {
|
|
109
|
+
error: {
|
|
110
|
+
code: FFID_LEGAL_ERROR_CODES.VALIDATION_ERROR,
|
|
111
|
+
message: "documentId is required"
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
return fetchWithApiKey(`/documents/${encodeURIComponent(documentId)}`);
|
|
116
|
+
}
|
|
117
|
+
async function recordAgreement(request) {
|
|
118
|
+
if (!request.externalUserId || !request.documentId) {
|
|
119
|
+
return {
|
|
120
|
+
error: {
|
|
121
|
+
code: FFID_LEGAL_ERROR_CODES.VALIDATION_ERROR,
|
|
122
|
+
message: "externalUserId and documentId are required"
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
return fetchWithApiKey("/agreements", {
|
|
127
|
+
method: "POST",
|
|
128
|
+
body: JSON.stringify(request)
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
async function checkAgreement(externalUserId, documentId) {
|
|
132
|
+
if (!externalUserId || !documentId) {
|
|
133
|
+
return {
|
|
134
|
+
error: {
|
|
135
|
+
code: FFID_LEGAL_ERROR_CODES.VALIDATION_ERROR,
|
|
136
|
+
message: "externalUserId and documentId are required"
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
const params = new URLSearchParams({
|
|
141
|
+
externalUserId,
|
|
142
|
+
documentId
|
|
143
|
+
});
|
|
144
|
+
return fetchWithApiKey(`/agreements/check?${params.toString()}`);
|
|
145
|
+
}
|
|
146
|
+
async function getPendingAgreements(externalUserId) {
|
|
147
|
+
if (!externalUserId) {
|
|
148
|
+
return {
|
|
149
|
+
error: {
|
|
150
|
+
code: FFID_LEGAL_ERROR_CODES.VALIDATION_ERROR,
|
|
151
|
+
message: "externalUserId is required"
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
const params = new URLSearchParams({ externalUserId });
|
|
156
|
+
return fetchWithApiKey(`/agreements/pending?${params.toString()}`);
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
/** Get all legal documents available to this service */
|
|
160
|
+
getDocuments,
|
|
161
|
+
/** Get a specific legal document by ID */
|
|
162
|
+
getDocument,
|
|
163
|
+
/** Record a user's agreement to a legal document */
|
|
164
|
+
recordAgreement,
|
|
165
|
+
/** Check if a user has agreed to a specific document */
|
|
166
|
+
checkAgreement,
|
|
167
|
+
/** Get all documents that a user has not yet agreed to */
|
|
168
|
+
getPendingAgreements,
|
|
169
|
+
/** Resolved logger instance */
|
|
170
|
+
logger,
|
|
171
|
+
/** API base URL */
|
|
172
|
+
baseUrl
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export { DEFAULT_API_BASE_URL, FFID_LEGAL_ERROR_CODES, createFFIDLegalClient };
|
package/package.json
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@feelflow/ffid-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "FeelFlow ID Platform SDK for React/Next.js applications",
|
|
5
|
+
"keywords": ["feelflow", "ffid", "sdk", "react", "nextjs", "authentication"],
|
|
6
|
+
"author": "FeelFlow <dev@feelflow.co.jp>",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"homepage": "https://github.com/feel-flow/feelflow-id-platform/tree/develop/sdk/typescript#readme",
|
|
9
|
+
"bugs": {
|
|
10
|
+
"url": "https://github.com/feel-flow/feelflow-id-platform/issues"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/feel-flow/feelflow-id-platform.git",
|
|
15
|
+
"directory": "sdk/typescript"
|
|
16
|
+
},
|
|
17
|
+
"type": "module",
|
|
18
|
+
"main": "./dist/index.cjs",
|
|
19
|
+
"module": "./dist/index.js",
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/index.js",
|
|
25
|
+
"require": "./dist/index.cjs"
|
|
26
|
+
},
|
|
27
|
+
"./components": {
|
|
28
|
+
"types": "./dist/components/index.d.ts",
|
|
29
|
+
"import": "./dist/components/index.js",
|
|
30
|
+
"require": "./dist/components/index.cjs"
|
|
31
|
+
},
|
|
32
|
+
"./legal": {
|
|
33
|
+
"types": "./dist/legal/index.d.ts",
|
|
34
|
+
"import": "./dist/legal/index.js",
|
|
35
|
+
"require": "./dist/legal/index.cjs"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"dist",
|
|
40
|
+
"README.md"
|
|
41
|
+
],
|
|
42
|
+
"sideEffects": false,
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "rm -rf dist && tsup",
|
|
45
|
+
"dev": "tsup --watch",
|
|
46
|
+
"type-check": "tsc --noEmit",
|
|
47
|
+
"lint": "eslint src",
|
|
48
|
+
"lint:fix": "eslint src --fix",
|
|
49
|
+
"test": "vitest run",
|
|
50
|
+
"test:watch": "vitest",
|
|
51
|
+
"test:coverage": "vitest run --coverage",
|
|
52
|
+
"prepublishOnly": "npm run build"
|
|
53
|
+
},
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
56
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
57
|
+
},
|
|
58
|
+
"peerDependenciesMeta": {
|
|
59
|
+
"react": {
|
|
60
|
+
"optional": true
|
|
61
|
+
},
|
|
62
|
+
"react-dom": {
|
|
63
|
+
"optional": true
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@testing-library/jest-dom": "^6.0.0",
|
|
68
|
+
"@testing-library/react": "^16.0.0",
|
|
69
|
+
"@types/react": "^19.0.0",
|
|
70
|
+
"@types/react-dom": "^19.0.0",
|
|
71
|
+
"jsdom": "^27.0.0",
|
|
72
|
+
"react": "^19.0.0",
|
|
73
|
+
"react-dom": "^19.0.0",
|
|
74
|
+
"tsup": "^8.0.0",
|
|
75
|
+
"typescript": "^5.0.0",
|
|
76
|
+
"vitest": "^4.0.0"
|
|
77
|
+
},
|
|
78
|
+
"engines": {
|
|
79
|
+
"node": ">=18.0.0"
|
|
80
|
+
},
|
|
81
|
+
"publishConfig": {
|
|
82
|
+
"access": "public"
|
|
83
|
+
}
|
|
84
|
+
}
|