@sealcode/sealgen 0.18.5 → 0.18.7

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.
@@ -1,4 +1,4 @@
1
- import SealiousSingleReference from "sealious/@types/src/app/base-chips/field-types/single-reference.js";
1
+ import SealiousSingleReference from "sealious/@types/app/base-chips/field-types/single-reference.js";
2
2
  import { CollectionField } from "../fields/collection-field.js";
3
3
  import { DropdownOptions, FreeformDropdown } from "./dropdown.js";
4
4
  import { Collection, CollectionItem } from "sealious";
@@ -36,7 +36,7 @@ export declare abstract class ListPage<ItemType, F extends typeof BaseListPageFi
36
36
  private renderPageButton;
37
37
  getFilterValues(ctx: Context): Promise<Record<string, unknown>>;
38
38
  getSort(ctx: Context): Promise<ListSort | null>;
39
- makeSortLink(ctx: Context, field: string, order: "asc" | "desc"): string;
39
+ makeSortLink(ctx: Context, field: string, order: "asc" | "desc" | null): string;
40
40
  renderFilters(ctx: Context): Promise<FlatTemplatable>;
41
41
  renderHeading(ctx: Context, field: string, label?: string): Promise<FlatTemplatable>;
42
42
  getDefaultSort(_: Context): ListSort | null;
@@ -3,6 +3,7 @@ import tempfile from "tempfile";
3
3
  import { promises as fs } from "fs";
4
4
  import { resolve } from "path";
5
5
  import { colord } from "colord";
6
+ import { hex } from "wcag-contrast";
6
7
  import { formatWithPrettier } from "../utils/prettier.js";
7
8
  import { Builder } from "./builder.js";
8
9
  import { exec } from "../utils/exec.js";
@@ -130,16 +131,31 @@ class ColorsBuilder extends Builder {
130
131
  }`,
131
132
  "css"
132
133
  );
134
+ function colorCodeFind(color_varibale_name) {
135
+ const parts = color_varibale_name.split("-").slice(2);
136
+ const colorGroup = parts[1];
137
+ const colorName = parts.slice(2).join("-").replace(/\)$/, "");
138
+ const colorCode = color_groups[colorGroup]?.[colorName]?.color;
139
+ return colorCode;
140
+ }
133
141
  function makeDemoPair(fg, bg, text, classname = "") {
142
+ let roundedContrast = "";
143
+ if (fg !== "") {
144
+ const fg_code = colorCodeFind(fg);
145
+ const bg_code = colorCodeFind(bg);
146
+ const contrast = hex(fg_code, bg_code);
147
+ roundedContrast = Math.round(contrast).toString();
148
+ }
134
149
  return (
135
150
  /* HTML */
136
151
  ` <div
137
152
  class="pair ${classname}"
138
153
  data-fg="${fg}"
139
154
  data-bg="${bg}"
140
- style="background-color: ${bg}; color: ${fg}"
155
+ style="background-color: ${bg}; color: ${fg}; display: flex; justify-content: space-between;"
141
156
  >
142
157
  <span>${text}</span>
158
+ <span>${roundedContrast}</span>
143
159
  </div>`
144
160
  );
145
161
  }
@@ -34,9 +34,21 @@ function generateURL(actionName, url) {
34
34
  ${actionName}URL.rawURL = "${encodeURI(url)}";`;
35
35
  }
36
36
  function sortRoutes(urls) {
37
- return urls.sort(
38
- ({ url: url1 }, { url: url2 }) => url1.includes(":") ? 1 : url2.includes(":") ? -1 : url1 < url2 ? -1 : 1
39
- );
37
+ return urls.sort(({ url: url1 }, { url: url2 }) => {
38
+ const [segments1, segments2] = [url1, url2].map(
39
+ (url) => url.split("/")
40
+ );
41
+ if (segments1.length < segments2.length) {
42
+ return -1;
43
+ }
44
+ if (segments1.length > segments2.length) {
45
+ return 1;
46
+ }
47
+ const [encoded1, encoded2] = [url1, url2].map(
48
+ (url) => url.split("/").map((e) => e.startsWith(":") ? "1" : "0")
49
+ );
50
+ return encoded1 < encoded2 ? -1 : 1;
51
+ });
40
52
  }
