Skip to content

Commit

Permalink
fix: PR changes
Browse files Browse the repository at this point in the history
  • Loading branch information
anku255 committed Apr 18, 2024
1 parent f8cf9de commit 417b2df
Show file tree
Hide file tree
Showing 5 changed files with 257 additions and 46 deletions.
2 changes: 1 addition & 1 deletion bulkimport_scripts/add_users_for_bulk_import/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
node_modules
./usersHavingInvalidSchema.json
./remainingUsers.json
./remainingUsers.json
23 changes: 14 additions & 9 deletions bulkimport_scripts/add_users_for_bulk_import/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@ The `/bulk-import/users` POST API endpoint in SuperTokens Core allows to add use

## How to Run

1. Ensure you have Node.js (V16 or higher) installed on your system.
1. Ensure you have Node.js (v16 or higher) installed on your system.
2. Open a terminal window and navigate to the directory where the script is located.
3. Run the following command:
3. Run `npm install` to install necessary dependencies.
4. Run the script using the following command:

```
node index.js <CoreAPIURL> <InputFileName>
```
```
node index.js --core-endpoint <CoreAPIURL> --input-file <InputFileName> [--invalid-schema-file <InvalidSchemaFile>] [--remaining-users-file <RemainingUsersFile>]
```
Replace `<CoreAPIURL>` with the URL of the core API endpoint and `<InputFileName>` with the path to the input JSON file containing user data.
- Replace `<CoreAPIURL>` with the URL of the core API endpoint.
- Replace `<InputFileName>` with the path to the input JSON file containing user data.
- Optionally, you can specify the paths for the output files:
- `--invalid-schema-file <InvalidSchemaFile>` specifies the path to the file storing users with invalid schema (default is `./usersHavingInvalidSchema.json`).
- `--remaining-users-file <RemainingUsersFile>` specifies the path to the file storing remaining users (default is `./remainingUsers.json`).
## Format of Input File
Expand All @@ -21,9 +26,9 @@ The input file should be a JSON file with the same format as requested by the `/
## Expected Outputs
- Upon successful execution, the script will output a summary message indicating the number of users processed, any remaining users, and any users with invalid schema.
- If there are remaining users to be processed, a file named `remainingUsers.json` will be generated, containing the details of remaining users.
- If there are users with invalid schema, a file named `usersHavingInvalidSchema.json` will be generated, containing the details of users with invalid schema.
- If there are remaining users to be processed, the file specified by `--remaining-users-file` (default `remainingUsers.json`) will be generated, containing the details of remaining users.
- If there are users with invalid schema, the file specified by `--invalid-schema-file` (default `usersHavingInvalidSchema.json`) will be generated, containing the details of users with invalid schema.
## Note
The script would re-write the `remainingUsers.json` and `usersHavingInvalidSchema.json` files on each run. Ensure to back up these files if needed.
The script would re-write the files specified by `--remaining-users-file` and `--invalid-schema-file` options on each run. Ensure to back up these files if needed.
94 changes: 59 additions & 35 deletions bulkimport_scripts/add_users_for_bulk_import/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,47 @@
*/

const fs = require('fs/promises');
const yargs = require('yargs');
const process = require('process');

const BATCH_SIZE = 10000;
const USERS_HAVING_INVALID_SCHEMA_FILE = './usersHavingInvalidSchema.json';
const REMAINING_USERS_FILE = './remainingUsers.json';

function parseInputArgs() {
if (process.argv.length !== 4) {
console.error('Usage: node index.js <CoreAPIURL> <InputFileName>');
process.exit(1);
}

return { coreAPIUrl: process.argv[2], inputFileName: process.argv[3] };
async function parseInputArgs() {
const argv = await yargs
.option('core-endpoint', {
alias: 'c',
type: 'string',
describe: 'Core API URL endpoint',
demandOption: true,
})
.option('input-file', {
alias: 'i',
type: 'string',
describe: 'Path to the input file',
demandOption: true,
})
.option('invalid-schema-file', {
alias: 's',
type: 'string',
describe: 'Path to the file storing users with invalid schema',
default: './usersHavingInvalidSchema.json',
})
.option('remaining-users-file', {
alias: 'r',
type: 'string',
describe: 'Path to the file storing remaining users',
default: './remainingUsers.json',
})
.argv;

return {
coreAPIUrl: argv['core-endpoint'],
inputFileName: argv['input-file'],
usersHavingInvalidSchemaFileName: argv['invalid-schema-file'],
remainingUsersFileName: argv['remaining-users-file'],
};
}


async function getUsersFromInputFile({ inputFileName }) {
try {
const inputFileDataString = await fs.readFile(inputFileName, 'utf8');
Expand All @@ -47,20 +72,20 @@ async function getUsersFromInputFile({ inputFileName }) {
}
}

async function deleteFailedToAddUsersFileIfExists() {
async function deleteUsersHavingInvalidSchemaFileIfExists({ usersHavingInvalidSchemaFileName }) {
try {
await fs.rm(USERS_HAVING_INVALID_SCHEMA_FILE);
await fs.rm(usersHavingInvalidSchemaFileName);
} catch (error) {
if (error.code !== 'ENOENT') {
console.error(`Failed to delete ${USERS_HAVING_INVALID_SCHEMA_FILE}:`, error.message);
console.error(`Failed to delete ${usersHavingInvalidSchemaFileName}:`, error.message);
}
}
}

async function addInvalidSchemaUsersToFile({ errors, users }) {
async function addInvalidSchemaUsersToFile({ errors, users, usersHavingInvalidSchemaFileName }) {
let parsedData = null;
try {
const existingData = await fs.readFile(USERS_HAVING_INVALID_SCHEMA_FILE, 'utf8');
const existingData = await fs.readFile(usersHavingInvalidSchemaFileName, 'utf8');
parsedData = JSON.parse(existingData);
} catch (error) {
if (error.code === 'ENOENT') {
Expand All @@ -71,35 +96,35 @@ async function addInvalidSchemaUsersToFile({ errors, users }) {
}
}

parsedData.users.push(...errors.map((err, index) => ({ user: users[index], errors: err.errors })));
parsedData.users.push(...errors.map((err) => ({ user: users[err.index], errors: err.errors })));

await fs.writeFile(USERS_HAVING_INVALID_SCHEMA_FILE, JSON.stringify(parsedData, null, 2));
await fs.writeFile(usersHavingInvalidSchemaFileName, JSON.stringify(parsedData, null, 2));

return users.filter((_, index) => !errors.some(err => err.index === index));
}

async function updateRemainingUsersFile({ users, index }) {
async function updateRemainingUsersFile({ users, index, remainingUsersFileName }) {
const remainingUsers = users.slice(index + 1);
await fs.writeFile(REMAINING_USERS_FILE, JSON.stringify({ users: remainingUsers }, null, 2));
await fs.writeFile(remainingUsersFileName, JSON.stringify({ users: remainingUsers }, null, 2));
}

async function removeRemainingUsersFile() {
async function removeRemainingUsersFile({ remainingUsersFileName }) {
try {
await fs.rm(REMAINING_USERS_FILE);
await fs.rm(remainingUsersFileName);
} catch (error) {
if (error.code !== 'ENOENT') {
console.error(`Failed to delete ${REMAINING_USERS_FILE}:`, error.message);
console.error(`Failed to delete ${remainingUsersFileName}:`, error.message);
}
}
}

async function main() {
const { coreAPIUrl, inputFileName } = parseInputArgs();
const { coreAPIUrl, inputFileName, usersHavingInvalidSchemaFileName, remainingUsersFileName } = await parseInputArgs();

const users = await getUsersFromInputFile({ inputFileName });

await deleteFailedToAddUsersFileIfExists();
await updateRemainingUsersFile({ users, index: 0 });
await deleteUsersHavingInvalidSchemaFileIfExists({ usersHavingInvalidSchemaFileName });
await updateRemainingUsersFile({ users, index: 0, remainingUsersFileName });

let usersToProcessInBatch = [];
let usersHavingInvalidSchemaCount = 0;
Expand Down Expand Up @@ -129,9 +154,9 @@ async function main() {
if (res.status === 400) {
const errors = await res.json();
usersHavingInvalidSchemaCount += errors.users.length;
usersToProcessInBatch = await addInvalidSchemaUsersToFile({ errors: errors.users, users: usersToProcessInBatch });
usersToProcessInBatch = await addInvalidSchemaUsersToFile({ errors: errors.users, users: usersToProcessInBatch, usersHavingInvalidSchemaFileName });
} else {
await updateRemainingUsersFile({ users, index: i });
await updateRemainingUsersFile({ users, index: i, remainingUsersFileName });
usersToProcessInBatch = [];
}

Expand All @@ -146,22 +171,21 @@ async function main() {
processedUsers: i,
remainingUsers: users.length - i,
usersHavingInvalidSchema: usersHavingInvalidSchemaCount,
...(users.length - i > 0 && { remainingUsersFileName: REMAINING_USERS_FILE }),
...(usersHavingInvalidSchemaCount > 0 && { usersHavingInvalidSchemaFileName: USERS_HAVING_INVALID_SCHEMA_FILE }),
...(users.length - i > 0 && { remainingUsersFileName }),
...(usersHavingInvalidSchemaCount > 0 && { usersHavingInvalidSchemaFileName }),
};

if (i < users.length) {
const message = usersHavingInvalidSchemaCount > 0 ?
`We processed ${i} users and ${usersHavingInvalidSchemaCount} users have invalid schema! Remaining users can be processed again by processing the ${REMAINING_USERS_FILE} file and users having invalid schema needs to be fixed and processed again by processing the ${USERS_HAVING_INVALID_SCHEMA_FILE} file.`
: `We processed ${i} users and ${users.length - i} users are remaining to be processed! Remaining users can be processed again by processing the ${REMAINING_USERS_FILE} file.`;
`We processed ${i} users and ${usersHavingInvalidSchemaCount} users have invalid schema! Remaining users can be processed again by processing the ${remainingUsersFileName} file and users having invalid schema needs to be fixed and processed again by processing the ${usersHavingInvalidSchemaFileName} file.`
: `We processed ${i} users and ${users.length - i} users are remaining to be processed! Remaining users can be processed again by processing the ${remainingUsersFileName} file.`;
console.log({ message, ...result });
} else {
await removeRemainingUsersFile();
await removeRemainingUsersFile({ remainingUsersFileName });
const message = usersHavingInvalidSchemaCount > 0 ?
`All users processed but ${usersHavingInvalidSchemaCount} users have invalid schema! Users having invalid schema needs to be fixed and processed again by processing the ${USERS_HAVING_INVALID_SCHEMA_FILE} file.` : `All users processed successfully!`;
`All users processed but ${usersHavingInvalidSchemaCount} users have invalid schema! Users having invalid schema needs to be fixed and processed again by processing the ${usersHavingInvalidSchemaFileName} file.` : `All users processed successfully!`;
console.log({ message, ...result }); ``
}
}


main()
main()
Loading

0 comments on commit 417b2df

Please sign in to comment.