@raketa-cloud/admin 0.0.4 → 0.0.6

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.
Files changed (33) hide show
  1. package/package.json +2 -2
  2. package/src/Adapter.js +62 -7
  3. package/src/HonoAdapter.js +191 -63
  4. package/src/RaketaContext.js +13 -0
  5. package/src/helpers/AuthHelper.js +44 -0
  6. package/src/helpers/FormBuilder.js +226 -0
  7. package/src/helpers/HTMLBuilder.js +38 -0
  8. package/src/helpers/Pagination.js +92 -0
  9. package/src/helpers/SortButton.js +102 -0
  10. package/src/helpers/form_for.js +6 -0
  11. package/src/helpers/pagination_helper.js +5 -0
  12. package/src/helpers/sort_button.js +5 -0
  13. package/src/index.js +6 -2
  14. package/src/{createResource.js → routeCollection.js} +13 -6
  15. package/src/routeMember.js +40 -0
  16. package/src/{createNestedResource.js → routeNestedCollection.js} +12 -5
  17. package/src/routeNestedMember.js +40 -0
  18. package/src/setGlobalConfig.js +5 -0
  19. package/src/setGlobalContext.js +5 -0
  20. package/src/setupAuthentication.js +99 -0
  21. package/src/styles/application.css +465 -3
  22. package/src/tests/Adapter.test.js +39 -0
  23. package/src/tests/HonoAdapter.test.js +1 -0
  24. package/src/tests/helpers/Pagination.test.js +65 -0
  25. package/src/tests/helpers/SortButton.test.js +85 -0
  26. package/src/tests/{createResource.test.js → routeCollection.test.js} +51 -16
  27. package/src/tests/routeMember.test.js +91 -0
  28. package/src/tests/{createNestedResource.test.js → routeNestedCollection.test.js} +36 -10
  29. package/src/tests/routeNestedMember.test.js +96 -0
  30. package/src/views/_auth/login.ejs +92 -0
  31. package/src/views/layouts/application.ejs +144 -19
  32. package/src/views/layouts/header.ejs +49 -0
  33. package/tailwind.config.js +32 -1
