@ramathibodi/nuxt-commons 4.0.3 → 4.0.4

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
@@ -107,6 +107,11 @@ npm run lint
107
107
  npm run test
108
108
  ```
109
109
 
110
+ ## Concepts
111
+
112
+ - [Model Components — Endpoint Reference](docs/model-endpoints.md) — how `modelName` translates to GraphQL operations and REST API endpoints, with body/response shapes and the `By<Qualifier>` rule for `model/*` components.
113
+ - [Document Template JSON Spec](docs/document-template-json-spec.md) — schema and conventions for document templates.
114
+
110
115
  ## Documentation
111
116
 
112
117
  Generate documentation artifacts from source:
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": "^4.3.1"
6
6
  },
7
- "version": "4.0.3",
7
+ "version": "4.0.4",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
@@ -1,15 +1,16 @@
1
1
  import type { FormDialogCallback } from '../types/formDialog.js';
2
2
  import { type GraphqlModelConfigProps } from './graphqlModelOperation.js';
3
- interface ApiHeaderProps {
4
- headers?: any[];
5
- }
6
- interface ApiInitialDataProps {
7
- initialData?: Record<string, any>;
8
- }
3
+ import type { HeaderProps, InitialDataProps } from './graphqlModel.js';
9
4
  export interface ApiModelProps {
10
5
  api?: boolean;
11
6
  }
12
- export type ApiModelComposableProps = GraphqlModelConfigProps & Partial<ApiHeaderProps> & Partial<ApiInitialDataProps>;
7
+ export type ApiModelComposableProps = GraphqlModelConfigProps & Partial<HeaderProps> & Partial<InitialDataProps>;
8
+ /**
9
+ * Strip a `By<Qualifier>` suffix from a model name (mirrors GraphQL's
10
+ * `computedModelName` rule). Used for mutation/search endpoint resolution.
11
+ * Reads keep the full modelName so qualifiers like `ByGroupKey` survive.
12
+ */
13
+ export declare function stripModelByQualifier(modelName: string): string;
13
14
  /**
14
15
  * Build a REST API endpoint URL for a model.
15
16
  * @param modelName - The model name (e.g., 'Patient')
@@ -37,4 +38,3 @@ export declare function useApiModel<T extends ApiModelComposableProps>(props: T)
37
38
  reload: () => void;
38
39
  isLoading: import("vue").Ref<boolean, boolean>;
39
40
  };
40
- export {};
@@ -4,6 +4,9 @@ import { useAlert } from "./alert.js";
4
4
  import { useApi } from "./api.js";
5
5
  import { arrayWrap } from "../utils/array.js";
6
6
  import pLimit from "p-limit";
7
+ export function stripModelByQualifier(modelName) {
8
+ return modelName.split("By")[0].trim();
9
+ }
7
10
  export function buildApiEndpoint(modelName, action) {
8
11
  const lowercasedName = modelName.charAt(0).toLowerCase() + modelName.slice(1);
9
12
  const base = `/model/${lowercasedName}`;
@@ -46,12 +49,12 @@ export function useApiModel(props) {
46
49
  }
47
50
  return [.../* @__PURE__ */ new Set([...fieldsProps, ...tmpFields])];
48
51
  });
