Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@balena/abstract-sql-to-typescript

Package Overview
Dependencies
Maintainers
0
Versions
235
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@balena/abstract-sql-to-typescript - npm Package Compare versions

Comparing version 5.0.4-build-renovate-major-22-node-eb139de0d737ac67172fc616e5cbf711ee00ce91-1 to 5.1.0-build-joshbwlng-serial-206e29c66965efbbf36bc072b2adf0edb1793e12-1

6

out/package.json
{
"name": "@balena/abstract-sql-to-typescript",
"version": "5.0.4",
"version": "5.1.0",
"description": "A translator for abstract sql into typescript types.",

@@ -25,3 +25,3 @@ "type": "commonjs",

"@balena/odata-to-abstract-sql": "^7.0.0",
"@types/node": "^22.0.0",
"@types/node": "^20.16.5",
"common-tags": "^1.8.2"

@@ -58,4 +58,4 @@ },

"versionist": {
"publishedAt": "2024-12-05T19:44:40.044Z"
"publishedAt": "2024-12-06T01:06:14.225Z"
}
}
import type { AbstractSqlModel } from '@balena/abstract-sql-compiler';
type RequiredModelSubset = Pick<AbstractSqlModel, 'tables' | 'relationships' | 'synonyms'>;
export declare const abstractSqlToTypescriptTypes: (m: RequiredModelSubset) => string;
export type Options = {
convertSerialToInteger?: boolean;
inlineWriteReferences?: boolean;
};
export declare const abstractSqlToTypescriptTypes: (m: RequiredModelSubset, opts?: Options) => string;
export {};

@@ -8,2 +8,3 @@ "use strict";

const trimNL = new common_tags_1.TemplateTag((0, common_tags_1.replaceResultTransformer)(/^[\r\n]*|[\r\n]*$/g, ''));
const replaceSerial = (s) => s.replace(/serial$/i, 'Integer');
const modelNameToCamelCaseName = (s) => s

@@ -14,3 +15,3 @@ .split(/[ -]/)