@@ -0,0 +1,226 @@
1
+ import HTMLBuilder from "./HTMLBuilder";
2
+
3
+ function dig(obj, path) {
4
+ return path.split(".").reduce((acc, key) => {
5
+ if (acc && Object.hasOwn(acc, key)) {
6
+ return acc[key];
7
+ }
8
+
9
+ return undefined;
10
+ }, obj);
11
+ }
12
+
13
+ function humanize(string) {
14
+ if (typeof string !== "string") {
15
+ return "";
16
+ }
17
+
18
+ return string
19
+ .replace(/^_+|_+$/g, "")
20
+ .replace(/_id$/, "")
21
+ .replace(/_/g, " ")
22
+ .replace(/([a-z\d])([A-Z])/g, "$1 $2")
23
+ .replace(/\b([A-Z]+)([A-Z][a-z])/g, "$1 $2")
24
+ .toLowerCase()
25
+ .replace(/\b\w/g, (c) => c.toUpperCase());
26
+ }
27
+
28
+ function toFormName(dotNotation) {
29
+ return dotNotation
30
+ .split(".")
31
+ .map((part, index) => (index === 0 ? part : `[${part}]`))
32
+ .join("");
33
+ }
34
+
35
+ export default class FormBuilder extends HTMLBuilder {
36
+ constructor(obj = {}, errors = {}) {
37
+ super();
38
+ this.obj = obj;
39
+ this.errors = errors;
40
+ }
41
+
42
+ __getValue(name) {
43
+ return dig(this.obj, name) || "";
44
+ }
45
+
46
+ __getError(name) {
47
+ return dig(this.errors, name) || "";
48
+ }
49
+
50
+ __getFieldName(name) {
51
+ return name.split(".").at(-1).replace("[]", "");
52
+ }
53
+
54
+ __getID(name) {
55
+ const field = this.__getFieldName(name);
56
+ return `f_${field}`;
57
+ }
58
+
59
+ __getDefaultLabel(name) {
60
+ const field = this.__getFieldName(name);
61
+ return humanize(field);
62
+ }
63
+
64
+ input(name, opts = {}) {
65
+ const value = this.__getValue(name);
66
+ return this.tag("input", null, { type: "text", name, value, ...opts });
67
+ }
68
+
69
+ textarea(name, opts = {}) {
70
+ const { value, ...rest } = opts;
71
+
72
+ return this.tag(
73
+ "textarea",
74
+ value || this.__getValue(name),
75
+ {
76
+ name,
77
+ ...rest,
78
+ },
79
+ { nonVoid: true }
80
+ );
81
+ }
82
+
83
+ select(name, opts = {}) {
84
+ const { value, options = [], prompt = "Please select...", ...rest } = opts;
85
+ const selected = value || this.__getValue(name);
86
+
87
+ const renderedOpts = [];
88
+ if (prompt) {
89
+ renderedOpts.push(this.tag("option", prompt, { value: "" }));
90
+ }
91
+
92
+ for (const o of options) {
93
+ const additionalOpts = o[0] === selected ? { selected: "selected" } : {};
94
+
95
+ renderedOpts.push(
96
+ this.tag("option", o[1], { value: o[0], ...additionalOpts })
97
+ );
98
+ }
99
+
100
+ return this.tag("select", renderedOpts.join(""), { name, ...rest });
101
+ }
102
+
103
+ radio_group(name, opts = {}) {
104
+ const { value, options = [], ...rest } = opts;
105
+ const selected = value || this.__getValue(name);
106
+
107
+ const renderedOpts = [];
108
+
109
+ for (const o of options) {
110
+ const additionalOpts = o[0] === selected ? { checked: "checked" } : {};
111
+
112
+ const radio = this.tag("input", null, {
113
+ type: "radio",
114
+ name: opts.name,
115
+ value: o[0],
116
+ ...additionalOpts,
117
+ });
118
+
119
+ renderedOpts.push(this.tag("label", `${radio} ${o[1]}`));
120
+ }
121
+
122
+ return this.tag("div", renderedOpts.join(""), { ...rest });
123
+ }
124
+
125
+ checkbox_group(name, opts = {}) {
126
+ const { value, options = [], ...rest } = opts;
127
+ const selected = value || this.__getValue(name);
128
+
129
+ const renderedOpts = [];
130
+
131
+ for (const o of options) {
132
+ const additionalOpts = selected.includes(o[0])
133
+ ? { checked: "checked" }
134
+ : {};
135
+
136
+ const checkbox = this.tag("input", null, {
137
+ type: "checkbox",
138
+ name: `${opts.name}[]`,
139
+ value: o[0],
140
+ ...additionalOpts,
141
+ });
142
+
143
+ renderedOpts.push(this.tag("label", `${checkbox} ${o[1]}`));
144
+ }
145
+
146
+ return this.tag("div", renderedOpts.join(""), {
147
+ ...rest,
148
+ class: ["checkbox-group", rest.class].filter(Boolean).join(" "),
149
+ });
150
+ }
151
+
152
+ checkbox(name, opts = {}) {
153
+ const { value: desiredValue } = opts;
154
+
155
+ const value = this.__getValue(name);
156
+ const selected = value === desiredValue ? { checked: "checked" } : {};
157
+
158
+ return this.tag("input", null, {
159
+ type: "checkbox",
160
+ name,
161
+ value,
162
+ ...opts,
163
+ ...selected,
164
+ });
165
+ }
166
+
167
+ label(name, children, opts = {}) {
168
+ const htmlID = this.__getID(name);
169
+ return this.tag("label", children, { for: htmlID, ...opts });
170
+ }
171
+
172
+ error(children) {
173
+ return this.tag("span", children, { class: "text-red-600" });
174
+ }
175
+
176
+ group(children, opts = {}) {
177
+ return this.tag("div", children, {
178
+ class: ["mb-4", opts.class].filter(Boolean).join(" "),
179
+ });
180
+ }
181
+
182
+ submit(label, opts = {}) {
183
+ return this.tag("button", label, { type: "submit", ...opts });
184
+ }
185
+
186
+ field(name, opts = {}) {
187
+ const { as = "input", label, ...rest } = opts;
188
+ const defaultLabel = opts?.label || this.__getDefaultLabel(name);
189
+ const htmlID = this.__getID(name);
190
+ const error = this.__getError(name);
191
+
192
+ if (as === "checkbox") {
193
+ return this.group(
194
+ [
195
+ this.tag(
196
+ "div",
197
+ [
198
+ this[as](name, { id: htmlID, name: toFormName(name), ...rest }),
199
+ this.label(name, `${label || defaultLabel}`),
200
+ ]
201
+ .filter(Boolean)
202
+ .join(""),
203
+ {
204
+ class: "checkbox-wrapper",
205
+ }
206
+ ),
207
+ error ? this.error(error) : "",
208
+ ]
209
+ .filter(Boolean)
210
+ .join(""),
211
+ { class: error ? "has-error" : "" }
212
+ );
213
+ }
214
+
215
+ return this.group(
216
+ [
217
+ this.label(name, label || defaultLabel),
218
+ this[as](name, { id: htmlID, name: toFormName(name), ...rest }),
219
+ error ? this.error(error) : "",
220
+ ]
221
+ .filter(Boolean)
222
+ .join(""),
223
+ { class: error ? "has-error" : "" }
224
+ );
225
+ }
226
+ }
@@ -0,0 +1,38 @@
1
+ export default class HTMLBuilder {
2
+ constructor() {
3
+ // biome-ignore lint/correctness/noConstructorReturn: <explanation>
4
+ return new Proxy(this, {
5
+ get: (target, prop) => {
6
+ if (prop in target) {
7
+ return target[prop];
8
+ }
9
+
10
+ return this.__notExisting.bind(this, prop);
11
+ },
12
+ });
13
+ }
14
+
15
+ __notExisting(methodName, ...args) {
16
+ return args.length === 1
17
+ ? this.tag(methodName, null, ...args)
18
+ : this.tag(methodName, ...args);
19
+ }
20
+
21
+ escape(str) {
22
+ return str.toString().replaceAll('"', '\\"');
23
+ }
24
+
25
+ tag(tag, children = null, attributes = {}, opts = {}) {
26
+ const nonVoid = opts?.nonVoid;
27
+
28
+ const htmlAttributes = Object.keys(attributes).reduce((acc, curr) => {
29
+ const appended = `${acc} ${curr}="${this.escape(attributes[curr])}"`;
30
+ return appended;
31
+ }, "");
32
+
33
+ if (children || nonVoid)
34
+ return `<${tag} ${htmlAttributes}>${children}</${tag}>`;
35
+
36
+ return `<${tag} ${htmlAttributes} />`;
37
+ }
38
+ }
@@ -0,0 +1,92 @@
1
+ import HTMLBuilder from "./HTMLBuilder";
2
+
3
+ export default class Pagination extends HTMLBuilder {
4
+ constructor(pagination, router) {
5
+ super();
6
+ this.pagination = pagination;
7
+ this.query = router.query;
8
+ this.path = router.path;
9
+ }
10
+
11
+ __inactiveButton(children) {
12
+ return this.tag("span", children, {
13
+ class: "btn-text is-inactive",
14
+ });
15
+ }
16
+
17
+ __activeButton(children, opts = {}) {
18
+ return this.tag("a", children, {
19
+ class: "btn-text",
20
+ ...opts,
21
+ });
22
+ }
23
+
24
+ __pageNumberForm() {
25
+ return this.tag(
26
+ "form",
27
+ [
28
+ this.tag("input", "", {
29
+ type: "number",
30
+ value: this.pagination.currentPage,
31
+ }),
32
+ `of ${this.pagination.pagesCount}`,
33
+ ].join(" "),
34
+ { action: this.path, method: "GET" }
35
+ );
36
+ }
37
+
38
+ __paginationElement(children) {
39
+ return this.tag("div", this.tag("div", children), { class: "pagination" });
40
+ }
41
+
42
+ __buildHref(pageNumber) {
43
+ return [
44
+ this.path,
45
+ new URLSearchParams({ ...this.query, page: pageNumber }).toString(),
46
+ ]
47
+ .filter(Boolean)
48
+ .join("?");
49
+ }
50
+
51
+ build() {
52
+ if (this.pagination.pagesCount === 1) {
53
+ return "";
54
+ }
55
+
56
+ const children = [];
57
+
58
+ if (this.pagination.currentPage === 1) {
59
+ children.push(
60
+ this.__inactiveButton("First"),
61
+ this.__inactiveButton("Previous")
62
+ );
63
+ } else {
64
+ children.push(
65
+ this.__activeButton("First", { href: this.__buildHref(1) }),
66
+ this.__activeButton("Previous", {
67
+ href: this.__buildHref(this.pagination.currentPage - 1),
68
+ })
69
+ );
70
+ }
71
+
72
+ children.push(this.__pageNumberForm());
73
+
74
+ if (this.pagination.currentPage === this.pagination.pagesCount) {
75
+ children.push(
76
+ this.__inactiveButton("Next"),
77
+ this.__inactiveButton("Last")
78
+ );
79
+ } else {
80
+ children.push(
81
+ this.__activeButton("Next", {
82
+ href: this.__buildHref(this.pagination.currentPage + 1),
83
+ }),
84
+ this.__activeButton("Last", {
85
+ href: this.__buildHref(this.pagination.pagesCount),
86
+ })
87
+ );
88
+ }
89
+
90
+ return this.__paginationElement(children.join("\n"));
91
+ }
92
+ }
@@ -0,0 +1,102 @@
1
+ import HTMLBuilder from "./HTMLBuilder";
2
+
3
+ export default class SortButton extends HTMLBuilder {
4
+ constructor(label, name, router) {
5
+ super();
6
+ this.title = label;
7
+ this.name = name;
8
+ this.query = router.query;
9
+ this.path = router.path;
10
+ }
11
+
12
+ inactiveIcon() {
13
+ return `<svg
14
+ xmlns="http://www.w3.org/2000/svg"
15
+ viewBox="0 0 20 20"
16
+ fill="currentColor"
17
+ class="size-4"
18
+ >
19
+ <path
20
+ fill-rule="evenodd"
21
+ d="M2.24 6.8a.75.75 0 0 0 1.06-.04l1.95-2.1v8.59a.75.75 0 0 0 1.5 0V4.66l1.95 2.1a.75.75 0 1 0 1.1-1.02l-3.25-3.5a.75.75 0 0 0-1.1 0L2.2 5.74a.75.75 0 0 0 .04 1.06Zm8 6.4a.75.75 0 0 0-.04 1.06l3.25 3.5a.75.75 0 0 0 1.1 0l3.25-3.5a.75.75 0 1 0-1.1-1.02l-1.95 2.1V6.75a.75.75 0 0 0-1.5 0v8.59l-1.95-2.1a.75.75 0 0 0-1.06-.04Z"
22
+ clip-rule="evenodd"
23
+ />
24
+ </svg>`;
25
+ }
26
+
27
+ descIcon() {
28
+ return `<svg
29
+ xmlns="http://www.w3.org/2000/svg"
30
+ viewBox="0 0 20 20"
31
+ fill="currentColor"
32
+ class="size-4"
33
+ >
34
+ <path
35
+ fill-rule="evenodd"
36
+ d="M10 3a.75.75 0 0 1 .75.75v10.638l3.96-4.158a.75.75 0 1 1 1.08 1.04l-5.25 5.5a.75.75 0 0 1-1.08 0l-5.25-5.5a.75.75 0 1 1 1.08-1.04l3.96 4.158V3.75A.75.75 0 0 1 10 3Z"
37
+ clip-rule="evenodd"
38
+ />
39
+ </svg>`;
40
+ }
41
+
42
+ ascIcon() {
43
+ return `<svg
44
+ xmlns="http://www.w3.org/2000/svg"
45
+ viewBox="0 0 20 20"
46
+ fill="currentColor"
47
+ class="size-4"
48
+ >
49
+ <path
50
+ fill-rule="evenodd"
51
+ d="M10 17a.75.75 0 0 1-.75-.75V5.612L5.29 9.77a.75.75 0 0 1-1.08-1.04l5.25-5.5a.75.75 0 0 1 1.08 0l5.25 5.5a.75.75 0 1 1-1.08 1.04l-3.96-4.158V16.25A.75.75 0 0 1 10 17Z"
52
+ clip-rule="evenodd"
53
+ />
54
+ </svg>`;
55
+ }
56
+
57
+ build() {
58
+ const updatedQuery = {};
59
+ const klass = ["btn-sort"];
60
+ let icon = this.inactiveIcon();
61
+
62
+ for (const [key, value] of Object.entries(this.query)) {
63
+ if (key !== "order_direction" && key !== "order_by") {
64
+ updatedQuery[key] = value;
65
+ }
66
+ }
67
+
68
+ if (this.query.order_by === this.name) {
69
+ updatedQuery.order_direction =
70
+ this.query.order_direction === "ASC" ? "DESC" : "ASC";
71
+ } else {
72
+ updatedQuery.order_direction = "ASC";
73
+ }
74
+
75
+ updatedQuery.order_by = this.name;
76
+
77
+ const href = [this.path, new URLSearchParams(updatedQuery).toString()]
78
+ .filter(Boolean)
79
+ .join("?");
80
+
81
+ if (
82
+ this.query.order_by === this.name &&
83
+ this.query.order_direction === "ASC"
84
+ ) {
85
+ klass.push("is-active");
86
+ icon = this.ascIcon();
87
+ }
88
+
89
+ if (
90
+ this.query.order_by === this.name &&
91
+ this.query.order_direction === "DESC"
92
+ ) {
93
+ klass.push("is-active");
94
+ icon = this.descIcon();
95
+ }
96
+
97
+ return this.tag("a", [icon, this.title].join("\n"), {
98
+ href: href,
99
+ class: klass.join(" "),
100
+ });
101
+ }
102
+ }
@@ -0,0 +1,6 @@
1
+ import FormBuilder from "./FormBuilder";
2
+
3
+ export default function form_for(obj = {}, errors = {}, callback = (_) => {}) {
4
+ const form = new FormBuilder(obj, errors);
5
+ return callback(form);
6
+ }
@@ -0,0 +1,5 @@
1
+ import Pagination from "./Pagination";
2
+
3
+ export default function pagination(pagination, router) {
4
+ return new Pagination(pagination, router).build();
5
+ }
@@ -0,0 +1,5 @@
1
+ import SortButton from "./SortButton";
2
+
3
+ export default function sort_button(label, name, router) {
4
+ return new SortButton(label, name, router).build();
5
+ }
package/src/index.js CHANGED
@@ -1,3 +1,7 @@
1
1
  export { default as HonoAdapter } from "./HonoAdapter";