41
53
  async function generateRoutes() {
42
54
  const files = await Promise.all(
@@ -1,4 +1,4 @@
1
- import { generateURL } from "./generate-routes.js";
1
+ import { generateURL, sortRoutes } from "./generate-routes.js";
2
2
  import * as prettier from "prettier";
3
3
  import { getPrettierConfig } from "./utils/prettier.js";
4
4
  import assert from "node:assert";
@@ -37,5 +37,29 @@ EditUserURL.rawURL = "/admin/u%C5%BCytkownicy/:id/edit/";`,
37
37
  )
38
38
  );
39
39
  });
40
+ it("sorts routes from most specific first to least specific last, considering directory structure", () => {
41
+ assert.deepStrictEqual(
42
+ sortRoutes(
43
+ [
44
+ "/home",
45
+ "/foo/:bar/:baz",
46
+ "/:param1/:param2/:param3",
47
+ "/foo/bar/baz",
48
+ "/foo/:bar",
49
+ "/:param1"
50
+ ].map((url) => ({
51
+ url
52
+ }))
53
+ ).map(({ url }) => url),
54
+ [
55
+ "/home",
56
+ "/:param1",
57
+ "/foo/:bar",
58
+ "/foo/bar/baz",
59
+ "/foo/:bar/:baz",
60
+ "/:param1/:param2/:param3"
61
+ ]
62
+ );
63
+ });
40
64
  });
41
65
  //# sourceMappingURL=generate-routes.test.js.map
package/lib/page/list.js CHANGED
@@ -176,7 +176,7 @@ class ListPage extends Page {
176
176
  const order = current_order === "asc" ? "desc" : current_order === null ? "asc" : null;
177
177
  return (
178
178
  /* HTML */
179
- `<th>
179
+ `<th data-field="${field}">
180
180
  <a href="${this.makeSortLink(ctx, field, order)}"
181
181
  >${label}
182
182
  ${current_order && (current_order == "asc" ? "\u2191" : "\u2193") || ""}</a
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sealcode/sealgen",
3
- "version": "0.18.5",
3
+ "version": "0.18.7",
4
4
  "description": "Module to automate adding routes and collections to a sealious application",
5
5
  "main": "lib/index.js",
6
6
  "type": "module",
@@ -36,6 +36,7 @@
36
36
  "@types/prettier": "^2.7.0",
37
37
  "@types/prompts": "^2.0.14",
38
38
  "@types/recursive-readdir": "^2.2.4",
39
+ "@types/wcag-contrast": "^3.0.3",
39
40
  "@types/ws": "^8.5.10",
40
41
  "@types/yargs": "^17.0.32",
41
42
  "@typescript-eslint/eslint-plugin": "^5.58.0",
@@ -82,6 +83,7 @@
82
83
  "tempfile": "^5.0.0",
83
84
  "tempstream": "^0.4.6",
84
85
  "tiny-glob": "^0.2.9",
86
+ "wcag-contrast": "^3.0.0",
85
87
  "ws": "^8.16.0",
86
88
  "yargs": "^17.6.2"
87
89
  },
@@ -4,6 +4,7 @@ import tempfile from "tempfile";
4
4
  import { promises as fs } from "fs";
5
5
  import { resolve } from "path";
6
6
  import { colord } from "colord";
7
+ import { hex } from "wcag-contrast";
7
8
 
8
9
  import { formatWithPrettier } from "../utils/prettier.js";
9
10
 
@@ -155,19 +156,37 @@ export class ColorsBuilder extends Builder {
155
156
  "css"
156
157
  );
157
158
 
159
+ function colorCodeFind(color_varibale_name: string) {
160
+ const parts = color_varibale_name.split("-").slice(2);
161
+ const colorGroup = parts[1];
162
+ const colorName = parts.slice(2).join("-").replace(/\)$/, "");
163
+ const colorCode = color_groups[colorGroup]?.[colorName]?.color;
164
+
165
+ return colorCode;
166
+ }
167
+
158
168
  function makeDemoPair(
159
169
  fg: string,
160
170
  bg: string,
161
171
  text: string,
162
172
  classname = ""
163
173
  ) {
174
+ let roundedContrast = "";
175
+ if (fg !== "") {
176
+ const fg_code = colorCodeFind(fg);
177
+ const bg_code = colorCodeFind(bg);
178
+ const contrast = hex(fg_code, bg_code);
179
+ roundedContrast = Math.round(contrast).toString();
180
+ }
181
+
164
182
  return /* HTML */ ` <div
165
183
  class="pair ${classname}"
166
184
  data-fg="${fg}"
167
185
  data-bg="${bg}"
168
- style="background-color: ${bg}; color: ${fg}"
186
+ style="background-color: ${bg}; color: ${fg}; display: flex; justify-content: space-between;"
169
187
  >
170
188
  <span>${text}</span>
189
+ <span>${roundedContrast}</span>
171
190
  </div>`;
172
191
  }
173
192
 
@@ -1,4 +1,4 @@
1
- import SealiousSingleReference from "sealious/@types/src/app/base-chips/field-types/single-reference.js";
1
+ import SealiousSingleReference from "sealious/@types/app/base-chips/field-types/single-reference.js";
2
2
  import { CollectionField } from "../fields/collection-field.js";
3
3
  import { DropdownOptions, FreeformDropdown } from "./dropdown.js";
4
4
  import { Collection, CollectionItem } from "sealious";
@@ -1,4 +1,4 @@
1
- import { generateURL } from "./generate-routes.js";
1
+ import { generateURL, sortRoutes } from "./generate-routes.js";
2
2
  import * as prettier from "prettier";
3
3
  import { getPrettierConfig } from "./utils/prettier.js";
4
4
  import assert from "node:assert";
@@ -40,4 +40,29 @@ EditUserURL.rawURL = "/admin/u%C5%BCytkownicy/:id/edit/";`,
40
40
  )
41
41
  );
