hyperapp-is 0.1.31 → 0.1.33

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 CHANGED
@@ -204,6 +204,11 @@ npm で非公開の関数 (実験用)は、解説に記載します
204
204
  - [subscription_nodesCleanup](#subscription_nodescleanup)
205
205
  - [subscription_nodesLifecycleByIds](#subscription_nodeslifecyclebyids)
206
206
 
207
+ **services / google**
208
+ - [getGoogle](#getgoogle)
209
+ - [googleAuth](#googleauth)
210
+ - [getAccessToken](#getaccesstoken)
211
+
207
212
  ## source file / ソースファイル
208
213
 
209
214
  ```
@@ -255,18 +260,24 @@ src
255
260
  ├ animationView
256
261
  │ └ carousel.ts
257
262
 
258
- dom
259
- ├ utils.ts
260
- │ ScrollMargin
261
- │ getScrollMargin
262
- │ MatrixState
263
- │ getMatrixState
264
-
265
- └ lifecycle.ts
266
- effect_setTimedValue
267
- effect_nodesInitialize
268
- subscription_nodesCleanup
269
- subscription_nodesLifecycleByIds
263
+ dom
264
+ ├ utils.ts
265
+ ScrollMargin
266
+ getScrollMargin
267
+ MatrixState
268
+ getMatrixState
269
+
270
+ └ lifecycle.ts
271
+ effect_setTimedValue
272
+ effect_nodesInitialize
273
+ subscription_nodesCleanup
274
+ subscription_nodesLifecycleByIds
275
+
276
+ └ service
277
+ └ google.ts
278
+ getGoogle
279
+ googleAuth
280
+ getAccessToken
270
281
  ```
271
282
 
272
283
  ## hyperapp-is/core
@@ -1576,3 +1587,56 @@ export const subscription_nodesLifecycleByIds = function <S> (
1576
1587
  - nodes.id : ユニークID
1577
1588
  - nodes.initialize: 初期化イベント
1578
1589
  - nodes.finalize : 終了時イベント
1590
+
1591
+ ---
1592
+
1593
+ ### getGoogle
1594
+ Google GIS 変数を取得する
1595
+
1596
+ ```ts
1597
+ export const getGoogle = async (): Promise<Google>
1598
+ ```
1599
+
1600
+ `<script src="https://accounts.google.com/gsi/client">` を読み込み、`window.google`の値(Promise結果)返却
1601
+
1602
+ ---
1603
+
1604
+ ### googleAuth
1605
+ グーグル認証を行い `{ idToken: string, user: GoogleUser }` を取得します
1606
+
1607
+ ```ts
1608
+ export const googleAuth = async (config: GoogleAuthConfig): Promise<GoogleAuthResult> =>
1609
+ ```
1610
+
1611
+ ```ts
1612
+ export interface GoogleAuthConfig {
1613
+ clientId : string
1614
+ autoSelect?: boolean // default: true
1615
+ uxMode ?: "popup" | "redirect" // default: "popup"
1616
+ }
1617
+ ```
1618
+
1619
+ - clientId : アプリケーションのID (https://console.cloud.google.com で作成)
1620
+ - autoSelect?: ユーザーが選択されていた場合、自動でログイン
1621
+ - uxMode ?: ポップアップ、もしくはリダイレクトでログインします
1622
+
1623
+ ---
1624
+
1625
+ ### getAccessToken
1626
+ Googleのaccess token を取得
1627
+
1628
+ ```ts
1629
+ export const getAccessToken = (config: GetAccessTokenConfig): Promise<string>
1630
+ ```
1631
+
1632
+ ```ts
1633
+ export interface GetAccessTokenConfig {
1634
+ clientId: string
1635
+ scope : GoogleScope[]
1636
+ prompt ?: "none" | "select_account" | "consent" // default: "select_account"
1637
+ }
1638
+ ```
1639
+
1640
+ - clientId: アプリケーションのID
1641
+ - scope : スコープの配列
1642
+ - prompt ?: ログイン制御 `none` の場合、先にログインしていなければエラーとなります
@@ -1,5 +1,6 @@
1
1
  // hyperapp-is / core / navigator.ts
2
2
  import { getValue, setValue, getLocalState, setLocalState, createLocalKey, } from "./state";
3
+ import { HistoryInput } from "./component";
3
4
  import { getScrollMargin } from "../dom/utils";
4
5
  import { el, deleteKeys, SelectButton } from "./component";
5
6
  // ---------- ---------- ---------- ---------- ----------
@@ -255,10 +256,11 @@ export const NavigatorFinder = function (props) {
255
256
  // toolBarNode
256
257
  const toolBarNode = div({
257
258
  class: "toolBar"
258
- }, input({
259
- type: "text",
259
+ }, HistoryInput({
260
+ state,
261
+ id: `${id}_searchText`,
262
+ keyNames: [createLocalKey(id), "searchText"],
260
263
  placeholder: "search keys",
261
- value: localState.searchText,
262
264
  oninput: action_inputSearchText
263
265
  }), button({
264
266
  type: "button",
@@ -12,3 +12,5 @@ export type { CarouselState, CarouselController } from "./animationView/carousel
12
12
  export { Carousel, effect_InitCarousel } from "./animationView/carousel";
13
13
  export type { ScrollMargin, MatrixState } from "./dom/utils";
14
14
  export { getScrollMargin, getMatrixState } from "./dom/utils";
15
+ export type { GoogleAccountsId, GoogleTokenClient, GoogleAccountsOAuth2, GoogleAccounts, Google, GoogleAuthConfig, GoogleUser, GoogleAuthResult, GoogleScope, GetAccessTokenConfig } from "./services/google";
16
+ export { getGoogle, googleAuth, getAccessToken } from "./services/google";
@@ -7,3 +7,4 @@ export { progress_easing } from "./animation/easing";
7
7
  export { createUnits, createRAFProperties, effect_RAFProperties } from "./animation/properties";
8
8
  export { Carousel, effect_InitCarousel } from "./animationView/carousel";
9
9
  export { getScrollMargin, getMatrixState } from "./dom/utils";
10
+ export { getGoogle, googleAuth, getAccessToken } from "./services/google";
@@ -0,0 +1,57 @@
1
+ export interface GoogleAccountsId {
2
+ initialize(config: {
3
+ client_id: string;
4
+ auto_select?: boolean;
5
+ ux_mode?: "popup" | "redirect";
6
+ callback: (response: {
7
+ credential: string;
8
+ }) => void;
9
+ }): void;
10
+ prompt(callback?: (notification: any) => void): void;
11
+ }
12
+ export interface GoogleTokenClient {
13
+ requestAccessToken(options?: {
14
+ prompt?: "none" | "consent" | "select_account";
15
+ }): void;
16
+ }
17
+ export interface GoogleAccountsOAuth2 {
18
+ initTokenClient(config: {
19
+ client_id: string;
20
+ scope: string;
21
+ callback: (response: {
22
+ access_token?: string;
23
+ error?: string;
24
+ }) => void;
25
+ }): GoogleTokenClient;
26
+ }
27
+ export interface GoogleAccounts {
28
+ id: GoogleAccountsId;
29
+ oauth2: GoogleAccountsOAuth2;
30
+ }
31
+ export interface Google {
32
+ accounts: GoogleAccounts;
33
+ }
34
+ export declare const getGoogle: () => Promise<Google>;
35
+ export interface GoogleAuthConfig {
36
+ clientId: string;
37
+ autoSelect?: boolean;
38
+ uxMode?: "popup" | "redirect";
39
+ }
40
+ export interface GoogleUser {
41
+ name: string;
42
+ email: string;
43
+ picture: string;
44
+ sub: string;
45
+ }
46
+ export interface GoogleAuthResult {
47
+ idToken: string;
48
+ user: GoogleUser;
49
+ }
50
+ export declare const googleAuth: (config: GoogleAuthConfig) => Promise<GoogleAuthResult>;
51
+ export type GoogleScope = "openid" | "email" | "profile" | "https://www.googleapis.com/auth/drive" | "https://www.googleapis.com/auth/drive.readonly" | "https://www.googleapis.com/auth/drive.file" | "https://www.googleapis.com/auth/drive.metadata.readonly" | "https://www.googleapis.com/auth/drive.appdata" | "https://www.googleapis.com/auth/calendar" | "https://www.googleapis.com/auth/calendar.readonly" | "https://www.googleapis.com/auth/calendar.events" | "https://www.googleapis.com/auth/calendar.events.readonly" | "https://www.googleapis.com/auth/gmail.readonly" | "https://www.googleapis.com/auth/gmail.modify" | "https://www.googleapis.com/auth/gmail.send" | "https://www.googleapis.com/auth/gmail.compose" | "https://www.googleapis.com/auth/gmail.labels" | "https://www.googleapis.com/auth/spreadsheets" | "https://www.googleapis.com/auth/spreadsheets.readonly" | "https://www.googleapis.com/auth/documents" | "https://www.googleapis.com/auth/documents.readonly" | "https://www.googleapis.com/auth/presentations" | "https://www.googleapis.com/auth/presentations.readonly" | "https://www.googleapis.com/auth/forms" | "https://www.googleapis.com/auth/forms.responses.readonly" | "https://www.googleapis.com/auth/youtube.readonly" | "https://www.googleapis.com/auth/youtube" | "https://www.googleapis.com/auth/youtube.upload" | "https://www.googleapis.com/auth/youtube.force-ssl" | "https://www.googleapis.com/auth/userinfo.email" | "https://www.googleapis.com/auth/userinfo.profile" | (string & {});
52
+ export interface GetAccessTokenConfig {
53
+ clientId: string;
54
+ scope: GoogleScope[];
55
+ prompt?: "none" | "select_account" | "consent";
56
+ }
57
+ export declare const getAccessToken: (config: GetAccessTokenConfig) => Promise<string>;
@@ -0,0 +1,117 @@
1
+ // ---------- ---------- ----------
2
+ // interface GoogleAccountsId
3
+ // ---------- ---------- ----------
4
+ // ---------- ---------- ----------
5
+ // getGoogle
6
+ // ---------- ---------- ----------
7
+ // 2重読み込み防止用の変数
8
+ let googlePromise = null;
9
+ // google 変数を取得する
10
+ export const getGoogle = async () => {
11
+ if (window.google)
12
+ return window.google;
13
+ if (googlePromise)
14
+ return googlePromise;
15
+ googlePromise = new Promise((resolve, reject) => {
16
+ const script = document.createElement("script");
17
+ script.src = "https://accounts.google.com/gsi/client";
18
+ // success
19
+ script.addEventListener("load", () => {
20
+ const result = window.google;
21
+ if (result) {
22
+ resolve(result);
23
+ }
24
+ else {
25
+ reject(new Error("error: loadGoogle: 001"));
26
+ }
27
+ });
28
+ // error
29
+ script.addEventListener("error", () => {
30
+ reject(new Error("error: loadGoogle: 002"));
31
+ });
32
+ // append child
33
+ document.body.appendChild(script);
34
+ });
35
+ return googlePromise;
36
+ };
37
+ // ---------- ---------- ---------- ---------- ----------
38
+ // googleAuth
39
+ // ---------- ---------- ---------- ---------- ----------
40
+ export const googleAuth = async (config) => {
41
+ var _a, _b;
42
+ // get google
43
+ const google = await getGoogle();
44
+ // variable
45
+ const autoSelect = (_a = config.autoSelect) !== null && _a !== void 0 ? _a : true;
46
+ const uxMode = (_b = config.uxMode) !== null && _b !== void 0 ? _b : "popup";
47
+ // result
48
+ return new Promise((resolve, reject) => {
49
+ // get client
50
+ const client = google.accounts.id;
51
+ // initialize
52
+ client.initialize({
53
+ client_id: config.clientId,
54
+ auto_select: autoSelect,
55
+ ux_mode: uxMode,
56
+ callback: (response) => {
57
+ try {
58
+ const idToken = response.credential;
59
+ const base64 = idToken.split(".")[1]
60
+ .replace(/-/g, "+")
61
+ .replace(/_/g, "/");
62
+ const decode = (str) => decodeURIComponent(atob(str)
63
+ .split("")
64
+ .map(c => "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2))
65
+ .join(""));
66
+ const payload = JSON.parse(decode(base64));
67
+ const user = {
68
+ name: payload.name,
69
+ email: payload.email,
70
+ picture: payload.picture,
71
+ sub: payload.sub
72
+ };
73
+ resolve({ idToken, user });
74
+ }
75
+ catch (error) {
76
+ reject(error);
77
+ }
78
+ }
79
+ }); // end initialize
80
+ // show prompt
81
+ client.prompt();
82
+ }); // end result
83
+ };
84
+ // ---------- ---------- ---------- ---------- ----------
85
+ // getAccessToken
86
+ // ---------- ---------- ---------- ---------- ----------
87
+ export const getAccessToken = (config) => new Promise((resolve, reject) => {
88
+ var _a;
89
+ // get google
90
+ const google = window.google;
91
+ if (!google) {
92
+ reject(new Error("error: Google SDK not loaded. Call getGoogle() before getAccessToken()."));
93
+ return;
94
+ }
95
+ // variable
96
+ const prompt = (_a = config.prompt) !== null && _a !== void 0 ? _a : "select_account";
97
+ // initialize
98
+ const tokenClient = google.accounts.oauth2.initTokenClient({
99
+ client_id: config.clientId,
100
+ scope: config.scope.join(" "),
101
+ callback: (response) => {
102
+ if (response.error) {
103
+ reject(response);
104
+ }
105
+ else {
106
+ if (response.access_token) {
107
+ resolve(response.access_token);
108
+ }
109
+ else {
110
+ reject(new Error("No access_token"));
111
+ }
112
+ }
113
+ }
114
+ }); // end initialize
115
+ // request AccessToken
116
+ tokenClient.requestAccessToken({ prompt }); // prompt == "none" のときには、事前にログインが必要
117
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hyperapp-is",
3
- "version": "0.1.31",
3
+ "version": "0.1.33",
4
4
  "description": "UI foundation library for Hyperapp by is4416",
5
5
  "license": "MIT",
6
6
  "type": "module",