2
- export { default as createResource } from "./createResource";
3
- export { default as createNestedResource } from "./createNestedResource";
2
+ export { default as routeCollection } from "./routeCollection";
3
+ export { default as routeNestedCollection } from "./routeNestedCollection";
4
+ export { default as routeMember } from "./routeMember";
5
+ export { default as routeNestedMember } from "./routeNestedMember";
6
+ export { default as setGlobalContext } from "./setGlobalContext";
7
+ export { default as setGlobalConfig } from "./setGlobalConfig";
@@ -1,4 +1,4 @@
1
- const createResource = (adapter, resource, handler) => {
1
+ const routeCollection = (adapter, resource, handler) => {
2
2
  const {
3
3
  before_filter,
4
4
  after_filter,
@@ -16,6 +16,7 @@ const createResource = (adapter, resource, handler) => {
16
16
  "GET",
17
17
  `/${resource}`,
18
18
  resource,
19
+ resource,
19
20
  "index",
20
21
  index,
21
22
  before_filter,
@@ -25,6 +26,7 @@ const createResource = (adapter, resource, handler) => {
25
26
  "GET",
26
27
  `/${resource}/new`,
27
28
  resource,
29
+ resource,
28
30
  "create_form",
29
31
  create_form,
30
32
  before_filter,
@@ -34,6 +36,7 @@ const createResource = (adapter, resource, handler) => {
34
36
  "GET",
35
37
  `/${resource}/:id`,
36
38
  resource,
39
+ resource,
37
40
  "show",
38
41
  show,
39
42
  before_filter,
@@ -43,6 +46,7 @@ const createResource = (adapter, resource, handler) => {
43
46
  "GET",
44
47
  `/${resource}/:id/edit`,
45
48
  resource,
49
+ resource,
46
50
  "edit_form",
47
51
  edit_form,
48
52
  before_filter,
@@ -52,16 +56,18 @@ const createResource = (adapter, resource, handler) => {
52
56
  "POST",
53
57
  `/${resource}`,
54
58
  resource,
55
- "create",
59
+ resource,
60
+ "create_form",
56
61
  create,
57
62
  before_filter,
58
63
  after_filter,
59
64
  ],
60
65
  [
61
- "PUT",
66
+ "POST",
62
67
  `/${resource}/:id`,
63
68
  resource,
64
- "update",
69
+ resource,
70
+ "edit_form",
65
71
  update,
66
72
  before_filter,
67
73
  after_filter,
@@ -70,6 +76,7 @@ const createResource = (adapter, resource, handler) => {
70
76
  "DELETE",
71
77
  `/${resource}/:id`,
72
78
  resource,
79
+ resource,
73
80
  "destroy",
74
81
  destroy,
75
82
  before_filter,
@@ -77,7 +84,7 @@ const createResource = (adapter, resource, handler) => {
77
84
  ],
78
85
  ];
79
86
 
80
- adapter.createResource(mapping);
87
+ adapter.routeCollection(mapping);
81
88
  };
82
89
 
83
- export default createResource;
90
+ export default routeCollection;
@@ -0,0 +1,40 @@
1
+ const routeMember = (adapter, resource, handler) => {
2
+ const { before_filter, after_filter, show, edit_form, update } = handler;
3
+
4
+ const mapping = [
5
+ [
6
+ "GET",
7
+ `/${resource}`,
8
+ resource,
9
+ resource,
10
+ "show",
11
+ show,
12
+ before_filter,
13
+ after_filter,
14
+ ],
15
+ [
16
+ "GET",
17
+ `/${resource}/edit`,
18
+ resource,
19
+ resource,
20
+ "edit_form",
21
+ edit_form,
22
+ before_filter,
23
+ after_filter,
24
+ ],
25
+ [
26
+ "POST",
27
+ `/${resource}`,
28
+ resource,
29
+ resource,
30
+ "edit_form",
31
+ update,
32
+ before_filter,
33
+ after_filter,
34
+ ],
35
+ ];
36
+
37
+ adapter.routeMember(mapping);
38
+ };
39
+
40
+ export default routeMember;
@@ -1,4 +1,4 @@
1
- const createNestedResource = (adapter, parent, resource, handler) => {
1
+ const routeNestedCollection = (adapter, parent, resource, handler) => {
2
2
  const {
3
3
  before_filter,
4
4
  after_filter,
@@ -16,6 +16,7 @@ const createNestedResource = (adapter, parent, resource, handler) => {
16
16
  "GET",
17
17
  `/${parent}/:parent_id/${resource}`,
18
18
  resource,
19
+ resource,
19
20
  "index",
20
21
  index,
21
22
  before_filter,
@@ -25,6 +26,7 @@ const createNestedResource = (adapter, parent, resource, handler) => {
25
26
  "GET",
26
27
  `/${parent}/:parent_id/${resource}/new`,
27
28
  resource,
29
+ resource,
28
30
  "create_form",
29
31
  create_form,
30
32
  before_filter,
@@ -34,6 +36,7 @@ const createNestedResource = (adapter, parent, resource, handler) => {
34
36
  "GET",
35
37
  `/${resource}/:id`,
36
38
  resource,
39
+ resource,
37
40
  "show",
38
41
  show,
39
42
  before_filter,
@@ -43,6 +46,7 @@ const createNestedResource = (adapter, parent, resource, handler) => {
43
46
  "GET",
44
47
  `/${resource}/:id/edit`,
45
48
  resource,
49
+ resource,
46
50
  "edit_form",
47
51
  edit_form,
48
52
  before_filter,
@@ -50,9 +54,10 @@ const createNestedResource = (adapter, parent, resource, handler) => {
50
54
  ],
51
55
  [
52
56
  "POST",
53
- `/orders/:parent_id/${resource}`,
57
+ `/${parent}/:parent_id/${resource}`,
54
58
  resource,
55
- "create",
59
+ resource,
60
+ "create_form",
56
61
  create,
57
62
  before_filter,
58
63
  after_filter,
@@ -61,6 +66,7 @@ const createNestedResource = (adapter, parent, resource, handler) => {
61
66
  "PUT",
62
67
  `/${resource}/:id`,
63
68
  resource,
69
+ resource,
64
70
  "update",
65
71
  update,
66
72
  before_filter,
@@ -70,6 +76,7 @@ const createNestedResource = (adapter, parent, resource, handler) => {
70
76
  "DELETE",
71
77
  `/${resource}/:id`,
72
78
  resource,
79
+ resource,
73
80
  "destroy",
74
81
  destroy,
75
82
  before_filter,
@@ -77,7 +84,7 @@ const createNestedResource = (adapter, parent, resource, handler) => {
77
84
  ],
78
85
  ];
79
86
 
80
- adapter.createNestedResource(mapping);
87
+ adapter.routeNestedCollection(mapping);
81
88
  };
82
89
 
83
- export default createNestedResource;
90
+ export default routeNestedCollection;