appbuild-oceanbase-console 1.10.2 → 1.10.4
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/cjs/sdk.js +358 -169
- package/dist/cjs/sdk.js.map +1 -1
- package/dist/esm/sdk.js +358 -169
- package/dist/esm/sdk.js.map +1 -1
- package/dist/iife/sdk.js +358 -169
- package/package.json +1 -1
- package/types/migrations.d.ts +35 -0
- package/dist/cjs/package.json +0 -3
- package/dist/esm/package.json +0 -3
package/dist/cjs/sdk.js
CHANGED
|
@@ -13795,6 +13795,154 @@ exports.AttributeStatus = void 0;
|
|
|
13795
13795
|
AttributeStatus["Failed"] = "failed";
|
|
13796
13796
|
})(exports.AttributeStatus || (exports.AttributeStatus = {}));
|
|
13797
13797
|
|
|
13798
|
+
/**
|
|
13799
|
+
* Helper class to generate permission strings for resources.
|
|
13800
|
+
*/
|
|
13801
|
+
class Permission {
|
|
13802
|
+
}
|
|
13803
|
+
/**
|
|
13804
|
+
* Generate read permission string for the provided role.
|
|
13805
|
+
*
|
|
13806
|
+
* @param {string} role
|
|
13807
|
+
* @returns {string}
|
|
13808
|
+
*/
|
|
13809
|
+
Permission.read = (role) => {
|
|
13810
|
+
return `read("${role}")`;
|
|
13811
|
+
};
|
|
13812
|
+
/**
|
|
13813
|
+
* Generate write permission string for the provided role.
|
|
13814
|
+
*
|
|
13815
|
+
* This is an alias of update, delete, and possibly create.
|
|
13816
|
+
* Don't use write in combination with update, delete, or create.
|
|
13817
|
+
*
|
|
13818
|
+
* @param {string} role
|
|
13819
|
+
* @returns {string}
|
|
13820
|
+
*/
|
|
13821
|
+
Permission.write = (role) => {
|
|
13822
|
+
return `write("${role}")`;
|
|
13823
|
+
};
|
|
13824
|
+
/**
|
|
13825
|
+
* Generate create permission string for the provided role.
|
|
13826
|
+
*
|
|
13827
|
+
* @param {string} role
|
|
13828
|
+
* @returns {string}
|
|
13829
|
+
*/
|
|
13830
|
+
Permission.create = (role) => {
|
|
13831
|
+
return `create("${role}")`;
|
|
13832
|
+
};
|
|
13833
|
+
/**
|
|
13834
|
+
* Generate update permission string for the provided role.
|
|
13835
|
+
*
|
|
13836
|
+
* @param {string} role
|
|
13837
|
+
* @returns {string}
|
|
13838
|
+
*/
|
|
13839
|
+
Permission.update = (role) => {
|
|
13840
|
+
return `update("${role}")`;
|
|
13841
|
+
};
|
|
13842
|
+
/**
|
|
13843
|
+
* Generate delete permission string for the provided role.
|
|
13844
|
+
*
|
|
13845
|
+
* @param {string} role
|
|
13846
|
+
* @returns {string}
|
|
13847
|
+
*/
|
|
13848
|
+
Permission.delete = (role) => {
|
|
13849
|
+
return `delete("${role}")`;
|
|
13850
|
+
};
|
|
13851
|
+
|
|
13852
|
+
/**
|
|
13853
|
+
* Helper class to generate role strings for `Permission`.
|
|
13854
|
+
*/
|
|
13855
|
+
class Role {
|
|
13856
|
+
/**
|
|
13857
|
+
* Grants access to anyone.
|
|
13858
|
+
*
|
|
13859
|
+
* This includes authenticated and unauthenticated users.
|
|
13860
|
+
*
|
|
13861
|
+
* @returns {string}
|
|
13862
|
+
*/
|
|
13863
|
+
static any() {
|
|
13864
|
+
return 'any';
|
|
13865
|
+
}
|
|
13866
|
+
/**
|
|
13867
|
+
* Grants access to a specific user by user ID.
|
|
13868
|
+
*
|
|
13869
|
+
* You can optionally pass verified or unverified for
|
|
13870
|
+
* `status` to target specific types of users.
|
|
13871
|
+
*
|
|
13872
|
+
* @param {string} id
|
|
13873
|
+
* @param {string} status
|
|
13874
|
+
* @returns {string}
|
|
13875
|
+
*/
|
|
13876
|
+
static user(id, status = '') {
|
|
13877
|
+
if (status === '') {
|
|
13878
|
+
return `user:${id}`;
|
|
13879
|
+
}
|
|
13880
|
+
return `user:${id}/${status}`;
|
|
13881
|
+
}
|
|
13882
|
+
/**
|
|
13883
|
+
* Grants access to any authenticated or anonymous user.
|
|
13884
|
+
*
|
|
13885
|
+
* You can optionally pass verified or unverified for
|
|
13886
|
+
* `status` to target specific types of users.
|
|
13887
|
+
*
|
|
13888
|
+
* @param {string} status
|
|
13889
|
+
* @returns {string}
|
|
13890
|
+
*/
|
|
13891
|
+
static users(status = '') {
|
|
13892
|
+
if (status === '') {
|
|
13893
|
+
return 'users';
|
|
13894
|
+
}
|
|
13895
|
+
return `users/${status}`;
|
|
13896
|
+
}
|
|
13897
|
+
/**
|
|
13898
|
+
* Grants access to any guest user without a session.
|
|
13899
|
+
*
|
|
13900
|
+
* Authenticated users don't have access to this role.
|
|
13901
|
+
*
|
|
13902
|
+
* @returns {string}
|
|
13903
|
+
*/
|
|
13904
|
+
static guests() {
|
|
13905
|
+
return 'guests';
|
|
13906
|
+
}
|
|
13907
|
+
/**
|
|
13908
|
+
* Grants access to a team by team ID.
|
|
13909
|
+
*
|
|
13910
|
+
* You can optionally pass a role for `role` to target
|
|
13911
|
+
* team members with the specified role.
|
|
13912
|
+
*
|
|
13913
|
+
* @param {string} id
|
|
13914
|
+
* @param {string} role
|
|
13915
|
+
* @returns {string}
|
|
13916
|
+
*/
|
|
13917
|
+
static team(id, role = '') {
|
|
13918
|
+
if (role === '') {
|
|
13919
|
+
return `team:${id}`;
|
|
13920
|
+
}
|
|
13921
|
+
return `team:${id}/${role}`;
|
|
13922
|
+
}
|
|
13923
|
+
/**
|
|
13924
|
+
* Grants access to a specific member of a team.
|
|
13925
|
+
*
|
|
13926
|
+
* When the member is removed from the team, they will
|
|
13927
|
+
* no longer have access.
|
|
13928
|
+
*
|
|
13929
|
+
* @param {string} id
|
|
13930
|
+
* @returns {string}
|
|
13931
|
+
*/
|
|
13932
|
+
static member(id) {
|
|
13933
|
+
return `member:${id}`;
|
|
13934
|
+
}
|
|
13935
|
+
/**
|
|
13936
|
+
* Grants access to a user with the specified label.
|
|
13937
|
+
*
|
|
13938
|
+
* @param {string} name
|
|
13939
|
+
* @returns {string}
|
|
13940
|
+
*/
|
|
13941
|
+
static label(name) {
|
|
13942
|
+
return `label:${name}`;
|
|
13943
|
+
}
|
|
13944
|
+
}
|
|
13945
|
+
|
|
13798
13946
|
/**
|
|
13799
13947
|
* Database Schema Migration Tool
|
|
13800
13948
|
*
|
|
@@ -13807,6 +13955,45 @@ class SchemaMigration {
|
|
|
13807
13955
|
constructor(databases) {
|
|
13808
13956
|
this.databases = databases;
|
|
13809
13957
|
}
|
|
13958
|
+
/**
|
|
13959
|
+
* Get default permissions for collections (read, create, update, delete all set to 'any')
|
|
13960
|
+
*/
|
|
13961
|
+
getDefaultPermissions() {
|
|
13962
|
+
return [
|
|
13963
|
+
Permission.read(Role.any()),
|
|
13964
|
+
Permission.create(Role.any()),
|
|
13965
|
+
Permission.update(Role.any()),
|
|
13966
|
+
Permission.delete(Role.any())
|
|
13967
|
+
];
|
|
13968
|
+
}
|
|
13969
|
+
/**
|
|
13970
|
+
* Check if an attribute key is a built-in field that cannot be modified
|
|
13971
|
+
* Built-in fields include:
|
|
13972
|
+
* - Fields starting with '$' prefix (e.g., $id, $createdAt, $updatedAt)
|
|
13973
|
+
* - Legacy field names: id, createdAt, updatedAt
|
|
13974
|
+
*/
|
|
13975
|
+
isBuiltInAttribute(key) {
|
|
13976
|
+
// Check if starts with '$' prefix (all system/built-in fields)
|
|
13977
|
+
if (key.startsWith('$')) {
|
|
13978
|
+
return true;
|
|
13979
|
+
}
|
|
13980
|
+
// Legacy field names for backwards compatibility
|
|
13981
|
+
return key === 'id' || key === 'createdAt' || key === 'updatedAt';
|
|
13982
|
+
}
|
|
13983
|
+
/**
|
|
13984
|
+
* Check if an index key is a built-in index that cannot be modified
|
|
13985
|
+
* Built-in indexes start with '$' prefix
|
|
13986
|
+
*/
|
|
13987
|
+
isBuiltInIndex(key) {
|
|
13988
|
+
return key.startsWith('$');
|
|
13989
|
+
}
|
|
13990
|
+
/**
|
|
13991
|
+
* Check if an index contains any built-in attributes
|
|
13992
|
+
* Built-in fields cannot have indexes created or deleted
|
|
13993
|
+
*/
|
|
13994
|
+
indexContainsBuiltInAttributes(index) {
|
|
13995
|
+
return index.attributes.some(attr => this.isBuiltInAttribute(attr));
|
|
13996
|
+
}
|
|
13810
13997
|
/**
|
|
13811
13998
|
* Generate migration plan by comparing current database state with target schema
|
|
13812
13999
|
*/
|
|
@@ -13816,9 +14003,30 @@ class SchemaMigration {
|
|
|
13816
14003
|
// Store schema for later use in execution
|
|
13817
14004
|
this._currentSchema = schema;
|
|
13818
14005
|
const operations = [];
|
|
14006
|
+
const skippedBuiltIns = [];
|
|
14007
|
+
// If databaseId is empty, create a database with id "default"
|
|
14008
|
+
let databaseId = schema.databaseId;
|
|
14009
|
+
if (!databaseId || databaseId.trim() === '') {
|
|
14010
|
+
databaseId = 'default';
|
|
14011
|
+
try {
|
|
14012
|
+
yield this.databases.create({
|
|
14013
|
+
databaseId: databaseId,
|
|
14014
|
+
name: 'default',
|
|
14015
|
+
enabled: true
|
|
14016
|
+
});
|
|
14017
|
+
}
|
|
14018
|
+
catch (error) {
|
|
14019
|
+
// If database already exists, that's fine
|
|
14020
|
+
if (!(error instanceof AppwriteException && error.code === 409)) {
|
|
14021
|
+
throw error;
|
|
14022
|
+
}
|
|
14023
|
+
}
|
|
14024
|
+
// Update schema.databaseId for later use
|
|
14025
|
+
schema.databaseId = databaseId;
|
|
14026
|
+
}
|
|
13819
14027
|
// Get current tables
|
|
13820
14028
|
const currentTables = yield this.databases.listTables({
|
|
13821
|
-
databaseId:
|
|
14029
|
+
databaseId: databaseId,
|
|
13822
14030
|
total: true
|
|
13823
14031
|
});
|
|
13824
14032
|
const currentTablesMap = new Map();
|
|
@@ -13841,6 +14049,16 @@ class SchemaMigration {
|
|
|
13841
14049
|
// For new tables, create all attributes and indexes
|
|
13842
14050
|
// Process target attributes
|
|
13843
14051
|
for (const targetAttr of targetCollection.attributes) {
|
|
14052
|
+
// Skip built-in attributes (starting with '$' or legacy names)
|
|
14053
|
+
if (this.isBuiltInAttribute(targetAttr.key)) {
|
|
14054
|
+
skippedBuiltIns.push({
|
|
14055
|
+
collectionId: collectionId,
|
|
14056
|
+
key: targetAttr.key,
|
|
14057
|
+
type: 'attribute',
|
|
14058
|
+
reason: `Built-in column '${targetAttr.key}' is automatically managed by the system`
|
|
14059
|
+
});
|
|
14060
|
+
continue;
|
|
14061
|
+
}
|
|
13844
14062
|
operations.push({
|
|
13845
14063
|
type: 'createAttribute',
|
|
13846
14064
|
databaseId: schema.databaseId,
|
|
@@ -13852,6 +14070,26 @@ class SchemaMigration {
|
|
|
13852
14070
|
// Process target indexes
|
|
13853
14071
|
if (targetCollection.indexes) {
|
|
13854
14072
|
for (const targetIndex of targetCollection.indexes) {
|
|
14073
|
+
// Skip built-in indexes (starting with '$')
|
|
14074
|
+
if (this.isBuiltInIndex(targetIndex.key)) {
|
|
14075
|
+
skippedBuiltIns.push({
|
|
14076
|
+
collectionId: collectionId,
|
|
14077
|
+
key: targetIndex.key,
|
|
14078
|
+
type: 'index',
|
|
14079
|
+
reason: `Built-in index '${targetIndex.key}' is automatically managed by the system`
|
|
14080
|
+
});
|
|
14081
|
+
continue;
|
|
14082
|
+
}
|
|
14083
|
+
// Skip indexes that contain built-in attributes
|
|
14084
|
+
if (this.indexContainsBuiltInAttributes(targetIndex)) {
|
|
14085
|
+
skippedBuiltIns.push({
|
|
14086
|
+
collectionId: collectionId,
|
|
14087
|
+
key: targetIndex.key,
|
|
14088
|
+
type: 'index',
|
|
14089
|
+
reason: `Index '${targetIndex.key}' references built-in columns and is automatically managed`
|
|
14090
|
+
});
|
|
14091
|
+
continue;
|
|
14092
|
+
}
|
|
13855
14093
|
operations.push({
|
|
13856
14094
|
type: 'createIndex',
|
|
13857
14095
|
databaseId: schema.databaseId,
|
|
@@ -13888,6 +14126,16 @@ class SchemaMigration {
|
|
|
13888
14126
|
});
|
|
13889
14127
|
// Process target attributes
|
|
13890
14128
|
for (const targetAttr of targetCollection.attributes) {
|
|
14129
|
+
// Skip built-in attributes (starting with '$' or legacy names)
|
|
14130
|
+
if (this.isBuiltInAttribute(targetAttr.key)) {
|
|
14131
|
+
skippedBuiltIns.push({
|
|
14132
|
+
collectionId: collectionId,
|
|
14133
|
+
key: targetAttr.key,
|
|
14134
|
+
type: 'attribute',
|
|
14135
|
+
reason: `Built-in column '${targetAttr.key}' is automatically managed by the system`
|
|
14136
|
+
});
|
|
14137
|
+
continue;
|
|
14138
|
+
}
|
|
13891
14139
|
const currentCol = currentColumnsMap.get(targetAttr.key);
|
|
13892
14140
|
if (!currentCol) {
|
|
13893
14141
|
// Column doesn't exist - create it
|
|
@@ -13923,6 +14171,11 @@ class SchemaMigration {
|
|
|
13923
14171
|
}
|
|
13924
14172
|
// Check for columns to delete (columns in current but not in target)
|
|
13925
14173
|
for (const [key, currentAttr] of currentColumnsMap.entries()) {
|
|
14174
|
+
// Skip built-in attributes (starting with '$' or legacy names)
|
|
14175
|
+
if (this.isBuiltInAttribute(key)) {
|
|
14176
|
+
// Don't add to skippedBuiltIns here since these are existing columns, not from target schema
|
|
14177
|
+
continue;
|
|
14178
|
+
}
|
|
13926
14179
|
const targetAttr = targetCollection.attributes.find(a => a.key === key);
|
|
13927
14180
|
if (!targetAttr) {
|
|
13928
14181
|
operations.push({
|
|
@@ -13947,6 +14200,26 @@ class SchemaMigration {
|
|
|
13947
14200
|
});
|
|
13948
14201
|
// Process target indexes
|
|
13949
14202
|
for (const targetIndex of targetCollection.indexes) {
|
|
14203
|
+
// Skip built-in indexes (starting with '$')
|
|
14204
|
+
if (this.isBuiltInIndex(targetIndex.key)) {
|
|
14205
|
+
skippedBuiltIns.push({
|
|
14206
|
+
collectionId: collectionId,
|
|
14207
|
+
key: targetIndex.key,
|
|
14208
|
+
type: 'index',
|
|
14209
|
+
reason: `Built-in index '${targetIndex.key}' is automatically managed by the system`
|
|
14210
|
+
});
|
|
14211
|
+
continue;
|
|
14212
|
+
}
|
|
14213
|
+
// Skip indexes that contain built-in attributes
|
|
14214
|
+
if (this.indexContainsBuiltInAttributes(targetIndex)) {
|
|
14215
|
+
skippedBuiltIns.push({
|
|
14216
|
+
collectionId: collectionId,
|
|
14217
|
+
key: targetIndex.key,
|
|
14218
|
+
type: 'index',
|
|
14219
|
+
reason: `Index '${targetIndex.key}' references built-in columns and is automatically managed`
|
|
14220
|
+
});
|
|
14221
|
+
continue;
|
|
14222
|
+
}
|
|
13950
14223
|
const currentIndex = currentIndexesMap.get(targetIndex.key);
|
|
13951
14224
|
if (!currentIndex) {
|
|
13952
14225
|
// Index doesn't exist - create it
|
|
@@ -13982,6 +14255,17 @@ class SchemaMigration {
|
|
|
13982
14255
|
}
|
|
13983
14256
|
// Check for indexes to delete
|
|
13984
14257
|
for (const [key, currentIndex] of currentIndexesMap.entries()) {
|
|
14258
|
+
// Skip built-in indexes (starting with '$')
|
|
14259
|
+
if (this.isBuiltInIndex(key)) {
|
|
14260
|
+
// Don't add to skippedBuiltIns here since these are existing indexes, not from target schema
|
|
14261
|
+
continue;
|
|
14262
|
+
}
|
|
14263
|
+
// Skip indexes that contain built-in attributes
|
|
14264
|
+
const indexAttributes = currentIndex.columns || [];
|
|
14265
|
+
if (indexAttributes.some((attr) => this.isBuiltInAttribute(attr))) {
|
|
14266
|
+
// Don't add to skippedBuiltIns here since these are existing indexes
|
|
14267
|
+
continue;
|
|
14268
|
+
}
|
|
13985
14269
|
const targetIndex = targetCollection.indexes.find(i => i.key === key);
|
|
13986
14270
|
if (!targetIndex) {
|
|
13987
14271
|
operations.push({
|
|
@@ -14021,7 +14305,8 @@ class SchemaMigration {
|
|
|
14021
14305
|
};
|
|
14022
14306
|
return {
|
|
14023
14307
|
operations,
|
|
14024
|
-
summary
|
|
14308
|
+
summary,
|
|
14309
|
+
skippedBuiltIns
|
|
14025
14310
|
};
|
|
14026
14311
|
});
|
|
14027
14312
|
}
|
|
@@ -14126,6 +14411,25 @@ class SchemaMigration {
|
|
|
14126
14411
|
plan.operations.forEach((op, index) => {
|
|
14127
14412
|
console.log(`${index + 1}. [${op.type}] ${op.reason}`);
|
|
14128
14413
|
});
|
|
14414
|
+
// Display skipped built-in items
|
|
14415
|
+
if (plan.skippedBuiltIns && plan.skippedBuiltIns.length > 0) {
|
|
14416
|
+
console.log('\n=== SKIPPED BUILT-IN ITEMS ===');
|
|
14417
|
+
console.log('The following items are built-in (starting with "$") and automatically managed by the system:');
|
|
14418
|
+
const skippedAttributes = plan.skippedBuiltIns.filter(item => item.type === 'attribute');
|
|
14419
|
+
const skippedIndexes = plan.skippedBuiltIns.filter(item => item.type === 'index');
|
|
14420
|
+
if (skippedAttributes.length > 0) {
|
|
14421
|
+
console.log('\nBuilt-in Columns:');
|
|
14422
|
+
skippedAttributes.forEach(item => {
|
|
14423
|
+
console.log(` - [${item.collectionId}] ${item.key}: ${item.reason}`);
|
|
14424
|
+
});
|
|
14425
|
+
}
|
|
14426
|
+
if (skippedIndexes.length > 0) {
|
|
14427
|
+
console.log('\nBuilt-in Indexes:');
|
|
14428
|
+
skippedIndexes.forEach(item => {
|
|
14429
|
+
console.log(` - [${item.collectionId}] ${item.key}: ${item.reason}`);
|
|
14430
|
+
});
|
|
14431
|
+
}
|
|
14432
|
+
}
|
|
14129
14433
|
return;
|
|
14130
14434
|
}
|
|
14131
14435
|
// Store schema for use in executeOperation
|
|
@@ -14304,7 +14608,7 @@ class SchemaMigration {
|
|
|
14304
14608
|
* Execute a single migration operation
|
|
14305
14609
|
*/
|
|
14306
14610
|
executeOperation(operation) {
|
|
14307
|
-
var _a, _b, _c, _d;
|
|
14611
|
+
var _a, _b, _c, _d, _e, _f;
|
|
14308
14612
|
return __awaiter(this, void 0, void 0, function* () {
|
|
14309
14613
|
switch (operation.type) {
|
|
14310
14614
|
case 'createCollection':
|
|
@@ -14317,7 +14621,7 @@ class SchemaMigration {
|
|
|
14317
14621
|
name: operation.collectionName,
|
|
14318
14622
|
rowSecurity: (_a = targetCollection === null || targetCollection === void 0 ? void 0 : targetCollection.documentSecurity) !== null && _a !== void 0 ? _a : false,
|
|
14319
14623
|
enabled: (_b = targetCollection === null || targetCollection === void 0 ? void 0 : targetCollection.enabled) !== null && _b !== void 0 ? _b : true,
|
|
14320
|
-
permissions: targetCollection === null || targetCollection === void 0 ? void 0 : targetCollection.permissions
|
|
14624
|
+
permissions: (_c = targetCollection === null || targetCollection === void 0 ? void 0 : targetCollection.permissions) !== null && _c !== void 0 ? _c : this.getDefaultPermissions()
|
|
14321
14625
|
});
|
|
14322
14626
|
break;
|
|
14323
14627
|
case 'updateCollection':
|
|
@@ -14328,9 +14632,9 @@ class SchemaMigration {
|
|
|
14328
14632
|
databaseId: operation.databaseId,
|
|
14329
14633
|
tableId: operation.collectionId,
|
|
14330
14634
|
name: operation.collectionName || operation.collectionId,
|
|
14331
|
-
rowSecurity: (
|
|
14332
|
-
enabled: (
|
|
14333
|
-
permissions: updateTargetCollection === null || updateTargetCollection === void 0 ? void 0 : updateTargetCollection.permissions
|
|
14635
|
+
rowSecurity: (_d = updateTargetCollection === null || updateTargetCollection === void 0 ? void 0 : updateTargetCollection.documentSecurity) !== null && _d !== void 0 ? _d : false,
|
|
14636
|
+
enabled: (_e = updateTargetCollection === null || updateTargetCollection === void 0 ? void 0 : updateTargetCollection.enabled) !== null && _e !== void 0 ? _e : true,
|
|
14637
|
+
permissions: (_f = updateTargetCollection === null || updateTargetCollection === void 0 ? void 0 : updateTargetCollection.permissions) !== null && _f !== void 0 ? _f : this.getDefaultPermissions()
|
|
14334
14638
|
});
|
|
14335
14639
|
break;
|
|
14336
14640
|
case 'deleteCollection':
|
|
@@ -14343,12 +14647,22 @@ class SchemaMigration {
|
|
|
14343
14647
|
if (!operation.attribute) {
|
|
14344
14648
|
throw new Error('Attribute definition missing for createAttribute operation');
|
|
14345
14649
|
}
|
|
14650
|
+
// Skip built-in attributes (id, createdAt, updatedAt)
|
|
14651
|
+
if (this.isBuiltInAttribute(operation.attribute.key)) {
|
|
14652
|
+
console.log(`Skipping createAttribute for built-in field: ${operation.attribute.key}`);
|
|
14653
|
+
break;
|
|
14654
|
+
}
|
|
14346
14655
|
yield this.createAttribute(operation.databaseId, operation.collectionId, operation.attribute);
|
|
14347
14656
|
break;
|
|
14348
14657
|
case 'deleteAttribute':
|
|
14349
14658
|
if (!operation.attributeKey) {
|
|
14350
14659
|
throw new Error('Column key missing for deleteAttribute operation');
|
|
14351
14660
|
}
|
|
14661
|
+
// Skip built-in attributes (id, createdAt, updatedAt)
|
|
14662
|
+
if (this.isBuiltInAttribute(operation.attributeKey)) {
|
|
14663
|
+
console.log(`Skipping deleteAttribute for built-in field: ${operation.attributeKey}`);
|
|
14664
|
+
break;
|
|
14665
|
+
}
|
|
14352
14666
|
yield this.databases.deleteColumn({
|
|
14353
14667
|
databaseId: operation.databaseId,
|
|
14354
14668
|
tableId: operation.collectionId,
|
|
@@ -14361,6 +14675,16 @@ class SchemaMigration {
|
|
|
14361
14675
|
if (!operation.index) {
|
|
14362
14676
|
throw new Error('Index definition missing for createIndex operation');
|
|
14363
14677
|
}
|
|
14678
|
+
// Skip built-in indexes (starting with '$')
|
|
14679
|
+
if (this.isBuiltInIndex(operation.index.key)) {
|
|
14680
|
+
console.log(`Skipping createIndex for built-in index: ${operation.index.key}`);
|
|
14681
|
+
break;
|
|
14682
|
+
}
|
|
14683
|
+
// Skip indexes that contain built-in attributes
|
|
14684
|
+
if (this.indexContainsBuiltInAttributes(operation.index)) {
|
|
14685
|
+
console.log(`Skipping createIndex for index ${operation.index.key} because it contains built-in attributes`);
|
|
14686
|
+
break;
|
|
14687
|
+
}
|
|
14364
14688
|
// Wait for all attributes used in the index to be available
|
|
14365
14689
|
yield this.waitForAttributesAvailable(operation.databaseId, operation.collectionId, operation.index.attributes);
|
|
14366
14690
|
yield this.databases.createIndex({
|
|
@@ -14377,6 +14701,11 @@ class SchemaMigration {
|
|
|
14377
14701
|
if (!operation.indexKey) {
|
|
14378
14702
|
throw new Error('Index key missing for deleteIndex operation');
|
|
14379
14703
|
}
|
|
14704
|
+
// Skip built-in indexes (starting with '$')
|
|
14705
|
+
if (this.isBuiltInIndex(operation.indexKey)) {
|
|
14706
|
+
console.log(`Skipping deleteIndex for built-in index: ${operation.indexKey}`);
|
|
14707
|
+
break;
|
|
14708
|
+
}
|
|
14380
14709
|
// Check if index exists before deleting
|
|
14381
14710
|
try {
|
|
14382
14711
|
const indexesList = yield this.databases.listIndexes({
|
|
@@ -14384,12 +14713,18 @@ class SchemaMigration {
|
|
|
14384
14713
|
tableId: operation.collectionId,
|
|
14385
14714
|
total: true
|
|
14386
14715
|
});
|
|
14387
|
-
const
|
|
14388
|
-
if (!
|
|
14716
|
+
const indexToDelete = indexesList.indexes.find(idx => idx.key === operation.indexKey);
|
|
14717
|
+
if (!indexToDelete) {
|
|
14389
14718
|
// Index doesn't exist, skip deletion
|
|
14390
14719
|
console.log(`Index ${operation.indexKey} does not exist, skipping deletion`);
|
|
14391
14720
|
break;
|
|
14392
14721
|
}
|
|
14722
|
+
// Check if index contains built-in attributes
|
|
14723
|
+
const indexAttributes = indexToDelete.columns || [];
|
|
14724
|
+
if (indexAttributes.some((attr) => this.isBuiltInAttribute(attr))) {
|
|
14725
|
+
console.log(`Skipping deleteIndex for index ${operation.indexKey} because it contains built-in attributes`);
|
|
14726
|
+
break;
|
|
14727
|
+
}
|
|
14393
14728
|
}
|
|
14394
14729
|
catch (error) {
|
|
14395
14730
|
// If we can't list indexes, try to delete anyway (might fail gracefully)
|
|
@@ -14417,45 +14752,47 @@ class SchemaMigration {
|
|
|
14417
14752
|
key: attr.key,
|
|
14418
14753
|
required: attr.required
|
|
14419
14754
|
};
|
|
14755
|
+
// Required fields cannot have default values
|
|
14756
|
+
const defaultParams = attr.required ? {} : (attr.default !== undefined ? { xdefault: attr.default } : {});
|
|
14420
14757
|
switch (attr.type) {
|
|
14421
14758
|
case 'string':
|
|
14422
|
-
yield this.databases.createStringColumn(Object.assign(Object.assign({}, baseParams), { size: attr.size || 255,
|
|
14759
|
+
yield this.databases.createStringColumn(Object.assign(Object.assign(Object.assign(Object.assign({}, baseParams), { size: attr.size || 255 }), defaultParams), { array: attr.array, encrypt: attr.encrypt }));
|
|
14423
14760
|
break;
|
|
14424
14761
|
case 'integer':
|
|
14425
|
-
yield this.databases.createIntegerColumn(Object.assign(Object.assign({}, baseParams), { min: attr.min, max: attr.max,
|
|
14762
|
+
yield this.databases.createIntegerColumn(Object.assign(Object.assign(Object.assign(Object.assign({}, baseParams), { min: attr.min, max: attr.max }), defaultParams), { array: attr.array }));
|
|
14426
14763
|
break;
|
|
14427
14764
|
case 'float':
|
|
14428
|
-
yield this.databases.createFloatColumn(Object.assign(Object.assign({}, baseParams), { min: attr.min, max: attr.max,
|
|
14765
|
+
yield this.databases.createFloatColumn(Object.assign(Object.assign(Object.assign(Object.assign({}, baseParams), { min: attr.min, max: attr.max }), defaultParams), { array: attr.array }));
|
|
14429
14766
|
break;
|
|
14430
14767
|
case 'boolean':
|
|
14431
|
-
yield this.databases.createBooleanColumn(Object.assign(Object.assign({}, baseParams), {
|
|
14768
|
+
yield this.databases.createBooleanColumn(Object.assign(Object.assign(Object.assign({}, baseParams), defaultParams), { array: attr.array }));
|
|
14432
14769
|
break;
|
|
14433
14770
|
case 'datetime':
|
|
14434
|
-
yield this.databases.createDatetimeColumn(Object.assign(Object.assign({}, baseParams), {
|
|
14771
|
+
yield this.databases.createDatetimeColumn(Object.assign(Object.assign(Object.assign({}, baseParams), defaultParams), { array: attr.array }));
|
|
14435
14772
|
break;
|
|
14436
14773
|
case 'email':
|
|
14437
|
-
yield this.databases.createEmailColumn(Object.assign(Object.assign({}, baseParams), {
|
|
14774
|
+
yield this.databases.createEmailColumn(Object.assign(Object.assign(Object.assign({}, baseParams), defaultParams), { array: attr.array }));
|
|
14438
14775
|
break;
|
|
14439
14776
|
case 'enum':
|
|
14440
14777
|
if (!attr.elements) {
|
|
14441
14778
|
throw new Error('Enum column requires elements array');
|
|
14442
14779
|
}
|
|
14443
|
-
yield this.databases.createEnumColumn(Object.assign(Object.assign({}, baseParams), { elements: attr.elements,
|
|
14780
|
+
yield this.databases.createEnumColumn(Object.assign(Object.assign(Object.assign(Object.assign({}, baseParams), { elements: attr.elements }), defaultParams), { array: attr.array }));
|
|
14444
14781
|
break;
|
|
14445
14782
|
case 'url':
|
|
14446
|
-
yield this.databases.createUrlColumn(Object.assign(Object.assign({}, baseParams), {
|
|
14783
|
+
yield this.databases.createUrlColumn(Object.assign(Object.assign(Object.assign({}, baseParams), defaultParams), { array: attr.array }));
|
|
14447
14784
|
break;
|
|
14448
14785
|
case 'ip':
|
|
14449
|
-
yield this.databases.createIpColumn(Object.assign(Object.assign({}, baseParams), {
|
|
14786
|
+
yield this.databases.createIpColumn(Object.assign(Object.assign(Object.assign({}, baseParams), defaultParams), { array: attr.array }));
|
|
14450
14787
|
break;
|
|
14451
14788
|
case 'point':
|
|
14452
|
-
yield this.databases.createPointColumn(Object.assign(Object.assign({}, baseParams),
|
|
14789
|
+
yield this.databases.createPointColumn(Object.assign(Object.assign({}, baseParams), defaultParams));
|
|
14453
14790
|
break;
|
|
14454
14791
|
case 'line':
|
|
14455
|
-
yield this.databases.createLineColumn(Object.assign(Object.assign({}, baseParams),
|
|
14792
|
+
yield this.databases.createLineColumn(Object.assign(Object.assign({}, baseParams), defaultParams));
|
|
14456
14793
|
break;
|
|
14457
14794
|
case 'polygon':
|
|
14458
|
-
yield this.databases.createPolygonColumn(Object.assign(Object.assign({}, baseParams),
|
|
14795
|
+
yield this.databases.createPolygonColumn(Object.assign(Object.assign({}, baseParams), defaultParams));
|
|
14459
14796
|
break;
|
|
14460
14797
|
case 'relationship':
|
|
14461
14798
|
if (!attr.relatedCollectionId) {
|
|
@@ -25590,154 +25927,6 @@ class Realtime {
|
|
|
25590
25927
|
}
|
|
25591
25928
|
}
|
|
25592
25929
|
|
|
25593
|
-
/**
|
|
25594
|
-
* Helper class to generate permission strings for resources.
|
|
25595
|
-
*/
|
|
25596
|
-
class Permission {
|
|
25597
|
-
}
|
|
25598
|
-
/**
|
|
25599
|
-
* Generate read permission string for the provided role.
|
|
25600
|
-
*
|
|
25601
|
-
* @param {string} role
|
|
25602
|
-
* @returns {string}
|
|
25603
|
-
*/
|
|
25604
|
-
Permission.read = (role) => {
|
|
25605
|
-
return `read("${role}")`;
|
|
25606
|
-
};
|
|
25607
|
-
/**
|
|
25608
|
-
* Generate write permission string for the provided role.
|
|
25609
|
-
*
|
|
25610
|
-
* This is an alias of update, delete, and possibly create.
|
|
25611
|
-
* Don't use write in combination with update, delete, or create.
|
|
25612
|
-
*
|
|
25613
|
-
* @param {string} role
|
|
25614
|
-
* @returns {string}
|
|
25615
|
-
*/
|
|
25616
|
-
Permission.write = (role) => {
|
|
25617
|
-
return `write("${role}")`;
|
|
25618
|
-
};
|
|
25619
|
-
/**
|
|
25620
|
-
* Generate create permission string for the provided role.
|
|
25621
|
-
*
|
|
25622
|
-
* @param {string} role
|
|
25623
|
-
* @returns {string}
|
|
25624
|
-
*/
|
|
25625
|
-
Permission.create = (role) => {
|
|
25626
|
-
return `create("${role}")`;
|
|
25627
|
-
};
|
|
25628
|
-
/**
|
|
25629
|
-
* Generate update permission string for the provided role.
|
|
25630
|
-
*
|
|
25631
|
-
* @param {string} role
|
|
25632
|
-
* @returns {string}
|
|
25633
|
-
*/
|
|
25634
|
-
Permission.update = (role) => {
|
|
25635
|
-
return `update("${role}")`;
|
|
25636
|
-
};
|
|
25637
|
-
/**
|
|
25638
|
-
* Generate delete permission string for the provided role.
|
|
25639
|
-
*
|
|
25640
|
-
* @param {string} role
|
|
25641
|
-
* @returns {string}
|
|
25642
|
-
*/
|
|
25643
|
-
Permission.delete = (role) => {
|
|
25644
|
-
return `delete("${role}")`;
|
|
25645
|
-
};
|
|
25646
|
-
|
|
25647
|
-
/**
|
|
25648
|
-
* Helper class to generate role strings for `Permission`.
|
|
25649
|
-
*/
|
|
25650
|
-
class Role {
|
|
25651
|
-
/**
|
|
25652
|
-
* Grants access to anyone.
|
|
25653
|
-
*
|
|
25654
|
-
* This includes authenticated and unauthenticated users.
|
|
25655
|
-
*
|
|
25656
|
-
* @returns {string}
|
|
25657
|
-
*/
|
|
25658
|
-
static any() {
|
|
25659
|
-
return 'any';
|
|
25660
|
-
}
|
|
25661
|
-
/**
|
|
25662
|
-
* Grants access to a specific user by user ID.
|
|
25663
|
-
*
|
|
25664
|
-
* You can optionally pass verified or unverified for
|
|
25665
|
-
* `status` to target specific types of users.
|
|
25666
|
-
*
|
|
25667
|
-
* @param {string} id
|
|
25668
|
-
* @param {string} status
|
|
25669
|
-
* @returns {string}
|
|
25670
|
-
*/
|
|
25671
|
-
static user(id, status = '') {
|
|
25672
|
-
if (status === '') {
|
|
25673
|
-
return `user:${id}`;
|
|
25674
|
-
}
|
|
25675
|
-
return `user:${id}/${status}`;
|
|
25676
|
-
}
|
|
25677
|
-
/**
|
|
25678
|
-
* Grants access to any authenticated or anonymous user.
|
|
25679
|
-
*
|
|
25680
|
-
* You can optionally pass verified or unverified for
|
|
25681
|
-
* `status` to target specific types of users.
|
|
25682
|
-
*
|
|
25683
|
-
* @param {string} status
|
|
25684
|
-
* @returns {string}
|
|
25685
|
-
*/
|
|
25686
|
-
static users(status = '') {
|
|
25687
|
-
if (status === '') {
|
|
25688
|
-
return 'users';
|
|
25689
|
-
}
|
|
25690
|
-
return `users/${status}`;
|
|
25691
|
-
}
|
|
25692
|
-
/**
|
|
25693
|
-
* Grants access to any guest user without a session.
|
|
25694
|
-
*
|
|
25695
|
-
* Authenticated users don't have access to this role.
|
|
25696
|
-
*
|
|
25697
|
-
* @returns {string}
|
|
25698
|
-
*/
|
|
25699
|
-
static guests() {
|
|
25700
|
-
return 'guests';
|
|
25701
|
-
}
|
|
25702
|
-
/**
|
|
25703
|
-
* Grants access to a team by team ID.
|
|
25704
|
-
*
|
|
25705
|
-
* You can optionally pass a role for `role` to target
|
|
25706
|
-
* team members with the specified role.
|
|
25707
|
-
*
|
|
25708
|
-
* @param {string} id
|
|
25709
|
-
* @param {string} role
|
|
25710
|
-
* @returns {string}
|
|
25711
|
-
*/
|
|
25712
|
-
static team(id, role = '') {
|
|
25713
|
-
if (role === '') {
|
|
25714
|
-
return `team:${id}`;
|
|
25715
|
-
}
|
|
25716
|
-
return `team:${id}/${role}`;
|
|
25717
|
-
}
|
|
25718
|
-
/**
|
|
25719
|
-
* Grants access to a specific member of a team.
|
|
25720
|
-
*
|
|
25721
|
-
* When the member is removed from the team, they will
|
|
25722
|
-
* no longer have access.
|
|
25723
|
-
*
|
|
25724
|
-
* @param {string} id
|
|
25725
|
-
* @returns {string}
|
|
25726
|
-
*/
|
|
25727
|
-
static member(id) {
|
|
25728
|
-
return `member:${id}`;
|
|
25729
|
-
}
|
|
25730
|
-
/**
|
|
25731
|
-
* Grants access to a user with the specified label.
|
|
25732
|
-
*
|
|
25733
|
-
* @param {string} name
|
|
25734
|
-
* @returns {string}
|
|
25735
|
-
*/
|
|
25736
|
-
static label(name) {
|
|
25737
|
-
return `label:${name}`;
|
|
25738
|
-
}
|
|
25739
|
-
}
|
|
25740
|
-
|
|
25741
25930
|
var _a, _ID_hexTimestamp;
|
|
25742
25931
|
/**
|
|
25743
25932
|
* Helper class to generate ID strings for resources.
|