const getReferencedInterface = (modelName, mode) => `${modelNameToCamelCaseName(modelName)}['${mode}']`;
const sqlTypeToTypescriptType = (m, f, mode) => {
const sqlTypeToTypescriptType = (m, f, mode, opts) => {
if (!['ForeignKey', 'ConceptType'].includes(f.dataType) && f.checks) {

@@ -31,2 +32,8 @@ const inChecks = f.checks.find((checkTuple) => checkTuple[0] === 'In');

if (mode === 'Write') {
if (opts?.inlineWriteReferences && f.references != null) {
const referencedField = m.tables[f.references.resourceName].fields.find(({ fieldName }) => fieldName === f.references.fieldName);
if (referencedField?.computed != null) {
return `Types['${opts?.convertSerialToInteger ? replaceSerial(referencedField.dataType) : referencedField.dataType}']['${mode}']`;
}
}
return referencedFieldType;

@@ -38,6 +45,6 @@ }

default:
return `Types['${f.dataType}']['${mode}']`;
return `Types['${opts?.convertSerialToInteger ? replaceSerial(f.dataType) : f.dataType}']['${mode}']`;
}
};
const fieldToInterfaceProps = (key, m, f, mode) => {
const fieldToInterfaceProps = (key, m, f, mode, opts) => {
if (mode === 'Write' && f.computed != null) {

@@ -47,6 +54,6 @@ return;

const nullable = f.required ? '' : ' | null';
return `${(0, odata_to_abstract_sql_1.sqlNameToODataName)(key)}: ${sqlTypeToTypescriptType(m, f, mode)}${nullable};`;
return `${(0, odata_to_abstract_sql_1.sqlNameToODataName)(key)}: ${sqlTypeToTypescriptType(m, f, mode, opts)}${nullable};`;
};
const fieldsToInterfaceProps = (m, fields, mode) => fields
.map((f) => fieldToInterfaceProps(f.fieldName, m, f, mode))
const fieldsToInterfaceProps = (m, fields, mode, opts) => fields
.map((f) => fieldToInterfaceProps(f.fieldName, m, f, mode, opts))
.filter((f) => f != null);

@@ -123,6 +130,6 @@ const getSynonyms = (s, inverseSynonyms) => {

};
const tableToInterface = (m, table) => {
const tableToInterface = (m, table, opts) => {
const writableFields = table.definition != null
? []
: fieldsToInterfaceProps(m, table.fields, 'Write');
: fieldsToInterfaceProps(m, table.fields, 'Write', opts);
const writeType = writableFields.length === 0

@@ -138,3 +145,3 @@ ?

${[
...fieldsToInterfaceProps(m, table.fields, 'Read'),
...fieldsToInterfaceProps(m, table.fields, 'Read', opts),
...relationshipsToInterfaceProps(m, table, 'Read'),

@@ -147,3 +154,3 @@ ].join('\n\t\t')}

};
const abstractSqlToTypescriptTypes = (m) => {
const abstractSqlToTypescriptTypes = (m, opts) => {
return trimNL `

@@ -157,3 +164,3 @@ // These types were generated by @balena/abstract-sql-to-typescript v${package_json_1.version}

const t = m.tables[tableName];
return tableToInterface(m, t);
return tableToInterface(m, t, opts);
})

@@ -160,0 +167,0 @@ .join('\n\n')}

{
"name": "@balena/abstract-sql-to-typescript",
"version": "5.0.4-build-renovate-major-22-node-eb139de0d737ac67172fc616e5cbf711ee00ce91-1",
"version": "5.1.0-build-joshbwlng-serial-206e29c66965efbbf36bc072b2adf0edb1793e12-1",
"description": "A translator for abstract sql into typescript types.",

@@ -25,3 +25,3 @@ "type": "commonjs",

"@balena/odata-to-abstract-sql": "^7.0.0",
"@types/node": "^22.0.0",
"@types/node": "^20.16.5",
"common-tags": "^1.8.2"

@@ -58,4 +58,4 @@ },

"versionist": {
"publishedAt": "2024-12-05T19:44:40.044Z"
"publishedAt": "2024-12-06T01:06:14.225Z"
}
}

@@ -20,2 +20,7 @@ import type {

export type Options = {
convertSerialToInteger?: boolean;
inlineWriteReferences?: boolean;
};
const trimNL = new TemplateTag(

@@ -25,2 +30,4 @@ replaceResultTransformer(/^[\r\n]*|[\r\n]*$/g, ''),

const replaceSerial = (s: string): string => s.replace(/serial$/i, 'Integer');
const modelNameToCamelCaseName = (s: string): string =>

@@ -39,2 +46,3 @@ s

mode: Mode,
opts?: Options,
): string => {

@@ -62,2 +70,12 @@ if (!['ForeignKey', 'ConceptType'].includes(f.dataType) && f.checks) {

if (mode === 'Write') {
if (opts?.inlineWriteReferences && f.references != null) {
const referencedField = m.tables[
f.references.resourceName
].fields.find(
({ fieldName }) => fieldName === f.references!.fieldName,
);
if (referencedField?.computed != null) {
return `Types['${opts?.convertSerialToInteger ? replaceSerial(referencedField.dataType) : referencedField.dataType}']['${mode}']`;
}
}
return referencedFieldType;

@@ -70,3 +88,3 @@ }

default:
return `Types['${f.dataType}']['${mode}']`;
return `Types['${opts?.convertSerialToInteger ? replaceSerial(f.dataType) : f.dataType}']['${mode}']`;
}

@@ -80,2 +98,3 @@ };

mode: Mode,
opts?: Options,
): string | undefined => {

@@ -91,2 +110,3 @@ if (mode === 'Write' && f.computed != null) {

mode,
opts,
)}${nullable};`;

@@ -99,5 +119,6 @@ };

mode: Mode,
opts?: Options,
): string[] =>
fields
.map((f) => fieldToInterfaceProps(f.fieldName, m, f, mode))
.map((f) => fieldToInterfaceProps(f.fieldName, m, f, mode, opts))
.filter((f) => f != null);

@@ -219,7 +240,11 @@

const tableToInterface = (m: RequiredModelSubset, table: AbstractSqlTable) => {
const tableToInterface = (
m: RequiredModelSubset,
table: AbstractSqlTable,
opts?: Options,
) => {
const writableFields =
table.definition != null
? []
: fieldsToInterfaceProps(m, table.fields, 'Write');
: fieldsToInterfaceProps(m, table.fields, 'Write', opts);
const writeType =

@@ -236,3 +261,3 @@ writableFields.length === 0

${[
...fieldsToInterfaceProps(m, table.fields, 'Read'),
...fieldsToInterfaceProps(m, table.fields, 'Read', opts),
...relationshipsToInterfaceProps(m, table, 'Read'),

@@ -250,2 +275,3 @@ ].join('\n\t\t')}

m: RequiredModelSubset,
opts?: Options,
): string => {

@@ -260,3 +286,3 @@ return trimNL`

const t = m.tables[tableName];
return tableToInterface(m, t);
return tableToInterface(m, t, opts);
})

@@ -263,0 +289,0 @@ .join('\n\n')}

import type { AbstractSqlModel } from '@balena/abstract-sql-compiler';
import { expect } from 'chai';
import { source } from 'common-tags';
import { abstractSqlToTypescriptTypes } from '../src/generate';
import { abstractSqlToTypescriptTypes, type Options } from '../src/generate';
import { version } from '../package.json';

@@ -11,2 +11,3 @@

expectation: string,
opts?: Options,
) => {

@@ -23,3 +24,3 @@ it(`should generate ${msg}`, () => {

};
const result = abstractSqlToTypescriptTypes(t);
const result = abstractSqlToTypescriptTypes(t, opts);

@@ -69,2 +70,3 @@ expect(result).to.equal(source`

index: 'PRIMARY KEY',
computed: ['Field', 'id'],
},

@@ -105,2 +107,3 @@ ],

index: 'PRIMARY KEY',
computed: ['Field', 'id'],
},

@@ -141,2 +144,3 @@ ],

index: 'PRIMARY KEY',
computed: ['Field', 'id'],
},

@@ -219,2 +223,3 @@ {

index: 'PRIMARY KEY',
computed: ['Field', 'id'],
},

@@ -324,3 +329,2 @@ ],

