@twilio/conversations 1.3.0-rc7 → 2.0.0-rc.3
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/CHANGELOG.md +201 -0
- package/README.md +5 -5
- package/dist/browser.js +7866 -0
- package/dist/browser.js.map +1 -0
- package/dist/docs/assets/css/main.css +2660 -0
- package/dist/docs/assets/images/icons.png +0 -0
- package/dist/docs/assets/images/icons@2x.png +0 -0
- package/dist/docs/assets/images/widgets.png +0 -0
- package/dist/docs/assets/images/widgets@2x.png +0 -0
- package/dist/docs/assets/js/main.js +248 -0
- package/dist/docs/assets/js/search.js +1 -0
- package/dist/docs/classes/AggregatedDeliveryReceipt.html +3286 -0
- package/dist/docs/classes/Client.html +4181 -0
- package/dist/docs/classes/Conversation.html +4397 -0
- package/dist/docs/classes/DetailedDeliveryReceipt.html +3265 -0
- package/dist/docs/classes/Media.html +3295 -0
- package/dist/docs/classes/Message.html +3713 -0
- package/dist/docs/classes/MessageBuilder.html +3280 -0
- package/dist/docs/classes/Participant.html +3517 -0
- package/dist/docs/classes/PushNotification.html +3232 -0
- package/dist/docs/classes/RestPaginator.html +3262 -0
- package/dist/docs/classes/UnsentMessage.html +3144 -0
- package/dist/docs/classes/User.html +3451 -0
- package/dist/docs/index.html +3387 -212
- package/dist/docs/interfaces/ClientOptions.html +3136 -0
- package/dist/docs/interfaces/ConversationState.html +3152 -0
- package/dist/docs/interfaces/CreateConversationOptions.html +3168 -0
- package/dist/docs/interfaces/LastMessage.html +3152 -0
- package/dist/docs/interfaces/Paginator.html +3243 -0
- package/dist/docs/interfaces/PushNotificationData.html +3168 -0
- package/dist/docs/interfaces/SendEmailOptions.html +3136 -0
- package/dist/docs/interfaces/SendMediaOptions.html +3169 -0
- package/dist/docs/modules.html +3418 -0
- package/dist/lib.d.ts +1944 -0
- package/dist/lib.js +7866 -0
- package/dist/lib.js.map +1 -0
- package/dist/post-install.js +29 -0
- package/dist/react-native.js +4031 -0
- package/dist/react-native.js.map +1 -0
- package/dist/twilio-conversations.js +40905 -0
- package/dist/twilio-conversations.min.js +156 -0
- package/package.json +59 -48
- package/.circleci/config.yml +0 -650
- package/.deepsource.toml +0 -6
- package/.env.example +0 -13
- package/browser/aggregateddeliveryreceipt.js +0 -152
- package/browser/client.js +0 -991
- package/browser/configuration.js +0 -80
- package/browser/conversation.js +0 -1826
- package/browser/data/conversations.js +0 -665
- package/browser/data/messages.js +0 -522
- package/browser/data/participants.js +0 -411
- package/browser/data/users.js +0 -281
- package/browser/detaileddeliveryreceipt.js +0 -44
- package/browser/index.js +0 -4
- package/browser/interfaces/limits.js +0 -3
- package/browser/interfaces/notificationtypes.js +0 -21
- package/browser/interfaces/paginator.js +0 -53
- package/browser/interfaces/responsecodes.js +0 -20
- package/browser/interfaces/transport.js +0 -3
- package/browser/logger.js +0 -141
- package/browser/media.js +0 -198
- package/browser/message.js +0 -685
- package/browser/participant.js +0 -415
- package/browser/pushnotification.js +0 -49
- package/browser/restpaginator.js +0 -74
- package/browser/services/network.js +0 -223
- package/browser/services/readhorizon.js +0 -181
- package/browser/services/typingindicator.js +0 -142
- package/browser/session.js +0 -505
- package/browser/sessionerror.js +0 -93
- package/browser/sri.json +0 -1
- package/browser/synclist.js +0 -90
- package/browser/synclistdescriptor.js +0 -29
- package/browser/syncpaginator.js +0 -63
- package/browser/user.js +0 -431
- package/browser/util/deferred.js +0 -56
- package/browser/util/index.js +0 -108
- package/dist/@twilio/conversations.js +0 -35565
- package/dist/@twilio/conversations.min.js +0 -204
- package/dist/docs/AggregatedDeliveryReceipt.html +0 -948
- package/dist/docs/Client.html +0 -5075
- package/dist/docs/Conversation.html +0 -6018
- package/dist/docs/DetailedDeliveryReceipt.html +0 -641
- package/dist/docs/Media.html +0 -694
- package/dist/docs/Message.html +0 -1934
- package/dist/docs/Paginator.html +0 -605
- package/dist/docs/Participant.html +0 -1510
- package/dist/docs/PushNotification.html +0 -836
- package/dist/docs/SessionError.html +0 -379
- package/dist/docs/User.html +0 -1315
- package/dist/docs/classes.list.html +0 -4431
- package/dist/docs/fonts/glyphicons-halflings-regular.eot +0 -0
- package/dist/docs/fonts/glyphicons-halflings-regular.svg +0 -288
- package/dist/docs/fonts/glyphicons-halflings-regular.ttf +0 -0
- package/dist/docs/fonts/glyphicons-halflings-regular.woff +0 -0
- package/dist/docs/fonts/glyphicons-halflings-regular.woff2 +0 -0
- package/dist/docs/img/glyphicons-halflings-white.png +0 -0
- package/dist/docs/img/glyphicons-halflings.png +0 -0
- package/dist/docs/quicksearch.html +0 -31
- package/dist/docs/scripts/docstrap.lib.js +0 -11
- package/dist/docs/scripts/fulltext-search-ui.js +0 -89
- package/dist/docs/scripts/fulltext-search.js +0 -36
- package/dist/docs/scripts/lunr.min.js +0 -6
- package/dist/docs/scripts/prettify/Apache-License-2.0.txt +0 -202
- package/dist/docs/scripts/prettify/jquery.min.js +0 -6
- package/dist/docs/scripts/prettify/lang-css.js +0 -21
- package/dist/docs/scripts/prettify/prettify.js +0 -496
- package/dist/docs/scripts/sunlight.js +0 -1157
- package/dist/docs/scripts/toc.js +0 -203
- package/dist/docs/styles/darkstrap.css +0 -960
- package/dist/docs/styles/prettify-tomorrow.css +0 -132
- package/dist/docs/styles/site.cerulean.css +0 -7008
- package/dist/docs/styles/site.cosmo.css +0 -7061
- package/dist/docs/styles/site.cyborg.css +0 -7048
- package/dist/docs/styles/site.darkly.css +0 -7171
- package/dist/docs/styles/site.darkstrap.css +0 -5638
- package/dist/docs/styles/site.dibs-bootstrap.css +0 -5899
- package/dist/docs/styles/site.flatly.css +0 -7147
- package/dist/docs/styles/site.journal.css +0 -6973
- package/dist/docs/styles/site.lumen.css +0 -7298
- package/dist/docs/styles/site.paper.css +0 -7623
- package/dist/docs/styles/site.readable.css +0 -6997
- package/dist/docs/styles/site.sandstone.css +0 -7035
- package/dist/docs/styles/site.simplex.css +0 -7023
- package/dist/docs/styles/site.slate.css +0 -7343
- package/dist/docs/styles/site.spacelab.css +0 -7055
- package/dist/docs/styles/site.superhero.css +0 -7131
- package/dist/docs/styles/site.united.css +0 -6895
- package/dist/docs/styles/site.yeti.css +0 -7195
- package/dist/docs/styles/sunlight.dark.css +0 -345
- package/dist/docs/styles/sunlight.default.css +0 -344
- package/dist/sri.json +0 -1
- package/lib/aggregateddeliveryreceipt.d.ts +0 -98
- package/lib/aggregateddeliveryreceipt.js +0 -112
- package/lib/client.d.ts +0 -317
- package/lib/client.js +0 -633
- package/lib/configuration.d.ts +0 -21
- package/lib/configuration.js +0 -41
- package/lib/conversation.d.ts +0 -460
- package/lib/conversation.js +0 -940
- package/lib/data/conversations.d.ts +0 -57
- package/lib/data/conversations.js +0 -318
- package/lib/data/messages.d.ts +0 -75
- package/lib/data/messages.js +0 -208
- package/lib/data/participants.d.ts +0 -94
- package/lib/data/participants.js +0 -204
- package/lib/data/users.d.ts +0 -42
- package/lib/data/users.js +0 -113
- package/lib/detaileddeliveryreceipt.d.ts +0 -45
- package/lib/detaileddeliveryreceipt.js +0 -34
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -3
- package/lib/interfaces/limits.d.ts +0 -8
- package/lib/interfaces/limits.js +0 -2
- package/lib/interfaces/notificationtypes.d.ts +0 -8
- package/lib/interfaces/notificationtypes.js +0 -11
- package/lib/interfaces/paginator.d.ts +0 -52
- package/lib/interfaces/paginator.js +0 -28
- package/lib/interfaces/responsecodes.d.ts +0 -8
- package/lib/interfaces/responsecodes.js +0 -10
- package/lib/interfaces/transport.d.ts +0 -13
- package/lib/interfaces/transport.js +0 -2
- package/lib/logger.d.ts +0 -18
- package/lib/logger.js +0 -35
- package/lib/media.d.ts +0 -52
- package/lib/media.js +0 -69
- package/lib/message.d.ts +0 -136
- package/lib/message.js +0 -305
- package/lib/participant.d.ts +0 -142
- package/lib/participant.js +0 -219
- package/lib/pushnotification.d.ts +0 -48
- package/lib/pushnotification.js +0 -39
- package/lib/restpaginator.d.ts +0 -19
- package/lib/restpaginator.js +0 -36
- package/lib/services/network.d.ts +0 -22
- package/lib/services/network.js +0 -87
- package/lib/services/readhorizon.d.ts +0 -28
- package/lib/services/readhorizon.js +0 -112
- package/lib/services/typingindicator.d.ts +0 -50
- package/lib/services/typingindicator.js +0 -102
- package/lib/session.d.ts +0 -63
- package/lib/session.js +0 -213
- package/lib/sessionerror.d.ts +0 -12
- package/lib/sessionerror.js +0 -24
- package/lib/sri.json +0 -1
- package/lib/synclist.d.ts +0 -24
- package/lib/synclist.js +0 -28
- package/lib/synclistdescriptor.d.ts +0 -27
- package/lib/synclistdescriptor.js +0 -19
- package/lib/syncpaginator.d.ts +0 -22
- package/lib/syncpaginator.js +0 -37
- package/lib/user.d.ts +0 -98
- package/lib/user.js +0 -219
- package/lib/util/deferred.d.ts +0 -12
- package/lib/util/deferred.js +0 -22
- package/lib/util/index.d.ts +0 -28
- package/lib/util/index.js +0 -82
- package/tools/rtd-sdk-cdn-pin/.gitrepo +0 -12
- package/tools/rtd-sdk-cdn-pin/README.md +0 -54
- package/tools/rtd-sdk-cdn-pin/bintray-settings.xml.template +0 -16
- package/tools/rtd-sdk-cdn-pin/cdn-common/cdn-prepare.sh +0 -67
- package/tools/rtd-sdk-cdn-pin/cdn-pin-latest.sh +0 -19
- package/tools/rtd-sdk-cdn-pin/cdn-pin.sh +0 -19
- package/tools/rtd-sdk-cdn-pin/cdn-upload.sh +0 -13
- package/tools/rtd-sdk-cdn-pin/fetch/common/fetch-bintray-android.sh +0 -34
- package/tools/rtd-sdk-cdn-pin/fetch/common/fetch-npm.sh +0 -18
- package/tools/rtd-sdk-cdn-pin/fetch/twilio-chat-android.sh +0 -5
- package/tools/rtd-sdk-cdn-pin/fetch/twilio-chat-js.sh +0 -5
- package/tools/rtd-sdk-cdn-pin/fetch/twilio-conversations-android.sh +0 -6
- package/tools/rtd-sdk-cdn-pin/fetch/twilio-conversations-js.sh +0 -5
- package/tools/rtd-sdk-cdn-pin/fetch/twilio-sync-android.sh +0 -5
- package/tools/rtd-sdk-cdn-pin/fetch/twilio-sync-js.sh +0 -5
- package/tools/rtd-sdk-cdn-pin/fetch-artifact.sh +0 -26
- package/tools/sdk-release-tool/.gitrepo +0 -12
- package/tools/sdk-release-tool/Makefile +0 -49
- package/tools/sdk-release-tool/README.md +0 -275
- package/tools/sdk-release-tool/delete +0 -3
- package/tools/sdk-release-tool/download +0 -3
- package/tools/sdk-release-tool/get-cors +0 -3
- package/tools/sdk-release-tool/list +0 -3
- package/tools/sdk-release-tool/pin +0 -3
- package/tools/sdk-release-tool/pin-latest +0 -3
- package/tools/sdk-release-tool/requirements.txt +0 -4
- package/tools/sdk-release-tool/sdk-release-tool +0 -3
- package/tools/sdk-release-tool/sdk_release_tools/__init__.py +0 -0
- package/tools/sdk-release-tool/sdk_release_tools/__main__.py +0 -110
- package/tools/sdk-release-tool/sdk_release_tools/aws.py +0 -70
- package/tools/sdk-release-tool/sdk_release_tools/cli.py +0 -181
- package/tools/sdk-release-tool/sdk_release_tools/log.py +0 -24
- package/tools/sdk-release-tool/sdk_release_tools/ops.py +0 -295
- package/tools/sdk-release-tool/sdk_release_tools/rpm.py +0 -28
- package/tools/sdk-release-tool/sdk_release_tools/util.py +0 -186
- package/tools/sdk-release-tool/sdk_release_tools/versions.py +0 -362
- package/tools/sdk-release-tool/signal-sdk-js.json +0 -28
- package/tools/sdk-release-tool/tests/test_versions.py +0 -94
- package/tools/sdk-release-tool/twilio-accessmanager-android.json +0 -19
- package/tools/sdk-release-tool/twilio-accessmanager-ios.json +0 -26
- package/tools/sdk-release-tool/twilio-auth-ios.json +0 -29
- package/tools/sdk-release-tool/twilio-authenticator-ios.json +0 -29
- package/tools/sdk-release-tool/twilio-chat-android-2.json +0 -19
- package/tools/sdk-release-tool/twilio-chat-android.json +0 -22
- package/tools/sdk-release-tool/twilio-chat-ios.json +0 -26
- package/tools/sdk-release-tool/twilio-chat-js.json +0 -27
- package/tools/sdk-release-tool/twilio-client-android-aar.json +0 -22
- package/tools/sdk-release-tool/twilio-client-android.json +0 -22
- package/tools/sdk-release-tool/twilio-client-ios.json +0 -20
- package/tools/sdk-release-tool/twilio-client-js.json +0 -17
- package/tools/sdk-release-tool/twilio-client-sounds-js.json +0 -14
- package/tools/sdk-release-tool/twilio-common-android-maven.json +0 -16
- package/tools/sdk-release-tool/twilio-common-android.json +0 -22
- package/tools/sdk-release-tool/twilio-common-ios-rtc.json +0 -25
- package/tools/sdk-release-tool/twilio-common-ios.json +0 -25
- package/tools/sdk-release-tool/twilio-common-js.json +0 -19
- package/tools/sdk-release-tool/twilio-conversations-android.json +0 -22
- package/tools/sdk-release-tool/twilio-conversations-ios.json +0 -26
- package/tools/sdk-release-tool/twilio-conversations-js.json +0 -27
- package/tools/sdk-release-tool/twilio-flex-js.json +0 -20
- package/tools/sdk-release-tool/twilio-flex-webchat-js.json +0 -16
- package/tools/sdk-release-tool/twilio-frame-chat-android.json +0 -22
- package/tools/sdk-release-tool/twilio-frame-chat-ios.json +0 -23
- package/tools/sdk-release-tool/twilio-frame-chat-js.json +0 -23
- package/tools/sdk-release-tool/twilio-ip-messaging-android-maven.json +0 -16
- package/tools/sdk-release-tool/twilio-ip-messaging-android.json +0 -22
- package/tools/sdk-release-tool/twilio-ip-messaging-ios.json +0 -25
- package/tools/sdk-release-tool/twilio-ip-messaging-js.json +0 -21
- package/tools/sdk-release-tool/twilio-sync-android.json +0 -22
- package/tools/sdk-release-tool/twilio-sync-ios.json +0 -26
- package/tools/sdk-release-tool/twilio-sync-js.json +0 -39
- package/tools/sdk-release-tool/twilio-taskrouter-js.json +0 -17
- package/tools/sdk-release-tool/twilio-video-android.json +0 -22
- package/tools/sdk-release-tool/twilio-video-cpp-linux-cross-rootfs.json +0 -13
- package/tools/sdk-release-tool/twilio-video-cpp.json +0 -33
- package/tools/sdk-release-tool/twilio-video-ios.json +0 -25
- package/tools/sdk-release-tool/twilio-video-js.json +0 -19
- package/tools/sdk-release-tool/twilio-video-jsdocs.json +0 -14
- package/tools/sdk-release-tool/twilio-voice-android.json +0 -22
- package/tools/sdk-release-tool/twilio-voice-ios.json +0 -29
- package/tools/sdk-release-tool/unpin +0 -3
- package/tools/sdk-release-tool/unpin-latest +0 -3
- package/tools/sdk-release-tool/upload +0 -3
- package/twilio-chat.js.iml +0 -9
@@ -1,110 +0,0 @@
|
|
1
|
-
#!/usr/local/bin/python
|
2
|
-
from sdk_release_tools import log
|
3
|
-
from sdk_release_tools.aws import (get_routing_rules, load_routing_rules,
|
4
|
-
update_routing_rules)
|
5
|
-
from sdk_release_tools.cli import parse_args
|
6
|
-
from sdk_release_tools.util import (delete, download, get_cors, get_pinned_by,
|
7
|
-
get_versions, load_schema,
|
8
|
-
pin, pin_latest, unpin, unpin_latest,
|
9
|
-
upload, version_exists)
|
10
|
-
from sdk_release_tools.versions import parse_major_minor, parse_version
|
11
|
-
|
12
|
-
|
13
|
-
import sys
|
14
|
-
|
15
|
-
|
16
|
-
def main():
|
17
|
-
sys.argv[0] = 'sdk-release-tool'
|
18
|
-
args = parse_args()
|
19
|
-
action = args.action
|
20
|
-
realm = args.realm
|
21
|
-
|
22
|
-
if action == 'delete':
|
23
|
-
schema = load_schema(args.product)
|
24
|
-
version = parse_version(args.version)
|
25
|
-
if not version_exists(realm, schema, version):
|
26
|
-
raise Exception('Version {} does not exist'.format(version))
|
27
|
-
elif get_pinned_by(realm, schema, version) and not args.force:
|
28
|
-
raise Exception(('Cannot delete a pinned version; '
|
29
|
-
'use -f or --force to override'))
|
30
|
-
delete(realm, schema, version, args.dry_run, args.silent)
|
31
|
-
|
32
|
-
elif action == 'download':
|
33
|
-
schema = load_schema(args.product)
|
34
|
-
version = parse_version(args.version)
|
35
|
-
if not version_exists(realm, schema, args.version):
|
36
|
-
raise Exception('Version {} does not exist'.format(version))
|
37
|
-
download(realm, schema, version, args.destination, args.dry_run)
|
38
|
-
|
39
|
-
elif action == 'list':
|
40
|
-
schema = load_schema(args.product)
|
41
|
-
ordered_versions, _, latest = get_versions(realm, schema)
|
42
|
-
for version, major_minor in ordered_versions.items():
|
43
|
-
line = version
|
44
|
-
if major_minor:
|
45
|
-
line += ' <- {}'.format(major_minor)
|
46
|
-
if str(version) == str(latest):
|
47
|
-
line += ' (latest)'
|
48
|
-
log.log(line)
|
49
|
-
|
50
|
-
elif action == 'list-routing-rules':
|
51
|
-
get_routing_rules(realm)
|
52
|
-
return
|
53
|
-
|
54
|
-
elif action == 'pin':
|
55
|
-
schema = load_schema(args.product)
|
56
|
-
version = parse_version(args.version)
|
57
|
-
if not version_exists(realm, schema, version):
|
58
|
-
raise Exception('Version {} does not exist'.format(version))
|
59
|
-
elif (hasattr(version, 'pre_release') and version.pre_release and
|
60
|
-
not args.force):
|
61
|
-
raise Exception(('Cannot pin a pre-release version; '
|
62
|
-
'use -f or --force to override'))
|
63
|
-
pin(realm, schema, version, args.dry_run)
|
64
|
-
|
65
|
-
elif action == 'pin-latest':
|
66
|
-
schema = load_schema(args.product)
|
67
|
-
version = parse_version(args.version)
|
68
|
-
_, _, latest_version = get_versions(realm, schema)
|
69
|
-
if not version_exists(realm, schema, version):
|
70
|
-
raise Exception('Version {} does not exist'.format(version))
|
71
|
-
elif (hasattr(version, 'pre_release') and version.pre_release and
|
72
|
-
not args.force):
|
73
|
-
raise Exception(('Cannot pin a pre-release version; '
|
74
|
-
'use -f or --force to override'))
|
75
|
-
elif (latest_version and version < latest_version and not args.force):
|
76
|
-
raise Exception(('Cannot pin version earlier than latest as next latest; '
|
77
|
-
'use -f or --force to override'))
|
78
|
-
pin_latest(realm, schema, version, args.dry_run)
|
79
|
-
|
80
|
-
elif action == 'unpin':
|
81
|
-
schema = load_schema(args.product)
|
82
|
-
major_minor = parse_major_minor(args.version)
|
83
|
-
unpin(realm, schema, major_minor, args.dry_run)
|
84
|
-
|
85
|
-
elif action == 'unpin-latest':
|
86
|
-
schema = load_schema(args.product)
|
87
|
-
version = parse_version(args.version)
|
88
|
-
unpin_latest(realm, schema, version, args.dry_run)
|
89
|
-
|
90
|
-
elif action == 'update-routing-rules':
|
91
|
-
routing_rules_xml_file = args.xml
|
92
|
-
routing_rules = load_routing_rules(routing_rules_xml_file)
|
93
|
-
update_routing_rules(realm, routing_rules, args.dry_run)
|
94
|
-
return
|
95
|
-
|
96
|
-
elif action == 'get-cors':
|
97
|
-
get_cors(realm)
|
98
|
-
return
|
99
|
-
|
100
|
-
elif action == 'upload':
|
101
|
-
schema = load_schema(args.product)
|
102
|
-
version = parse_version(args.version)
|
103
|
-
if version_exists(realm, schema, version) and not args.force:
|
104
|
-
raise Exception(('Cannot overwrite an existing version; '
|
105
|
-
'use -f or --force to override'))
|
106
|
-
upload(realm, schema, version, args.source, args.dry_run)
|
107
|
-
|
108
|
-
|
109
|
-
if __name__ == '__main__':
|
110
|
-
main()
|
@@ -1,70 +0,0 @@
|
|
1
|
-
from boto.s3.connection import S3Connection, OrdinaryCallingFormat
|
2
|
-
|
3
|
-
import json
|
4
|
-
import os
|
5
|
-
|
6
|
-
|
7
|
-
__all__ = ['get_bucket', 'get_routing_rules', 'update_routing_rules']
|
8
|
-
|
9
|
-
|
10
|
-
def get_bucket(environment):
|
11
|
-
"""
|
12
|
-
Get the SDK S3 bucket for the given realm, e.g. media.twiliocdn.com. This
|
13
|
-
requires AWS credentials for AWS user cdn-sdki in either a JSON file at the
|
14
|
-
root of this project or in environment variables.
|
15
|
-
"""
|
16
|
-
def get_aws_creds(environment, aws_user):
|
17
|
-
if (os.getenv('AWS_' + environment.upper() + '_ACCESS_KEY_ID') and
|
18
|
-
os.getenv('AWS_' + environment.upper() + '_SECRET_ACCESS_KEY')):
|
19
|
-
return (os.getenv('AWS_' + environment.upper() + '_ACCESS_KEY_ID'),
|
20
|
-
os.getenv('AWS_' + environment.upper() + '_SECRET_ACCESS_KEY'))
|
21
|
-
aws_user_json_path = os.path.join(
|
22
|
-
os.path.dirname(os.path.realpath(__file__)),
|
23
|
-
'../{}.{}.json'.format(aws_user, environment))
|
24
|
-
with open(aws_user_json_path) as aws_user_json_file:
|
25
|
-
aws_user_json = json.loads(aws_user_json_file.read())
|
26
|
-
return (aws_user_json['AccessKeyId'],
|
27
|
-
aws_user_json['SecretAccessKey'])
|
28
|
-
raise (Exception(
|
29
|
-
'Unable to find AWS credentials for user {} in realm {}'.format(
|
30
|
-
aws_user, environment)))
|
31
|
-
|
32
|
-
def create_s3_conn(environment, aws_user):
|
33
|
-
key_id, secret_key = get_aws_creds(environment, aws_user)
|
34
|
-
return S3Connection(aws_access_key_id=key_id,
|
35
|
-
aws_secret_access_key=secret_key,
|
36
|
-
calling_format=OrdinaryCallingFormat())
|
37
|
-
|
38
|
-
conn = create_s3_conn(environment, 'cdn-sdki')
|
39
|
-
bucket_name_prefix = environment
|
40
|
-
if environment == 'prod':
|
41
|
-
bucket_name_prefix = 'media'
|
42
|
-
bucket_name = bucket_name_prefix + '.twiliocdn.com'
|
43
|
-
bucket = conn.get_bucket(bucket_name)
|
44
|
-
return bucket
|
45
|
-
|
46
|
-
|
47
|
-
def get_routing_rules(realm):
|
48
|
-
bucket = get_bucket(realm)
|
49
|
-
config = bucket.get_website_configuration_obj()
|
50
|
-
print(config.routing_rules.to_xml())
|
51
|
-
|
52
|
-
|
53
|
-
def load_routing_rules(routing_rules_xml_file_path):
|
54
|
-
class ToXML(object):
|
55
|
-
def __init__(self, xml):
|
56
|
-
self.xml = xml
|
57
|
-
|
58
|
-
def to_xml(self):
|
59
|
-
return self.xml
|
60
|
-
with open(routing_rules_xml_file_path) as routing_rules_xml_file:
|
61
|
-
return ToXML(routing_rules_xml_file.read())
|
62
|
-
|
63
|
-
|
64
|
-
def update_routing_rules(realm, routing_rules, dry_run=True):
|
65
|
-
bucket = get_bucket(realm)
|
66
|
-
config = bucket.get_website_configuration_obj()
|
67
|
-
if not dry_run:
|
68
|
-
bucket.configure_website(suffix=config.suffix,
|
69
|
-
error_key=config.error_key,
|
70
|
-
routing_rules=routing_rules)
|
@@ -1,181 +0,0 @@
|
|
1
|
-
from argparse import ArgumentParser
|
2
|
-
from sdk_release_tools import log
|
3
|
-
|
4
|
-
__all__ = ['parse_args']
|
5
|
-
|
6
|
-
|
7
|
-
def parse_realms(parser):
|
8
|
-
realm_grp = parser.add_mutually_exclusive_group()
|
9
|
-
for realm in ['dev', 'stage', 'prod']:
|
10
|
-
realm_grp.add_argument('--' + realm, action='store_const',
|
11
|
-
const=realm, dest='realm',
|
12
|
-
help=realm + ' realm flag')
|
13
|
-
return parser
|
14
|
-
|
15
|
-
|
16
|
-
def parse_dry_run(parser):
|
17
|
-
parser.add_argument('--dry-run', action='store_true', default=False,
|
18
|
-
dest='dry_run', help='do not perform any updates')
|
19
|
-
return parser
|
20
|
-
|
21
|
-
|
22
|
-
def parse_delete_action(parser):
|
23
|
-
parser = parser.add_parser('delete', help=('delete product artifacts at a '
|
24
|
-
'version number'))
|
25
|
-
parse_realms(parser)
|
26
|
-
parser.add_argument('product', type=str,
|
27
|
-
help='the product to delete')
|
28
|
-
parser.add_argument('version', type=str,
|
29
|
-
help='the version number to delete at, e.g. "1.2.3"')
|
30
|
-
parser.add_argument('-f', '--force', action='store_true', default=False,
|
31
|
-
help=('force a delete regardless of whether or not '
|
32
|
-
'the artifact is pinned by a major/minor '
|
33
|
-
'version'))
|
34
|
-
parser.add_argument('-s', '--silent', action='store_true', default=False, help=('skip user confirmation of files to be deleted'))
|
35
|
-
parse_dry_run(parser)
|
36
|
-
return parser
|
37
|
-
|
38
|
-
|
39
|
-
def parse_download_action(parser):
|
40
|
-
parser = parser.add_parser('download', help=('download product artifacts '
|
41
|
-
'from a version number'))
|
42
|
-
parse_realms(parser)
|
43
|
-
parser.add_argument('product', type=str, help='the product to download')
|
44
|
-
parser.add_argument('version', type=str,
|
45
|
-
help=('the version number to download from, e.g. '
|
46
|
-
'"1.2.3"; you may also pass a major/minor pair '
|
47
|
-
'to download the pinned version number, e.g. '
|
48
|
-
'"v1.0"'))
|
49
|
-
parser.add_argument('destination', type=str,
|
50
|
-
help=('the directory to download to'))
|
51
|
-
parse_dry_run(parser)
|
52
|
-
return parser
|
53
|
-
|
54
|
-
|
55
|
-
def parse_list_action(parser):
|
56
|
-
parser = parser.add_parser('list', help=('list the version numbers of '
|
57
|
-
'uploaded product artifacts and '
|
58
|
-
'any pinned major/minor pairs'))
|
59
|
-
parse_realms(parser)
|
60
|
-
parser.add_argument('product', type=str, help='the product to list')
|
61
|
-
return parser
|
62
|
-
|
63
|
-
|
64
|
-
def parse_list_routing_rules_action(parser):
|
65
|
-
parser = parser.add_parser('list-routing-rules',
|
66
|
-
help=('list Routing Rules XML'))
|
67
|
-
parse_realms(parser)
|
68
|
-
return parser
|
69
|
-
|
70
|
-
|
71
|
-
def parse_pin_action(parser):
|
72
|
-
parser = parser.add_parser('pin', help=('pin a major/minor pair to a '
|
73
|
-
'version number'))
|
74
|
-
parse_realms(parser)
|
75
|
-
parser.add_argument('product', type=str, help='the product to pin')
|
76
|
-
parser.add_argument('version', type=str,
|
77
|
-
help='the version number to pin, e.g. "1.2.3"')
|
78
|
-
parser.add_argument('-f', '--force', action='store_true', default=False,
|
79
|
-
help=('force a pin regardless of whether or not the '
|
80
|
-
'version is a pre-release version'))
|
81
|
-
parse_dry_run(parser)
|
82
|
-
return parser
|
83
|
-
|
84
|
-
|
85
|
-
def parse_pin_latest_action(parser):
|
86
|
-
parser = parser.add_parser('pin-latest',
|
87
|
-
help=('pin "latest" to a version number'))
|
88
|
-
parse_realms(parser)
|
89
|
-
parser.add_argument('product', type=str, help='the product to pin')
|
90
|
-
parser.add_argument('version', type=str,
|
91
|
-
help='the version number to pin, e.g. "1.2.3"')
|
92
|
-
parser.add_argument('-f', '--force', action='store_true', default=False,
|
93
|
-
help=('force a pin regardless of whether or not the '
|
94
|
-
'version is a pre-release version'))
|
95
|
-
parse_dry_run(parser)
|
96
|
-
return parser
|
97
|
-
|
98
|
-
|
99
|
-
def parse_unpin_action(parser):
|
100
|
-
parser = parser.add_parser('unpin', help=('unpin a major/minor pair from '
|
101
|
-
'a version number'))
|
102
|
-
parse_realms(parser)
|
103
|
-
parser.add_argument('product', type=str, help='the product to unpin')
|
104
|
-
parser.add_argument('version', type=str,
|
105
|
-
help='the major/minor pair to unpin, e.g. "v1.2"')
|
106
|
-
parse_dry_run(parser)
|
107
|
-
return parser
|
108
|
-
|
109
|
-
|
110
|
-
def parse_unpin_latest_action(parser):
|
111
|
-
parser = parser.add_parser('unpin-latest',
|
112
|
-
help=('unpin "latest" from a version number'))
|
113
|
-
parse_realms(parser)
|
114
|
-
parser.add_argument('product', type=str, help='the product to unpin')
|
115
|
-
parser.add_argument('version', type=str,
|
116
|
-
help='the version number to unpin, e.g. "1.2.3"')
|
117
|
-
parse_dry_run(parser)
|
118
|
-
return parser
|
119
|
-
|
120
|
-
|
121
|
-
def parse_upload_action(parser):
|
122
|
-
parser = parser.add_parser('upload', help=('upload product artifacts to '
|
123
|
-
'a version number'))
|
124
|
-
parse_realms(parser)
|
125
|
-
parser.add_argument('product', type=str, help='the product to upload')
|
126
|
-
parser.add_argument('version', type=str,
|
127
|
-
help='the version number to upload to, e.g. "1.2.3"')
|
128
|
-
parser.add_argument('source', type=str,
|
129
|
-
help='a directory or RPM containing the artifacts')
|
130
|
-
parser.add_argument('-f', '--force', action='store_true', default=False,
|
131
|
-
help=('force an upload regardless of whether or not '
|
132
|
-
'the artifact already exists'))
|
133
|
-
parse_dry_run(parser)
|
134
|
-
return parser
|
135
|
-
|
136
|
-
def parse_get_cors_action(parser):
|
137
|
-
parser = parser.add_parser('get-cors',
|
138
|
-
help=('Get the cors settings for the realm'))
|
139
|
-
parse_realms(parser)
|
140
|
-
return parser
|
141
|
-
|
142
|
-
|
143
|
-
def parse_update_routing_rules_action(parser):
|
144
|
-
parser = parser.add_parser('update-routing-rules',
|
145
|
-
help=('manually update Routing Rules '
|
146
|
-
'(dangerous)'))
|
147
|
-
parse_realms(parser)
|
148
|
-
parser.add_argument('xml', type=str,
|
149
|
-
help=('the Routing Rules XML file'))
|
150
|
-
parse_dry_run(parser)
|
151
|
-
return parser
|
152
|
-
|
153
|
-
|
154
|
-
def parse_args():
|
155
|
-
parser = ArgumentParser(description=('Manage Twilio SDK releases on the '
|
156
|
-
'CDN'))
|
157
|
-
|
158
|
-
action_parser = parser.add_subparsers(help='sub-command help',
|
159
|
-
dest='action')
|
160
|
-
parse_delete_action(action_parser)
|
161
|
-
parse_download_action(action_parser)
|
162
|
-
parse_list_action(action_parser)
|
163
|
-
parse_list_routing_rules_action(action_parser)
|
164
|
-
parse_pin_action(action_parser)
|
165
|
-
parse_pin_latest_action(action_parser)
|
166
|
-
parse_unpin_action(action_parser)
|
167
|
-
parse_unpin_latest_action(action_parser)
|
168
|
-
parse_upload_action(action_parser)
|
169
|
-
parse_get_cors_action(action_parser)
|
170
|
-
parse_update_routing_rules_action(action_parser)
|
171
|
-
|
172
|
-
args = parser.parse_args()
|
173
|
-
# if parser.has_errors:
|
174
|
-
# parser.handle_error()
|
175
|
-
if not hasattr(args, 'realm') or not args.realm:
|
176
|
-
args.realm = 'dev'
|
177
|
-
log.warn(' No realm specified, assuming dev')
|
178
|
-
if not args.action:
|
179
|
-
args.action = 'list'
|
180
|
-
|
181
|
-
return args
|
@@ -1,24 +0,0 @@
|
|
1
|
-
from clint.textui import colored
|
2
|
-
|
3
|
-
import sys
|
4
|
-
|
5
|
-
|
6
|
-
def debug(message):
|
7
|
-
print(colored.green(message))
|
8
|
-
|
9
|
-
|
10
|
-
def error(message):
|
11
|
-
print(colored.red(message))
|
12
|
-
sys.exit(1)
|
13
|
-
|
14
|
-
|
15
|
-
def info(message):
|
16
|
-
print(colored.blue(message))
|
17
|
-
|
18
|
-
|
19
|
-
def log(message):
|
20
|
-
print(message)
|
21
|
-
|
22
|
-
|
23
|
-
def warn(message):
|
24
|
-
print(colored.yellow(message))
|
@@ -1,295 +0,0 @@
|
|
1
|
-
from boto.s3.key import Key
|
2
|
-
from sdk_release_tools import log
|
3
|
-
from sdk_release_tools.versions import parse_major_minor
|
4
|
-
|
5
|
-
import os
|
6
|
-
|
7
|
-
__all__ = ['Delete', 'Download', 'Pin', 'Unpin', 'Upload', 'delete',
|
8
|
-
'download', 'pin', 'unpin', 'upload']
|
9
|
-
|
10
|
-
|
11
|
-
def absolute(root):
|
12
|
-
if not os.path.isabs(root):
|
13
|
-
root = os.path.join(os.getcwd(), root)
|
14
|
-
return root
|
15
|
-
|
16
|
-
|
17
|
-
class Context(object):
|
18
|
-
def __init__(self, root=None, variables=None, bucket=None, dry_run=True, silent=False,
|
19
|
-
copy_on_pin=False):
|
20
|
-
self.root = root
|
21
|
-
self.variables = variables or {}
|
22
|
-
self.bucket = bucket
|
23
|
-
self.rules = (bucket.get_website_configuration_obj().routing_rules if
|
24
|
-
bucket else None)
|
25
|
-
self.dry_run = dry_run
|
26
|
-
self.silent = silent
|
27
|
-
self.copy_on_pin = copy_on_pin
|
28
|
-
|
29
|
-
def absolute(self, key):
|
30
|
-
"""
|
31
|
-
Get the absolute path to a key prepended by this Context's root, and
|
32
|
-
interpolate any variables.
|
33
|
-
"""
|
34
|
-
path = self.relative(key)
|
35
|
-
if self.root:
|
36
|
-
path = os.path.join(self.root, path)
|
37
|
-
return absolute(path)
|
38
|
-
|
39
|
-
def relative(self, key):
|
40
|
-
"""
|
41
|
-
Get the relative path to a key, and interpolate any variables.
|
42
|
-
"""
|
43
|
-
return key.format(**self.variables)
|
44
|
-
|
45
|
-
|
46
|
-
class Ops(object):
|
47
|
-
def __init__(self, tree):
|
48
|
-
self.tree = tree
|
49
|
-
|
50
|
-
def _fold(self, context, tree=None):
|
51
|
-
tree = tree or self.tree
|
52
|
-
for key, value in tree.items():
|
53
|
-
context = self._op(key, value, context)
|
54
|
-
return context
|
55
|
-
|
56
|
-
def _op(self, key, value, context):
|
57
|
-
if key.endswith('/'):
|
58
|
-
return self._op_dir(key, value, context)
|
59
|
-
return self._op_file(key, value, context)
|
60
|
-
|
61
|
-
def _op_dir(self, key, value, context):
|
62
|
-
return context
|
63
|
-
|
64
|
-
def _op_file(self, key, value, context):
|
65
|
-
return context
|
66
|
-
|
67
|
-
def run(self, context):
|
68
|
-
return self._fold(context)
|
69
|
-
|
70
|
-
|
71
|
-
class Delete(Ops):
|
72
|
-
def _op_dir(self, key, value, context):
|
73
|
-
src = context.relative(value)
|
74
|
-
for sub_key in context.bucket.list(src):
|
75
|
-
context = self._op_file(sub_key.name, sub_key.name, context)
|
76
|
-
return context
|
77
|
-
|
78
|
-
def _op_file(self, key, value, context):
|
79
|
-
src = context.relative(value)
|
80
|
-
|
81
|
-
if not context.silent:
|
82
|
-
response = raw_input("Confirm deletion of " + src + " [y/n]: ").lower()
|
83
|
-
if response == "yes" or response == "y":
|
84
|
-
log.log(" Continuing deletion of: " + src + "\n")
|
85
|
-
self._delete_file(src, context)
|
86
|
-
else:
|
87
|
-
log.log(" Skipping, " + src + " will be protected.\n")
|
88
|
-
else:
|
89
|
-
log.log(src)
|
90
|
-
self._delete_file(src,context)
|
91
|
-
return context
|
92
|
-
|
93
|
-
def _delete_file(self, src, context):
|
94
|
-
src_key = context.bucket.get_key(src)
|
95
|
-
if not src_key:
|
96
|
-
log.warn(' Key {} does not exist'.format(src))
|
97
|
-
|
98
|
-
if not context.dry_run and src_key:
|
99
|
-
context.bucket.delete_key(src)
|
100
|
-
log.log(" " + src + " deleted")
|
101
|
-
return context
|
102
|
-
|
103
|
-
|
104
|
-
class Download(Ops):
|
105
|
-
def _op_dir(self, key, value, context):
|
106
|
-
src = context.relative(value)
|
107
|
-
for sub_key in context.bucket.list(src):
|
108
|
-
context = self._op_file(
|
109
|
-
os.path.join(key, sub_key.name[len(src):]), sub_key.name,
|
110
|
-
context)
|
111
|
-
return context
|
112
|
-
|
113
|
-
def _op_file(self, key, value, context):
|
114
|
-
src = context.relative(value)
|
115
|
-
dst = context.absolute(key)
|
116
|
-
log.log('{} -> {}'.format(src, dst))
|
117
|
-
|
118
|
-
src_key = context.bucket.get_key(src)
|
119
|
-
if not src_key:
|
120
|
-
log.error(' Key {} does not exist'.format(src))
|
121
|
-
|
122
|
-
if not context.dry_run and src_key:
|
123
|
-
dst_dir = os.path.dirname(dst)
|
124
|
-
try:
|
125
|
-
os.makedirs(dst_dir)
|
126
|
-
except:
|
127
|
-
pass
|
128
|
-
src_key.get_contents_to_filename(dst)
|
129
|
-
|
130
|
-
return context
|
131
|
-
|
132
|
-
|
133
|
-
def reconfigure_website(bucket, rules):
|
134
|
-
config = bucket.get_website_configuration_obj()
|
135
|
-
bucket.configure_website(suffix=config.suffix, error_key=config.error_key,
|
136
|
-
routing_rules=rules)
|
137
|
-
|
138
|
-
|
139
|
-
class Pin(Ops):
|
140
|
-
def _op(self, key, value, context):
|
141
|
-
src = context.relative(key)
|
142
|
-
dst = context.relative(value)
|
143
|
-
log.log('{} -> {}'.format(src, dst))
|
144
|
-
|
145
|
-
# Delete any previous RoutingRules. We have to use S3 Key redirects.
|
146
|
-
for rule in list(context.rules):
|
147
|
-
key_prefix = rule.condition.key_prefix
|
148
|
-
if not src.startswith(key_prefix):
|
149
|
-
continue
|
150
|
-
|
151
|
-
replace_key_prefix = rule.redirect.replace_key_prefix
|
152
|
-
|
153
|
-
try:
|
154
|
-
major_minor = parse_major_minor(
|
155
|
-
os.path.split(key_prefix.rstrip('/'))[1])
|
156
|
-
except:
|
157
|
-
continue
|
158
|
-
|
159
|
-
if (major_minor != parse_major_minor(
|
160
|
-
'{major}.{minor}'.format(**context.variables))):
|
161
|
-
continue
|
162
|
-
|
163
|
-
context.rules.remove(rule)
|
164
|
-
|
165
|
-
log.warn(' Deleting RoutingRule that pointed to {}'.format(
|
166
|
-
replace_key_prefix))
|
167
|
-
|
168
|
-
# Create S3 Key redirect.
|
169
|
-
src_key = context.bucket.get_key(src)
|
170
|
-
if not src_key:
|
171
|
-
log.log(' Creating S3 Key redirect')
|
172
|
-
else:
|
173
|
-
existing_redirect = src_key.get_redirect()
|
174
|
-
log.warn(' Updating S3 Key redirect that pointed to {}'.format(
|
175
|
-
existing_redirect))
|
176
|
-
|
177
|
-
if not context.dry_run:
|
178
|
-
if not src_key:
|
179
|
-
src_key = Key(context.bucket)
|
180
|
-
src_key.key = src
|
181
|
-
src_key.set_redirect('/' + dst.lstrip('/'), headers={
|
182
|
-
'Cache-Control': 'max-age=0, no-cache, no-store'
|
183
|
-
})
|
184
|
-
|
185
|
-
return context
|
186
|
-
|
187
|
-
def run(self, context):
|
188
|
-
context = super(Pin, self).run(context)
|
189
|
-
if not context.dry_run:
|
190
|
-
reconfigure_website(context.bucket, context.rules)
|
191
|
-
return context
|
192
|
-
|
193
|
-
|
194
|
-
class Unpin(Ops):
|
195
|
-
def _op(self, key, value, context):
|
196
|
-
src = context.relative(key)
|
197
|
-
dst = context.relative(value)
|
198
|
-
log.log('{} -> {}'.format(src, dst))
|
199
|
-
|
200
|
-
found = False
|
201
|
-
|
202
|
-
# Delete any RoutingRules.
|
203
|
-
for rule in list(context.rules):
|
204
|
-
key_prefix = rule.condition.key_prefix
|
205
|
-
if not src.startswith(key_prefix):
|
206
|
-
continue
|
207
|
-
|
208
|
-
replace_key_prefix = rule.redirect.replace_key_prefix
|
209
|
-
|
210
|
-
try:
|
211
|
-
major_minor = parse_major_minor(
|
212
|
-
os.path.split(key_prefix.rstrip('/'))[1])
|
213
|
-
except:
|
214
|
-
continue
|
215
|
-
|
216
|
-
if (major_minor != parse_major_minor(
|
217
|
-
'{major}.{minor}'.format(**context.variables))):
|
218
|
-
continue
|
219
|
-
|
220
|
-
found = True
|
221
|
-
context.rules.remove(rule)
|
222
|
-
log.warn(' Deleting RoutingRule that pointed to {}'.format(
|
223
|
-
replace_key_prefix))
|
224
|
-
|
225
|
-
# Delete any S3 Key redirects.
|
226
|
-
src_key = context.bucket.get_key(src)
|
227
|
-
if src_key:
|
228
|
-
found = True
|
229
|
-
if not context.dry_run:
|
230
|
-
context.bucket.delete_key(src)
|
231
|
-
|
232
|
-
if not found:
|
233
|
-
log.warn(' Redirect {} does not exist'.format(src))
|
234
|
-
|
235
|
-
return context
|
236
|
-
|
237
|
-
def run(self, context):
|
238
|
-
context = super(Unpin, self).run(context)
|
239
|
-
if not context.dry_run:
|
240
|
-
reconfigure_website(context.bucket, context.rules)
|
241
|
-
return context
|
242
|
-
|
243
|
-
|
244
|
-
class Upload(Ops):
|
245
|
-
def _op_dir(self, key, value, context):
|
246
|
-
srcdir = context.absolute(key)
|
247
|
-
|
248
|
-
for path, _, srcs in os.walk(srcdir):
|
249
|
-
for src in srcs:
|
250
|
-
sub_path = path[len(context.absolute(key)):]
|
251
|
-
sub_key = os.path.join(key, sub_path, src)
|
252
|
-
sub_value = os.path.join(value, sub_path, src)
|
253
|
-
context = self._op_file(sub_key, sub_value, context)
|
254
|
-
|
255
|
-
return context
|
256
|
-
|
257
|
-
def _op_file(self, key, value, context):
|
258
|
-
src = context.absolute(key)
|
259
|
-
dst = context.relative(value)
|
260
|
-
log.log('{} -> {}'.format(src, dst))
|
261
|
-
|
262
|
-
dst_key = context.bucket.get_key(dst)
|
263
|
-
if dst_key:
|
264
|
-
log.warn(' Updating Key')
|
265
|
-
|
266
|
-
if not context.dry_run:
|
267
|
-
if not dst_key:
|
268
|
-
dst_key = Key(context.bucket)
|
269
|
-
dst_key.key = dst
|
270
|
-
dst_key.set_contents_from_filename(src, headers={
|
271
|
-
'Cache-Control': 'max-age=315360000',
|
272
|
-
'Expires': 'Thu, 31 Dec 2037 23:55:55 GMT'
|
273
|
-
})
|
274
|
-
|
275
|
-
return context
|
276
|
-
|
277
|
-
|
278
|
-
def delete(tree, **kwargs):
|
279
|
-
return Delete(tree).run(Context(**kwargs))
|
280
|
-
|
281
|
-
|
282
|
-
def download(tree, **kwargs):
|
283
|
-
return Download(tree).run(Context(**kwargs))
|
284
|
-
|
285
|
-
|
286
|
-
def pin(tree, **kwargs):
|
287
|
-
return Pin(tree).run(Context(**kwargs))
|
288
|
-
|
289
|
-
|
290
|
-
def unpin(tree, **kwargs):
|
291
|
-
return Unpin(tree).run(Context(**kwargs))
|
292
|
-
|
293
|
-
|
294
|
-
def upload(tree, **kwargs):
|
295
|
-
return Upload(tree).run(Context(**kwargs))
|