@jskit-ai/crud-server-generator 0.1.63 → 0.1.64

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.
@@ -36,7 +36,7 @@ function findRoute(routes, method, path) {
36
36
  return routes.find((route) => route.method === method && route.path === path) || null;
37
37
  }
38
38
 
39
- test("crud routes build create/update action input with explicit payload and patch keys", async () => {
39
+ test("crud routes build flattened create/update action input", async () => {
40
40
  const registeredRoutes = [];
41
41
  const router = {
42
42
  register(method, path, route, handler) {
@@ -100,12 +100,14 @@ test("crud routes build create/update action input with explicit payload and pat
100
100
 
101
101
  assert.deepEqual(calls[0].input, {
102
102
  workspaceSlug: "acme",
103
- payload: { textField: "A", dateField: "2026-03-11", numberField: 2 }
103
+ textField: "A",
104
+ dateField: "2026-03-11",
105
+ numberField: 2
104
106
  });
105
107
  assert.deepEqual(calls[1].input, {
106
108
  workspaceSlug: "acme",
107
109
  recordId: 12,
108
- patch: { textField: "Renamed" }
110
+ textField: "Renamed"
109
111
  });
110
112
  });
111
113
 
@@ -138,7 +140,7 @@ test("crud routes omit workspaceSlug for non-workspace calls and apply configure
138
140
  const createRoute = findRoute(registeredRoutes, "POST", "/api/customers");
139
141
  assert.ok(createRoute);
140
142
  assert.equal(createRoute.route.surface, "console");
141
- assert.equal(createRoute.route.paramsValidator, undefined);
143
+ assert.equal(createRoute.route.params, undefined);
142
144
 
143
145
  const calls = [];
144
146
  const executeAction = async (payload) => {
@@ -158,7 +160,9 @@ test("crud routes omit workspaceSlug for non-workspace calls and apply configure
158
160
  );
159
161
 
160
162
  assert.deepEqual(calls[0].input, {
161
- payload: { textField: "A", dateField: "2026-03-11", numberField: 2 }
163
+ textField: "A",
164
+ dateField: "2026-03-11",
165
+ numberField: 2
162
166
  });
163
167
  });
164
168
 
@@ -195,9 +199,74 @@ test("crud non-workspace record routes validate only recordId params", () => {
195
199
  assert.ok(viewRoute);
196
200
  assert.ok(updateRoute);
197
201
  assert.ok(deleteRoute);
198
- assert.equal(viewRoute.route.paramsValidator, recordIdParamsValidator);
199
- assert.equal(updateRoute.route.paramsValidator, recordIdParamsValidator);
200
- assert.equal(deleteRoute.route.paramsValidator, recordIdParamsValidator);
202
+ assert.equal(viewRoute.route.params, recordIdParamsValidator);
203
+ assert.equal(updateRoute.route.params, recordIdParamsValidator);
204
+ assert.equal(deleteRoute.route.params, recordIdParamsValidator);
205
+ });
206
+
207
+ test("crud routes register JSON:API transport contracts and delete replies with 204", async () => {
208
+ const registeredRoutes = [];
209
+ const router = {
210
+ register(method, path, route, handler) {
211
+ registeredRoutes.push({
212
+ method,
213
+ path,
214
+ route,
215
+ handler
216
+ });
217
+ }
218
+ };
219
+ const app = {
220
+ make(token) {
221
+ if (token !== "jskit.http.router") {
222
+ throw new Error(`Unexpected token: ${String(token)}`);
223
+ }
224
+ return router;
225
+ }
226
+ };
227
+
228
+ registerWorkspaceRoutes(app, {
229
+ routeRelativePath: "/customers"
230
+ });
231
+
232
+ const workspaceRouteBase = resolveScopedApiBasePath({
233
+ routeBase: "/w/:workspaceSlug",
234
+ relativePath: "/customers",
235
+ strictParams: false
236
+ });
237
+ const listRoute = findRoute(registeredRoutes, "GET", workspaceRouteBase);
238
+ const viewRoute = findRoute(registeredRoutes, "GET", `${workspaceRouteBase}/:recordId`);
239
+ const createRoute = findRoute(registeredRoutes, "POST", workspaceRouteBase);
240
+ const updateRoute = findRoute(registeredRoutes, "PATCH", `${workspaceRouteBase}/:recordId`);
241
+ const deleteRoute = findRoute(registeredRoutes, "DELETE", `${workspaceRouteBase}/:recordId`);
242
+
243
+ assert.ok(listRoute);
244
+ assert.ok(viewRoute);
245
+ assert.ok(createRoute);
246
+ assert.ok(updateRoute);
247
+ assert.ok(deleteRoute);
248
+ assert.equal(listRoute.route.transport?.kind, "jsonapi-resource");
249
+ assert.equal(viewRoute.route.transport?.kind, "jsonapi-resource");
250
+ assert.equal(createRoute.route.transport?.kind, "jsonapi-resource");
251
+ assert.equal(updateRoute.route.transport?.kind, "jsonapi-resource");
252
+ assert.equal(deleteRoute.route.transport?.kind, "jsonapi-resource");
253
+ assert.ok(listRoute.route.advanced?.fastifySchema?.querystring);
254
+ assert.ok(viewRoute.route.advanced?.fastifySchema?.querystring);
255
+ assert.ok(createRoute.route.advanced?.fastifySchema?.body);
256
+ assert.ok(updateRoute.route.advanced?.fastifySchema?.body);
257
+
258
+ const reply = createReplyDouble();
259
+ await deleteRoute.handler(
260
+ {
261
+ input: {
262
+ params: { workspaceSlug: "acme", recordId: 7 }
263
+ },
264
+ executeAction: async () => ({ id: 7 })
265
+ },
266
+ reply
267
+ );
268
+
269
+ assert.equal(reply.statusCode, 204);
201
270
  });
202
271
 
203
272
  test("crud routes validate route ownership filter values before registering visibility", () => {
@@ -7,7 +7,7 @@ function resolveTemplatePath(relativePath) {
7
7
  return fileURLToPath(new URL(`../templates/${relativePath}`, import.meta.url));
8
8
  }
9
9
 
10
- test("actions template uses resource symbol for view output validator", async () => {
10
+ test("actions template does not emit resource action output validators", async () => {
11
11
  const actionsTemplate = await readFile(
12
12
  resolveTemplatePath("src/local-package/server/actions.js"),
13
13
  "utf8"
@@ -15,11 +15,11 @@ test("actions template uses resource symbol for view output validator", async ()
15
15
 
16
16
  assert.match(
17
17
  actionsTemplate,
18
- /outputValidator:\s*resource\.operations\.view\.outputValidator,/
18
+ /output:\s*null,/
19
19
  );
20
20
  assert.doesNotMatch(
21
21
  actionsTemplate,
22
- /\$\{option:namespace\|singular\|camel\}Resource\.operations\.view\.outputValidator/
22
+ /createJsonApiResourceActionOutputValidator/
23
23
  );
24
24
  });
25
25
 
@@ -38,3 +38,19 @@ test("shared index template re-exports standardized resource symbol", async () =
38
38
  /export\s*\{\s*\$\{option:namespace\|singular\|camel\}Resource\s*\}/s
39
39
  );
40
40
  });
41
+
42
+ test("shared resource template uses defineCrudResource export", async () => {
43
+ const sharedResourceTemplate = await readFile(
44
+ resolveTemplatePath("src/local-package/shared/crudResource.js"),
45
+ "utf8"
46
+ );
47
+
48
+ assert.match(
49
+ sharedResourceTemplate,
50
+ /import\s*\{\s*defineCrudResource\s*\}\s*from\s*"@jskit-ai\/resource-crud-core\/shared\/crudResource";/s
51
+ );
52
+ assert.doesNotMatch(
53
+ sharedResourceTemplate,
54
+ /from\s*"json-rest-schema";/
55
+ );
56
+ });
@@ -64,38 +64,97 @@ function buildTemplateReplacements({
64
64
  ["${option:namespace|camel}", CRUD_NAMESPACE.camel],
65
65
  ["${option:namespace|singular|camel}", CRUD_NAMESPACE.singularCamel],
66
66
  ["${option:namespace|pascal}", CRUD_NAMESPACE.pascal],
67
+ ["__JSKIT_CRUD_TABLE_NAME__", JSON.stringify("customers")],
67
68
  ["__JSKIT_CRUD_ID_COLUMN__", JSON.stringify("id")],
68
69
  ["__JSKIT_CRUD_SURFACE_ID__", JSON.stringify(surfaceId)],
69
70
  ["__JSKIT_CRUD_ACTION_PERMISSION_SUPPORT__", actionPermissionSupport],
70
71
  ["__JSKIT_CRUD_ACTION_WORKSPACE_VALIDATOR_IMPORT__", actionWorkspaceValidatorImport],
72
+ ["__JSKIT_CRUD_LIST_ACTION_INPUT__", surfaceRequiresWorkspace
73
+ ? [
74
+ "composeSchemaDefinitions([",
75
+ " workspaceSlugParamsValidator,",
76
+ " listCursorPaginationQueryValidator,",
77
+ " listSearchQueryValidator,",
78
+ " listParentFilterQueryValidator,",
79
+ " lookupIncludeQueryValidator,",
80
+ "])"
81
+ ].join("\n")
82
+ : [
83
+ "composeSchemaDefinitions([",
84
+ " listCursorPaginationQueryValidator,",
85
+ " listSearchQueryValidator,",
86
+ " listParentFilterQueryValidator,",
87
+ " lookupIncludeQueryValidator,",
88
+ "])"
89
+ ].join("\n")],
90
+ ["__JSKIT_CRUD_VIEW_ACTION_INPUT__", surfaceRequiresWorkspace
91
+ ? [
92
+ "composeSchemaDefinitions([",
93
+ " workspaceSlugParamsValidator,",
94
+ " recordIdParamsValidator,",
95
+ " lookupIncludeQueryValidator,",
96
+ "])"
97
+ ].join("\n")
98
+ : [
99
+ "composeSchemaDefinitions([",
100
+ " recordIdParamsValidator,",
101
+ " lookupIncludeQueryValidator,",
102
+ "])"
103
+ ].join("\n")],
104
+ ["__JSKIT_CRUD_CREATE_ACTION_INPUT__", surfaceRequiresWorkspace
105
+ ? [
106
+ "composeSchemaDefinitions([",
107
+ " workspaceSlugParamsValidator,",
108
+ " resource.operations.create.body,",
109
+ '], {',
110
+ ' mode: "create"',
111
+ "})"
112
+ ].join("\n")
113
+ : "resource.operations.create.body"],
114
+ ["__JSKIT_CRUD_UPDATE_ACTION_INPUT__", surfaceRequiresWorkspace
115
+ ? [
116
+ "composeSchemaDefinitions([",
117
+ " workspaceSlugParamsValidator,",
118
+ " recordIdParamsValidator,",
119
+ " resource.operations.patch.body,",
120
+ "])"
121
+ ].join("\n")
122
+ : [
123
+ "composeSchemaDefinitions([",
124
+ " recordIdParamsValidator,",
125
+ " resource.operations.patch.body,",
126
+ "])"
127
+ ].join("\n")],
128
+ ["__JSKIT_CRUD_DELETE_ACTION_INPUT__", surfaceRequiresWorkspace
129
+ ? [
130
+ "composeSchemaDefinitions([",
131
+ " workspaceSlugParamsValidator,",
132
+ " recordIdParamsValidator,",
133
+ "])"
134
+ ].join("\n")
135
+ : "recordIdParamsValidator"],
71
136
  ["__JSKIT_CRUD_LIST_ACTION_PERMISSION__", listActionPermission],
72
- ["__JSKIT_CRUD_LIST_ACTION_INPUT_VALIDATOR__", surfaceRequiresWorkspace
73
- ? "[workspaceSlugParamsValidator, listCursorPaginationQueryValidator, listSearchQueryValidator, listParentFilterQueryValidator, lookupIncludeQueryValidator]"
74
- : "[listCursorPaginationQueryValidator, listSearchQueryValidator, listParentFilterQueryValidator, lookupIncludeQueryValidator]"],
75
137
  ["__JSKIT_CRUD_VIEW_ACTION_PERMISSION__", viewActionPermission],
76
- ["__JSKIT_CRUD_VIEW_ACTION_INPUT_VALIDATOR__", surfaceRequiresWorkspace
77
- ? "[workspaceSlugParamsValidator, recordIdParamsValidator, lookupIncludeQueryValidator]"
78
- : "[recordIdParamsValidator, lookupIncludeQueryValidator]"],
79
138
  ["__JSKIT_CRUD_CREATE_ACTION_PERMISSION__", createActionPermission],
80
- ["__JSKIT_CRUD_CREATE_ACTION_INPUT_VALIDATOR__", surfaceRequiresWorkspace
81
- ? '[workspaceSlugParamsValidator, { payload: resource.operations.create.bodyValidator }]'
82
- : "{ payload: resource.operations.create.bodyValidator }"],
83
139
  ["__JSKIT_CRUD_UPDATE_ACTION_PERMISSION__", updateActionPermission],
84
- ["__JSKIT_CRUD_UPDATE_ACTION_INPUT_VALIDATOR__", surfaceRequiresWorkspace
85
- ? '[workspaceSlugParamsValidator, recordIdParamsValidator, { patch: resource.operations.patch.bodyValidator }]'
86
- : "[recordIdParamsValidator, { patch: resource.operations.patch.bodyValidator }]"],
87
140
  ["__JSKIT_CRUD_DELETE_ACTION_PERMISSION__", deleteActionPermission],
88
- ["__JSKIT_CRUD_DELETE_ACTION_INPUT_VALIDATOR__", surfaceRequiresWorkspace
89
- ? "[workspaceSlugParamsValidator, recordIdParamsValidator]"
90
- : "recordIdParamsValidator"],
91
141
  ["__JSKIT_CRUD_ROUTE_SURFACE_REQUIRES_WORKSPACE__", String(surfaceRequiresWorkspace === true)],
92
142
  ["__JSKIT_CRUD_ROUTE_BASE__", JSON.stringify(surfaceRequiresWorkspace ? "/w/:workspaceSlug" : "/")],
93
143
  ["__JSKIT_CRUD_ROUTE_WORKSPACE_SUPPORT_IMPORTS__", routeWorkspaceSupportImports],
94
- ["__JSKIT_CRUD_LIST_ROUTE_PARAMS_VALIDATOR_LINE__", surfaceRequiresWorkspace ? " paramsValidator: routeParamsValidator," : ""],
95
- ["__JSKIT_CRUD_VIEW_ROUTE_PARAMS_VALIDATOR_LINE__", surfaceRequiresWorkspace ? " paramsValidator: [routeParamsValidator, recordIdParamsValidator]," : " paramsValidator: recordIdParamsValidator,"],
96
- ["__JSKIT_CRUD_CREATE_ROUTE_PARAMS_VALIDATOR_LINE__", surfaceRequiresWorkspace ? " paramsValidator: routeParamsValidator," : ""],
97
- ["__JSKIT_CRUD_UPDATE_ROUTE_PARAMS_VALIDATOR_LINE__", surfaceRequiresWorkspace ? " paramsValidator: [routeParamsValidator, recordIdParamsValidator]," : " paramsValidator: recordIdParamsValidator,"],
98
- ["__JSKIT_CRUD_DELETE_ROUTE_PARAMS_VALIDATOR_LINE__", surfaceRequiresWorkspace ? " paramsValidator: [routeParamsValidator, recordIdParamsValidator]," : " paramsValidator: recordIdParamsValidator,"],
144
+ ["__JSKIT_CRUD_ROUTE_CONTRACTS_RESOURCE_ARGS__", surfaceRequiresWorkspace ? ",\n routeParamsValidator" : ""],
145
+ ["__JSKIT_CRUD_ROUTE_VALIDATOR_CONSTANTS__", surfaceRequiresWorkspace
146
+ ? [
147
+ "const recordRouteParamsValidator = composeSchemaDefinitions([",
148
+ " routeParamsValidator,",
149
+ " recordIdParamsValidator",
150
+ "]);"
151
+ ].join("\n")
152
+ : ""],
153
+ ["__JSKIT_CRUD_LIST_ROUTE_PARAMS_VALIDATOR_LINE__", surfaceRequiresWorkspace ? " params: routeParamsValidator," : ""],
154
+ ["__JSKIT_CRUD_VIEW_ROUTE_PARAMS_VALIDATOR_LINE__", " params: recordRouteParamsValidator,"],
155
+ ["__JSKIT_CRUD_CREATE_ROUTE_PARAMS_VALIDATOR_LINE__", surfaceRequiresWorkspace ? " params: routeParamsValidator," : ""],
156
+ ["__JSKIT_CRUD_UPDATE_ROUTE_PARAMS_VALIDATOR_LINE__", " params: recordRouteParamsValidator,"],
157
+ ["__JSKIT_CRUD_DELETE_ROUTE_PARAMS_VALIDATOR_LINE__", " params: recordRouteParamsValidator,"],
99
158
  ["__JSKIT_CRUD_LIST_ROUTE_INPUT_LINES__", surfaceRequiresWorkspace
100
159
  ? [" ...buildWorkspaceInputFromRouteParams(request.input.params),", " ...(request.input.query || {})"].join("\n")
101
160
  : " ...(request.input.query || {})"],
@@ -112,18 +171,18 @@ function buildTemplateReplacements({
112
171
  ["__JSKIT_CRUD_CREATE_ROUTE_INPUT_LINES__", surfaceRequiresWorkspace
113
172
  ? [
114
173
  " ...buildWorkspaceInputFromRouteParams(request.input.params),",
115
- " payload: request.input.body"
174
+ " ...(request.input.body || {})"
116
175
  ].join("\n")
117
- : " payload: request.input.body"],
176
+ : " ...(request.input.body || {})"],
118
177
  ["__JSKIT_CRUD_UPDATE_ROUTE_INPUT_LINES__", surfaceRequiresWorkspace
119
178
  ? [
120
179
  " ...buildWorkspaceInputFromRouteParams(request.input.params),",
121
180
  " recordId: request.input.params.recordId,",
122
- " patch: request.input.body"
181
+ " ...(request.input.body || {})"
123
182
  ].join("\n")
124
183
  : [
125
184
  " recordId: request.input.params.recordId,",
126
- " patch: request.input.body"
185
+ " ...(request.input.body || {})"
127
186
  ].join("\n")],
128
187
  ["__JSKIT_CRUD_DELETE_ROUTE_INPUT_LINES__", surfaceRequiresWorkspace
129
188
  ? [
@@ -131,14 +190,41 @@ function buildTemplateReplacements({
131
190
  " recordId: request.input.params.recordId"
132
191
  ].join("\n")
133
192
  : " recordId: request.input.params.recordId"],
134
- [
135
- "__JSKIT_CRUD_LIST_CONFIG_LINES__",
136
- [
137
- " // defaultLimit: 20,",
138
- " // maxLimit: 100,",
139
- " // searchColumns: [\"name\"],"
140
- ].join("\n")
141
- ]
193
+ ["__JSKIT_CRUD_JSONREST_SCOPE_NAME__", JSON.stringify("customers")],
194
+ ["__JSKIT_CRUD_RESOURCE_AUTOFILTER__", JSON.stringify(surfaceRequiresWorkspace ? "workspace" : "public")],
195
+ ["__JSKIT_CRUD_RESOURCE_SEARCH_SCHEMA_LINES__", [
196
+ ' id: { type: "id", actualField: "id" },',
197
+ ' q: { type: "string", oneOf: ["name"], filterOperator: "like", splitBy: " ", matchAll: true },'
198
+ ].join("\n")],
199
+ ["__JSKIT_CRUD_RESOURCE_DEFAULT_SORT__", '["-createdAt"]'],
200
+ ["__JSKIT_CRUD_RESOURCE_SCHEMA_PROPERTIES__", [
201
+ " name: {",
202
+ ' type: "string",',
203
+ " required: true,",
204
+ " search: true,",
205
+ " operations: {",
206
+ ' output: { required: true },',
207
+ ' create: { required: true },',
208
+ ' patch: { required: false }',
209
+ " }",
210
+ " },",
211
+ " createdAt: {",
212
+ ' type: "dateTime",',
213
+ ' default: "now()",',
214
+ ' storage: { writeSerializer: "datetime-utc" },',
215
+ " operations: {",
216
+ ' output: { required: true }',
217
+ " }",
218
+ " },",
219
+ " updatedAt: {",
220
+ ' type: "dateTime",',
221
+ ' default: "now()",',
222
+ ' storage: { writeSerializer: "datetime-utc" },',
223
+ " operations: {",
224
+ ' output: { required: true }',
225
+ " }",
226
+ " },"
227
+ ].join("\n")]
142
228
  ]);
143
229
  }
144
230
 
@@ -151,93 +237,50 @@ function applyTemplateReplacements(sourceText = "", options = {}) {
151
237
  }
152
238
 
153
239
  function buildResourceStubSource() {
154
- return `const recordOutputValidator = Object.freeze({
155
- schema: {
156
- properties: {
157
- id: {},
158
- name: {}
159
- }
160
- },
161
- normalize(payload = {}) {
162
- return payload;
163
- }
164
- });
240
+ return `import { defineCrudResource } from "@jskit-ai/resource-crud-core/shared/crudResource";
165
241
 
166
- const createBodyValidator = Object.freeze({
167
- schema: {
168
- properties: {
169
- name: {},
170
- contactId: {}
171
- }
172
- },
173
- normalize(payload = {}) {
174
- return payload;
175
- }
176
- });
177
-
178
- const patchBodyValidator = Object.freeze({
242
+ const resource = defineCrudResource({
243
+ namespace: "customers",
244
+ tableName: "customers",
179
245
  schema: {
180
- properties: {
181
- name: {},
182
- contactId: {}
246
+ name: {
247
+ type: "string",
248
+ required: true,
249
+ search: true,
250
+ operations: {
251
+ output: { required: true },
252
+ create: { required: true },
253
+ patch: { required: false }
183
254
  }
184
255
  },
185
- normalize: createBodyValidator.normalize
186
- });
187
-
188
- const resource = Object.freeze({
189
- namespace: "customers",
190
- tableName: "customers",
191
- idColumn: "id",
192
- operations: {
193
- list: {
194
- outputValidator: Object.freeze({
195
- schema: {
196
- properties: {
197
- items: {},
198
- nextCursor: {}
199
- }
200
- },
201
- normalize(payload = {}) {
202
- return payload;
203
- }
204
- })
205
- },
206
- view: {
207
- outputValidator: recordOutputValidator
256
+ contactId: {
257
+ type: "id",
258
+ nullable: true,
259
+ relation: {
260
+ kind: "lookup",
261
+ namespace: "contacts",
262
+ valueKey: "id"
208
263
  },
209
- create: {
210
- bodyValidator: createBodyValidator,
211
- outputValidator: recordOutputValidator
212
- },
213
- patch: {
214
- bodyValidator: patchBodyValidator,
215
- outputValidator: recordOutputValidator
216
- },
217
- delete: {
218
- outputValidator: Object.freeze({
219
- schema: {
220
- properties: {
221
- id: {},
222
- deleted: {}
223
- }
224
- },
225
- normalize(payload = {}) {
226
- return payload;
227
- }
228
- })
264
+ operations: {
265
+ output: { required: true },
266
+ create: { required: false },
267
+ patch: { required: false }
229
268
  }
269
+ }
230
270
  },
231
- fieldMeta: [
232
- {
233
- key: "contactId",
234
- relation: {
235
- kind: "lookup",
236
- namespace: "contacts",
237
- valueKey: "id"
238
- }
271
+ searchSchema: {
272
+ id: { type: "id", actualField: "id" },
273
+ q: { type: "string", oneOf: ["name"], filterOperator: "like", splitBy: " ", matchAll: true }
274
+ },
275
+ defaultSort: ["-createdAt"],
276
+ autofilter: "workspace",
277
+ contract: {
278
+ lookup: {
279
+ containerKey: "lookups",
280
+ defaultInclude: "*",
281
+ maxDepth: 3
239
282
  }
240
- ]
283
+ }
241
284
  });
242
285
 
243
286
  export { resource };
@@ -266,7 +309,7 @@ async function createTemplateServerFixture(options = {}) {
266
309
  );
267
310
  await writeFile(path.join(sharedRoot, "customerResource.js"), buildResourceStubSource(), "utf8");
268
311
 
269
- for (const fileName of ["actionIds.js", "actions.js", "listConfig.js", "registerRoutes.js", "repository.js", "service.js"]) {
312
+ for (const fileName of ["actions.js", "registerRoutes.js", "repository.js", "service.js"]) {
270
313
  await renderServerTemplateFile(serverRoot, fileName, options);
271
314
  }
272
315
 
@@ -1,9 +0,0 @@
1
- const actionIds = Object.freeze({
2
- list: "crud.${option:namespace|snake}.list",
3
- view: "crud.${option:namespace|snake}.view",
4
- create: "crud.${option:namespace|snake}.create",
5
- update: "crud.${option:namespace|snake}.update",
6
- delete: "crud.${option:namespace|snake}.delete"
7
- });
8
-
9
- export { actionIds };
@@ -1,5 +0,0 @@
1
- const LIST_CONFIG = Object.freeze({
2
- __JSKIT_CRUD_LIST_CONFIG_LINES__
3
- });
4
-
5
- export { LIST_CONFIG };