42
42
  });
43
+
44
+ it("sorts routes from most specific first to least specific last, considering directory structure", () => {
45
+ assert.deepStrictEqual(
46
+ sortRoutes(
47
+ [
48
+ "/home",
49
+ "/foo/:bar/:baz",
50
+ "/:param1/:param2/:param3",
51
+ "/foo/bar/baz",
52
+ "/foo/:bar",
53
+ "/:param1",
54
+ ].map((url) => ({
55
+ url,
56
+ }))
57
+ ).map(({ url }: { url: string }) => url),
58
+ [
59
+ "/home",
60
+ "/:param1",
61
+ "/foo/:bar",
62
+ "/foo/bar/baz",
63
+ "/foo/:bar/:baz",
64
+ "/:param1/:param2/:param3",
65
+ ]
66
+ );
67
+ });
43
68
  });
@@ -48,15 +48,24 @@ export function generateURL(actionName: string, url: string) {
48
48
  }
49
49
 
50
50
  export function sortRoutes<T extends { url: string }>(urls: T[]): T[] {
51
- return urls.sort(({ url: url1 }, { url: url2 }) =>
52
- url1.includes(":") // make sure the parametrized ones come later, so the more concrete ones show up first. This is not a full solution, but works for single-parameter urls
53
- ? 1
54
- : url2.includes(":")
55
- ? -1
56
- : url1 < url2
57
- ? -1
58
- : 1
59
- );
51
+ return urls.sort(({ url: url1 }, { url: url2 }) => {
52
+ const [segments1, segments2] = [url1, url2].map((url) =>
53
+ url.split("/")
54
+ );
55
+ if (segments1.length < segments2.length) {
56
+ return -1;
57
+ }
58
+ if (segments1.length > segments2.length) {
59
+ return 1;
60
+ }
61
+ // if they are the same length, map each url to a string like 00010
62
+ // where "0" is for static (so should be sorted earlier, and "1" is for
63
+ // dynamic parts
64
+ const [encoded1, encoded2] = [url1, url2].map((url) =>
65
+ url.split("/").map((e) => (e.startsWith(":") ? "1" : "0"))
66
+ );
67
+ return encoded1 < encoded2 ? -1 : 1;
68
+ });
60
69
  }
61
70
 
62
71
  export async function generateRoutes(): Promise<void> {
package/src/page/list.ts CHANGED
@@ -248,7 +248,7 @@ export abstract class ListPage<
248
248
  : current_order === null
249
249
  ? "asc"
250
250
  : null;
251
- return /* HTML */ `<th>
251
+ return /* HTML */ `<th data-field="${field}">
252
252
  <a href="${this.makeSortLink(ctx, field, order)}"
253
253
  >${label}
254
254
  ${(current_order && (current_order == "asc" ? "↑" : "↓")) ||