modified_at: Types['Date Time']['Write'];
id: Types['Serial']['Write'];
};

@@ -339,3 +343,2 @@ }

modified_at: Types['Date Time']['Write'];
id: Types['Serial']['Write'];
};

@@ -362,3 +365,2 @@ }

modified_at: Types['Date Time']['Write'];
id: Types['Serial']['Write'];
a_date: Types['Date']['Write'];

@@ -384,3 +386,2 @@ a_file: Types['WebResource']['Write'];

tag_key: Types['Short Text']['Write'];
id: Types['Serial']['Write'];
};

@@ -399,1 +400,254 @@ }

);
test(
'correct types for a test table with convertSerialToInteger=true',
testTable,
source`
export interface Parent {
Read: {
created_at: Types['Date Time']['Read'];
modified_at: Types['Date Time']['Read'];
id: Types['Integer']['Read'];
};
Write: {
created_at: Types['Date Time']['Write'];
modified_at: Types['Date Time']['Write'];
};
}
export interface Other {
Read: {
created_at: Types['Date Time']['Read'];
modified_at: Types['Date Time']['Read'];
id: Types['Integer']['Read'];
is_referenced_by__test?: Array<Test['Read']>;
};
Write: {
created_at: Types['Date Time']['Write'];
modified_at: Types['Date Time']['Write'];
};
}
export interface Test {
Read: {
created_at: Types['Date Time']['Read'];
modified_at: Types['Date Time']['Read'];
id: Types['Integer']['Read'];
a_date: Types['Date']['Read'];
a_file: Types['WebResource']['Read'];
parent: { __id: Parent['Read']['id'] } | [Parent['Read']];
references__other: { __id: Other['Read']['id'] } | [Other['Read']];
aliased__tag?: Array<TestTag['Read']>;
references__test__has__tag_key?: Array<TestTag['Read']>;
references__test_tag?: Array<TestTag['Read']>;
test__has__tag_key?: Array<TestTag['Read']>;
test_tag?: Array<TestTag['Read']>;
};
Write: {
created_at: Types['Date Time']['Write'];
modified_at: Types['Date Time']['Write'];
a_date: Types['Date']['Write'];
a_file: Types['WebResource']['Write'];
parent: Parent['Write']['id'];
references__other: Other['Write']['id'];
};
}
export interface TestTag {
Read: {
created_at: Types['Date Time']['Read'];
modified_at: Types['Date Time']['Read'];
test: { __id: Test['Read']['id'] } | [Test['Read']];
tag_key: Types['Short Text']['Read'];
id: Types['Integer']['Read'];
};
Write: {
created_at: Types['Date Time']['Write'];
modified_at: Types['Date Time']['Write'];
test: Test['Write']['id'];
tag_key: Types['Short Text']['Write'];
};
}
export default interface $Model {
parent: Parent;
other: Other;
test: Test;
test__has__tag_key: TestTag;
// Synonyms
test_tag: TestTag;
}
`,
{
convertSerialToInteger: true,
},
);
test(
'correct types for a test table with noMissingReferences=true',
testTable,
source`
export interface Parent {
Read: {
created_at: Types['Date Time']['Read'];
modified_at: Types['Date Time']['Read'];
id: Types['Serial']['Read'];
};
Write: {
created_at: Types['Date Time']['Write'];
modified_at: Types['Date Time']['Write'];
};
}
export interface Other {
Read: {
created_at: Types['Date Time']['Read'];
modified_at: Types['Date Time']['Read'];
id: Types['Serial']['Read'];
is_referenced_by__test?: Array<Test['Read']>;
};
Write: {
created_at: Types['Date Time']['Write'];
modified_at: Types['Date Time']['Write'];
};
}
export interface Test {
Read: {
created_at: Types['Date Time']['Read'];
modified_at: Types['Date Time']['Read'];
id: Types['Serial']['Read'];
a_date: Types['Date']['Read'];
a_file: Types['WebResource']['Read'];
parent: { __id: Parent['Read']['id'] } | [Parent['Read']];
references__other: { __id: Other['Read']['id'] } | [Other['Read']];
aliased__tag?: Array<TestTag['Read']>;
references__test__has__tag_key?: Array<TestTag['Read']>;
references__test_tag?: Array<TestTag['Read']>;
test__has__tag_key?: Array<TestTag['Read']>;
test_tag?: Array<TestTag['Read']>;
};
Write: {
created_at: Types['Date Time']['Write'];
modified_at: Types['Date Time']['Write'];
a_date: Types['Date']['Write'];
a_file: Types['WebResource']['Write'];
parent: Types['Serial']['Write'];
references__other: Types['Serial']['Write'];
};
}
export interface TestTag {
Read: {
created_at: Types['Date Time']['Read'];
modified_at: Types['Date Time']['Read'];
test: { __id: Test['Read']['id'] } | [Test['Read']];
tag_key: Types['Short Text']['Read'];
id: Types['Serial']['Read'];
};
Write: {
created_at: Types['Date Time']['Write'];
modified_at: Types['Date Time']['Write'];
test: Types['Serial']['Write'];
tag_key: Types['Short Text']['Write'];
};
}
export default interface $Model {
parent: Parent;
other: Other;
test: Test;
test__has__tag_key: TestTag;
// Synonyms
test_tag: TestTag;
}
`,
{
inlineWriteReferences: true,
},
);
test(
'correct types for a test table with noMissingReferences=true and noSerial=true',
testTable,
source`
export interface Parent {
Read: {
created_at: Types['Date Time']['Read'];
modified_at: Types['Date Time']['Read'];
id: Types['Integer']['Read'];
};
Write: {
created_at: Types['Date Time']['Write'];
modified_at: Types['Date Time']['Write'];
};
}
export interface Other {
Read: {
created_at: Types['Date Time']['Read'];
modified_at: Types['Date Time']['Read'];
id: Types['Integer']['Read'];
is_referenced_by__test?: Array<Test['Read']>;
};
Write: {
created_at: Types['Date Time']['Write'];
modified_at: Types['Date Time']['Write'];
};
}
export interface Test {
Read: {
created_at: Types['Date Time']['Read'];
modified_at: Types['Date Time']['Read'];
id: Types['Integer']['Read'];
a_date: Types['Date']['Read'];
a_file: Types['WebResource']['Read'];
parent: { __id: Parent['Read']['id'] } | [Parent['Read']];
references__other: { __id: Other['Read']['id'] } | [Other['Read']];
aliased__tag?: Array<TestTag['Read']>;
references__test__has__tag_key?: Array<TestTag['Read']>;
references__test_tag?: Array<TestTag['Read']>;
test__has__tag_key?: Array<TestTag['Read']>;
test_tag?: Array<TestTag['Read']>;
};
Write: {
created_at: Types['Date Time']['Write'];
modified_at: Types['Date Time']['Write'];
a_date: Types['Date']['Write'];
a_file: Types['WebResource']['Write'];
parent: Types['Integer']['Write'];
references__other: Types['Integer']['Write'];
};
}
export interface TestTag {
Read: {
created_at: Types['Date Time']['Read'];
modified_at: Types['Date Time']['Read'];
test: { __id: Test['Read']['id'] } | [Test['Read']];
tag_key: Types['Short Text']['Read'];
id: Types['Integer']['Read'];
};
Write: {
created_at: Types['Date Time']['Write'];
modified_at: Types['Date Time']['Write'];
test: Types['Integer']['Write'];
tag_key: Types['Short Text']['Write'];
};
}
export default interface $Model {
parent: Parent;
other: Other;
test: Test;
test__has__tag_key: TestTag;
// Synonyms
test_tag: TestTag;
}
`,
{
inlineWriteReferences: true,
convertSerialToInteger: true,
},
);

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc