connectbase-client 0.12.2 → 0.13.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/dist/index.js CHANGED
@@ -37,10 +37,12 @@ module.exports = __toCommonJS(index_exports);
37
37
 
38
38
  // src/types/error.ts
39
39
  var ApiError = class extends Error {
40
- constructor(statusCode, message) {
40
+ constructor(statusCode, message, code, details) {
41
41
  super(message);
42
42
  this.statusCode = statusCode;
43
43
  this.name = "ApiError";
44
+ this.code = code;
45
+ this.details = details;
44
46
  }
45
47
  };
46
48
  var AuthError = class extends Error {
@@ -193,7 +195,17 @@ var HttpClient = class {
193
195
  const errorData = await response.json().catch(() => ({
194
196
  message: response.statusText
195
197
  }));
196
- throw new ApiError(response.status, errorData.message || errorData.error || "Unknown error");
198
+ const rawError = errorData.error;
199
+ if (rawError && typeof rawError === "object" && "message" in rawError) {
200
+ throw new ApiError(
201
+ response.status,
202
+ rawError.message || "Unknown error",
203
+ rawError.code,
204
+ rawError.details
205
+ );
206
+ }
207
+ const message = typeof rawError === "string" ? rawError : errorData.message || "Unknown error";
208
+ throw new ApiError(response.status, message);
197
209
  }
198
210
  if (response.status === 204 || response.headers.get("content-length") === "0") {
199
211
  return {};
@@ -550,10 +562,15 @@ var DatabaseAPI = class {
550
562
  this.http = http;
551
563
  }
552
564
  /**
553
- * API Key 인증 시 /v1/public 접두사 반환
565
+ * Database 공개 API 접두사.
566
+ *
567
+ * 서버의 테이블/컬럼/데이터 CRUD 는 모두 `/v1/public/*` 경로에서만 제공되며
568
+ * (core-server → data-server 프록시), JWT 기반 `/v1/*` 경로는 존재하지 않습니다.
569
+ * 따라서 항상 `/v1/public` 을 사용합니다. 인증은 `X-Public-Key` 헤더에
570
+ * `publicKey` (`cb_pk_*`) 를 실어 서버가 검증합니다.
554
571
  */
555
572
  getPublicPrefix() {
556
- return this.http.hasPublicKey() ? "/v1/public" : "/v1";
573
+ return "/v1/public";
557
574
  }
558
575
  // ============ Table Methods ============
559
576
  /**
@@ -574,18 +591,39 @@ var DatabaseAPI = class {
574
591
  return this.http.get(`${prefix}/tables/${tableId}`);
575
592
  }
576
593
  /**
577
- * 테이블 생성
594
+ * 테이블 생성.
595
+ *
596
+ * 서버 DTO (`{title, schema, access_level}`) 로 변환하여 전송합니다.
597
+ * `schema` 가 비어있으면 요청 본문에서 키 자체를 생략하여 빈 테이블을
598
+ * 생성합니다. (서버는 explicit 빈 맵을 거부)
599
+ *
600
+ * 서버는 `{message}` 만 돌려주므로 반환 타입은 `void` 입니다.
601
+ * 생성된 테이블 메타데이터가 필요하면 이어서 `getTables()` 로 조회하세요.
578
602
  */
579
603
  async createTable(data) {
580
604
  const prefix = this.getPublicPrefix();
581
- return this.http.post(`${prefix}/tables`, data);
605
+ const body = {
606
+ title: data.name,
607
+ access_level: data.accessLevel ?? "Creator"
608
+ };
609
+ if (data.schema && Object.keys(data.schema).length > 0) {
610
+ body.schema = data.schema;
611
+ }
612
+ await this.http.post(`${prefix}/tables`, body);
582
613
  }
583
614
  /**
584
- * 테이블 수정
615
+ * 테이블 수정.
616
+ *
617
+ * `name` 은 서버의 `title` 로, `accessLevel` 은 `access_level` 로 매핑됩니다.
585
618
  */
586
619
  async updateTable(tableId, data) {
587
620
  const prefix = this.getPublicPrefix();
588
- await this.http.patch(`${prefix}/tables/${tableId}`, data);
621
+ const body = {};
622
+ if (data.name !== void 0) body.title = data.name;
623
+ if (data.schema !== void 0) body.schema = data.schema;
624
+ if (data.accessLevel !== void 0) body.access_level = data.accessLevel;
625
+ if (data.description !== void 0) body.description = data.description;
626
+ await this.http.patch(`${prefix}/tables/${tableId}`, body);
589
627
  }
590
628
  /**
591
629
  * 테이블 삭제
@@ -594,48 +632,139 @@ var DatabaseAPI = class {
594
632
  const prefix = this.getPublicPrefix();
595
633
  await this.http.delete(`${prefix}/tables/${tableId}`);
596
634
  }
635
+ // ============ Validation Schema Methods (table-level 검증 규칙) ============
636
+ /**
637
+ * 테이블 검증 스키마 조회.
638
+ *
639
+ * 검증 스키마가 설정되어 있지 않으면 `null` 을 반환합니다.
640
+ * Public Key 인증으로 호출 가능 (조회 권한).
641
+ */
642
+ async getValidationSchema(tableId) {
643
+ const prefix = this.getPublicPrefix();
644
+ const response = await this.http.get(
645
+ `${prefix}/tables/${tableId}/validation-schema`
646
+ );
647
+ return response.validation_schema;
648
+ }
649
+ /**
650
+ * 테이블 검증 스키마 설정/교체.
651
+ *
652
+ * **권한**: 콘솔 (앱 소유자 JWT) 전용. Public Key 로는 설정 불가.
653
+ * SDK 에서는 `accessToken` 이 설정되어 있어야 하며, 콘솔에서 사용하는 패턴입니다.
654
+ *
655
+ * 빈 fields 는 거부됩니다. 검증 스키마를 제거하려면 `deleteValidationSchema` 사용.
656
+ *
657
+ * @example
658
+ * ```ts
659
+ * await cb.database.setValidationSchema(tableId, {
660
+ * fields: {
661
+ * email: { type: 'string', pattern: '^.+@.+$', required: true },
662
+ * age: { type: 'int', min: 0, max: 150 }
663
+ * },
664
+ * required: ['email'],
665
+ * immutable: ['email']
666
+ * })
667
+ * ```
668
+ */
669
+ async setValidationSchema(tableId, schema) {
670
+ await this.http.put(
671
+ `/v1/apps/${this.requireAppId()}/databases/tables/${tableId}/validation-schema`,
672
+ { validation_schema: schema }
673
+ );
674
+ }
675
+ /**
676
+ * 테이블 검증 스키마 제거 (schemaless 모드로 복귀).
677
+ *
678
+ * **권한**: 콘솔 (앱 소유자 JWT) 전용.
679
+ */
680
+ async deleteValidationSchema(tableId) {
681
+ await this.http.delete(
682
+ `/v1/apps/${this.requireAppId()}/databases/tables/${tableId}/validation-schema`
683
+ );
684
+ }
685
+ /**
686
+ * appId 가 설정되어 있어야 콘솔 경로를 호출할 수 있습니다 (validation_schema set/delete).
687
+ */
688
+ requireAppId() {
689
+ const appId = this.http.config?.appId;
690
+ if (!appId) {
691
+ throw new Error(
692
+ "setValidationSchema/deleteValidationSchema \uB294 \uCF58\uC194 (JWT) \uC778\uC99D\uC774 \uD544\uC694\uD558\uBA70 ConnectBase config \uC5D0 appId \uAC00 \uC124\uC815\uB418\uC5B4\uC57C \uD569\uB2C8\uB2E4."
693
+ );
694
+ }
695
+ return appId;
696
+ }
597
697
  // ============ Column Methods ============
598
698
  /**
599
- * 컬럼 목록 조회 (Table.schema에서 추출)
699
+ * 컬럼 목록 조회 (`Table.schema` 맵을 컬럼 객체 배열로 변환).
700
+ *
701
+ * 서버는 컬럼을 다음 두 가지 중 하나로 저장합니다:
702
+ * - 플랫: `"email": "string"` (추가 속성이 없는 경우)
703
+ * - 중첩: `"email": { "type": "string", "required": true, ... }` (추가 속성이 있는 경우)
704
+ *
705
+ * `$required` 키는 별도 배열로 필수 컬럼을 지정할 수 있으며, 중첩 객체의
706
+ * `required: true` 와 병합되어 판정됩니다.
600
707
  */
601
708
  async getColumns(tableId) {
602
709
  const table = await this.getTable(tableId);
603
- const schema = table.schema;
604
- if (!schema) return [];
710
+ const schema = table.schema ?? {};
711
+ const requiredSet = new Set(
712
+ Array.isArray(schema.$required) ? schema.$required : []
713
+ );
605
714
  const columns = [];
715
+ let order = 0;
606
716
  for (const [name, def] of Object.entries(schema)) {
607
- if (name.startsWith("$")) continue;
608
- const colDef = def;
717
+ if (name.startsWith("$") || def === void 0) continue;
718
+ if (Array.isArray(def)) continue;
719
+ let data_type = "string";
720
+ let is_required = requiredSet.has(name);
721
+ let default_value;
722
+ let description;
723
+ let encrypted;
724
+ if (typeof def === "string") {
725
+ data_type = def;
726
+ } else {
727
+ data_type = def.type;
728
+ if (def.required === true) is_required = true;
729
+ if (def.default !== void 0) default_value = def.default;
730
+ if (def.description !== void 0) description = def.description;
731
+ if (def.encrypted !== void 0) encrypted = def.encrypted;
732
+ }
609
733
  columns.push({
610
734
  id: name,
611
735
  name,
612
- data_type: colDef.type || "string",
613
- is_required: colDef.required || false,
614
- default_value: colDef.default,
615
- description: colDef.description,
616
- encrypted: colDef.encrypted,
617
- order: 0,
618
- created_at: ""
736
+ data_type,
737
+ is_required,
738
+ default_value,
739
+ description,
740
+ encrypted,
741
+ order: order++,
742
+ created_at: table.created_at
619
743
  });
620
744
  }
621
745
  return columns;
622
746
  }
623
747
  /**
624
- * 컬럼 생성
748
+ * 컬럼 생성.
749
+ *
750
+ * 서버는 `{message}` 만 돌려주므로 반환 타입은 `void` 입니다.
751
+ * 생성 결과 컬럼을 얻으려면 이어서 `getColumns(tableId)` 로 조회하세요.
625
752
  */
626
753
  async createColumn(tableId, data) {
627
754
  const prefix = this.getPublicPrefix();
628
- return this.http.post(
755
+ await this.http.post(
629
756
  `${prefix}/tables/${tableId}/columns`,
630
757
  data
631
758
  );
632
759
  }
633
760
  /**
634
- * 컬럼 수정
761
+ * 컬럼 수정.
762
+ *
763
+ * 서버는 `{message}` 만 돌려주므로 반환 타입은 `void` 입니다.
635
764
  */
636
765
  async updateColumn(tableId, columnName, data) {
637
766
  const prefix = this.getPublicPrefix();
638
- return this.http.patch(
767
+ await this.http.patch(
639
768
  `${prefix}/tables/${tableId}/columns/${columnName}`,
640
769
  data
641
770
  );
@@ -689,11 +818,27 @@ var DatabaseAPI = class {
689
818
  return this.http.get(`${prefix}/tables/${tableId}/data/${dataId}`);
690
819
  }
691
820
  /**
692
- * 데이터 생성
821
+ * 데이터 생성.
822
+ *
823
+ * `tableIdOrName` 은 테이블 UUID 또는 이름. UUID 형식이면 기존 경로
824
+ * (`/tables/:tableId/data`), 그렇지 않으면 이름 기반 경로
825
+ * (`/tables/name/:tableName/data`) 를 사용합니다.
826
+ *
827
+ * `options.autoCreate: true` 시 테이블이 없으면 빈 schemaless 테이블을
828
+ * 자동으로 생성한 뒤 insert. opt-in 이며 프로토타입/AI 자동화 워크플로에
829
+ * 권장합니다. production 앱은 명시적 `createTable` 호출 권장.
693
830
  */
694
- async createData(tableId, data) {
831
+ async createData(tableIdOrName, data, options) {
695
832
  const prefix = this.getPublicPrefix();
696
- return this.http.post(`${prefix}/tables/${tableId}/data`, data);
833
+ const isUUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(tableIdOrName);
834
+ if (isUUID) {
835
+ return this.http.post(`${prefix}/tables/${tableIdOrName}/data`, data);
836
+ }
837
+ const query = options?.autoCreate ? "?auto_create=true" : "";
838
+ return this.http.post(
839
+ `${prefix}/tables/name/${encodeURIComponent(tableIdOrName)}/data${query}`,
840
+ data
841
+ );
697
842
  }
698
843
  /**
699
844
  * 데이터 수정 (부분 업데이트)
package/dist/index.mjs CHANGED
@@ -1,9 +1,11 @@
1
1
  // src/types/error.ts
2
2
  var ApiError = class extends Error {
3
- constructor(statusCode, message) {
3
+ constructor(statusCode, message, code, details) {
4
4
  super(message);
5
5
  this.statusCode = statusCode;
6
6
  this.name = "ApiError";
7
+ this.code = code;
8
+ this.details = details;
7
9
  }
8
10
  };
9
11
  var AuthError = class extends Error {
@@ -156,7 +158,17 @@ var HttpClient = class {
156
158
  const errorData = await response.json().catch(() => ({
157
159
  message: response.statusText
158
160
  }));
159
- throw new ApiError(response.status, errorData.message || errorData.error || "Unknown error");
161
+ const rawError = errorData.error;
162
+ if (rawError && typeof rawError === "object" && "message" in rawError) {
163
+ throw new ApiError(
164
+ response.status,
165
+ rawError.message || "Unknown error",
166
+ rawError.code,
167
+ rawError.details
168
+ );
169
+ }
170
+ const message = typeof rawError === "string" ? rawError : errorData.message || "Unknown error";
171
+ throw new ApiError(response.status, message);
160
172
  }
161
173
  if (response.status === 204 || response.headers.get("content-length") === "0") {
162
174
  return {};
@@ -513,10 +525,15 @@ var DatabaseAPI = class {
513
525
  this.http = http;
514
526
  }
515
527
  /**
516
- * API Key 인증 시 /v1/public 접두사 반환
528
+ * Database 공개 API 접두사.
529
+ *
530
+ * 서버의 테이블/컬럼/데이터 CRUD 는 모두 `/v1/public/*` 경로에서만 제공되며
531
+ * (core-server → data-server 프록시), JWT 기반 `/v1/*` 경로는 존재하지 않습니다.
532
+ * 따라서 항상 `/v1/public` 을 사용합니다. 인증은 `X-Public-Key` 헤더에
533
+ * `publicKey` (`cb_pk_*`) 를 실어 서버가 검증합니다.
517
534
  */
518
535
  getPublicPrefix() {
519
- return this.http.hasPublicKey() ? "/v1/public" : "/v1";
536
+ return "/v1/public";
520
537
  }
521
538
  // ============ Table Methods ============
522
539
  /**
@@ -537,18 +554,39 @@ var DatabaseAPI = class {
537
554
  return this.http.get(`${prefix}/tables/${tableId}`);
538
555
  }
539
556
  /**
540
- * 테이블 생성
557
+ * 테이블 생성.
558
+ *
559
+ * 서버 DTO (`{title, schema, access_level}`) 로 변환하여 전송합니다.
560
+ * `schema` 가 비어있으면 요청 본문에서 키 자체를 생략하여 빈 테이블을
561
+ * 생성합니다. (서버는 explicit 빈 맵을 거부)
562
+ *
563
+ * 서버는 `{message}` 만 돌려주므로 반환 타입은 `void` 입니다.
564
+ * 생성된 테이블 메타데이터가 필요하면 이어서 `getTables()` 로 조회하세요.
541
565
  */
542
566
  async createTable(data) {
543
567
  const prefix = this.getPublicPrefix();
544
- return this.http.post(`${prefix}/tables`, data);
568
+ const body = {
569
+ title: data.name,
570
+ access_level: data.accessLevel ?? "Creator"
571
+ };
572
+ if (data.schema && Object.keys(data.schema).length > 0) {
573
+ body.schema = data.schema;
574
+ }
575
+ await this.http.post(`${prefix}/tables`, body);
545
576
  }
546
577
  /**
547
- * 테이블 수정
578
+ * 테이블 수정.
579
+ *
580
+ * `name` 은 서버의 `title` 로, `accessLevel` 은 `access_level` 로 매핑됩니다.
548
581
  */
549
582
  async updateTable(tableId, data) {
550
583
  const prefix = this.getPublicPrefix();
551
- await this.http.patch(`${prefix}/tables/${tableId}`, data);
584
+ const body = {};
585
+ if (data.name !== void 0) body.title = data.name;
586
+ if (data.schema !== void 0) body.schema = data.schema;
587
+ if (data.accessLevel !== void 0) body.access_level = data.accessLevel;
588
+ if (data.description !== void 0) body.description = data.description;
589
+ await this.http.patch(`${prefix}/tables/${tableId}`, body);
552
590
  }
553
591
  /**
554
592
  * 테이블 삭제
@@ -557,48 +595,139 @@ var DatabaseAPI = class {
557
595
  const prefix = this.getPublicPrefix();
558
596
  await this.http.delete(`${prefix}/tables/${tableId}`);
559
597
  }
598
+ // ============ Validation Schema Methods (table-level 검증 규칙) ============
599
+ /**
600
+ * 테이블 검증 스키마 조회.
601
+ *
602
+ * 검증 스키마가 설정되어 있지 않으면 `null` 을 반환합니다.
603
+ * Public Key 인증으로 호출 가능 (조회 권한).
604
+ */
605
+ async getValidationSchema(tableId) {
606
+ const prefix = this.getPublicPrefix();
607
+ const response = await this.http.get(
608
+ `${prefix}/tables/${tableId}/validation-schema`
609
+ );
610
+ return response.validation_schema;
611
+ }
612
+ /**
613
+ * 테이블 검증 스키마 설정/교체.
614
+ *
615
+ * **권한**: 콘솔 (앱 소유자 JWT) 전용. Public Key 로는 설정 불가.
616
+ * SDK 에서는 `accessToken` 이 설정되어 있어야 하며, 콘솔에서 사용하는 패턴입니다.
617
+ *
618
+ * 빈 fields 는 거부됩니다. 검증 스키마를 제거하려면 `deleteValidationSchema` 사용.
619
+ *
620
+ * @example
621
+ * ```ts
622
+ * await cb.database.setValidationSchema(tableId, {
623
+ * fields: {
624
+ * email: { type: 'string', pattern: '^.+@.+$', required: true },
625
+ * age: { type: 'int', min: 0, max: 150 }
626
+ * },
627
+ * required: ['email'],
628
+ * immutable: ['email']
629
+ * })
630
+ * ```
631
+ */
632
+ async setValidationSchema(tableId, schema) {
633
+ await this.http.put(
634
+ `/v1/apps/${this.requireAppId()}/databases/tables/${tableId}/validation-schema`,
635
+ { validation_schema: schema }
636
+ );
637
+ }
638
+ /**
639
+ * 테이블 검증 스키마 제거 (schemaless 모드로 복귀).
640
+ *
641
+ * **권한**: 콘솔 (앱 소유자 JWT) 전용.
642
+ */
643
+ async deleteValidationSchema(tableId) {
644
+ await this.http.delete(
645
+ `/v1/apps/${this.requireAppId()}/databases/tables/${tableId}/validation-schema`
646
+ );
647
+ }
648
+ /**
649
+ * appId 가 설정되어 있어야 콘솔 경로를 호출할 수 있습니다 (validation_schema set/delete).
650
+ */
651
+ requireAppId() {
652
+ const appId = this.http.config?.appId;
653
+ if (!appId) {
654
+ throw new Error(
655
+ "setValidationSchema/deleteValidationSchema \uB294 \uCF58\uC194 (JWT) \uC778\uC99D\uC774 \uD544\uC694\uD558\uBA70 ConnectBase config \uC5D0 appId \uAC00 \uC124\uC815\uB418\uC5B4\uC57C \uD569\uB2C8\uB2E4."
656
+ );
657
+ }
658
+ return appId;
659
+ }
560
660
  // ============ Column Methods ============
561
661
  /**
562
- * 컬럼 목록 조회 (Table.schema에서 추출)
662
+ * 컬럼 목록 조회 (`Table.schema` 맵을 컬럼 객체 배열로 변환).
663
+ *
664
+ * 서버는 컬럼을 다음 두 가지 중 하나로 저장합니다:
665
+ * - 플랫: `"email": "string"` (추가 속성이 없는 경우)
666
+ * - 중첩: `"email": { "type": "string", "required": true, ... }` (추가 속성이 있는 경우)
667
+ *
668
+ * `$required` 키는 별도 배열로 필수 컬럼을 지정할 수 있으며, 중첩 객체의
669
+ * `required: true` 와 병합되어 판정됩니다.
563
670
  */
564
671
  async getColumns(tableId) {
565
672
  const table = await this.getTable(tableId);
566
- const schema = table.schema;
567
- if (!schema) return [];
673
+ const schema = table.schema ?? {};
674
+ const requiredSet = new Set(
675
+ Array.isArray(schema.$required) ? schema.$required : []
676
+ );
568
677
  const columns = [];
678
+ let order = 0;
569
679
  for (const [name, def] of Object.entries(schema)) {
570
- if (name.startsWith("$")) continue;
571
- const colDef = def;
680
+ if (name.startsWith("$") || def === void 0) continue;
681
+ if (Array.isArray(def)) continue;
682
+ let data_type = "string";
683
+ let is_required = requiredSet.has(name);
684
+ let default_value;
685
+ let description;
686
+ let encrypted;
687
+ if (typeof def === "string") {
688
+ data_type = def;
689
+ } else {
690
+ data_type = def.type;
691
+ if (def.required === true) is_required = true;
692
+ if (def.default !== void 0) default_value = def.default;
693
+ if (def.description !== void 0) description = def.description;
694
+ if (def.encrypted !== void 0) encrypted = def.encrypted;
695
+ }
572
696
  columns.push({
573
697
  id: name,
574
698
  name,
575
- data_type: colDef.type || "string",
576
- is_required: colDef.required || false,
577
- default_value: colDef.default,
578
- description: colDef.description,
579
- encrypted: colDef.encrypted,
580
- order: 0,
581
- created_at: ""
699
+ data_type,
700
+ is_required,
701
+ default_value,
702
+ description,
703
+ encrypted,
704
+ order: order++,
705
+ created_at: table.created_at
582
706
  });
583
707
  }
584
708
  return columns;
585
709
  }
586
710
  /**
587
- * 컬럼 생성
711
+ * 컬럼 생성.
712
+ *
713
+ * 서버는 `{message}` 만 돌려주므로 반환 타입은 `void` 입니다.
714
+ * 생성 결과 컬럼을 얻으려면 이어서 `getColumns(tableId)` 로 조회하세요.
588
715
  */
589
716
  async createColumn(tableId, data) {
590
717
  const prefix = this.getPublicPrefix();
591
- return this.http.post(
718
+ await this.http.post(
592
719
  `${prefix}/tables/${tableId}/columns`,
593
720
  data
594
721
  );
595
722
  }
596
723
  /**
597
- * 컬럼 수정
724
+ * 컬럼 수정.
725
+ *
726
+ * 서버는 `{message}` 만 돌려주므로 반환 타입은 `void` 입니다.
598
727
  */
599
728
  async updateColumn(tableId, columnName, data) {
600
729
  const prefix = this.getPublicPrefix();
601
- return this.http.patch(
730
+ await this.http.patch(
602
731
  `${prefix}/tables/${tableId}/columns/${columnName}`,
603
732
  data
604
733
  );
@@ -652,11 +781,27 @@ var DatabaseAPI = class {
652
781
  return this.http.get(`${prefix}/tables/${tableId}/data/${dataId}`);
653
782
  }
654
783
  /**
655
- * 데이터 생성
784
+ * 데이터 생성.
785
+ *
786
+ * `tableIdOrName` 은 테이블 UUID 또는 이름. UUID 형식이면 기존 경로
787
+ * (`/tables/:tableId/data`), 그렇지 않으면 이름 기반 경로
788
+ * (`/tables/name/:tableName/data`) 를 사용합니다.
789
+ *
790
+ * `options.autoCreate: true` 시 테이블이 없으면 빈 schemaless 테이블을
791
+ * 자동으로 생성한 뒤 insert. opt-in 이며 프로토타입/AI 자동화 워크플로에
792
+ * 권장합니다. production 앱은 명시적 `createTable` 호출 권장.
656
793
  */
657
- async createData(tableId, data) {
794
+ async createData(tableIdOrName, data, options) {
658
795
  const prefix = this.getPublicPrefix();
659
- return this.http.post(`${prefix}/tables/${tableId}/data`, data);
796
+ const isUUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(tableIdOrName);
797
+ if (isUUID) {
798
+ return this.http.post(`${prefix}/tables/${tableIdOrName}/data`, data);
799
+ }
800
+ const query = options?.autoCreate ? "?auto_create=true" : "";
801
+ return this.http.post(
802
+ `${prefix}/tables/name/${encodeURIComponent(tableIdOrName)}/data${query}`,
803
+ data
804
+ );
660
805
  }
661
806
  /**
662
807
  * 데이터 수정 (부분 업데이트)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "connectbase-client",
3
- "version": "0.12.2",
3
+ "version": "0.13.0",
4
4
  "description": "Connect Base JavaScript/TypeScript SDK for browser and Node.js",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,6 +33,7 @@
33
33
  "build": "tsup",
34
34
  "dev": "tsup --watch",
35
35
  "typecheck": "tsc --noEmit",
36
+ "test:types": "tsc --noEmit -p test/tsconfig.json",
36
37
  "release": "pnpm build && npm publish --access public"
37
38
  },
38
39
  "keywords": [