@stacksjs/orm 0.75.408 → 0.75.417
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/dist/generate-database-schema.js +1 -1
- package/package.json +23 -23
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import process from"node:process";import{log}from"@stacksjs/logging";import{path}from"@stacksjs/path";import{fs}from"@stacksjs/storage";import{deriveMigrationTables}from"./migration-tables";function resolveDialect(explicit){if(explicit)return explicit;if(process.env.STACKS_CANONICAL_FEATURES==="1")return"sqlite";const configured=String(process.env.DB_CONNECTION??"").toLowerCase();return configured==="postgres"||configured==="mysql"?configured:"sqlite"}function booleanType(dialect){return dialect==="postgres"?"boolean":"number"}function snakeCase(str){return str.replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").toLowerCase()}function fromDefault(attr,dialect){const value=attr.default;if(typeof value==="boolean")return booleanType(dialect);if(typeof value==="number")return"number";if(typeof value==="string")return"string";return"unknown"}function ruleOf(attr){const validation=attr.validation;if(!validation||typeof validation!=="object")return null;const rule=validation.rule;return rule&&typeof rule==="object"?rule:null}function enumUnion(rule){if(!rule||String(rule.name??"")!=="enum")return null;const literals=(Array.isArray(rule.allowedValues)?rule.allowedValues:[]).filter((one)=>typeof one==="string"||typeof one==="number").map((one)=>typeof one==="number"?String(one):JSON.stringify(one));return literals.length>0?literals.join(" | "):null}function attributeToTsType(attr,dialect){const rule=ruleOf(attr),literals=enumUnion(rule);if(literals!==null)return attr.nullable===!0?`${literals} | null`:literals;const declared=typeof attr.type==="string"?attr.type.toLowerCase():String(rule?.name??"").toLowerCase(),base=(()=>{switch(declared){case"string":case"text":case"longtext":case"mediumtext":case"tinytext":case"char":case"varchar":case"enum":case"uuid":case"date":case"datetime":case"timestamp":case"timestamptz":case"password":case"time":case"year":return"string";case"number":case"integer":case"int":case"tinyint":case"smallint":case"mediumint":case"float":case"double":case"decimal":case"numeric":return"number";case"bigint":return"number | bigint";case"boolean":case"bool":return booleanType(dialect);case"json":case"jsonb":return"unknown";case"binary":case"blob":case"bytea":return"Uint8Array";case"unix":return"number";case"array":return"unknown[]";case"object":return"Record<string, unknown>";default:return fromDefault(attr,dialect)}})();return attr.nullable===!0?`${base} | null`:base}function deriveFkColumns(model){const out={},rel=model.belongsTo;if(!rel)return out;const entries=Array.isArray(rel)?rel:Object.values(rel);for(const entry of entries){if(typeof entry==="string"){out[`${snakeCase(entry)}_id`]="number";continue}if(entry&&typeof entry==="object"){const relation=entry;if(typeof relation.foreignKey==="string"){out[relation.foreignKey]="number";continue}if(typeof relation.model==="string")out[`${snakeCase(relation.model)}_id`]="number"}}return out}function pivotTableName(a,b){const[first,second]=[snakeCase(a),snakeCase(b)].sort();return`${first}_${second}`}function pivotColumnToTsType(attribute,dialect){const value=attribute.default,base=typeof value==="string"?"string":typeof value==="number"?"number":typeof value==="boolean"?booleanType(dialect):value instanceof Date?"string":"unknown";return attribute.nullable?`${base} | null`:base}function derivePivotTables(modelName,model,dialect){const rel=model.belongsToMany;if(!rel)return[];const out=[],entries=Array.isArray(rel)?rel:Object.values(rel);for(const entry of entries){let related,table,firstFk,secondFk,pivotColumns={},timestamps=!0;if(typeof entry==="string")related=entry;else if(entry&&typeof entry==="object"&&"model"in entry){const obj=entry;related=obj.model;if("pivotTable"in obj||"firstForeignKey"in obj||"secondForeignKey"in obj){table=obj.pivotTable;firstFk=obj.firstForeignKey;secondFk=obj.secondForeignKey}else{const modern=entry;table=modern.table;firstFk=modern.foreignKey;secondFk=modern.relatedKey;pivotColumns=modern.pivot?.columns??{};timestamps=Boolean(modern.pivot?.timestamps)}}else continue;const tableName=table??pivotTableName(modelName,related),fkA=firstFk??`${snakeCase(modelName)}_id`,fkB=secondFk??`${snakeCase(related)}_id`,columns={id:"number"
|
|
1
|
+
import process from"node:process";import{log}from"@stacksjs/logging";import{path}from"@stacksjs/path";import{fs}from"@stacksjs/storage";import{deriveMigrationTables}from"./migration-tables";function resolveDialect(explicit){if(explicit)return explicit;if(process.env.STACKS_CANONICAL_FEATURES==="1")return"sqlite";const configured=String(process.env.DB_CONNECTION??"").toLowerCase();return configured==="postgres"||configured==="mysql"?configured:"sqlite"}function booleanType(dialect){return dialect==="postgres"?"boolean":"number"}function snakeCase(str){return str.replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").toLowerCase()}function fromDefault(attr,dialect){const value=attr.default;if(typeof value==="boolean")return booleanType(dialect);if(typeof value==="number")return"number";if(typeof value==="string")return"string";return"unknown"}function ruleOf(attr){const validation=attr.validation;if(!validation||typeof validation!=="object")return null;const rule=validation.rule;return rule&&typeof rule==="object"?rule:null}function enumUnion(rule){if(!rule||String(rule.name??"")!=="enum")return null;const literals=(Array.isArray(rule.allowedValues)?rule.allowedValues:[]).filter((one)=>typeof one==="string"||typeof one==="number").map((one)=>typeof one==="number"?String(one):JSON.stringify(one));return literals.length>0?literals.join(" | "):null}function attributeToTsType(attr,dialect){const rule=ruleOf(attr),literals=enumUnion(rule);if(literals!==null)return attr.nullable===!0?`${literals} | null`:literals;const declared=typeof attr.type==="string"?attr.type.toLowerCase():String(rule?.name??"").toLowerCase(),base=(()=>{switch(declared){case"string":case"text":case"longtext":case"mediumtext":case"tinytext":case"char":case"varchar":case"enum":case"uuid":case"date":case"datetime":case"timestamp":case"timestamptz":case"password":case"time":case"year":return"string";case"number":case"integer":case"int":case"tinyint":case"smallint":case"mediumint":case"float":case"double":case"decimal":case"numeric":return"number";case"bigint":return"number | bigint";case"boolean":case"bool":return booleanType(dialect);case"json":case"jsonb":return"unknown";case"binary":case"blob":case"bytea":return"Uint8Array";case"unix":return"number";case"array":return"unknown[]";case"object":return"Record<string, unknown>";default:return fromDefault(attr,dialect)}})();return attr.nullable===!0?`${base} | null`:base}function deriveFkColumns(model){const out={},rel=model.belongsTo;if(!rel)return out;const entries=Array.isArray(rel)?rel:Object.values(rel);for(const entry of entries){if(typeof entry==="string"){out[`${snakeCase(entry)}_id`]="number";continue}if(entry&&typeof entry==="object"){const relation=entry;if(typeof relation.foreignKey==="string"){out[relation.foreignKey]="number";continue}if(typeof relation.model==="string")out[`${snakeCase(relation.model)}_id`]="number"}}return out}function pivotTableName(a,b){const[first,second]=[snakeCase(a),snakeCase(b)].sort();return`${first}_${second}`}function pivotColumnToTsType(attribute,dialect){const value=attribute.default,base=typeof value==="string"?"string":typeof value==="number"?"number":typeof value==="boolean"?booleanType(dialect):value instanceof Date?"string":"unknown";return attribute.nullable?`${base} | null`:base}function derivePivotTables(modelName,model,dialect){const rel=model.belongsToMany;if(!rel)return[];const out=[],entries=Array.isArray(rel)?rel:Object.values(rel);for(const entry of entries){let related,table,firstFk,secondFk,pivotColumns={},timestamps=!0;if(typeof entry==="string")related=entry;else if(entry&&typeof entry==="object"&&"model"in entry){const obj=entry;related=obj.model;if("pivotTable"in obj||"firstForeignKey"in obj||"secondForeignKey"in obj){table=obj.pivotTable;firstFk=obj.firstForeignKey;secondFk=obj.secondForeignKey}else{const modern=entry;table=modern.table;firstFk=modern.foreignKey;secondFk=modern.relatedKey;pivotColumns=modern.pivot?.columns??{};timestamps=Boolean(modern.pivot?.timestamps)}}else continue;const tableName=table??pivotTableName(modelName,related),fkA=firstFk??`${snakeCase(modelName)}_id`,fkB=secondFk??`${snakeCase(related)}_id`,columns={id:"number"};for(const foreignKey of[fkA,fkB].sort())columns[foreignKey]="number";for(const[column,attribute]of Object.entries(pivotColumns))columns[column]=pivotColumnToTsType(attribute,dialect);if(timestamps){columns.created_at="string";columns.updated_at="string | null"}out.push({table:tableName,columns})}return out}function usersGuaranteed(dialect){return{email_verified_at:"string | null",password_changed_at:"string | null",two_factor_secret:"string | null",two_factor_enabled:`${booleanType(dialect)} | null`,two_factor_last_used_step:"number | null",stripe_id:"string | null"}}function deriveSystemColumns(model,dialect){const out={id:"number"},traits=model.traits??{};if(traits.useUuid)out.uuid="string";if((traits.useTimestamps??traits.timestampable)!==!1){out.created_at="string";out.updated_at="string | null"}if(traits.useSoftDeletes??traits.softDeletable)out.deleted_at="string | null";if((model.table??"")==="users"||model.name==="User")Object.assign(out,usersGuaranteed(dialect));return out}function deriveAttributeColumns(model,dialect){const out={},attributes=model.attributes??{};for(const[name,attr]of Object.entries(attributes))out[snakeCase(name)]=attributeToTsType(attr,dialect);return out}function renderTableEntry(table,columns,indent=2){const outer=" ".repeat(indent),inner=" ".repeat(indent+1),cols=Object.entries(columns).map(([col,ty])=>`${inner}${col}: ${ty}`).join(`
|
|
2
2
|
`),key=/^[A-Z_a-z]\w*$/.test(table)?table:`'${table}'`;return`${outer}${key}: {
|
|
3
3
|
${inner}// columns
|
|
4
4
|
${cols}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/orm",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.417",
|
|
6
6
|
"description": "The Stacks ORM integration",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"contributors": [
|
|
@@ -63,31 +63,31 @@
|
|
|
63
63
|
"prepublishOnly": "bun run build"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
-
"@stacksjs/cache": "0.75.
|
|
67
|
-
"@stacksjs/cli": "0.75.
|
|
68
|
-
"@stacksjs/config": "0.75.
|
|
69
|
-
"@stacksjs/database": "0.75.
|
|
70
|
-
"@stacksjs/env": "0.75.
|
|
71
|
-
"@stacksjs/error-handling": "0.75.
|
|
72
|
-
"@stacksjs/events": "0.75.
|
|
73
|
-
"@stacksjs/logging": "0.75.
|
|
74
|
-
"@stacksjs/model-meta": "0.75.
|
|
75
|
-
"@stacksjs/pagination": "0.75.
|
|
76
|
-
"@stacksjs/path": "0.75.
|
|
77
|
-
"@stacksjs/query-builder": "0.75.
|
|
78
|
-
"@stacksjs/realtime": "0.75.
|
|
79
|
-
"@stacksjs/router": "0.75.
|
|
80
|
-
"@stacksjs/storage": "0.75.
|
|
81
|
-
"@stacksjs/strings": "0.75.
|
|
66
|
+
"@stacksjs/cache": "0.75.417",
|
|
67
|
+
"@stacksjs/cli": "0.75.417",
|
|
68
|
+
"@stacksjs/config": "0.75.417",
|
|
69
|
+
"@stacksjs/database": "0.75.417",
|
|
70
|
+
"@stacksjs/env": "0.75.417",
|
|
71
|
+
"@stacksjs/error-handling": "0.75.417",
|
|
72
|
+
"@stacksjs/events": "0.75.417",
|
|
73
|
+
"@stacksjs/logging": "0.75.417",
|
|
74
|
+
"@stacksjs/model-meta": "0.75.417",
|
|
75
|
+
"@stacksjs/pagination": "0.75.417",
|
|
76
|
+
"@stacksjs/path": "0.75.417",
|
|
77
|
+
"@stacksjs/query-builder": "0.75.417",
|
|
78
|
+
"@stacksjs/realtime": "0.75.417",
|
|
79
|
+
"@stacksjs/router": "0.75.417",
|
|
80
|
+
"@stacksjs/storage": "0.75.417",
|
|
81
|
+
"@stacksjs/strings": "0.75.417",
|
|
82
82
|
"@stacksjs/ts-validation": "^0.5.6",
|
|
83
|
-
"@stacksjs/validation": "0.75.
|
|
83
|
+
"@stacksjs/validation": "0.75.417",
|
|
84
84
|
"bun-query-builder": "^0.3.32"
|
|
85
85
|
},
|
|
86
86
|
"peerDependencies": {
|
|
87
|
-
"@stacksjs/auth": "0.75.
|
|
88
|
-
"@stacksjs/payments": "0.75.
|
|
89
|
-
"@stacksjs/queue": "0.75.
|
|
90
|
-
"@stacksjs/search-engine": "0.75.
|
|
87
|
+
"@stacksjs/auth": "0.75.417",
|
|
88
|
+
"@stacksjs/payments": "0.75.417",
|
|
89
|
+
"@stacksjs/queue": "0.75.417",
|
|
90
|
+
"@stacksjs/search-engine": "0.75.417",
|
|
91
91
|
"stripe": "23.0.0"
|
|
92
92
|
},
|
|
93
93
|
"peerDependenciesMeta": {
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
}
|
|
109
109
|
},
|
|
110
110
|
"devDependencies": {
|
|
111
|
-
"@stacksjs/types": "0.75.
|
|
111
|
+
"@stacksjs/types": "0.75.417",
|
|
112
112
|
"better-dx": "^0.2.24",
|
|
113
113
|
"stripe": "23.0.0"
|
|
114
114
|
}
|