49
- function getModelName() {
50
- return props.modelName.split("By")[0].trim();
52
+ function mutationModelName() {
53
+ return stripModelByQualifier(props.modelName);
51
54
  }
52
55
  function createItem(item, callback, importing = false) {
53
56
  isLoading.value = true;
54
- const endpoint = buildApiEndpoint(getModelName(), "create");
57
+ const endpoint = buildApiEndpoint(mutationModelName(), "create");
55
58
  return api.postPromise(endpoint, { input: item, fields: fields.value }).then((result) => {
56
59
  if (canServerPageable.value) {
57
60
  if (!importing) loadItems(currentOptions.value);
@@ -89,7 +92,7 @@ export function useApiModel(props) {
89
92
  }
90
93
  function updateItem(item, callback) {
91
94
  isLoading.value = true;
92
- const endpoint = buildApiEndpoint(getModelName(), "update");
95
+ const endpoint = buildApiEndpoint(mutationModelName(), "update");
93
96
  return api.postPromise(endpoint, { input: item, fields: fields.value }).then((result) => {
94
97
  if (canServerPageable.value) {
95
98
  loadItems(currentOptions.value);
@@ -110,7 +113,7 @@ export function useApiModel(props) {
110
113
  }
111
114
  function deleteItem(item, callback) {
112
115
  isLoading.value = true;
113
- const endpoint = buildApiEndpoint(getModelName(), "delete");
116
+ const endpoint = buildApiEndpoint(mutationModelName(), "delete");
114
117
  return api.postPromise(endpoint, { input: item, fields: fields.value }).catch((error) => {
115
118
  alert?.addAlert({ alertType: "error", message: error?.message || String(error) });
116
119
  }).finally(() => {
@@ -121,7 +124,7 @@ export function useApiModel(props) {
121
124
  }
122
125
  function loadItems(options) {
123
126
  currentOptions.value = options;
124
- const endpoint = buildApiEndpoint(getModelName(), "pageable");
127
+ const endpoint = buildApiEndpoint(props.modelName, "pageable");
125
128
  isLoading.value = true;
126
129
  api.postPromise(
127
130
  endpoint,
@@ -148,7 +151,7 @@ export function useApiModel(props) {
148
151
  loadItems(currentOptions.value);
149
152
  } else {
150
153
  isLoading.value = true;
151
- const endpoint = buildApiEndpoint(getModelName());
154
+ const endpoint = buildApiEndpoint(props.modelName);
152
155
  api.postPromise(
153
156
  endpoint,
154
157
  { variables: props.modelBy, fields: fields.value }
@@ -1,7 +1,7 @@
1
1
  import { computed, ref, watch } from "vue";
2
2
  import { useAlert } from "./alert.js";
3
3
  import { useApi } from "./api.js";
4
- import { buildApiEndpoint } from "./apiModel.js";
4
+ import { buildApiEndpoint, stripModelByQualifier } from "./apiModel.js";
5
5
  export function useApiModelItem(props) {
6
6
  const alert = useAlert();
7
7
  const api = useApi();
@@ -38,7 +38,7 @@ export function useApiModelItem(props) {
38
38
  }
39
39
  function createItem(createItem2, callback) {
40
40
  isLoading.value = true;
41
- const endpoint = buildApiEndpoint(props.modelName, "create");
41
+ const endpoint = buildApiEndpoint(stripModelByQualifier(props.modelName), "create");
42
42
  return api.postPromise(endpoint, {
43
43
  input: createItem2,
44
44
  fields: fields.value
@@ -54,7 +54,7 @@ export function useApiModelItem(props) {
54
54
  }
55
55
  function updateItem(updateItem2, callback) {
56
56
  isLoading.value = true;
57
- const endpoint = buildApiEndpoint(props.modelName, "update");
57
+ const endpoint = buildApiEndpoint(stripModelByQualifier(props.modelName), "update");
58
58
  return api.postPromise(endpoint, {
59
59
  input: updateItem2,
60
60
  fields: fields.value
@@ -70,7 +70,7 @@ export function useApiModelItem(props) {
70
70
  }
71
71
  function deleteItem(deleteItem2, callback) {
72
72
  isLoading.value = true;
73
- const endpoint = buildApiEndpoint(props.modelName, "delete");
73
+ const endpoint = buildApiEndpoint(stripModelByQualifier(props.modelName), "delete");
74
74
  return api.postPromise(endpoint, {
75
75
  input: deleteItem2,
76
76
  fields: fields.value
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ramathibodi/nuxt-commons",
3
- "version": "4.0.3",
3
+ "version": "4.0.4",
4
4
  "description": "Ramathibodi Nuxt modules for common components",
5
5
  "repository": {
6
6
  "type": "git",