@jskit-ai/crud-server-generator 0.1.58 → 0.1.59

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,7 +1,7 @@
1
1
  export default Object.freeze({
2
2
  packageVersion: 1,
3
3
  packageId: "@jskit-ai/crud-server-generator",
4
- version: "0.1.58",
4
+ version: "0.1.59",
5
5
  kind: "generator",
6
6
  description: "CRUD server generator with routes, actions, and persistence scaffolding.",
7
7
  options: {
@@ -151,13 +151,13 @@ export default Object.freeze({
151
151
  mutations: {
152
152
  dependencies: {
153
153
  runtime: {
154
- "@jskit-ai/auth-core": "0.1.49",
155
- "@jskit-ai/crud-core": "0.1.58",
156
- "@jskit-ai/database-runtime": "0.1.50",
157
- "@jskit-ai/http-runtime": "0.1.49",
158
- "@jskit-ai/kernel": "0.1.50",
159
- "@jskit-ai/realtime": "0.1.49",
160
- "@jskit-ai/users-core": "0.1.60",
154
+ "@jskit-ai/auth-core": "0.1.50",
155
+ "@jskit-ai/crud-core": "0.1.59",
156
+ "@jskit-ai/database-runtime": "0.1.51",
157
+ "@jskit-ai/http-runtime": "0.1.50",
158
+ "@jskit-ai/kernel": "0.1.51",
159
+ "@jskit-ai/realtime": "0.1.50",
160
+ "@jskit-ai/users-core": "0.1.61",
161
161
  "@local/${option:namespace|kebab}": "file:packages/${option:namespace|kebab}",
162
162
  "typebox": "^1.0.81"
163
163
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/crud-server-generator",
3
- "version": "0.1.58",
3
+ "version": "0.1.59",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
@@ -13,11 +13,11 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "@babel/parser": "^7.29.2",
16
- "@jskit-ai/crud-core": "0.1.58",
17
- "@jskit-ai/database-runtime": "0.1.50",
18
- "@jskit-ai/http-runtime": "0.1.49",
19
- "@jskit-ai/kernel": "0.1.50",
20
- "@jskit-ai/users-core": "0.1.60",
16
+ "@jskit-ai/crud-core": "0.1.59",
17
+ "@jskit-ai/database-runtime": "0.1.51",
18
+ "@jskit-ai/http-runtime": "0.1.50",
19
+ "@jskit-ai/kernel": "0.1.51",
20
+ "@jskit-ai/users-core": "0.1.61",
21
21
  "recast": "^0.23.11",
22
22
  "typebox": "^1.0.81"
23
23
  }
@@ -731,7 +731,7 @@ function renderResourceFieldSchema(column, { forOutput = false } = {}) {
731
731
  return schemaExpression;
732
732
  }
733
733
 
734
- function renderResourceValidatorsImport({ needsHtmlTimeSchemas = false, recordIdValidatorImports = [] } = {}) {
734
+ function renderResourceValidatorsImport({ htmlTimeSchemaImports = [], recordIdValidatorImports = [] } = {}) {
735
735
  const imports = [
736
736
  "normalizeObjectInput",
737
737
  "createCursorListValidator"
@@ -741,12 +741,30 @@ function renderResourceValidatorsImport({ needsHtmlTimeSchemas = false, recordId
741
741
  imports.push(importName);
742
742
  }
743
743
  }
744
- if (needsHtmlTimeSchemas) {
745
- imports.push("HTML_TIME_STRING_SCHEMA", "NULLABLE_HTML_TIME_STRING_SCHEMA");
744
+ for (const importName of Array.isArray(htmlTimeSchemaImports) ? htmlTimeSchemaImports : []) {
745
+ if (!imports.includes(importName)) {
746
+ imports.push(importName);
747
+ }
746
748
  }
747
749
  return `import {\n ${imports.join(",\n ")}\n} from "@jskit-ai/kernel/shared/validators";`;
748
750
  }
749
751
 
752
+ function resolveHtmlTimeSchemaImports(columns = []) {
753
+ const imports = [];
754
+ for (const column of Array.isArray(columns) ? columns : []) {
755
+ if (column?.typeKind !== "time") {
756
+ continue;
757
+ }
758
+ const importName = column.nullable === true
759
+ ? "NULLABLE_HTML_TIME_STRING_SCHEMA"
760
+ : "HTML_TIME_STRING_SCHEMA";
761
+ if (!imports.includes(importName)) {
762
+ imports.push(importName);
763
+ }
764
+ }
765
+ return imports;
766
+ }
767
+
750
768
  function resolveRecordIdValidatorImports(...sources) {
751
769
  const imports = ["recordIdSchema"];
752
770
  const joinedSource = sources
@@ -1788,7 +1806,7 @@ function buildReplacementsFromSnapshot({
1788
1806
  const needsNullableDateInput = writableColumns.some(
1789
1807
  (column) => column.typeKind === "date" && column.nullable === true
1790
1808
  );
1791
- const needsHtmlTimeSchemas = resourceColumns.some((column) => column.typeKind === "time");
1809
+ const htmlTimeSchemaImports = resolveHtmlTimeSchemaImports(resourceColumns);
1792
1810
  const needsDate = resourceColumns.some((column) => column.typeKind === "date");
1793
1811
  const needsJson = resourceColumns.some((column) => column.typeKind === "json");
1794
1812
  const needsNormalizeText = resourceColumns.some((column) =>
@@ -1882,7 +1900,7 @@ function buildReplacementsFromSnapshot({
1882
1900
  surfaceRequiresWorkspace
1883
1901
  }),
1884
1902
  __JSKIT_CRUD_RESOURCE_VALIDATORS_IMPORT__: renderResourceValidatorsImport({
1885
- needsHtmlTimeSchemas,
1903
+ htmlTimeSchemaImports,
1886
1904
  recordIdValidatorImports: resolveRecordIdValidatorImports(
1887
1905
  renderResourceSchemaPropertyLines(outputColumns, {
1888
1906
  forOutput: true
@@ -1056,7 +1056,11 @@ test("buildReplacementsFromSnapshot uses shared framework time schemas in genera
1056
1056
 
1057
1057
  assert.match(
1058
1058
  replacements.__JSKIT_CRUD_RESOURCE_VALIDATORS_IMPORT__,
1059
- /NULLABLE_HTML_TIME_STRING_SCHEMA/
1059
+ /(^|\n)\s*NULLABLE_HTML_TIME_STRING_SCHEMA(,|\n)/m
1060
+ );
1061
+ assert.doesNotMatch(
1062
+ replacements.__JSKIT_CRUD_RESOURCE_VALIDATORS_IMPORT__,
1063
+ /(^|\n)\s*HTML_TIME_STRING_SCHEMA(,|\n)/m
1060
1064
  );
1061
1065
  assert.match(
1062
1066
  replacements.__JSKIT_CRUD_RESOURCE_OUTPUT_SCHEMA_PROPERTIES__,
@@ -1072,6 +1076,54 @@ test("buildReplacementsFromSnapshot uses shared framework time schemas in genera
1072
1076
  );
1073
1077
  });
1074
1078
 
1079
+ test("buildReplacementsFromSnapshot imports only the non-nullable time schema when nullable time fields are absent", () => {
1080
+ const snapshot = createSnapshot({
1081
+ tableName: "opening_hours"
1082
+ });
1083
+ const timeColumn = Object.freeze({
1084
+ name: "from_time",
1085
+ key: "fromTime",
1086
+ dataType: "time",
1087
+ columnType: "time",
1088
+ typeKind: "time",
1089
+ nullable: false,
1090
+ hasDefault: false,
1091
+ defaultValue: null,
1092
+ autoIncrement: false,
1093
+ unsigned: false,
1094
+ extra: "",
1095
+ maxLength: null,
1096
+ numericPrecision: null,
1097
+ numericScale: null,
1098
+ enumValues: Object.freeze([])
1099
+ });
1100
+ const replacements = __testables.buildReplacementsFromSnapshot({
1101
+ namespace: "opening-hours",
1102
+ snapshot: {
1103
+ ...snapshot,
1104
+ columns: Object.freeze([...snapshot.columns, timeColumn])
1105
+ },
1106
+ resolvedOwnershipFilter: "workspace_user"
1107
+ });
1108
+
1109
+ assert.match(
1110
+ replacements.__JSKIT_CRUD_RESOURCE_VALIDATORS_IMPORT__,
1111
+ /(^|\n)\s*HTML_TIME_STRING_SCHEMA(,|\n)/m
1112
+ );
1113
+ assert.doesNotMatch(
1114
+ replacements.__JSKIT_CRUD_RESOURCE_VALIDATORS_IMPORT__,
1115
+ /(^|\n)\s*NULLABLE_HTML_TIME_STRING_SCHEMA(,|\n)/m
1116
+ );
1117
+ assert.match(
1118
+ replacements.__JSKIT_CRUD_RESOURCE_OUTPUT_SCHEMA_PROPERTIES__,
1119
+ /fromTime: HTML_TIME_STRING_SCHEMA/
1120
+ );
1121
+ assert.match(
1122
+ replacements.__JSKIT_CRUD_RESOURCE_CREATE_SCHEMA_PROPERTIES__,
1123
+ /fromTime: HTML_TIME_STRING_SCHEMA/
1124
+ );
1125
+ });
1126
+
1075
1127
  test("buildReplacementsFromSnapshot only imports record-id validator helpers that the resource actually uses", () => {
1076
1128
  const snapshot = createSnapshot({
1077
1129
  tableName: "pollen_types",