New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@strapi/typescript-utils

Package Overview
Dependencies
Maintainers
7
Versions
1497
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@strapi/typescript-utils - npm Package Compare versions

Comparing version 0.0.0-8581854cb3 to 0.0.0-a5ae7a818c08e91a4950ad2483d177664ba8ab04

lib/generators/schemas/mappers.js

4

lib/__tests__/generators/schemas/attributes.test.js

@@ -26,7 +26,7 @@ 'use strict';

const toPropertySignature = attribute => {
const toPropertySignature = (attribute) => {
return attributeToPropertySignature(schema, attributeName, attribute);
};
const defaultAssertion = node => {
const defaultAssertion = (node) => {
expect(node.kind).toBe(ts.SyntaxKind.PropertySignature);

@@ -33,0 +33,0 @@ expect(node.name.escapedText).toBe(attributeName);

@@ -20,3 +20,3 @@ 'use strict';

const assertGlobalNodeStructure = node => {
const assertGlobalNodeStructure = (node) => {
// "declare global"

@@ -23,0 +23,0 @@ expect(node.kind).toBe(ts.SyntaxKind.ModuleDeclaration);

@@ -6,3 +6,3 @@ 'use strict';

module.exports = async dest => {
module.exports = async (dest) => {
const tsConfig = {

@@ -9,0 +9,0 @@ compilerOptions: {

@@ -13,3 +13,3 @@ 'use strict';

*/
const reportWatchStatusChanged = diagnostic => {
const reportWatchStatusChanged = (diagnostic) => {
console.info(ts.formatDiagnostic(diagnostic, formatHost));

@@ -22,5 +22,5 @@ };

const { fileNames, options, projectReferences, watchOptions } = resolveConfigOptions(
configPath
);
const { fileNames, options, projectReferences, watchOptions } =
resolveConfigOptions(configPath);
const host = ts.createWatchCompilerHost(

@@ -27,0 +27,0 @@ fileNames,

'use strict';
const ts = require('typescript');
const { factory } = require('typescript');

@@ -9,31 +8,5 @@ const _ = require('lodash/fp');

const { getTypeNode, toTypeLiteral } = require('./utils');
const mappers = require('./mappers');
/**
* Generate a property signature node for a given attribute
*
* @param {object} schema
* @param {string} attributeName
* @param {object} attribute
* @returns {object}
*/
const attributeToPropertySignature = (schema, attributeName, attribute) => {
const baseType = getAttributeType(attributeName, attribute, schema.uid);
if (baseType === null) {
return null;
}
const modifiers = getAttributeModifiers(attribute);
const nodes = [baseType, ...modifiers];
return factory.createPropertySignature(
undefined,
factory.createIdentifier(attributeName),
undefined,
factory.createIntersectionTypeNode(nodes)
);
};
/**
* Create the base type node for a given attribute

@@ -68,3 +41,3 @@ *

*/
const getAttributeModifiers = attribute => {
const getAttributeModifiers = (attribute) => {
const modifiers = [];

@@ -156,123 +129,27 @@

const mappers = {
string() {
return ['StringAttribute'];
},
text() {
return ['TextAttribute'];
},
richtext() {
return ['RichTextAttribute'];
},
password() {
return ['PasswordAttribute'];
},
email() {
return ['EmailAttribute'];
},
date() {
return ['DateAttribute'];
},
time() {
return ['TimeAttribute'];
},
datetime() {
return ['DateTimeAttribute'];
},
timestamp() {
return ['TimestampAttribute'];
},
integer() {
return ['IntegerAttribute'];
},
biginteger() {
return ['BigIntegerAttribute'];
},
float() {
return ['FloatAttribute'];
},
decimal() {
return ['DecimalAttribute'];
},
uid({ attribute, uid }) {
const { targetField, options } = attribute;
/**
* Generate a property signature node for a given attribute
*
* @param {object} schema
* @param {string} attributeName
* @param {object} attribute
* @returns {object}
*/
const attributeToPropertySignature = (schema, attributeName, attribute) => {
const baseType = getAttributeType(attributeName, attribute, schema.uid);
// If there are no params to compute, then return the attribute type alone
if (targetField === undefined && options === undefined) {
return ['UIDAttribute'];
}
if (baseType === null) {
return null;
}
const params = [];
const modifiers = getAttributeModifiers(attribute);
// If the targetField property is defined, then reference it,
// otherwise, put `undefined` keyword type nodes as placeholders
const targetFieldParams = _.isUndefined(targetField)
? [
factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword),
factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword),
]
: [factory.createStringLiteral(uid), factory.createStringLiteral(targetField)];
const nodes = [baseType, ...modifiers];
params.push(...targetFieldParams);
// If the options property is defined, transform it to
// a type literral node and add it to the params list
if (_.isObject(options)) {
params.push(toTypeLiteral(options));
}
return ['UIDAttribute', params];
},
enumeration({ attribute }) {
const { enum: enumValues } = attribute;
return ['EnumerationAttribute', [toTypeLiteral(enumValues)]];
},
boolean() {
return ['BooleanAttribute'];
},
json() {
return ['JSONAttribute'];
},
media() {
return ['MediaAttribute'];
},
relation({ uid, attribute }) {
const { relation, target } = attribute;
const isMorphRelation = relation.toLowerCase().includes('morph');
if (isMorphRelation) {
return [
'RelationAttribute',
[factory.createStringLiteral(uid, true), factory.createStringLiteral(relation, true)],
];
}
return [
'RelationAttribute',
[
factory.createStringLiteral(uid, true),
factory.createStringLiteral(relation, true),
factory.createStringLiteral(target, true),
],
];
},
component({ attribute }) {
const target = attribute.component;
const params = [factory.createStringLiteral(target, true)];
if (attribute.repeatable) {
params.push(factory.createTrue());
}
return ['ComponentAttribute', params];
},
dynamiczone({ attribute }) {
const componentsParam = factory.createTupleTypeNode(
attribute.components.map(component => factory.createStringLiteral(component))
);
return ['DynamicZoneAttribute', [componentsParam]];
},
return factory.createPropertySignature(
undefined,
factory.createIdentifier(attributeName),
undefined,
factory.createIntersectionTypeNode(nodes)
);
};

@@ -279,0 +156,0 @@

'use strict';
/* eslint-disable no-bitwise */
const ts = require('typescript');

@@ -9,2 +11,21 @@ const { factory } = require('typescript');

/**
*
* @param {object} schemaDefinition
* @param {ts.InterfaceDeclaration} schemaDefinition.definition
* @param {object} schemaDefinition.schema
*/
const schemaDefinitionToPropertySignature = ({ schema }) => {
const { uid } = schema;
const interfaceTypeName = getSchemaInterfaceName(uid);
return factory.createPropertySignature(
undefined,
factory.createStringLiteral(uid, true),
undefined,
factory.createTypeReferenceNode(factory.createIdentifier(interfaceTypeName))
);
};
/**
* Generate the global module augmentation block

@@ -50,21 +71,2 @@ *

/**
*
* @param {object} schemaDefinition
* @param {ts.InterfaceDeclaration} schemaDefinition.definition
* @param {object} schemaDefinition.schema
*/
const schemaDefinitionToPropertySignature = ({ schema }) => {
const { uid } = schema;
const interfaceTypeName = getSchemaInterfaceName(uid);
return factory.createPropertySignature(
undefined,
factory.createStringLiteral(uid, true),
undefined,
factory.createTypeReferenceNode(factory.createIdentifier(interfaceTypeName))
);
};
module.exports = { generateGlobalDefinition };

@@ -21,3 +21,3 @@ 'use strict';

generateImportDefinition() {
const formattedImports = imports.map(key =>
const formattedImports = imports.map((key) =>
factory.createImportSpecifier(false, undefined, factory.createIdentifier(key))

@@ -24,0 +24,0 @@ );

@@ -26,63 +26,3 @@ 'use strict';

/**
* Generate type definitions for Strapi schemas
*
* @param {object} options
* @param {Strapi} options.strapi
* @param {{ distDir: string; appDir: string; }} options.dirs
* @param {string} [options.outDir]
* @param {string} [options.file]
* @param {boolean} [options.verbose]
*/
const generateSchemasDefinitions = async (options = {}) => {
const {
strapi,
outDir = process.cwd(),
file = DEFAULT_OUT_FILENAME,
verbose = false,
silent = false,
} = options;
const schemas = getAllStrapiSchemas(strapi);
const schemasDefinitions = Object.values(schemas).map(schema => ({
schema,
definition: generateSchemaDefinition(schema),
}));
const formattedSchemasDefinitions = schemasDefinitions.reduce((acc, def) => {
acc.push(
// Definition
def.definition,
// Add a newline between each interface declaration
factory.createIdentifier('\n')
);
return acc;
}, []);
const allDefinitions = [
// Imports
generateImportDefinition(),
// Add a newline after the import statement
factory.createIdentifier('\n'),
// Schemas
...formattedSchemasDefinitions,
// Global
generateGlobalDefinition(schemasDefinitions),
];
const output = emitDefinitions(allDefinitions);
const formattedOutput = await format(output);
const definitionFilepath = await saveDefinitionToFileSystem(outDir, file, formattedOutput);
logDebugInformation(schemasDefinitions, { filepath: definitionFilepath, verbose, silent });
};
const emitDefinitions = definitions => {
const emitDefinitions = (definitions) => {
const nodeArray = factory.createNodeArray(definitions);

@@ -118,3 +58,3 @@

*/
const format = async content => {
const format = async (content) => {
const configFile = await prettier.resolveConfigFile();

@@ -149,3 +89,3 @@ const config = configFile

const sortedDefinitions = definitions.map(def => ({
const sortedDefinitions = definitions.map((def) => ({
...def,

@@ -188,2 +128,62 @@ attributesCount: getDefinitionAttributesCount(def.definition),

/**
* Generate type definitions for Strapi schemas
*
* @param {object} options
* @param {Strapi} options.strapi
* @param {{ distDir: string; appDir: string; }} options.dirs
* @param {string} [options.outDir]
* @param {string} [options.file]
* @param {boolean} [options.verbose]
*/
const generateSchemasDefinitions = async (options = {}) => {
const {
strapi,
outDir = process.cwd(),
file = DEFAULT_OUT_FILENAME,
verbose = false,
silent = false,
} = options;
const schemas = getAllStrapiSchemas(strapi);
const schemasDefinitions = Object.values(schemas).map((schema) => ({
schema,
definition: generateSchemaDefinition(schema),
}));
const formattedSchemasDefinitions = schemasDefinitions.reduce((acc, def) => {
acc.push(
// Definition
def.definition,
// Add a newline between each interface declaration
factory.createIdentifier('\n')
);
return acc;
}, []);
const allDefinitions = [
// Imports
generateImportDefinition(),
// Add a newline after the import statement
factory.createIdentifier('\n'),
// Schemas
...formattedSchemasDefinitions,
// Global
generateGlobalDefinition(schemasDefinitions),
];
const output = emitDefinitions(allDefinitions);
const formattedOutput = await format(output);
const definitionFilepath = await saveDefinitionToFileSystem(outDir, file, formattedOutput);
logDebugInformation(schemasDefinitions, { filepath: definitionFilepath, verbose, silent });
};
module.exports = generateSchemasDefinitions;

@@ -12,2 +12,32 @@ 'use strict';

/**
* Generate a property signature for the schema's `attributes` field
*
* @param {object} schema
* @returns {ts.PropertySignature}
*/
const generateAttributePropertySignature = (schema) => {
const { attributes } = schema;
const properties = Object.entries(attributes).map(([attributeName, attribute]) => {
return attributeToPropertySignature(schema, attributeName, attribute);
});
return factory.createPropertySignature(
undefined,
factory.createIdentifier('attributes'),
undefined,
factory.createTypeLiteralNode(properties)
);
};
const generatePropertyLiteralDefinitionFactory = (schema) => (key) => {
return factory.createPropertySignature(
undefined,
factory.createIdentifier(key),
undefined,
toTypeLiteral(schema[key])
);
};
/**
* Generate an interface declaration for a given schema

@@ -18,3 +48,3 @@ *

*/
const generateSchemaDefinition = schema => {
const generateSchemaDefinition = (schema) => {
const { uid } = schema;

@@ -32,3 +62,3 @@

// Ignore non-existent or empty declarations
.filter(key => !isEmpty(schema[key]))
.filter((key) => !isEmpty(schema[key]))
// Generate literal definition for each property

@@ -60,32 +90,2 @@ .map(generatePropertyLiteralDefinitionFactory(schema));

/**
* Generate a property signature for the schema's `attributes` field
*
* @param {object} schema
* @returns {ts.PropertySignature}
*/
const generateAttributePropertySignature = schema => {
const { attributes } = schema;
const properties = Object.entries(attributes).map(([attributeName, attribute]) => {
return attributeToPropertySignature(schema, attributeName, attribute);
});
return factory.createPropertySignature(
undefined,
factory.createIdentifier('attributes'),
undefined,
factory.createTypeLiteralNode(properties)
);
};
const generatePropertyLiteralDefinitionFactory = schema => key => {
return factory.createPropertySignature(
undefined,
factory.createIdentifier(key),
undefined,
toTypeLiteral(schema[key])
);
};
module.exports = { generateSchemaDefinition };

@@ -26,3 +26,3 @@ 'use strict';

*/
const getAllStrapiSchemas = strapi => ({ ...strapi.contentTypes, ...strapi.components });
const getAllStrapiSchemas = (strapi) => ({ ...strapi.contentTypes, ...strapi.components });

@@ -37,15 +37,3 @@ /**

/**
* Get the parent type name to extend based on the schema's nature
*
* @param {object} schema
* @returns {string}
*/
const getSchemaExtendsTypeName = schema => {
const base = getSchemaModelType(schema);
return upperFirst(base) + 'Schema';
};
const getSchemaModelType = schema => {
const getSchemaModelType = (schema) => {
const { modelType, kind } = schema;

@@ -59,3 +47,3 @@

// Content-Types
else if (modelType === 'contentType') {
if (modelType === 'contentType') {
return kind;

@@ -68,2 +56,14 @@ }

/**
* Get the parent type name to extend based on the schema's nature
*
* @param {object} schema
* @returns {string}
*/
const getSchemaExtendsTypeName = (schema) => {
const base = getSchemaModelType(schema);
return `${upperFirst(base)}Schema`;
};
/**
* Get a type node based on a type and its params

@@ -84,3 +84,3 @@ *

*/
const toTypeLiteral = data => {
const toTypeLiteral = (data) => {
if (isUndefined(data)) {

@@ -107,3 +107,3 @@ return factory.createLiteralTypeNode(ts.SyntaxKind.UndefinedKeyword);

if (isArray(data)) {
return factory.createTupleTypeNode(data.map(item => toTypeLiteral(item)));
return factory.createTupleTypeNode(data.map((item) => toTypeLiteral(item)));
}

@@ -148,3 +148,3 @@

*/
const getDefinitionAttributesCount = definition => {
const getDefinitionAttributesCount = (definition) => {
const attributesNode = definition.members.find(propEq('name.escapedText', 'attributes'));

@@ -151,0 +151,0 @@

@@ -11,3 +11,3 @@ 'use strict';

*/
module.exports = diagnostics => {
module.exports = (diagnostics) => {
const formattedDiagnostics = ts.formatDiagnosticsWithColorAndContext(

@@ -14,0 +14,0 @@ Array.isArray(diagnostics) ? diagnostics : [diagnostics],

@@ -7,3 +7,3 @@ 'use strict';

module.exports = configPath => {
module.exports = (configPath) => {
// Parse the tsconfig.json file and resolve every file name & compiler options

@@ -10,0 +10,0 @@ const { errors, ...configOptions } = ts.getParsedCommandLineOfConfigFile(

'use strict';
const path = require('path');

@@ -3,0 +4,0 @@ const resolveConfigOptions = require('./resolve-config-options');

{
"name": "@strapi/typescript-utils",
"version": "0.0.0-8581854cb3",
"version": "0.0.0-a5ae7a818c08e91a4950ad2483d177664ba8ab04",
"description": "Typescript support for Strapi",

@@ -38,3 +38,3 @@ "keywords": [

},
"gitHead": "8581854cb3c817ae42b829ea686a1b0702ed9245"
"gitHead": "a5ae7a818c08e91a4950ad2483d177664ba8ab04"
}
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